How to cycle 3 images on a rect button?

2019-09-19 03:18发布

问题:

Just started learning Python/Pygame watching videos and reading to learn . I would like to see a example code to cycle 3 images on a rect button from a mouse press and return to first image. Really I want the pictures to be three options and return different results. So be able to cycle image be able to select option and option when triggered execute choice.

回答1:

Example

import pygame

pygame.init()

screen = pygame.display.set_mode((300,200))

# three images 
images = [
    pygame.Surface((100,100)),    
    pygame.Surface((100,100)),    
    pygame.Surface((100,100)),    
]

images[0].fill((255,0,0))
images[1].fill((0,255,0))
images[2].fill((0,0,255))

# image size and position    
images_rect = images[0].get_rect()

# starting index
index = 0

running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            # check mouse position and pressed button
            if event.button == 1 and images_rect.collidepoint(event.pos):
                # cycle index
                index = (index+1) % 3

    screen.blit(images[index], images_rect)
    pygame.display.flip()

pygame.quit()

Example using class - to create many buttons

import pygame

class Button(object):

    def __init__(self, position, size):
        self._images = [
            pygame.Surface(size),    
            pygame.Surface(size),    
            pygame.Surface(size),    
        ]

        self._images[0].fill((255,0,0))
        self._images[1].fill((0,255,0))
        self._images[2].fill((0,0,255))

        self._rect = pygame.Rect(position, size)

        self._index = 0

    def draw(self, screen):
        screen.blit(self._images[self._index], self._rect)

    def event_handler(self, event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1 and self._rect.collidepoint(event.pos):
                self._index = (self._index+1) % 3


pygame.init()

screen = pygame.display.set_mode((320,110))

button1 = Button((5, 5), (100, 100))
button2 = Button((110, 5), (100, 100))
button3 = Button((215, 5), (100, 100))

running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        button1.event_handler(event)
        button2.event_handler(event)
        button3.event_handler(event)

    button1.draw(screen)
    button2.draw(screen)
    button3.draw(screen)

    pygame.display.flip()

pygame.quit()



回答2:

If I understood the question correctly, you need a single button that changes the look every time you click on it, and changes its relative function accordingly.

You should be able to solve your problem by creating a class that takes two list and a counter

1) list of images

2) list of functions

3) the counter tells you which image/function is selected.

The functions needs to be built in the class, but you can provide the image that you want in the class argument (actually, you could pass them as arguments, but I don't think is worth it).

Here is the code, I commented some lines with their intended meaning (in line comments)

import pygame
import sys
pygame.init()

width = 600
height = 400

screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("Magic Buttons")
background = pygame.Surface(screen.get_size())

clock = pygame.time.Clock()

class Buttons:
    def __init__(self, posX, posY, image1, image2, image3):
        self.image_list = [image1, image2, image3] # static list of images 
        self.function_list = [self.button_function_1,self.button_function_2,self.button_function_3 ]
        self.rect_position = (posX, posY) # this is a tuple to identify the upper left corner of the rectangle of the image
        self.button_type = 0 # initial value of the button, both for the function and the image
        self.image = pygame.image.load(self.image_list[0]) #default image, index number 0 of image_list
        self.rect = pygame.Rect(posX, posY, self.image.get_width(), self.image.get_height()) # create a rectangle object same size of the images

    def check(self, pos):
        if self.rect.collidepoint(pos) ==True:
            self.change_button()
        else:
            pass

    def change_button(self):
        self.button_type = (self.button_type +1)%3
        self.image = pygame.image.load(self.image_list[self.button_type ]) # load the image relative to button_type
        self.function_list[self.button_type -1]() # execute the function relative to the new value of button_type
        self.draw_button()

    def draw_button(self):
        screen.blit(self.image, self.rect_position) # blit the new button image

    def button_function_1(self):
        print ("function 1 in action")

    def button_function_2(self):
        print ("function 2 in action")

    def button_function_3(self):
        print ("function 3 in action")


multibutton = Buttons(100,100,"button1.png","button2.png","button3.png") # create an istance of the button in the x=100, y = 100, with the three image button



while True:
    background.fill((0,0,0))

    clock.tick(30)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.MOUSEBUTTONUP:
            pos = pygame.mouse.get_pos() # fetch the position of the mouse
            multibutton.check(pos) # check if the mouse is on the button

    multibutton.draw_button()

    pygame.display.flip()


标签: pygame