Elyctricity
Elyctricity

Reputation: 1

Speed logic for pygame game

I'm doing a final project for my coding class at school. I learnt from a tutorial online on how to use pygame by making pong. Then, I decided to create an Undertale battle system with the knowledge I had gained from learning how to make pong in pygame. I have come across an issue however, and its regarding the heart's speed.

Here is the code:

import pygame
import sys

# setup
pygame.init()
clock = pygame.time.Clock()

# main window
screen_width = 900
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Undertale')
icon = pygame.image.load('heart.png')
pygame.display.set_icon(icon)

# game rectangles
heart = pygame.image.load('heart.png')
DEFAULT_IMAGE_SIZE = (20, 20)
heart_img = pygame.transform.scale(heart, DEFAULT_IMAGE_SIZE)
battle_width = 10
battle_height = 200
middle_offset = 30
length = 200 + 2*battle_width
battle_left = pygame.Rect(screen_width/2 - 100, screen_height/2 + middle_offset, battle_width, battle_height)
battle_right = pygame.Rect(screen_width/2 + 100 + battle_width, screen_height/2 + 30, battle_width, battle_height)
battle_up = pygame.Rect(screen_width/2 - 100, screen_height/2 + middle_offset, length, battle_width)
battle_down = pygame.Rect(screen_width/2 - 100, screen_height/2 + middle_offset + battle_height, length, battle_width)

# colours
bg_color = pygame.Color(0, 0, 0)
red = (255, 0, 0)
white = (255, 255, 255)

# game vars
heart_x = screen_width/2
heart_y = screen_height/2 + middle_offset + battle_height/2 - 10
# Using half of Default Image Size Width
heart_speed_x = 0
heart_speed_y = 0
speed = 4

while True:
    # input handles
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                heart_speed_x -= speed
            if event.key == pygame.K_RIGHT:
                heart_speed_x += speed
            if event.key == pygame.K_UP:
                heart_speed_y -= speed
            if event.key == pygame.K_DOWN:
                heart_speed_y += speed
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                heart_speed_x += speed
            if event.key == pygame.K_RIGHT:
                heart_speed_x -= speed
            if event.key == pygame.K_UP:
                heart_speed_y += speed
            if event.key == pygame.K_DOWN:
                heart_speed_y -= speed

    # logic
    heart_x += heart_speed_x
    heart_y += heart_speed_y
    heart_rect = heart_img.get_rect(topleft=(heart_x, heart_y))
    if heart_rect.colliderect(battle_left) or heart_rect.colliderect(battle_right):
        heart_speed_x *= -1
    if heart_rect.colliderect(battle_up) or heart_rect.colliderect(battle_down):
        heart_speed_y *= -1

    # visuals
    screen.fill(bg_color)
    pygame.draw.rect(screen, white, battle_left)
    pygame.draw.rect(screen, white, battle_right)
    pygame.draw.rect(screen, white, battle_up)
    pygame.draw.rect(screen, white, battle_down)
    screen.blit(heart_img, (heart_x, heart_y))

    # window update
    pygame.display.flip()
    clock.tick(60)

The heart is the player. I want it to be able to move around inside the box, and I do not want it to come out, I want it to stay inside. I made it so that the heart image is a rectangle so that it can collide with the box. It worked, but the speed makes it so that the heart is constantly moving, I want it to stop whenever the KEYUP event occurs. And that's what I did, yet it refused to cooperate.

Upvotes: 0

Views: 177

Answers (1)

Elyctricity
Elyctricity

Reputation: 1

I figured out the solution:

heart_x += 0 - heart_speed_x

and

heart_y += 0 - heart_speed_y

The problem was that the either or both of the x and y position constantly changed after hitting the surface. This was because the speed of the variables stayed the same. So in the solution, I made it so that the x any y positions only change once once it conditionally checks for collision.

Upvotes: 0

Related Questions