Mush-A
Mush-A

Reputation: 447

OOP Pygame platform game: controlling and moving a square on a screen

import pygame
import random
import math
import sys

screenWidth = 1200
screenHeight = 600

class Hero:
    def __init__(self, pos):
        self.pos = pos
        self.width = 30
        self.height = 30
        self.color = (0, 0, 0)
        self.dirX = 0
        self.dirY = 0

    def move(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.dirX = 1
                elif event.key == pygame.K_LEFT:
                    self.dirX = -1

    def draw(self, display):
        x = self.pos[0]
        y = self.pos[1]
        pygame.draw.rect(display, self.color, (x + self.dirX, y + self.dirY, self.width, self.height))
        print(self.pos, self.dirX, self.dirY)
    
    def jump(self):
        pass


    def die(self):
        pass


class Enemy:
    pass

class Background:
    pass

class Obstacles:
    pass

class Camera:
    pass

def score():
    pass

def create(w, h):
    display = pygame.display.set_mode((w, h))
    display.fill((255, 255, 255))
    #create background
    #create Obstacles
    #create Hero
    heroOne = Hero([150, 450])
    heroOne.move()
    heroOne.draw(display)
    #create Enemy
    pygame.display.update()

def main():
    pygame.init()

    clock = pygame.time.Clock()

    running = True
    while running:

        clock.tick(300)

        create(screenWidth, screenHeight)

main()

Hi, I am making an OOP Game using Pygame in which a square would be controlled by the user and move along a floor, jump over obstacles and other enemy squares.

The way I want it to work: When I press K_LEFT, dirX = 1 it will add to the x-coordinate of the pos and hence the x-position of the square will be updated and the square will begin to slide towards the right. When I press dir = -1and square will move to the left.

The way it is working: No

I think the problem is the pos of the main cube does not seem to update and the dirX updates from 0 to 1 and goes back to 0.

I guess changing the values of the variables under the __init__() function is done as I am doing it or perhaps it is completely wrong.

Is this any way to make my code work the way I am trying to do it or is it completely a wrong way and there is some other way?

I am learning OOP and python, any additional advice or links regarding the best practices, relating to this code, would be highly appreciated.

Thank you.

Upvotes: 1

Views: 251

Answers (2)

Rabbid76
Rabbid76

Reputation: 211136

First of all you've to invoke move in the main application loop:

def main():
    pygame.init()
    display = pygame.display.set_mode((screenWidth, screenHeight))
    clock = pygame.time.Clock()

    heroOne = Hero([150, 450])
    running = True
    while running:
        clock.tick(300)

        display.fill((255, 255, 255))
        heroOne.move()
        heroOne.draw(display)
        pygame.display.update()        

You have to change the position of the player by self.dirX and self.dirY, in every frame:

class Hero:
    # [...]

    def move(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RIGHT:
                    self.dirX = 1
                elif event.key == pygame.K_LEFT:
                    self.dirX = -1

        new_x = self.pos[0] + self.dirX
        new_y = self.pos[1] + self.dirY
        self.pos = [new_x , new_y]

    def draw(self, display):
        pygame.draw.rect(display, self.color, (*self.pos, self.width, self.height))

If you wan to move the rectangle, just when a key is pressed, then I recommend to use pygame.key.get_pressed rather than the KEYDOWN event:

class Hero:
    # [...]

    def move(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.pos[0] -= 1 
        if keys[pygame.K_RIGHT]:
            self.pos[0] += 1
        if keys[pygame.K_UP]:
            self.pos[1] -= 1 
        if keys[pygame.K_DOWN]:
            self.pos[1] += 1

Complete code:

import pygame
import random
import math
import sys

screenWidth = 1200
screenHeight = 600

class Hero:
    def __init__(self, pos):
        self.pos = pos
        self.width = 30
        self.height = 30
        self.color = (0, 0, 0)
        self.dirX = 0
        self.dirY = 0

    def move(self, events):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.pos[0] -= 1 
        if keys[pygame.K_RIGHT]:
            self.pos[0] += 1
        if keys[pygame.K_UP]:
            self.pos[1] -= 1 
        if keys[pygame.K_DOWN]:
            self.pos[1] += 1

    def draw(self, display):
        pygame.draw.rect(display, self.color, (*self.pos, self.width, self.height))
    
    def jump(self):
        pass


    def die(self):
        pass


class Enemy:
    pass

class Background:
    pass

class Obstacles:
    pass

class Camera:
    pass

def score():
    pass


def main():
    pygame.init()
    display = pygame.display.set_mode((screenWidth, screenHeight))
    clock = pygame.time.Clock()

    heroOne = Hero([150, 450])
    running = True
    while running:
        clock.tick(300)
        events = pygame.event.get()
        for event in events:
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

        heroOne.move(events)

        display.fill((255, 255, 255))
        heroOne.draw(display)
        pygame.display.update()   

main()

Upvotes: 1

kaktus_car
kaktus_car

Reputation: 986

In your create function you are creating new instance of the Hero each time its being called.

Instead, init heroOne in the main, and pass it as an argument so you can use it:

def main():
    pygame.init()
    heroOne = Hero([150, 450])
    clock = pygame.time.Clock()

    running = True
    while running:

        clock.tick(30)

        create(screenWidth, screenHeight, heroOne)

Also add increment in the move method:

self.dirX += 1

and:

self.dirX -= 1

Now the object will move by one on each keypress.

And if you want continuous movement you should put some flag, e.g. if it is True +=1 and "False" -=1 and key presses will change the flag state.

Upvotes: 1

Related Questions