2024-07-14 00:10:48 +08:00
|
|
|
|
import pygame
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_events(settings):
|
|
|
|
|
for event in pygame.event.get():
|
|
|
|
|
# 当按关闭或者按ESC键退出游戏
|
|
|
|
|
if event.type == pygame.QUIT:
|
|
|
|
|
pygame.quit()
|
|
|
|
|
sys.exit()
|
|
|
|
|
elif event.type == pygame.KEYDOWN:
|
|
|
|
|
if event.key == pygame.K_ESCAPE:
|
|
|
|
|
pygame.quit()
|
|
|
|
|
sys.exit()
|
|
|
|
|
# 按1键选择手动模式
|
|
|
|
|
elif event.key == pygame.K_1:
|
2024-07-15 00:53:49 +08:00
|
|
|
|
settings.game_mode = 1
|
2024-07-14 00:10:48 +08:00
|
|
|
|
# 按2键选择自动模式
|
|
|
|
|
elif event.key == pygame.K_2:
|
2024-07-15 00:53:49 +08:00
|
|
|
|
settings.game_mode = 2
|
2024-07-14 00:10:48 +08:00
|
|
|
|
|
2024-07-18 16:48:01 +08:00
|
|
|
|
|
|
|
|
|
def check_play_events(snake):
|
|
|
|
|
"""检测游戏过程中的按键"""
|
|
|
|
|
for event in pygame.event.get():
|
|
|
|
|
if event.type == pygame.QUIT:
|
|
|
|
|
pygame.quit()
|
|
|
|
|
sys.exit()
|
|
|
|
|
elif event.type == pygame.KEYDOWN:
|
|
|
|
|
if event.key == pygame.K_ESCAPE:
|
|
|
|
|
pygame.quit()
|
|
|
|
|
sys.exit()
|
|
|
|
|
elif event.key == pygame.K_LEFT and not snake.direction == 'right': #防止反向移动
|
|
|
|
|
snake.direction = 'left'
|
|
|
|
|
break
|
|
|
|
|
elif event.key == pygame.K_RIGHT and not snake.direction == 'left':
|
|
|
|
|
snake.direction = 'right'
|
|
|
|
|
break
|
|
|
|
|
elif event.key == pygame.K_UP and not snake.direction == 'down':
|
|
|
|
|
snake.direction = 'up'
|
|
|
|
|
break
|
|
|
|
|
elif event.key == pygame.K_DOWN and not snake.direction == 'up':
|
|
|
|
|
snake.direction = 'down'
|
|
|
|
|
break
|
|
|
|
|
|
2024-07-14 00:10:48 +08:00
|
|
|
|
|
|
|
|
|
def show_start(settings, screen):
|
|
|
|
|
"""模式选择界面"""
|
2024-07-14 00:46:17 +08:00
|
|
|
|
title_Font = pygame.font.Font(settings.font_name, 80) # 设置标题字体
|
2024-07-14 00:10:48 +08:00
|
|
|
|
title_image = title_Font.render("贪吃蛇", True, (255, 255, 255), (0, 0, 0))
|
|
|
|
|
title_rect = title_image.get_rect()
|
|
|
|
|
title_rect.center = screen.get_rect().center
|
|
|
|
|
|
2024-07-14 00:46:17 +08:00
|
|
|
|
presskey_font = pygame.font.Font(settings.font_name, 15) # 设置说明文字的字体
|
2024-07-14 00:10:48 +08:00
|
|
|
|
presskey_image = presskey_font.render(
|
|
|
|
|
'按1为手动模式,按2为自动模式,按ESC可退出游戏', True, (255, 255, 255), (0, 0, 0))
|
|
|
|
|
presskey_rect = presskey_image.get_rect()
|
|
|
|
|
presskey_rect.centerx = title_rect.centerx
|
|
|
|
|
presskey_rect.top = title_rect.bottom
|
2024-07-18 16:48:01 +08:00
|
|
|
|
|
|
|
|
|
screen.fill(settings.bg_color) # 绘制屏幕
|
|
|
|
|
screen.blit(title_image, title_rect) # 绘制标题
|
|
|
|
|
screen.blit(presskey_image, presskey_rect) # 绘制说明文字
|
2024-07-14 00:10:48 +08:00
|
|
|
|
while True:
|
|
|
|
|
check_events(settings) # 检测键盘
|
|
|
|
|
if settings.game_mode != 0: # 说明按了1或2,退出循环
|
|
|
|
|
break
|
|
|
|
|
pygame.display.flip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def show_end(settings, screen):
|
2024-07-15 00:53:49 +08:00
|
|
|
|
"""失败结算界面"""
|
2024-07-14 00:46:17 +08:00
|
|
|
|
title_font = pygame.font.Font(settings.font_name, 80)
|
2024-07-14 00:10:48 +08:00
|
|
|
|
game_image = title_font.render('Game', True, (233, 150, 122))
|
|
|
|
|
over_image = title_font.render('Over', True, (233, 150, 122))
|
|
|
|
|
game_rect = game_image.get_rect()
|
|
|
|
|
over_rect = over_image.get_rect()
|
|
|
|
|
screen_rect = screen.get_rect()
|
|
|
|
|
game_rect.midtop = (settings.width / 2, screen_rect.top + 70)
|
|
|
|
|
over_rect.midtop = (settings.width / 2, game_rect.bottom + 50)
|
|
|
|
|
screen.blit(game_image, game_rect)
|
|
|
|
|
screen.blit(over_image, over_rect)
|
|
|
|
|
pygame.display.flip()
|
|
|
|
|
pygame.time.wait(1500)
|
|
|
|
|
settings.game_mode = 0
|
2024-07-15 00:53:49 +08:00
|
|
|
|
|
2024-07-15 01:07:37 +08:00
|
|
|
|
|
2024-07-15 00:53:49 +08:00
|
|
|
|
def draw_grid(settings, screen):
|
2024-07-15 01:07:37 +08:00
|
|
|
|
# 绘制横向线
|
|
|
|
|
for x in range(0, settings.width, settings.cell_size):
|
|
|
|
|
pygame.draw.line(screen, (40, 40, 40), (x, 0), (x, settings.height))
|
|
|
|
|
# 绘制竖向线
|
|
|
|
|
for y in range(0, settings.height, settings.cell_size):
|
|
|
|
|
pygame.draw.line(screen, (40, 40, 40), (0, y), (settings.width, y))
|
|
|
|
|
|
|
|
|
|
|
2024-07-18 16:48:01 +08:00
|
|
|
|
def draw_snake(settings, screen, snake):
|
2024-07-15 01:07:37 +08:00
|
|
|
|
# 头部用白色
|
2024-07-18 16:48:01 +08:00
|
|
|
|
head_index = snake.coords[0]
|
|
|
|
|
x = head_index['x'] * settings.cell_size
|
|
|
|
|
y = head_index['y'] * settings.cell_size
|
2024-07-15 01:07:37 +08:00
|
|
|
|
snake_head_rect = pygame.Rect(
|
2024-07-18 16:48:01 +08:00
|
|
|
|
x, y, settings.cell_size, settings.cell_size)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
pygame.draw.rect(screen, (255, 255, 255), snake_head_rect)
|
|
|
|
|
# 蛇身内部用浅绿,外框用深绿
|
2024-07-18 16:48:01 +08:00
|
|
|
|
for bodies_index in snake.coords[1: -1]:
|
|
|
|
|
x = bodies_index['x'] * settings.cell_size
|
|
|
|
|
y = bodies_index['y'] * settings.cell_size
|
2024-07-15 01:07:37 +08:00
|
|
|
|
snake_part_rect = pygame.Rect(
|
2024-07-18 16:48:01 +08:00
|
|
|
|
x, y, settings.cell_size, settings.cell_size)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
pygame.draw.rect(screen, (0, 155, 0), snake_part_rect)
|
|
|
|
|
snake_part_inner_rect = pygame.Rect(
|
2024-07-18 16:48:01 +08:00
|
|
|
|
x + 4, y + 4, settings.cell_size - 8, settings.cell_size - 8)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
pygame.draw.rect(screen, (0, 255, 0), snake_part_inner_rect)
|
|
|
|
|
# 蛇尾用浅绿
|
2024-07-18 16:48:01 +08:00
|
|
|
|
tail_index = snake.coords[-1]
|
|
|
|
|
x = tail_index['x'] * settings.cell_size
|
|
|
|
|
y = tail_index['y'] * settings.cell_size
|
2024-07-15 01:07:37 +08:00
|
|
|
|
snake_tail_rect = pygame.Rect(
|
2024-07-18 16:48:01 +08:00
|
|
|
|
x, y, settings.cell_size, settings.cell_size)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
pygame.draw.rect(screen, (0, 255, 0), snake_tail_rect)
|
|
|
|
|
|
2024-07-18 16:48:01 +08:00
|
|
|
|
|
|
|
|
|
def draw_apple(apple,settings,screen):
|
|
|
|
|
x = apple.x * settings.cell_size
|
|
|
|
|
y = apple.y * settings.cell_size
|
|
|
|
|
apple_rect = pygame.Rect(
|
|
|
|
|
x, y, settings.cell_size, settings.cell_size)
|
|
|
|
|
pygame.draw.rect(screen, (255, 0, 0), apple_rect)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
|
|
|
|
|
|
2024-07-18 16:48:01 +08:00
|
|
|
|
# 绘制游戏界面
|
|
|
|
|
def update_screen(settings, screen, snake,apple):
|
2024-07-15 01:07:37 +08:00
|
|
|
|
screen.fill(settings.bg_color)
|
|
|
|
|
draw_grid(settings, screen)
|
2024-07-18 16:48:01 +08:00
|
|
|
|
draw_apple(apple,settings,screen)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
# 移动蛇
|
2024-07-18 16:48:01 +08:00
|
|
|
|
snake.move_head() # 加蛇头
|
|
|
|
|
if game_over(snake,settings):
|
2024-07-15 01:07:37 +08:00
|
|
|
|
settings.game_mode = -1
|
2024-07-18 16:48:01 +08:00
|
|
|
|
elif eat_apple(snake,apple):
|
|
|
|
|
apple.spawn(settings)
|
|
|
|
|
draw_apple(apple,settings,screen)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
else:
|
2024-07-18 16:48:01 +08:00
|
|
|
|
del snake.coords[-1] # 去蛇尾
|
|
|
|
|
draw_snake(settings, screen, snake)
|
|
|
|
|
pygame.display.flip()
|
|
|
|
|
# 暂停一下
|
|
|
|
|
settings.my_clock.tick(settings.clock_frq)
|
2024-07-15 01:07:37 +08:00
|
|
|
|
|
|
|
|
|
|
2024-07-18 16:48:01 +08:00
|
|
|
|
def game_over(snake,settings):
|
2024-07-15 01:07:37 +08:00
|
|
|
|
# 碰到左右墙壁
|
|
|
|
|
if (snake.coords[snake.head_index]['x'] == -1 or snake.coords[snake.head_index]['x'] == settings.cell_w):
|
2024-07-18 16:48:01 +08:00
|
|
|
|
return True
|
2024-07-15 01:07:37 +08:00
|
|
|
|
# 碰到上下墙壁
|
|
|
|
|
if (snake.coords[snake.head_index]['y'] == -1 or snake.coords[snake.head_index]['y'] == settings.cell_h):
|
2024-07-18 16:48:01 +08:00
|
|
|
|
return True
|
2024-07-15 01:07:37 +08:00
|
|
|
|
# 碰到自己
|
|
|
|
|
if (snake.coords[snake.head_index] in snake.coords[1:]):
|
2024-07-18 16:48:01 +08:00
|
|
|
|
return True
|
|
|
|
|
return False
|
2024-07-15 01:07:37 +08:00
|
|
|
|
|
|
|
|
|
|
2024-07-18 16:48:01 +08:00
|
|
|
|
def eat_apple(snake,apple):
|
|
|
|
|
if (snake.coords[snake.head_index]['x'] == apple.x and snake.coords[snake.head_index]['y'] == apple.y):
|
|
|
|
|
return True
|
|
|
|
|
return False
|