0

I´m a beginner in coding, and I was trying to code a basic game using pytmx, tiled, and pyscroll. so when I run my game it does successfully, the game screen pop up and everything seems to be fine, but when I try to move my player, there´s no answer. anyway, here´s the player´s code in the movi, please help, thanks in advance.

import pygame

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.sprite_sheet = pygame.image.load('player.png')
        self.image = self.get_image(0,0)
        self.image.set_colorkey([0,0,0])
        self.rect = self.image.get_rect()
        self.position = [x,y]
        self.speed = 3

def move_right(self): self.position[0] += self.speed

def move_left(self): self.position[0] -= self.speed

def move_up(self): self.position[1] -= self.speed

def move_down(self): self.position[1] += self.speed

def update(self):
    self.rect.topleft = self.position

def get_image(self, x, y):
    image = pygame.Surface([32,32])
    image.blit(self.sprite_sheet,(0,0),(x,y,32,32))
    return image

here´s the game´s code

import pygame
import pytmx
import pyscroll
from player import Player

class Game:
    def __init__(self):
        #creer la fenetre du Jeu 
        self.screen = pygame.display.set_mode((800, 600))
        pygame.display.set_caption('Yelda')
    
    #charger la carte tmx
    tmx_data = pytmx.util_pygame.load_pygame('carte.tmx')
    map_data = pyscroll.data.TiledMapData(tmx_data)
    map_layer = pyscroll.orthographic.BufferedRenderer(map_data, self.screen.get_size())
    map_layer.zoom = 2

    #generer un joeur
    player_position = tmx_data.get_object_by_name('player')
    self.player = Player(player_position.x, player_position.y)
    
    #dessiner le groupe de calques 
    self.group = pyscroll.PyscrollGroup(map_layer=map_layer, default_layer=5)
    self.group.add(self.player)

def handle_input(self):
    pressed = pygame.key.get_pressed()
    for event in pressed:
        if pressed[pygame.K_UP]:
            print('up')
            self.player.move_up()
        elif pressed[pygame.K_DOWN]:
            self.player.move_down()
        elif pressed[pygame.K_RIGHT]:
            self.player.move_right()
        elif pressed[pygame.K_LEFT]:
            self.player.move_left()

     


def run(self):
    #boucle du jeu 
    running = True
    
    while running:

        self.group.update()
        self.group.center(self.player.rect)
        self.group.draw(self.screen)
        pygame.display.flip()
       


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

pygame.quit()

and here the main code

import pygame
from game import Game

if __name__ == '__main__':
    pygame.init()
    game = Game()
    game.run()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174

2 Answers2

2

You need to run handle_input() in the while loop

while running:
    ...
    handle_input()
    ...
  • thanks a lot for your help, really apreciate it, even though still not working... well, it´s funny, I try to add te function in the main loop but when I run the code, appear NameError: name 'handle_input' is not defined But if I call that function outside of the run loop, well it appears on yellow, that recognizes itself, but still not working. – rene matias Oct 11 '22 at 02:20
0

Reformated code with fixed indentation and added handle_input in main loop

import pygame
import pyscroll
import pytmx


class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.sprite_sheet = pygame.image.load('player.png')
        self.image = self.get_image(0, 0)
        self.image.set_colorkey([0, 0, 0])
        self.rect = self.image.get_rect()
        self.position = [x, y]
        self.speed = 3

    def move_right(self): self.position[0] += self.speed

    def move_left(self): self.position[0] -= self.speed

    def move_up(self): self.position[1] -= self.speed

    def move_down(self): self.position[1] += self.speed

    def update(self):
        self.rect.topleft = self.position

    def get_image(self, x, y):
        image = pygame.Surface([32, 32])
        image.blit(self.sprite_sheet, (0, 0), (x, y, 32, 32))
        return image


class Game:
    def __init__(self):
        # creer la fenetre du Jeu
        self.screen = pygame.display.set_mode((800, 600))
        pygame.display.set_caption('Yelda')

        # charger la carte tmx
        tmx_data = pytmx.util_pygame.load_pygame('carte.tmx')
        map_data = pyscroll.data.TiledMapData(tmx_data)
        map_layer = pyscroll.orthographic.BufferedRenderer(map_data, self.screen.get_size())
        map_layer.zoom = 2

        # generer un joeur
        player_position = tmx_data.get_object_by_name('player')
        self.player = Player(player_position.x, player_position.y)

        # dessiner le groupe de calques
        self.group = pyscroll.PyscrollGroup(map_layer=map_layer, default_layer=5)
        self.group.add(self.player)

    def handle_input(self):
        pressed = pygame.key.get_pressed()
        if pressed[pygame.K_UP]:
            print('up')
            self.player.move_up()
        elif pressed[pygame.K_DOWN]:
            self.player.move_down()
        elif pressed[pygame.K_RIGHT]:
            self.player.move_right()
        elif pressed[pygame.K_LEFT]:
            self.player.move_left()

    def run(self):
        # boucle du jeu
        running = True

        while running:

            self.group.update()
            self.group.center(self.player.rect)
            self.group.draw(self.screen)
            pygame.display.flip()

            self.handle_input()

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


if __name__ == '__main__':
    pygame.init()
    game = Game()
    game.run()
Ovski
  • 575
  • 3
  • 14
  • thank you so much for your time helping me, it´s funny, actually the tutorial that I am following write the code and this part of this is especific way as you suggested, but it doesn´t work though. – rene matias Oct 11 '22 at 02:22
  • I could not test what I updated in the above answer as I don't have the needed tmx file. But please give this a try. I tested the key event handler and it should work this way. What you missed is the input_handle function in the main loop. Maybe it works like this. – Ovski Oct 11 '22 at 16:13
  • Your right!!!! it´s working now, it seems that to call a function in the main loop you need to do it trough self.handle_input And I was missing the self. I promise you, My had is blowing up, thank you for the support. – rene matias Oct 11 '22 at 23:57
  • Let us be honest, you didn't write this yourself, but that's okay. ;) The reason why you need to call it using "self" is that the run and handle_input methods are part of the Game class. The only parameter of the run method is self. You could compare it to Game.handle_input() but this would only work for a static method. As you instantiated the Game class to an object game it uses the self parameter to address itself and call the methods within the object. – Ovski Oct 13 '22 at 12:05