python - snake keeps dying randomly pygame
问题描述
I'm learning pygame
and I created a simple snake
game, but the snake keeps dying randomly:
I think its because the if condition that makes it die when the head hits a part of the body:
if snake.headX in snake.bodyX and snake.headY in snake.bodyY:
snake.alive = False
snake.moveX = 0
snake.moveY = 0
Don't really understand whats the problem.
An other issue I have is that you can exploit the if statement that prevents you from moving into the body by fast tapping down/up and the side you want to go. This is because you change the direction for a split second and then you can go where you want to go:
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'
All the code:
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)
解决方案
您在第一个代码块中突出显示了逻辑问题:
if snake.headX in snake.bodyX and snake.headY in snake.bodyY:
用英文阅读:
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]ody 和 [H]ead 正方形的情况。
B B
B
B H
头部与尾部正方形在同一列,与“颈部”正方形在同一行。你把它编码为死亡。
您需要检查的是头部正方形是否与身体正方形匹配。您必须配对坐标才能使其工作。就像是:
if (snake.headX, snake.headY in zip(snake.budyX, snake.bodyY):
推荐阅读
- sql-server - 读取大文件时的 ssis 脚本任务 (vb) 问题
- bash - 如何在带有多参数的bash curl命令中使用--data-binary
- json - LogParser JSON 日志文件
- r - 循环功能运行非常缓慢
- django - 在“热”或“实时”数据库上使用 `django-admin dumpdata` 会发生什么?
- python-3.x - 如何在tensorflow库中找到RFCN模型上的相似图片?
- postgresql - PostgreSQL:将用户定义的函数从一个数据库复制/导入到另一个数据库
- redis - ai.grakn.redismock.exception.ParseErrorException
- sql - SQL - 将文本插入字段 WHERE ___
- angularjs - angularjs 中的路由 - 其他语法中的条件路由