Search code examples
pythonpygame

Player Not Falling After Thrown


VIDEO I'm working on a Pygame project where I have a player that can be thrown towards the pointed aiming dots when the space bar is clicekd. The throwing motion works as expected; however, I'm encountering an issue with the player not falling back down after being thrown like a bell shape. . Any suggestions or insights into what might be causing this issue would be greatly appreciated!

# Inside the main game loop
if keys[pygame.K_SPACE] and not player1.isThrown:
    player1.isThrown = True
    player1.throwCount = 0
    player1.angle = math.atan2(dot.y - player1.y, dot.x - player1.x) + math.pi / 2 

if player1.isThrown:
    throw_distance = player1.throwSpeed * player1.throwCount
    player1.y -= throw_distance * math.cos(player1.angle)  
    player1.x += throw_distance * math.sin(player1.angle) 
    player1.throwCount += 1


# Falling motion after the throw
if not player1.isThrown and player1.y < 400:
    fall_speed = 5
    player1.y += fall_speed

    if player1.y > 400:
        player1.y = 400

the full code


import pygame
import math

pygame.init()

window = pygame.display.set_mode((500, 500))

class Player:
    def __init__(self, x, y, height, width, color):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.color = color
        self.rect = pygame.Rect(x, y, height, width)
        self.isThrown = False
        self.throwCount = 0
        self.throwSpeed = 1
        self.angle = 0
        self.initial_throw_height = 50

    def draw(self):
        self.rect.topleft = (self.x, self.y)
        pygame.draw.rect(window, self.color, self.rect)

class Dot:
    def __init__(self, x, y, size, color, alpha):
        self.x = x
        self.y = y
        self.size = size
        self.color = color
        self.alpha = alpha

    def draw(self):
        pygame.draw.rect(window, (self.color[0], self.color[1], self.color[2], self.alpha), (self.x - self.size // 2, self.y - self.size // 2, self.size, self.size))

player1 = Player(50, 400, 50, 50, (55, 255, 255))
bottom1 = Player(0, 450, 550, 40, (145, 215, 15))

dots = [
    Dot(0, 0, 10, (255, 255, 255), 128),
    Dot(0, 0, 20, (255, 255, 255), 128),
    Dot(0, 0, 30, (255, 255, 255), 128),
    Dot(0, 0, 40, (255, 255, 255), 128),
    Dot(0, 0, 50, (255, 255, 255), 128)
]

prev_mouse_pos = (0, 0)

run = True
while run:
    pygame.time.delay(50)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()
    mouse_x, mouse_y = pygame.mouse.get_pos()

    for dot in dots:
        dot.x = player1.x + player1.width // 2 + (mouse_x - player1.x - player1.width // 2) * (dot.size / 25)
        dot.y = player1.y + player1.height // 2 + (mouse_y - player1.y - player1.height // 2) * (dot.size / 25)

    window.fill((28, 40, 51))

    for dot in dots:
        dot.draw()

    player1.draw()
    bottom1.draw()

    # Inside the main game loop
    if keys[pygame.K_SPACE] and not player1.isThrown:
        player1.isThrown = True
        player1.throwCount = 0
        player1.angle = math.atan2(dot.y - player1.y, dot.x - player1.x) + math.pi / 2 
    if player1.isThrown:
        throw_distance = player1.throwSpeed * player1.throwCount
        player1.y -= throw_distance * math.cos(player1.angle) 
        player1.x += throw_distance * math.sin(player1.angle)  
        player1.throwCount += 1

 

    # Falling motion after the throw
    if not player1.isThrown and player1.y < 400:
        fall_speed = 5
        player1.y += fall_speed

        if player1.y > 400:
            player1.y = 400

    pygame.display.update()

pygame.quit()


Solution

  • Increase the self.throwSpeed:

    self.throwSpeed = 10
    

    but do not increment the movement vector:

    throw_distance = player1.throwSpeed * player1.throwCount
    player1.throwCount += 1

    Falling is an accelerated movement, so the falling speed must be increased in each frame:

    fall_speed = 0
    run = True
    while run:
        # [...]
    
        if keys[pygame.K_SPACE] and not player1.isThrown:
            player1.isThrown = True
            player1.angle = math.atan2(dot.y - player1.y, dot.x - player1.x) + math.pi / 2 
            fall_speed = 0
    
        if player1.isThrown:
            player1.y -= player1.throwSpeed * math.cos(player1.angle) 
            player1.x += player1.throwSpeed * math.sin(player1.angle) 
            player1.y += fall_speed
            fall_speed += 0.5
            if player1.y > 400:
                player1.y = 400
                player1.isThrown = False
                fall_speed = 0
    
        pygame.display.update()