Problem with creating a pygame object inside a class

Question:

So this is the code that I created, it’s going to be a simple 2D game. I was trying to experiment with classes while making another game to make it more functional and organized. But the problem is that when I run the code and try to move the player in the main() function the position of the player doesn’t change when Im pressing the buttons.

import pygame as pg

#------------------------------------------------------------------------------------

# Colors

RED = (255,0,0)
GREEN = (0, 255, 0)
BLUE = (0,0,255)
WHITE = (255,255,255)
BLACK = (0,0,0)
#------------------------------------------------------------------------------------

# Constants

FPS = 60
WIDTH, HEIGHT = 1400, 900
P_VEL = 10
#------------------------------------------------------------------------------------

# Variables

#------------------------------------------------------------------------------------

# Objects

#------------------------------------------------------------------------------------

# Fonts

#------------------------------------------------------------------------------------

# Sprites

#------------------------------------------------------------------------------------

# Sounds

#------------------------------------------------------------------------------------
WINDOW = pg.display.set_mode((WIDTH,HEIGHT))
pg.display.set_caption("Game Project")

#------------------------------------------------------------------------------------
class Hero:
    def __init__(self, x_cord, y_cord, width, height):
        self.xc = x_cord
        self.yc = y_cord
        self.width = width
        self.height = height
        self.hero = pg.Rect(self.xc,self.yc,self.width,self.height)

    def player_movement(self, keys_pressed):
        if keys_pressed[pg.K_d]:
            self.xc += P_VEL
        if keys_pressed[pg.K_a]:
            self.xc -= P_VEL
        if keys_pressed[pg.K_w]:
            self.yc -= P_VEL
        if keys_pressed[pg.K_s]:
            self.yc += P_VEL
    
    def draw(self):
        pg.draw.rect(WINDOW, GREEN, self.hero)

player = Hero(500,400,40,60)

def gravis():
    WINDOW.fill(BLACK)
    player.draw()
    pg.display.update()

def main():
    clock = pg.time.Clock()
    run = True
    while run:
        clock.tick(FPS)
        for event in pg.event.get():
            if event.type == pg.QUIT:
                run = False

        keys_pressed = pg.key.get_pressed()
        
        player.player_movement(keys_pressed)
    
        gravis()

main()

I tried searching for answers on youtube and looking through the code but I couldn’t find anything.

Asked By: LStep

||

Answers:

Trying out your program, the button pressing is updating the x an y coordinates of your object; however, the hero attribute is not changed as it is defined and built via the pg.Rect() function. When I added a line of code in the draw() function, there was a response and the rectangle moved.

    def draw(self):
        self.hero = pg.Rect(self.xc,self.yc,self.width,self.height)     # Redefined the rectangle's size and location
        pg.draw.rect(WINDOW, GREEN, self.hero)

Give that a try to see if it meets the spirit of your project.

Answered By: NoDakker

If you change self.xc or self.yc, the position stored in self.hero does not change. However, self.hero is used to draw the rectangle. Therefore, you must update self.hero after changing self.xc or self.yc:

class Hero:
    def __init__(self, x_cord, y_cord, width, height):
        self.xc = x_cord
        self.yc = y_cord
        self.width = width
        self.height = height
        self.hero = pg.Rect(self.xc,self.yc,self.width,self.height)

    def player_movement(self, keys_pressed):
        if keys_pressed[pg.K_d]:
            self.xc += P_VEL
        if keys_pressed[pg.K_a]:
            self.xc -= P_VEL
        if keys_pressed[pg.K_w]:
            self.yc -= P_VEL
        if keys_pressed[pg.K_s]:
            self.yc += P_VEL

        self.hero.x = self.xc                          # <---
        self.hero.y = self.yc
    
    def draw(self):
        pg.draw.rect(WINDOW, GREEN, self.hero)
Answered By: Rabbid76