nick_rinaldi
nick_rinaldi

Reputation: 707

Can I alter a pygame object's constant movement direction through a keypress?

I am creating a snake game in pygame. Basically, I want my snake object to be constantly moving at all times.

However, I want to be able to change direction of that object's movement upon a keypress.

Right now, I am able to move the object, but I have to either keep pressing down a key, or hold that key down. It's not a constant movement.

My goal here is to have the snake object moving in one direction at all times, and simply have a keypress to alter the direction it's moving in. Is this possible?

Here's my object code:

class Snake:
    def __init__(self, block_size, surface, x_loc, y_loc):
        self.block_size = block_size
        self.surface = surface # red
        self.x_loc = x_loc
        self.y_loc = y_loc
             
    def draw(self, window):
        window.blit(self.surface, (self.x_loc, self.y_loc))

    def collide(self, obj):
        pass

    def move_x_left(self, surface, x_loc, y_loc):
        window.blit(surface, (self.x_loc, self.y_loc))
        self.x_loc -= 20

    def move_y_up(self, surface, x_loc, y_loc):
        window.blit(surface, (self.x_loc, self.y_loc))
        self.y_loc -= 20

    def move_x_right(self, surface, x_loc, y_loc):
        window.blit(surface, (self.x_loc, self.y_loc))
        self.x_loc += 20

    def move_y_down(self, surface, x_loc, y_loc):
        window.blit(surface, (self.x_loc, self.y_loc))
        self.y_loc += 20

and here's my game loop inside my main function

  while game_running:

        snake.draw(window)

        redraw_window()

        clock.tick(FPS) # tick the clock based on our FPS rate. 

        # snake.move_y_down(mask, snake.x_loc, snake.y_loc)

        for event in pygame.event.get(): # if we hit "x" to close out the game, close out the game.
            if event.type == pygame.QUIT:
                pygame.quit()
                exit()
        keys = pygame.key.get_pressed()

        if keys[pygame.K_RIGHT]: 
            snake.move_x_right(mask, snake.x_loc, snake.y_loc)

        if keys[pygame.K_LEFT]:
            snake.move_x_left(mask, snake.x_loc, snake.y_loc)

        if keys[pygame.K_DOWN]:
                snake.move_y_down(mask, snake.x_loc, snake.y_loc)

        if keys[pygame.K_UP]:
                snake.move_y_up(mask, snake.x_loc, snake.y_loc)

FPS rate is 60. Still not exactly sure how/if I'm even implementing that properly, but it may be irrelevant to this question anyways.

Upvotes: 1

Views: 301

Answers (2)

user12291970
user12291970

Reputation:

You can create a variable to keep track of which direction the snake is moving in and keep moving in that direction.

Add direction variable to snake class

class Snake:
    def __init__(self, block_size, surface, x_loc, y_loc):
        # omited code
        self.direction = None

Check for key pressed and set the variable accordingly:

# SET A CERTAIN DIRECTION IF A CERTAIN KEY IS PRESSED
    if keys[pygame.K_RIGHT]:
        snake.direction = "right"
    if keys[pygame.K_LEFT]:
        snake.direction = "left"            
    if keys[pygame.K_DOWN]:
        snake.direction = "down"
    if keys[pygame.K_UP]:
        snake.direction = "up"

Then simply move in that direction every frame

 # MOVE ACCORDING TO DIRECTION
        if snake.direction == "right":
            snake.move_x_right(mask, snake.x_loc, snake.y_loc)
        if snake.direction == "left":
            snake.move_x_left(mask, snake.x_loc, snake.y_loc)
        if snake.direction == "down":
            snake.move_y_down(mask, snake.x_loc, snake.y_loc)
        if snake.direction == "up":
            snake.move_y_up(mask, snake.x_loc, snake.y_loc)

Re-written code:

while game_running:

    snake.draw(window)

    for event in pygame.event.get(): # if we hit "x" to close out the game, close out the game.
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
    keys = pygame.key.get_pressed()

    if snake.direction == "right":
        snake.move_x_right(mask, snake.x_loc, snake.y_loc)
    if snake.direction == "left":
        snake.move_x_left(mask, snake.x_loc, snake.y_loc)
    if snake.direction == "down":
        snake.move_y_down(mask, snake.x_loc, snake.y_loc)
    if snake.direction == "up":
        snake.move_y_up(mask, snake.x_loc, snake.y_loc)
        

    if keys[pygame.K_RIGHT]:
        snake.direction = "right"

    if keys[pygame.K_LEFT]:
        snake.direction = "left"
        snake.move_x_left(mask, snake.x_loc, snake.y_loc)
        
    if keys[pygame.K_DOWN]:
        snake.direction = "down"

    if keys[pygame.K_UP]:
        snake.direction = "up"

I cannot test this code because i don't have the rest of your code, but you get the idea.

Upvotes: 2

kiwibg
kiwibg

Reputation: 334

You can do it by defining a function that you can run on every game tick

def move_snake:
    speed = 20
    window.blit(surface, (self.x_loc, self.y_loc))
    self.x_loc += speed * x_heading        
    self.y_loc += speed * y_heading     

You could then change the heading of y to 0 on each up or down keypress and x to 1 or -1, and vice versa.

If your game ticks are linked to your fps, you might need correct the speed to reflect your game scenario. :)

EDIT: You can define the speed as well as headings as properties of the snake itself so the code is better grouped.

Upvotes: 1

Related Questions