Home > Net >  How to alternate showing object in different position at different speed with pygame
How to alternate showing object in different position at different speed with pygame

Time:10-15

I'm new using pygame. When I run the code I have a GUI with a ball fixed on the left side of the screen. I also have 10 different buttons that represents different speeds. When I click one of speed button I want to change ball position from left to right and viceversa (without moving the ball, just disappaer and appear in the other position) in a loop until I press the button "STOP" or I change the speed. My two problems are: when the code starts my ball is alternating at high speed instead of the speed is 0 (I can't understand why) and the second problem is that when the ball is moving the script doesn't accept other input button. If a press for a long time the button or if a quickly press it more then 30 times, then it receive the command (it's useful)

Here the code:

WHITE = (255, 255, 255)
BLUE = (83, 175, 190)
#initial set up
pygame.init()
size = width, height = 1500, 650
background = WHITE
screen = pygame.display.set_mode(size)
pygame.display.set_caption("nuovo alternato")
#circle = pygame.Surface((200, 300))
screen.fill(WHITE)
#drawing a circle
pygame.draw.circle(screen, (83, 175, 190), (105, 105), 100, 0)
pygame.draw.circle(screen, (255, 255, 255), (1395, 105), 100, 0)
counter = 0
speed=0
mainClock = pygame.time.Clock()
logo = pygame.image.load("C:\\...logodef.png").convert_alpha()
start = pygame.image.load("C:\\...startdef.png").convert_alpha()
stop = pygame.image.load("C:\\...stopdef.png").convert_alpha()
uno = pygame.image.load("C:\\...\\1.png").convert_alpha()
due = pygame.image.load("C:\\...\\2.png").convert_alpha()
tre = pygame.image.load("C:\\...\\3.png").convert_alpha()
quattro = pygame.image.load("C:\\...\\4.png").convert_alpha()
cinque = pygame.image.load("C:\\...\\5.png").convert_alpha()
sei = pygame.image.load("C:\\...\\6.png").convert_alpha()
sette = pygame.image.load("C:\\...\\7.png").convert_alpha()
otto = pygame.image.load("C:\\...\\8.png").convert_alpha()
nove = pygame.image.load("C:\\...\\9.png").convert_alpha()
zero = pygame.image.load("C:\\...\\0.png").convert_alpha()
class Button():
    def __init__(self, x, y, image, scale):
        width = image.get_width()
        height = image.get_height()
        self.image = pygame.transform.scale(image, (int(width * scale), int(height * scale)))
        self.rect = self.image.get_rect()
        self.rect.topleft = (x, y)
        self.clicked = False
    def draw(self):
        action = False
        pos = pygame.mouse.get_pos()
        if self.rect.collidepoint(pos):
            if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
                self.clicked = True
                action = True
        if pygame.mouse.get_pressed()[0] == 0:
            self.clicked = False               
        screen.blit(self.image, (self.rect.x, self.rect.y))
        return action
immagine = Button(500, 430, logo, 1)
buttonvel1 = Button(200, 250, uno, 1)
buttonvel2 = Button(350, 250, due, 1)
buttonvel3 = Button(500, 250, tre, 1)
buttonvel4 = Button(650, 250, quattro, 1)
buttonvel5 = Button(800, 250, cinque, 1)
buttonvel6 = Button(950, 250, sei, 1)
buttonvel7 = Button(1100, 250, sette, 1)
buttonvel8 = Button(1250, 250, otto, 1)
buttonvel9 = Button(1400, 250, nove, 1)
buttonvel0 = Button(50, 250, zero, 1)
buttonstart = Button(400, 350, start, 1)
buttonstop = Button(900, 350, stop, 1)
clock=pygame.time.Clock()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
    if counter % 2 == 0:
        fl_color = BLUE
        fl_color2 = WHITE
    else:
        fl_color = WHITE
        fl_color2 = BLUE
    pygame.draw.circle(screen, fl_color, (105, 105), 100, 0)
    pygame.draw.circle(screen, fl_color2, (1395, 105), 100, 0)
    pygame.display.flip()
    counter  = 1
    clock.tick(speed) 
    pygame.display.flip()
    pygame.display.update()
    pygame_widgets.update(event)
    screen.fill(background)
    immagine.draw()
    if buttonstart.draw() == True:
        speed = 1
        print("Click su START")
    if buttonstop.draw() == True:
        speed = 100
        print("Click su STOP")
    if buttonvel1.draw() == True:
        speed = 0.2
        print("Click su 1")
    if buttonvel2.draw() == True:
        speed = 0.4
        print("Click su 2")
    if buttonvel3.draw() == True:
        speed = 0.6 
        print("Click su 3")
    if buttonvel4.draw() == True:
        speed = 0.8
        print("Click su 4")
    if buttonvel5.draw() == True:
        speed = 1
        print("Click su 5")
    if buttonvel6.draw() == True:
        speed = 1.2   
        print("Click su 6")
    if buttonvel7.draw() == True:
        speed = 1.4
        print("Click su 7")
    if buttonvel8.draw() == True:
        speed = 1.6
        print("Click su 8")
    if buttonvel9.draw() == True:
        speed = 1.8     
        print("Click su 9") 
    if buttonvel0.draw() == True:
        speed = 0.1   
        print("Click su 0")

CodePudding user response:

You can solve your problem in two ways.

  1. Instead of increasing your value progressively like you are doing, create a timer and hard set your ball's position to the right or the left emplacement.

  2. You could have a bool global var like show_ball and you only draw your ball if show_ball:. You can now move your ball while it's hidden.


If you choose option one. Define your right and left emplacements :

RIGHT_EMPLACEMENT = (25, 25)
LEFT_EMPLACEMENT = (475, 25)

Create a blinking_speed var :

blinking_speed = 50

Then create a custom event and timer to go with it (put it to 0 if you don't want the ball to move at first) :

BLINK = pg.USEREVENT
pg.time.set_timer(BLINK, blinking_speed) # Or 0 if you wish

Then simply catch your BLINK event :

for evt in pg.event.get():
    if evt.type == BLINK:
        blink()

Finally you can manage your logic inside blink :

def blink():
    if ball_pos == right_emplacement:
        ball_pos = left_emplacement
    else:
        ball_pos = right_emplacement

Your button can just redefine your timer (it will override the previous timer):

blinking_speed = some_value
pg.time.set_timer(BLINK, blinking_speed)

If you go for the second option then just create a ball_speed var :

ball_speed = 50

Then your ball can move from direction * ball_speed direction is either 1 or -1 depending on if you are going right or left


Other points to consider : your draw function should only be responsible for drawing the button and nothing else.
See : SRP

Store all your buttons inside a list to simply / shorten your code

buttons = []

Happy programming

  • Related