Есть ли способ заставить спрайт следовать за другим в сетке? - PullRequest
0 голосов
/ 30 апреля 2020

Я пытаюсь сделать игру в Snake. У меня есть большинство функций (голова змеи, движение в сетке, еда). У меня проблема в том, чтобы заставить змею расти после того, как она съела кусочек пищи. Я заставил голову змеи исправлять ее путь к центру сетки, но я хочу создать новый спрайт, который следует за головой (телом змеи).

Я думал создать body body, затем задержите этот объект, поэтому для поворота требуется некоторое время после того, как игрок нажмет клавишу со стрелкой. Таким образом, он будет имитировать тело вслед за змеей. Вот что у меня есть (с некоторым тестовым кодом):

#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()

Вот код для Snake06 (поколение до этого), который работает так, как я хочу, просто без роста змеи:

#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()

Я использую Python 3.1, но любые предложения помогут.

1 Ответ

0 голосов
/ 30 апреля 2020

Я бы не "двигал" части тела, но у каждой части был возраст. Когда возраст превышает длину, он исчезает. Когда вы растете, вам просто нужно увеличить длину, и части тела живут на один тик дольше. Когда голова двигается, вы помещаете новую часть тела и старую локацию головы с возрастом 1.

...