[Python] Speed changing too much on a moving pygame object

Discussão em 'Python' iniciado por Stack, Agosto 25, 2025.

  1. Stack

    Stack Membro Participativo

    I am currently making a game in pygame where the player controls a ball that is constantly bouncing and has to pass through 2 moving platforms to reach the other side before going back. I am trying to make it so that the speed of the platforms changes depending on the score of the player, however, when the score goes from 12 to 13 or from 7 to 8, the speed jumps way more than the other changes.

    Here is my code:

    bounce.py:

    import pygame
    import sys
    from ball import Ball
    from Vplatform import Vplatform
    from scoreboard import Scorboard
    from time import time
    from menu import Menu

    class Bounce:
    def __init__(self):
    pygame.init()
    self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
    self.screen_rect = self.screen.get_rect()
    self.ball = Ball(self)
    self.bottom_bounce = 10
    self.bounces = [self.bottom_bounce]
    self.platspeed = 2
    self.platform1 = Vplatform(self, self.platspeed)
    self.platform2 = Vplatform(self, -self.platspeed)
    self.score = 10
    self.goal = 15
    self.start = time()
    self.scoreboard = Scorboard(self)
    self.bouncedr = False
    self.bouncedl = False
    self.win = False
    self.active = False
    self.lose = False
    self.menu = Menu(self)

    def reset(self):
    self.bottom_bounce = 10
    self.ball.rect.center = self.screen_rect.center
    self.ball.upspeed = 0
    self.ball.speed = 0
    self.score = 10
    self.platspeed = 2
    self.start = time()
    self.elapsed = 0
    self.win = False
    self.lose = False

    def run(self):
    while True:
    self.check_events()
    self.update_score()
    self.check_collisions()
    if self.active:
    self.ball.update()
    self.platform1.update()
    self.platform2.update()
    self.scoreboard.text()
    self.menu.text()
    self.update_screen()

    def update_screen(self):
    self.screen.fill((0,0,0))
    self.ball.draw()
    self.platform1.draw()
    self.platform2.draw()
    self.scoreboard.draw()
    if not self.active:
    self.menu.draw()
    pygame.display.flip()

    def check_events(self):
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    sys.exit()
    elif event.type == pygame.KEYDOWN:
    self.keydowns(event)
    elif event.type == pygame.KEYUP:
    self.keyups(event)
    elif event.type == pygame.MOUSEBUTTONDOWN:
    pos = pygame.mouse.get_pos()
    self.mouse(pos)

    def mouse(self, pos):
    if self.menu.p_rect.collidepoint(pos):
    self.active = True
    self.menu.control = False
    if self.win == True:
    self.reset()
    self.menu.control = -1
    if self.menu.c_rect.collidepoint(pos):
    self.menu.control *= -1

    def keydowns(self, event):
    if event.key == pygame.K_q:
    sys.exit()
    if event.key == pygame.K_p:
    self.active = False
    if self.active:
    if event.key == pygame.K_a:
    self.ball.lacel = True
    self.ball.speed += 0.5
    if event.key == pygame.K_d:
    self.ball.racel = True
    self.ball.speed -= 0.5
    if event.key == pygame.K_w:
    self.ball.speed = 0

    def keyups(self, event):
    if event.key == pygame.K_a:
    self.ball.lacel = False
    if event.key == pygame.K_d:
    self.ball.racel = False

    def check_collisions(self):
    if (self.ball.rect.y+100) >= self.screen_rect.height:
    self.ball.upspeed *= -0.999
    """self.ball.upspeed += self.bottom_bounce
    self.bottom_bounce *= 0.99"""
    if self.bottom_bounce <= 0.1:
    #self.bottom_bounce = 0
    self.ball.rect.y = self.screen_rect.height - 100
    self.ball.upspeed = 0
    if self.ball.rect.left <= self.screen_rect.left:
    self.ball.rect.left = self.screen_rect.left + 1
    self.left_bounce()
    if not self.bouncedl:
    self.score += 1
    self.bouncedl =True
    self.bouncedr = False
    if self.ball.rect.right >= self.screen_rect.right:
    self.right_bounce()
    if not self.bouncedr:
    self.score += 1
    self.bouncedr =True
    self.bouncedl = False
    self.plat_collides()

    def right_bounce(self):
    self.ball.rect.right = self.screen_rect.right - 1
    self.ball.speed *= -1

    def left_bounce(self):
    self.ball.rect.left = self.screen_rect.left + 1
    self.ball.speed *= -1

    def plat_collides(self):
    if self.ball.rect.colliderect(self.platform1.rect):
    if self.ball.rect.x > (self.platform1.rect.x+5):
    self.left_bounce()
    self.bouncedl =True
    self.bouncedr = False
    else:
    self.right_bounce()
    self.bouncedr =True
    self.bouncedl = False
    self.score -= 1
    if self.ball.rect.colliderect(self.platform2.rect):
    if self.ball.rect.x > (self.platform2.rect.x+5):
    self.left_bounce()
    else:
    self.right_bounce()
    self.score -= 1

    def update_score(self):
    if self.active:
    now = time()
    self.elapsed = now-self.start
    if self.score == self.goal:
    self.win = True
    self.lose = False
    self.active=False
    elif self.score == 0:
    self.win = False
    self.lose = True
    self.active = False
    self.reset()
    self.speed_scale()

    def speed_scale(self):
    if 1<=self.score<=15:
    self.platspeed = self.score*0.2



    ru = Bounce().run()


    vplatform.py:

    import pygame

    class Vplatform:
    def __init__(self, game, d):
    pygame.init()
    self.screen = game.screen
    self.screen_rect = game.screen_rect
    self.game = game
    self.image = pygame.image.load("images\wall.bmp")
    self.image = pygame.transform.scale(self.image, (50, 200))
    if d < 0:
    x = self.screen_rect.width/3
    else:
    x = (2*self.screen_rect.width)/3
    self.rect = self.image.get_rect()
    self.rect.x = x
    self.rect.y = self.screen_rect.height/3
    self.direct = d

    def draw(self):
    self.screen.blit(self.image, self.rect)

    def update(self):
    if self.direct < 0:
    self.direct = self.game.platspeed * -1
    else:
    self.direct = self.game.platspeed
    self.rect.y -= self.direct
    if self.rect.top <= self.screen_rect.top:
    self.rect.top = self.screen_rect.top
    self.direct *= -1
    if self.rect.bottom >= self.screen_rect.bottom:
    self.rect.bottom = self.screen_rect.bottom
    self.direct *= -1


    I have also tried to make the speed scale manual as an if ladder, and the same thing happened. I have tried print debugging by inserting a print(self.platspeed) into the speed_scale() function and the onlyvalues that it prints are the values for 12, 13, and 3.

    Can someone tell me why this happens?

    Continue reading...

Compartilhe esta Página