Eugene Levinson
Eugene Levinson

Reputation: 182

Object not moving when keys are pressed

I just started learning pygame to create a simple game for a project. I have an object "Rectangle" which has a method which changes the x and y position. However, for some reason, the object doesn't move. I found some examples where the x and y are changed when a key is pressed and a new object is drawn with the new coordinates. However, rather than do that I want to call a method which will move that rectangle and not create a new one. What's the best way to do it?

My code:

import pygame

#init the pygame and create a screen
pygame.init()
screen = pygame.display.set_mode((1080,720))
done = False

#colours
blue = (0,0,255)
red = (255,0,0)
green = (0,255,0)
black = (0,0,0)
white = (255,255,255)
yellow = (255,255,0)

x = 540
y = 660

#starts the game clock
clock = pygame.time.Clock()

#class for all of the objects on the screen
class shape():
    def __init__(self, place, colour, x, y):
        self.place = place
        self.colour = colour
        self.x = x
        self.y = y

#class for a rectangle
class rectangle(shape):
    def __init__(self, place, colour, x, y, length, width):
        super().__init__(place, colour, x, y)
        self.length = length
        self.width = width

        pygame.draw.rect(screen, colour, pygame.Rect(x, y, length, width))

    def move_up(self):
        self.y = self.y + 3

    def move_down(self):
        self.y = self.y - 3

    def move_right(self):
        self.x = self.x + 3

    def move_left(self):
        self.x = self.x - 3


#main loop
while not done:

        #checking for game events
        for event in pygame.event.get():

                #quitting gamw when window is closed
                if event.type == pygame.QUIT:
                        done = True

        Rectangle = rectangle(screen, yellow, x, y, 30, 30)

        #detecting key presses
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_UP]:Rectangle.move_up()
        if pressed[pygame.K_DOWN]:Rectangle.move_down()
        if pressed[pygame.K_LEFT]:Rectangle.move_left()
        if pressed[pygame.K_RIGHT]:Rectangle.move_right()

        pygame.display.update() 

        #controls FPS
        clock.tick(60)

Upvotes: 1

Views: 156

Answers (1)

Rabbid76
Rabbid76

Reputation: 210968

What you actually do is to create a new rectangle at the initial position in every frame. The position is of the rectangle is updated, but since a new rectangle is created in the next frame, the rectangles seems to be immovable.

Do not draw the rectangle in its constructor, but add a draw method to the class rectangle:

class rectangle(shape):
    def __init__(self, place, colour, x, y, length, width):
        super().__init__(place, colour, x, y)
        self.length = length
        self.width = width

    def move_up(self):
        self.y = self.y - 3
    def move_down(self):
        self.y = self.y + 3
    def move_right(self):
        self.x = self.x + 3
    def move_left(self):
        self.x = self.x - 3

    def draw(self):
        pygame.draw.rect(screen, self.colour, pygame.Rect(self.x, self.y, self.length, self.width))

Create a rectangle object before the main application loop and call the draw() method in the main application loop:

# create rectangle object
Rectangle = rectangle(screen, yellow, x, y, 30, 30)

#main loop
while not done:

        #checking for game events
        for event in pygame.event.get():
                #quitting gamw when window is closed
                if event.type == pygame.QUIT:
                        done = True

        # detecting key presses and change location of the rectangle
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_UP]:Rectangle.move_up()
        if pressed[pygame.K_DOWN]:Rectangle.move_down()
        if pressed[pygame.K_LEFT]:Rectangle.move_left()
        if pressed[pygame.K_RIGHT]:Rectangle.move_right()

        # clear display
        screen.fill(0)

        # draw rectangle
        Rectangle.draw()

        # update diesplay
        pygame.display.update() 

        #controls FPS
        clock.tick(60)

Upvotes: 1

Related Questions