python - 用 pygame 制作蛇。当蛇接触到饼干时,难以使蛇变长
问题描述
我正在尝试在pygame中制作蛇游戏,但是一旦蛇接触到点,我就无法使蛇变长。当我触摸点时,游戏有时会冻结,并且在极少数情况下它会给我一个记忆错误。
另外,当我成功吃掉点后,蛇就不再长了。
任何帮助,将不胜感激。谢谢!
我的代码:
import pygame
import sys
import random
pygame.init()
width = 800
height = 800
snake_pos = [width/2, height/2]
snake_list = []
color_red = (255, 0, 0)
snake_size = 20
game_over = False
screen = pygame.display.set_mode((width, height))
cookie_pos = [random.randint(0, width), random.randint(0, height)]
cookie_size = 10
color_white = (255, 255, 255)
cookie = []
direction = ''
game_over = False
def draw_snake():
for snake in snake_list:
pygame.draw.rect(screen, color_red, (snake[0], snake[1], snake_size, snake_size))
if not snake_list:
snake_list.append([snake_pos[0], snake_pos[1]])
def create_snake(direction):
length = len(snake_list)
for snake in snake_list:
if direction == 'left':
snake_list.append([snake[0] + (length * snake_size), snake[1]])
elif direction == 'right':
snake_list.append([snake[0] - (length * snake_size), snake[1]])
elif direction == 'top':
snake_list.append([snake[0], snake[1] + (length * snake_size)])
elif direction == 'bottom':
snake_list.append([snake[0], snake[1] - (length * snake_size)])
def create_cookie():
cookie.append([random.randint(0, width), random.randint(0, height)])
draw_cookie()
def draw_cookie():
for cookie_pos in cookie:
pygame.draw.rect(screen, color_white, (cookie_pos[0], cookie_pos[1], cookie_size, cookie_size))
def check_cookie(direction):
for snake_pos in snake_list:
for cookie_pos in cookie:
p_x = snake_pos[0]
p_y = snake_pos[1]
e_x = cookie_pos[0]
e_y = cookie_pos[1]
if e_x >= p_x and e_x < (p_x + snake_size) or p_x >= e_x and p_x < (e_x + cookie_size):
if e_y >= p_y and e_y < (p_y + snake_size) or p_y >= e_y and p_y < (e_y + cookie_size):
cookie.pop(0)
create_cookie()
create_snake(direction)
if not cookie:
cookie.append([random.randint(0, width), random.randint(0, height)])
def update_snake():
pass
def move_snake(direction):
keys = pygame.key.get_pressed()
for snake_pos in snake_list:
if keys[pygame.K_LEFT]:
direction = 'left'
snake_pos[0] -= 0.2
if keys[pygame.K_RIGHT]:
direction = 'right'
snake_pos[0] += 0.2
if keys[pygame.K_UP]:
direction = 'up'
snake_pos[1] -= 0.2
if keys[pygame.K_DOWN]:
direction = 'down'
snake_pos[1] += 0.2
screen.fill((0,0,0))
return direction
def main_game(direction):
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
draw_snake()
check_cookie(direction)
draw_cookie()
pygame.display.update()
direction = move_snake(direction)
main_game(direction)
解决方案
如果要写入全局变量,则必须使用global
语句。
在事件循环中使用它来设置 game_over
. 进一步注意,清除显示应该在主循环中完成:
def main_game(direction):
global game_over
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
# update snake and cookies
direction = move_snake(direction)
check_cookie(direction)
# draw the scene
screen.fill(0)
draw_snake()
draw_cookie()
pygame.display.update()
教蛇的部分有一个大小snake_size = 20
。但蛇0.2
每帧移动。所以不可能在前一帧的位置上绘制蛇的第二部分,因为到前一位置的距离是0.2
。这几乎是相同的位置,并且会导致几乎完全自覆盖的部件。
蛇的第二部分的正确位置是头部在 100 (=20/0.2) 帧前的位置。
跟踪列表中蛇的所有位置:
def move_snake(direction):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
direction = 'left'
if keys[pygame.K_RIGHT]:
direction = 'right'
if keys[pygame.K_UP]:
direction = 'up'
if keys[pygame.K_DOWN]:
direction = 'down'
if snake_list:
new_pos = snake_list[0][:]
if direction == 'left':
new_pos[0] -= 0.2
if direction == 'right':
new_pos[0] += 0.2
if direction == 'up':
new_pos[1] -= 0.2
if direction == 'down':
new_pos[1] += 0.2
if direction != '':
snake_list.insert(0, new_pos)
return direction
创建一个全局变量,它存储蛇snake_len
的pygame.Rect
部分.colliderect()
数(
snake_len = 1
def check_cookie(direction):
global snake_len, cookie
if snake_list:
for i, cookie_pos in enumerate(cookie):
cookie_rect = pygame.Rect(*cookie_pos, cookie_size, cookie_size)
snake_rect = pygame.Rect(*snake_list[0], snake_size, snake_size)
if snake_rect.colliderect(cookie_rect):
snake_len += 1
del cookie[i]
break
if not cookie:
cookie.append([random.randint(0, width), random.randint(0, height)])
蛇由snake_len
部分组成。蛇的每一部分都有一个索引。该索引必须与存储在的位置相关联snake_list
:
pos_i = round(snake_size * i / 0.2)
pos = snake_list[pos_i]
在存储的适当位置绘制蛇上的零件snake_list
并删除列表的尾部,不再需要:
def draw_snake():
global snake_list
if not snake_list:
snake_list.append(snake_pos[:])
for i in range(snake_len):
pos_i = round(snake_size * i / 0.2)
if pos_i < len(snake_list):
pygame.draw.rect(screen, color_red, (*snake_list[pos_i], snake_size, snake_size))
max_len = round(snake_size * snake_len / 0.2)
del snake_list[max_len:]
推荐阅读
- bubble-sort - 具有可变输入数量的冒泡排序
- javafx - 从终端运行 JavaFX 时出错 - 找不到或加载主类
- c# - 自定义 XAML 绑定源类
- php - 使用不同的 .env 从其他 Artisan 命令调用 Artisan 命令
- reactjs - 反应:在 setState() 之后为不在我的页面上的组件调用渲染函数
- excel - AppleScript 和 Numbers:无法向单元格添加值
- google-sheets - 谷歌表格 | 按类型分组计数项目
- javascript - 如何在 Angular 中将动态数据添加到 IBM 碳表?
- java - 如何初始化反应堆 HttpClient 的基本身份验证标头?
- powerbi - 电源BI。两个表面上相等的计算量度实际上是不同的。为什么?