-1

I am trying to make a game of Snake. I have most of the functions (snake head, moving in grid, eating food). The problem I am having is making the snake grow after it eats a piece of food. I have made the head of the snake corrects it's path to the center of the grid, but I want to create a new sprite that follows the head (the body of the snake).

I was thinking to create a body object, then have a delay on that object so it takes some time to turn after the player presses an arrow key. That way it would simulate the body following the snake. Here is what I have (with some testing code):

#Snake07
#Snake grows after eating food

import random
from livewires import games

games.init(screen_width = 530, screen_height = 530, fps = 50)

squares = [(17, 17), (17, 50), (17, 83), (17, 116), (17, 149), (17, 182), (17, 215), (17, 248),
           (17, 281), (17, 314), (17, 347), (17, 380), (17, 413), (17, 446), (17, 479), (17, 512),
           (50, 17), (50, 50), (50, 83), (50, 116), (50, 149), (50, 182), (50, 215), (50, 248),
           (50, 281), (50, 314), (50, 347), (50, 380), (50, 413), (50, 446), (50, 479), (50, 512),
           (83, 17), (83, 50), (83, 83), (83, 116), (83, 149), (83, 182), (83, 215), (83, 248),
           (83, 281), (83, 314), (83, 347), (83, 380), (83, 413), (83, 446), (83, 479), (83, 512),
           (116, 17), (116, 50), (116, 83), (116, 116), (116, 149), (116, 182), (116, 215), (116, 248),
           (116, 281), (116, 314), (116, 347), (116, 380), (116, 413), (116, 446), (116, 479), (116, 512),
           (149, 17), (149, 50), (149, 83), (149, 116), (149, 149), (149, 182), (149, 215), (149, 248),
           (149, 281), (149, 314), (149, 347), (149, 380), (149, 413), (149, 446), (149, 479), (149, 512),
           (182, 17), (182, 50), (182, 83), (182, 116), (182, 149), (182, 182), (182, 215), (182, 248),
           (182, 281), (182, 314), (182, 347), (182, 380), (182, 413), (182, 446), (182, 479), (182, 512),
           (215, 17), (215, 50), (215, 83), (215, 116), (215, 149), (215, 182), (215, 215), (215, 248),
           (215, 281), (215, 314), (215, 347), (215, 380), (215, 413), (215, 446), (215, 479), (215, 512),
           (248, 17), (248, 50), (248, 83), (248, 116), (248, 149), (248, 182), (248, 215), (248, 248),
           (248, 281), (248, 314), (248, 347), (248, 380), (248, 413), (248, 446), (248, 479), (248, 512),
           (281, 17), (281, 50), (281, 83), (281, 116), (281, 149), (281, 182), (281, 215), (281, 248),
           (281, 281), (281, 314), (281, 347), (281, 380), (281, 413), (281, 446), (281, 479), (281, 512),
           (314, 17), (314, 50), (314, 83), (314, 116), (314, 149), (314, 182), (314, 215), (314, 248),
           (314, 281), (314, 314), (314, 347), (314, 380), (314, 413), (314, 446), (314, 479), (314, 512),
           (347, 17), (347, 50), (347, 83), (347, 116), (347, 149), (347, 182), (347, 215), (347, 248),
           (347, 281), (347, 314), (347, 347), (347, 380), (347, 413), (347, 446), (347, 479), (347, 512),
           (380, 17), (380, 50), (380, 83), (380, 116), (380, 149), (380, 182), (380, 215), (380, 248),
           (380, 281), (380, 314), (380, 347), (380, 380), (380, 413), (380, 446), (380, 479), (380, 512),
           (413, 17), (413, 50), (413, 83), (413, 116), (413, 149), (413, 182), (413, 215), (413, 248),
           (413, 281), (413, 314), (413, 347), (413, 380), (413, 413), (413, 446), (413, 479), (413, 512),
           (446, 17), (446, 50), (446, 83), (446, 116), (446, 149), (446, 182), (446, 215), (446, 248),
           (446, 281), (446, 314), (446, 347), (446, 380), (446, 413), (446, 446), (446, 479), (446, 512),
           (479, 17), (479, 50), (479, 83), (479, 116), (479, 149), (479, 182), (479, 215), (479, 248),
           (479, 281), (479, 314), (479, 347), (479, 380), (479, 413), (479, 446), (479, 479), (479, 512),
           (512, 17), (512, 50), (512, 83), (512, 116), (512, 149), (512, 182), (512, 215), (512, 248),
           (512, 281), (512, 314), (512, 347), (512, 380), (512, 413), (512, 446), (512, 479), (512, 512)]

class Snake(games.Sprite):
    """ The snake. """
    image = games.load_image("snake_sprite.png")
    snake_length = 0

    def update(self):
        """ Move up, down, left, and right. """

        #move up/down/left/right with arrow keys
        if games.keyboard.is_pressed(games.K_UP) or games.keyboard.is_pressed(games.K_DOWN):
            if games.keyboard.is_pressed(games.K_UP):
                self.dy = -2
                self.dx = 0

            if games.keyboard.is_pressed(games.K_DOWN):
                self.dy = 2
                self.dx = 0

            if self.x > 0 and self.x < 35:
                self.x = 17
            if self.x > 34 and self.x < 68:
                self.x = 50
            if self.x > 67 and self.x < 101:
                self.x = 83
            if self.x > 100 and self.x < 134:
                self.x = 116
            if self.x > 133 and self.x < 167:
                self.x = 149
            if self.x > 166 and self.x < 200:
                self.x = 182
            if self.x > 199 and self.x < 233:
                self.x = 215
            if self.x > 232 and self.x < 266:
                self.x = 248
            if self.x > 265 and self.x < 299:
                self.x = 281
            if self.x > 298 and self.x < 332:
                self.x = 314
            if self.x > 331 and self.x < 365:
                self.x = 347
            if self.x > 364 and self.x < 397:
                self.x = 380
            if self.x > 397 and self.x < 431:
                self.x = 413
            if self.x > 430 and self.x < 464:
                self.x = 446
            if self.x > 463 and self.x < 497:
                self.x = 479
            if self.x > 496 and self.x < 530:
                self.x = 512


        if games.keyboard.is_pressed(games.K_LEFT) or games.keyboard.is_pressed(games.K_RIGHT):
            if games.keyboard.is_pressed(games.K_LEFT):
                self.dx = -2
                self.dy = 0

            if games.keyboard.is_pressed(games.K_RIGHT):
                self.dx = 2
                self.dy = 0

            if self.y > 0 and self.y < 35:
                self.y = 17
            if self.y > 34 and self.y < 68:
                self.y = 50
            if self.y > 67 and self.y < 101:
                self.y = 83
            if self.y > 100 and self.y < 134:
                self.y = 116
            if self.y > 133 and self.y < 167:
                self.y = 149
            if self.y > 166 and self.y < 200:
                self.y = 182
            if self.y > 199 and self.y < 233:
                self.y = 215
            if self.y > 232 and self.y < 266:
                self.y = 248
            if self.y > 265 and self.y < 299:
                self.y = 281
            if self.y > 298 and self.y < 332:
                self.y = 314
            if self.y > 331 and self.y < 365:
                self.y = 347
            if self.y > 364 and self.y < 397:
                self.y = 380
            if self.y > 397 and self.y < 431:
                self.y = 413
            if self.y > 430 and self.y < 464:
                self.y = 446
            if self.y > 463 and self.y < 497:
                self.y = 479
            if self.y > 496 and self.y < 530:
                self.y = 512

        #collision with wall
        if self.bottom > games.screen.height or self.top < 0 or self.right > games.screen.width or self.left < 0:
            self.die()

        if self.overlapping_sprites:
            Snake.snake_length += 1

    def die(self):
        self.destroy()

class Food(games.Sprite):
    """ Food that the snake eats. """
    image = games.load_image("food_sprite.png")

    def __init__(self, x, y):
        """ Create food. """
        super(Food, self).__init__(
            image = Food.image,
            x = x, y = y)

    def update(self):
        """Check for overlap. """
        if self.overlapping_sprites:
            self.die()

    def die(self):
        """Destroy food. """
        food_space = random.choice(squares)
        x = food_space[0]
        y = food_space[1]

        new_food = Food(x = x,
                        y = y)

        games.screen.add(new_food)

        #snake_length += 1

        self.destroy()

class Body(games.Sprite):
    """ The body dots of the snake. """

    def __init__(self, delay):
        self.delay = delay

    def update(self):
        if self.delay > 0:
            self.delay -= 1

        if games.keyboard.is_pressed(games.K_UP) or games.keyboard.is_pressed(games.K_DOWN):
            if games.keyboard.is_pressed(games.K_UP) and self.delay == 0:
                self.dy = -2
                self.dx = 0

            if games.keyboard.is_pressed(games.K_DOWN) and self.delay == 0:
                self.dy = 2
                self.dx = 0

            if self.x > 0 and self.x < 35:
                self.x = 17
            if self.x > 34 and self.x < 68:
                self.x = 50
            if self.x > 67 and self.x < 101:
                self.x = 83
            if self.x > 100 and self.x < 134:
                self.x = 116
            if self.x > 133 and self.x < 167:
                self.x = 149
            if self.x > 166 and self.x < 200:
                self.x = 182
            if self.x > 199 and self.x < 233:
                self.x = 215
            if self.x > 232 and self.x < 266:
                self.x = 248
            if self.x > 265 and self.x < 299:
                self.x = 281
            if self.x > 298 and self.x < 332:
                self.x = 314
            if self.x > 331 and self.x < 365:
                self.x = 347
            if self.x > 364 and self.x < 397:
                self.x = 380
            if self.x > 397 and self.x < 431:
                self.x = 413
            if self.x > 430 and self.x < 464:
                self.x = 446
            if self.x > 463 and self.x < 497:
                self.x = 479
            if self.x > 496 and self.x < 530:
                self.x = 512

        if games.keyboard.is_pressed(games.K_LEFT) or games.keyboard.is_pressed(games.K_RIGHT):
            if games.keyboard.is_pressed(games.K_LEFT) and self.delay == 0:
                self.dx = -2
                self.dy = 0

            if games.keyboard.is_pressed(games.K_RIGHT) and self.delay == 0:
                self.dx = 2
                self.dy = 0

            if self.y > 0 and self.y < 35:
                self.y = 17
            if self.y > 34 and self.y < 68:
                self.y = 50
            if self.y > 67 and self.y < 101:
                self.y = 83
            if self.y > 100 and self.y < 134:
                self.y = 116
            if self.y > 133 and self.y < 167:
                self.y = 149
            if self.y > 166 and self.y < 200:
                self.y = 182
            if self.y > 199 and self.y < 233:
                self.y = 215
            if self.y > 232 and self.y < 266:
                self.y = 248
            if self.y > 265 and self.y < 299:
                self.y = 281
            if self.y > 298 and self.y < 332:
                self.y = 314
            if self.y > 331 and self.y < 365:
                self.y = 347
            if self.y > 364 and self.y < 397:
                self.y = 380
            if self.y > 397 and self.y < 431:
                self.y = 413
            if self.y > 430 and self.y < 464:
                self.y = 446
            if self.y > 463 and self.y < 497:
                self.y = 479
            if self.y > 496 and self.y < 530:
                self.y = 512

def main():
    #background
    grid_image = games.load_image("grid.png")
    games.screen.background = grid_image

    #create snake
    snake_length = 0
    snake = Snake(image = Snake.image,
                  x = games.screen.width/2,
                  y = games.screen.height/2)
    games.screen.add(snake)

    #create food
    food_space = random.choice(squares)
    x = food_space[0]
    y = food_space[1]

    new_food = Food(x = x,
                    y = y)
    games.screen.add(new_food)

    #create body parts
    delay = 25
    if Snake.snake_length == 1:
        body1 = Body(delay)
        games.screen.add(body1)

    #body2 = Body(delay *2)

    games.screen.mainloop()

main()

Here is the code for Snake06 (the generation before this) that works the way I want it, just without the snake growing:

#Snake06
#Food respawns after eaten

import random
from livewires import games

games.init(screen_width = 530, screen_height = 530, fps = 50)

squares = [(17, 17), (17, 50), (17, 83), (17, 116), (17, 149), (17, 182), (17, 215), (17, 248),
           (17, 281), (17, 314), (17, 347), (17, 380), (17, 413), (17, 446), (17, 479), (17, 512),
           (50, 17), (50, 50), (50, 83), (50, 116), (50, 149), (50, 182), (50, 215), (50, 248),
           (50, 281), (50, 314), (50, 347), (50, 380), (50, 413), (50, 446), (50, 479), (50, 512),
           (83, 17), (83, 50), (83, 83), (83, 116), (83, 149), (83, 182), (83, 215), (83, 248),
           (83, 281), (83, 314), (83, 347), (83, 380), (83, 413), (83, 446), (83, 479), (83, 512),
           (116, 17), (116, 50), (116, 83), (116, 116), (116, 149), (116, 182), (116, 215), (116, 248),
           (116, 281), (116, 314), (116, 347), (116, 380), (116, 413), (116, 446), (116, 479), (116, 512),
           (149, 17), (149, 50), (149, 83), (149, 116), (149, 149), (149, 182), (149, 215), (149, 248),
           (149, 281), (149, 314), (149, 347), (149, 380), (149, 413), (149, 446), (149, 479), (149, 512),
           (182, 17), (182, 50), (182, 83), (182, 116), (182, 149), (182, 182), (182, 215), (182, 248),
           (182, 281), (182, 314), (182, 347), (182, 380), (182, 413), (182, 446), (182, 479), (182, 512),
           (215, 17), (215, 50), (215, 83), (215, 116), (215, 149), (215, 182), (215, 215), (215, 248),
           (215, 281), (215, 314), (215, 347), (215, 380), (215, 413), (215, 446), (215, 479), (215, 512),
           (248, 17), (248, 50), (248, 83), (248, 116), (248, 149), (248, 182), (248, 215), (248, 248),
           (248, 281), (248, 314), (248, 347), (248, 380), (248, 413), (248, 446), (248, 479), (248, 512),
           (281, 17), (281, 50), (281, 83), (281, 116), (281, 149), (281, 182), (281, 215), (281, 248),
           (281, 281), (281, 314), (281, 347), (281, 380), (281, 413), (281, 446), (281, 479), (281, 512),
           (314, 17), (314, 50), (314, 83), (314, 116), (314, 149), (314, 182), (314, 215), (314, 248),
           (314, 281), (314, 314), (314, 347), (314, 380), (314, 413), (314, 446), (314, 479), (314, 512),
           (347, 17), (347, 50), (347, 83), (347, 116), (347, 149), (347, 182), (347, 215), (347, 248),
           (347, 281), (347, 314), (347, 347), (347, 380), (347, 413), (347, 446), (347, 479), (347, 512),
           (380, 17), (380, 50), (380, 83), (380, 116), (380, 149), (380, 182), (380, 215), (380, 248),
           (380, 281), (380, 314), (380, 347), (380, 380), (380, 413), (380, 446), (380, 479), (380, 512),
           (413, 17), (413, 50), (413, 83), (413, 116), (413, 149), (413, 182), (413, 215), (413, 248),
           (413, 281), (413, 314), (413, 347), (413, 380), (413, 413), (413, 446), (413, 479), (413, 512),
           (446, 17), (446, 50), (446, 83), (446, 116), (446, 149), (446, 182), (446, 215), (446, 248),
           (446, 281), (446, 314), (446, 347), (446, 380), (446, 413), (446, 446), (446, 479), (446, 512),
           (479, 17), (479, 50), (479, 83), (479, 116), (479, 149), (479, 182), (479, 215), (479, 248),
           (479, 281), (479, 314), (479, 347), (479, 380), (479, 413), (479, 446), (479, 479), (479, 512),
           (512, 17), (512, 50), (512, 83), (512, 116), (512, 149), (512, 182), (512, 215), (512, 248),
           (512, 281), (512, 314), (512, 347), (512, 380), (512, 413), (512, 446), (512, 479), (512, 512)]

class Snake(games.Sprite):
    """ The snake. """
    image = games.load_image("snake_sprite.png")

    def update(self):
        """ Move up, down, left, and right. """

        #move up/down/left/right with arrow keys
        if games.keyboard.is_pressed(games.K_UP) or games.keyboard.is_pressed(games.K_DOWN):
            if games.keyboard.is_pressed(games.K_UP):
                self.dy = -2
                self.dx = 0

            if games.keyboard.is_pressed(games.K_DOWN):
                self.dy = 2
                self.dx = 0

            if self.x > 0 and self.x < 35:
                self.x = 17
            if self.x > 34 and self.x < 68:
                self.x = 50
            if self.x > 67 and self.x < 101:
                self.x = 83
            if self.x > 100 and self.x < 134:
                self.x = 116
            if self.x > 133 and self.x < 167:
                self.x = 149
            if self.x > 166 and self.x < 200:
                self.x = 182
            if self.x > 199 and self.x < 233:
                self.x = 215
            if self.x > 232 and self.x < 266:
                self.x = 248
            if self.x > 265 and self.x < 299:
                self.x = 281
            if self.x > 298 and self.x < 332:
                self.x = 314
            if self.x > 331 and self.x < 365:
                self.x = 347
            if self.x > 364 and self.x < 397:
                self.x = 380
            if self.x > 397 and self.x < 431:
                self.x = 413
            if self.x > 430 and self.x < 464:
                self.x = 446
            if self.x > 463 and self.x < 497:
                self.x = 479
            if self.x > 496 and self.x < 530:
                self.x = 512

        if games.keyboard.is_pressed(games.K_LEFT) or games.keyboard.is_pressed(games.K_RIGHT):
            if games.keyboard.is_pressed(games.K_LEFT):
                self.dx = -2
                self.dy = 0

            if games.keyboard.is_pressed(games.K_RIGHT):
                self.dx = 2
                self.dy = 0

            if self.y > 0 and self.y < 35:
                self.y = 17
            if self.y > 34 and self.y < 68:
                self.y = 50
            if self.y > 67 and self.y < 101:
                self.y = 83
            if self.y > 100 and self.y < 134:
                self.y = 116
            if self.y > 133 and self.y < 167:
                self.y = 149
            if self.y > 166 and self.y < 200:
                self.y = 182
            if self.y > 199 and self.y < 233:
                self.y = 215
            if self.y > 232 and self.y < 266:
                self.y = 248
            if self.y > 265 and self.y < 299:
                self.y = 281
            if self.y > 298 and self.y < 332:
                self.y = 314
            if self.y > 331 and self.y < 365:
                self.y = 347
            if self.y > 364 and self.y < 397:
                self.y = 380
            if self.y > 397 and self.y < 431:
                self.y = 413
            if self.y > 430 and self.y < 464:
                self.y = 446
            if self.y > 463 and self.y < 497:
                self.y = 479
            if self.y > 496 and self.y < 530:
                self.y = 512

        #collision with wall
        if self.bottom > games.screen.height or self.top < 0 or self.right > games.screen.width or self.left < 0:
            self.die()

        ### THE PICTURE IS TOO BIG (BEING BASED OFF PICTURE AND NOT GREEN DOT)

    def die(self):
        self.destroy()

class Food(games.Sprite):
    """ Food that the snake eats. """
    image = games.load_image("food_sprite.png")

    def __init__(self, x, y):
        """ Create food. """
        super(Food, self).__init__(
            image = Food.image,
            x = x, y = y)

    def update(self):
        """Check for overlap. """
        if self.overlapping_sprites:
            self.die()

    def die(self):
        """Destroy food. """
        food_space = random.choice(squares)
        x = food_space[0]
        y = food_space[1]

        new_food = Food(x = x,
                        y = y)

        games.screen.add(new_food)

        self.destroy()

def main():
    #background
    grid_image = games.load_image("grid.png")
    games.screen.background = grid_image

    #create snake
    snake = Snake(image = Snake.image,
                  x = games.screen.width/2,
                  y = games.screen.height/2)
    games.screen.add(snake)

    #create food

    food_space = random.choice(squares)
    x = food_space[0]
    y = food_space[1]

    new_food = Food(x = x,
                    y = y)
    games.screen.add(new_food)

    games.screen.mainloop()

main()

I am using Python 3.1, but any suggestions would help.

user4157124
  • 2,809
  • 13
  • 27
  • 42

1 Answers1

0

I would not "move" the parts of the body, but have each part have an age. When the age exceeds the length, it despawns. When you grow you simply need to increase the length and the body parts live one tick longer. When the head moves you place a new body part at the old head location with an age of 1.

cmd
  • 5,754
  • 16
  • 30