蛇不断随机死亡pygame

时间:2020-09-17 15:54:37

标签: python pygame

我正在学习pygame,并创建了一个简单的snake游戏,但蛇仍然随机死亡: enter image description here

我认为这是因为当头部撞到身体的一部分时,if条件会使其死亡:

if snake.headX in snake.bodyX and snake.headY in snake.bodyY:
    snake.alive = False
    snake.moveX = 0
    snake.moveY = 0

不太了解问题所在。

我遇到的另一个问题是,您可以利用if语句来防止您通过快速向下/向上轻按想要移动的一侧而进入身体。这是因为您将方向更改了一秒钟,然后就可以转到想要的位置了:

keys = pygame.key.get_pressed()

if snake.alive:
    if snake.direction != 'down':
        if keys[pygame.K_UP]:
            snake.moveY = -25
            snake.moveX = 0
            snake.direction = 'up'
    if snake.direction != 'up':
        if keys[pygame.K_DOWN]:
            snake.moveY = 25
            snake.moveX = 0
            snake.direction = 'down'
    if snake.direction != 'right':
        if keys[pygame.K_LEFT]:
            snake.moveX = -25
            snake.moveY = 0
            snake.direction = 'left'
    if snake.direction != 'left':
        if keys[pygame.K_RIGHT]:
            snake.moveX = 25
            snake.moveY = 0
            snake.direction = 'right'

所有代码:

import random

import pygame

pygame.init()

pygame.display.set_caption('Snake')


class Grid(object):

    def __init__(self, rows, width, x, y):
        self.rows = rows
        self.width = width
        self.x = x
        self.y = y
        self.sizeBetween = width // rows

    def draw(self, surface):
        x, y = self.x, self.y
        for p in range(self.rows - 1):
            x += self.sizeBetween
            y += self.sizeBetween

            pygame.draw.line(surface, (255, 255, 255), (x, 0), (x, self.width), 1)
            pygame.draw.line(surface, (255, 255, 255), (0, y), (self.width, y), 1)
            pygame.draw.rect(surface, (255, 255, 255), (0, 0, self.width, self.width), 1)


class Player(object):
    def __init__(self, width, x, y):
        self.width = width
        self.headX = x
        self.headY = y
        self.alive = True
        self.moveX = 0
        self.moveY = 0
        self.direction = 'right'
        self.bodyParts = 0
        self.bodyX = []
        self.bodyY = []

    def draw(self, surface):
        if snake.alive:
            self.bodyX.insert(0, self.headX)
            self.bodyY.insert(0, self.headY)
        while len(self.bodyX) > self.bodyParts:
            del self.bodyX[-1]

        while len(self.bodyY) > self.bodyParts:
            del self.bodyY[-1]

        self.move()


        for x in range(self.bodyParts):
            pygame.draw.rect(surface, (255, 0, 0),
                             (round(self.bodyX[x]), round(self.bodyY[x]), self.width, self.width))
        pygame.draw.rect(surface, (0, 0, 255), (round(self.headX), round(self.headY), self.width, self.width))

    def move(self):
        self.headX += self.moveX
        self.headY += self.moveY


class Food(object):
    def __init__(self, width):
        self.width = width
        self.amount = 1
        self.amountCheck = 1
        self.x = 326
        self.y = 226

    def draw(self, surface):
        for i in range(self.amount):
            pygame.draw.rect(surface, (0, 255, 0), (self.x, self.y, self.width, self.width))


def window(surface):
    field.draw(surface)
    snake.draw(surface)
    snack.draw(surface)
    pygame.display.update()


snake = Player(24, 176, 226)
field = Grid(20, 500, 0, 0)
snack = Food(24)
clock = pygame.time.Clock()
win = pygame.display.set_mode((field.width, field.width))
run = True
while run:
    clock.tick(10)
    win.fill((0, 0, 0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()

    if snake.alive:
        if snake.direction != 'down':
            if keys[pygame.K_UP]:
                snake.moveY = -25
                snake.moveX = 0
                snake.direction = 'up'
        if snake.direction != 'up':
            if keys[pygame.K_DOWN]:
                snake.moveY = 25
                snake.moveX = 0
                snake.direction = 'down'
        if snake.direction != 'right':
            if keys[pygame.K_LEFT]:
                snake.moveX = -25
                snake.moveY = 0
                snake.direction = 'left'
        if snake.direction != 'left':
            if keys[pygame.K_RIGHT]:
                snake.moveX = 25
                snake.moveY = 0
                snake.direction = 'right'

    if snake.headY >= 500:
        snake.alive = False
        snake.moveX = 0
        snake.moveY = 0
        snake.headY = 476
    elif snake.headY <= 0:
        snake.alive = False
        snake.moveX = 0
        snake.moveY = 0
        snake.headY = 1
    elif snake.headX >= 500:
        snake.alive = False
        snake.moveX = 0
        snake.moveY = 0
        snake.headX = 476
    elif snake.headX <= 0:
        snake.alive = False
        snake.moveX = 0
        snake.moveY = 0
        snake.headX = 1

    if snake.headX in snake.bodyX and snake.headY in snake.bodyY:
        snake.alive = False
        snake.moveX = 0
        snake.moveY = 0

    if snake.headX == snack.x and snake.headY == snack.y:
        snack.x = random.randint(0, 19) * 25 + 1
        snack.y = random.randint(0, 19) * 25 + 1
        snake.bodyParts += 1

    if not snake.alive:
        print('dead')

    window(win)

2 个答案:

答案 0 :(得分:3)

您在第一段代码中突出显示了逻辑问题:

TypeError: No method matches given arguments for SetStreamDestination: (<class 'str'>, <class 'int>)

用英语阅读:

if snake.headX in snake.bodyX and snake.headY in snake.bodyY:

您的图形清楚地显示了[B] ody和[H] ead平方为真的情况。

if the head is in the same column as any body square AND
   the head is in the same row as any body square:

头部与尾端方格在同一列中,与“颈部”方格在同一行中。您将其编码为死亡。

您需要检查的是头部正方形是否与身体正方形匹配。您必须配对坐标才能使其正常工作。像这样:

B B
B
B H

答案 1 :(得分:2)

您必须评估蛇头与身体部位的位置是否相同:

if (snake.headX, snake.headY) in zip(snake.bodyX, snake.bodyY):
    snake.alive = False
    snake.moveX = 0
    snake.moveY = 0
    break

您实际要做的是评估头部的x坐标是否等于蛇形体的任何x坐标,以及头部的y坐标是否等于蛇形体的任何y坐标。

例如,如果蛇的头是(1,1)且身体有3个部分[(1,2),(2,2),(2,1)],则您的原始条件为{{1 }},因为头部(1)的x坐标位于 列表中,主体x坐标 [1、2、2] 和头部的y坐标( 1)在正文y坐标列表 [2,2,1] 中。