使用Python语言写一个贪吃蛇小游戏,要求是能够实现自动寻径
时间: 2024-01-07 18:02:58 浏览: 84
Python编写一个贪吃蛇游戏
好的,以下是一个使用 Python 实现的贪吃蛇小游戏,并且实现了自动寻径的功能:
```python
import pygame
import random
# 初始化 Pygame
pygame.init()
# 定义颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# 定义游戏窗口大小和方块大小
WINDOW_WIDTH = 480
WINDOW_HEIGHT = 480
BLOCK_SIZE = 20
# 创建游戏窗口
WINDOW = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("贪吃蛇")
# 定义字体
FONT = pygame.font.SysFont(None, 30)
# 定义方向常量
LEFT = (-1, 0)
RIGHT = (1, 0)
UP = (0, -1)
DOWN = (0, 1)
# 定义贪吃蛇类
class Snake:
def __init__(self):
self.head = (WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2)
self.body = [self.head]
self.direction = random.choice([LEFT, RIGHT, UP, DOWN])
# 获取下一步的位置
def get_next_pos(self):
return (self.head[0] + self.direction[0] * BLOCK_SIZE, self.head[1] + self.direction[1] * BLOCK_SIZE)
# 移动贪吃蛇
def move(self):
next_pos = self.get_next_pos()
self.body.insert(0, next_pos)
self.head = next_pos
self.body.pop()
# 改变贪吃蛇的方向
def change_direction(self, direction):
if direction != (-self.direction[0], -self.direction[1]):
self.direction = direction
# 检查是否吃到食物
def check_eat_food(self, food):
if self.head == food:
self.body.append(self.body[-1])
return True
return False
# 检查是否撞墙或撞到自己
def check_game_over(self):
if self.head[0] < 0 or self.head[0] >= WINDOW_WIDTH or self.head[1] < 0 or self.head[1] >= WINDOW_HEIGHT:
return True
for pos in self.body[1:]:
if self.head == pos:
return True
return False
# 定义食物类
class Food:
def __init__(self):
self.pos = self.get_random_pos()
# 获取随机位置
def get_random_pos(self):
return (random.randint(0, (WINDOW_WIDTH - BLOCK_SIZE) // BLOCK_SIZE) * BLOCK_SIZE,
random.randint(0, (WINDOW_HEIGHT - BLOCK_SIZE) // BLOCK_SIZE) * BLOCK_SIZE)
# 重新生成食物
def regenerate(self):
self.pos = self.get_random_pos()
# 定义 A* 寻路算法
def astar_search(start, end, obstacles):
# 定义节点类
class Node:
def __init__(self, pos, parent=None):
self.pos = pos
self.parent = parent
self.g = 0
self.h = abs(pos[0] - end[0]) + abs(pos[1] - end[1])
self.f = self.g + self.h
# 计算 G 值
def calc_g(self):
if self.parent:
self.g = self.parent.g + 1
else:
self.g = 0
self.f = self.g + self.h
# 获取邻居节点
def get_neighbors(self):
neighbors = [(self.pos[0] + 1, self.pos[1]),
(self.pos[0] - 1, self.pos[1]),
(self.pos[0], self.pos[1] + 1),
(self.pos[0], self.pos[1] - 1)]
neighbors = [pos for pos in neighbors if pos[0] >= 0 and pos[0] < WINDOW_WIDTH // BLOCK_SIZE and
pos[1] >= 0 and pos[1] < WINDOW_HEIGHT // BLOCK_SIZE]
neighbors = [pos for pos in neighbors if pos not in obstacles]
return neighbors
# 判断节点是否相同
def __eq__(self, other):
return self.pos == other.pos
def __hash__(self):
return hash(self.pos)
# 定义 open 和 close 列表
open_list = set()
close_list = set()
# 创建起点和终点节点
start_node = Node(start)
end_node = Node(end)
# 将起点加入 open 列表
open_list.add(start_node)
while open_list:
# 获取 F 值最小的节点,并将其从 open 列表中移除
current_node = min(open_list, key=lambda node: node.f)
open_list.remove(current_node)
# 将当前节点加入 close 列表
close_list.add(current_node)
if current_node == end_node:
# 生成路径
path = []
while current_node:
path.append(current_node.pos)
current_node = current_node.parent
path.reverse()
return path
# 获取邻居节点
neighbors = current_node.get_neighbors()
for neighbor_pos in neighbors:
neighbor_node = Node(neighbor_pos, current_node)
if neighbor_node in close_list:
continue
if neighbor_node not in open_list:
neighbor_node.calc_g()
open_list.add(neighbor_node)
else:
if current_node.g + 1 < neighbor_node.g:
neighbor_node.parent = current_node
neighbor_node.calc_g()
# 没有找到路径,返回空列表
return []
# 定义主函数
def main():
# 创建贪吃蛇和食物对象
snake = Snake()
food = Food()
# 定义计时器和时间常量
clock = pygame.time.Clock()
MOVE_INTERVAL = 100
# 定义初始方向,防止贪吃蛇立即掉头
direction = snake.direction
# 游戏循环
while True:
# 处理事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
return
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
direction = LEFT
elif event.key == pygame.K_RIGHT:
direction = RIGHT
elif event.key == pygame.K_UP:
direction = UP
elif event.key == pygame.K_DOWN:
direction = DOWN
# 计算贪吃蛇的下一步位置
next_pos = snake.get_next_pos()
# 如果下一步位置是食物,则重新生成食物
if snake.check_eat_food(food.pos):
food.regenerate()
# 计算 A* 寻路
obstacles = snake.body + [food.pos]
path = astar_search(snake.head, food.pos, obstacles)
# 如果 A* 寻路成功,则根据路径来改变方向
if path:
next_pos = path[1]
dx = next_pos[0] - snake.head[0]
dy = next_pos[1] - snake.head[1]
if dx < 0:
direction = LEFT
elif dx > 0:
direction = RIGHT
elif dy < 0:
direction = UP
elif dy > 0:
direction = DOWN
# 移动贪吃蛇
snake.change_direction(direction)
snake.move()
# 检查游戏是否结束
if snake.check_game_over():
pygame.quit()
return
# 绘制游戏界面
WINDOW.fill(BLACK)
for pos in snake.body:
pygame.draw.rect(WINDOW, GREEN, (pos[0], pos[1], BLOCK_SIZE, BLOCK_SIZE))
pygame.draw.rect(WINDOW, RED, (food.pos[0], food.pos[1], BLOCK_SIZE, BLOCK_SIZE))
score_text = FONT.render("Score: {}".format(len(snake.body) - 1), True, WHITE)
WINDOW.blit(score_text, (10, 10))
pygame.display.update()
# 控制帧率
clock.tick(60)
# 控制贪吃蛇移动的时间间隔
pygame.time.delay(MOVE_INTERVAL)
# 运行主函数
if __name__ == "__main__":
main()
```
这个贪吃蛇小游戏可以使用方向键来控制贪吃蛇的移动方向,同时也实现了自动寻径功能,使用 A* 寻路算法来计算贪吃蛇下一步的位置。
阅读全文