Reputation: 707
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
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
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