KremlingKoder
KremlingKoder

Reputation: 59

How do I get the player character to move?

I was starting to improve my code when I encountered a roadblock. My player character can jump but cannot move left and right.Program runs as if there are no syntax errors. The main aim is trying to get the character to move left and right

here is the player class where its attributes and functions are defined

class player:
    def __init__(self,x,y):
        self.x = x
        self.y = y
        self.width = 64
        self.height = 64
        self.standing = True
        self.left = False
        self.right = True
        self.vel = 15
        self.jumping = False
        self.jumpCount = 10
        self.k = pygame.key.get_pressed()
    def move(self,x,y):
        if not self.standing:
            if self.k[pygame.K_LEFT] and self.x  > 0 - 150:
                self.left = True
                self.right = False            
                self.x -= self.vel
            elif self.k[pygame.K_RIGHT] and self.x  < 500 - 150 :
                self.right = True
                self.left = False
               self.x += self.vel
        else:
            self.standing = True

Main loop

run = True
wizard = player(25,320)
while run:#main game loop
    pygame.time.delay(15)
    for event in pygame.event.get():#loops through a list of keyboard or mouse events
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                wizard.jumping = True    
    wizard.move(wizard.x,wizard.y)
    win.blit(bg,(0,0))
    wizard.jump(wizard.y)
    wizard.draw(win) 
    pygame.display.update()
pygame.quit()

Upvotes: 1

Views: 1056

Answers (1)

Kingsley
Kingsley

Reputation: 14906

Ok, some of the code seems a bit mixed-up. I think it would be better if your player class just handled being a wizard (which is a big enough task on its own), and your main event-loop should take care the user-input.

The main loop is using the pygame.KEYDOWN event. This is fine if you want that key-down, key-up "typing" sort of movement. But a more natural way is to simply check pygame.key.get_pressed() which returns the state of all buttons. Since your player already maintains a velocity, use the key-states to adjust the velocity.

FPS=20
clock = pygame.time.Clock()   # clock to limit the FPS
while run: #main game loop
    #pygame.time.delay(15)   # <-- No need to delay here, see FPS limit below
    for event in pygame.event.get():  #loops through event list
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                wizard.goJump()

    # Handle keys pressed
    if ( keys[pygame.K_LEFT] ):
        wizard.goLeft()
    elif ( keys[pygame.K_RIGHT] ):
        wizard.goRight()

    # Update the player's position
    #wizard.move(wizard.x,wizard.y)
    wizard.update()

    # redraw the screen
    win.blit( bg, (0, 0) )
    wizard.draw( win ) 
    pygame.display.update()

    # Update the window, but at a useful FPS
    clock.tick_busy_loop( FPS )

pygame.quit() 

So this means a few changes to the player. I've tried to keep all the "player handling" functions inside the player, while moving all the user-input handling code outside of the class.

class player:
    def __init__(self,x,y):
        self.x = x
        self.y = y
        self.width = 64
        self.height = 64
        #self.standing = True          <-- Standing is "not self.jumping"
        #self.left = False
        #self.right = True
        self.vel = 15                 # current player speed
        self.max_vel = 20             # Limit the player speed extremes
        self.mix_vel = -20
        self.jumping = False
        self.jumpCount = 10
        # self.k = pygame.key.get_pressed()  <-- Don't handle events inside the player

    def goLeft( self ):
        """ Handle the user-input to move left """      
        self.vel -= 1
        if ( self.vel <= self.min_vel ):
            self.vel = self.min_vel

    def goRight( self ):
        """ Handle the user-input to move right """
        self.vel += 1
        if ( self.vel >= self.max_vel ):
            self.vel = self.max_vel

    def goJump( self ):
        """ Handle the user-input to jump """
        if ( self.jumping == False ):
            self.jumping = True
            print( "TODO: Handle Jumping" )
        else:
            print( "TODO: Already Jumping" )

    def update( self ):
        # Move the character left/right
        self.x += self.vel   # (+) velocity is right, (-) is left
        # handle the progress of the jump
        if ( self.jumping == True ):
            print( "TODO: jump wizard - GO!" )

The jumping is not implemented. One way to do this is instead of simply recording self.jumping as boolean, perhaps store the milliseconds-time the jump started instead. Then during the player.update(), use the real-time difference to move the player through their (parabolic?) path up & back down. Once player.jumptime is reset back to zero, they user can make the wizard jump again.

Upvotes: 1

Related Questions