想必贪吃蛇这个游戏大家都玩过,那么贪吃蛇怎么在python代码里实现呢?
今天需要引入
PyQt5是一个基于Qt框架的Python GUI编程工具包,它提供了一系列的Python模块,使得开发者可以使用Python语言来开发跨平台的桌面应用程序。PyQt5是Qt官方推荐的Python绑定工具之一,它支持最新的Qt 5框架,并且提供了良好的文档和示例代码。
PyQt5包含了大量的类和函数,可以用于创建各种GUI组件,如窗口、标签、按钮、列表框、文本框等等。它还提供了一些高级组件,如图形场景、绘图区域、多媒体播放器等等。此外,PyQt5还支持与Qt Designer集成,使得开发者可以使用可视化的方式设计和布局界面。
根据需求需要引用如下的类和函数:
from PyQt5.QtWidgets import QApplication, QMainWindow, QDesktopWidget, QLabel, QPushButton, QGraphicsScene, QGraphicsView
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter
简单介绍这些类和函数:
QApplication:Qt应用程序类,用于管理应用程序的生命周期和事件循环。QMainWindow:Qt主窗口类,提供了一个带有菜单栏、工具栏、状态栏等基本界面组件的窗口。QDesktopWidget:Qt桌面窗口类,提供了一些方法来获取桌面的大小和屏幕分辨率等信息。QLabel:Qt标签类,用于显示文本或图像等内容。QPushButton:Qt按钮类,用于创建可点击的按钮。QGraphicsScene:Qt图形场景类,提供了一个二维图形场景,可以在其中添加、移动、缩放和旋转图形项。QGraphicsView:Qt图形视图类,提供了一个二维图形视图,可以在其中显示QGraphicsScene中的图形项。QPainter:Qt绘图类,提供了一些方法来绘制各种图形、文本和图像等内容。
源代码如下所示(详细注释已列出):
import sys
import random
import pygame
from PyQt5.QtWidgets import QApplication, QMainWindow, QDesktopWidget, QLabel, QPushButton, QGraphicsScene, QGraphicsView
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter
# 游戏窗口大小
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
# 贪吃蛇方块大小
BLOCK_SIZE = 20
# 游戏区域大小
GAME_AREA_WIDTH = WINDOW_WIDTH - BLOCK_SIZE * 2
GAME_AREA_HEIGHT = WINDOW_HEIGHT - BLOCK_SIZE * 6
# 贪吃蛇初始位置
SNAKE_INIT_X = GAME_AREA_WIDTH // 2
SNAKE_INIT_Y = GAME_AREA_HEIGHT // 2
# 贪吃蛇初始移动方向
SNAKE_INIT_DIRECTION = 'right'
# 食物颜色
FOOD_COLOR = (255, 0, 0)
# 贪吃蛇颜色
SNAKE_COLOR = (0, 255, 0)
# 分数颜色
SCORE_COLOR = (255, 255, 255)
class SnakeGame:
def __init__(self):
# 初始化Pygame库
pygame.init()
# 创建游戏窗口
self.window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('Snake Game')
# 创建游戏区域表面
self.game_area_surface = pygame.Surface((GAME_AREA_WIDTH, GAME_AREA_HEIGHT))
# 创建游戏区域矩形
self.game_area_rect = pygame.Rect(BLOCK_SIZE, BLOCK_SIZE, GAME_AREA_WIDTH, GAME_AREA_HEIGHT)
# 创建贪吃蛇表面
self.snake_surface = pygame.Surface((BLOCK_SIZE, BLOCK_SIZE))
# 创建食物表面
self.food_surface = pygame.Surface((BLOCK_SIZE, BLOCK_SIZE))
self.food_surface.fill(FOOD_COLOR)
# 创建贪吃蛇初始位置和移动方向
self.snake = [(SNAKE_INIT_X, SNAKE_INIT_Y)]
self.direction = SNAKE_INIT_DIRECTION
# 创建食物位置
self.food_pos = self.get_random_pos()
# 创建分数
self.score = 0
def start(self):
# 创建游戏时钟
clock = pygame.time.Clock()
# 游戏循环
while True:
# 处理事件
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_UP and self.direction != 'down':
self.direction = 'up'
elif event.key == pygame.K_DOWN and self.direction != 'up':
self.direction = 'down'
elif event.key == pygame.K_LEFT and self.direction != 'right':
self.direction = 'left'
elif event.key == pygame.K_RIGHT and self.direction != 'left':
self.direction = 'right'
# 移动贪吃蛇
head_x, head_y = self.snake[0]
if self.direction == 'up':
head_y -= BLOCK_SIZE
elif self.direction == 'down':
head_y += BLOCK_SIZE
elif self.direction == 'left':
head_x -= BLOCK_SIZE
elif self.direction == 'right':
head_x += BLOCK_SIZE
# 判断是否吃到食物
if head_x == self.food_pos[0] and head_y == self.food_pos[1]:
self.snake.insert(0, (head_x, head_y))
self.food_pos = self.get_random_pos()
self.score += 10
else:
# 删除贪吃蛇尾部方块
self.snake.pop()
# 判断是否撞墙或自撞
if not (BLOCK_SIZE <= head_x < GAME_AREA_WIDTH and BLOCK_SIZE <= head_y < GAME_AREA_HEIGHT) or (head_x, head_y) in self.snake:
self.game_over()
else:
# 添加贪吃蛇头部方块
self.snake.insert(0, (head_x, head_y))
# 绘制游戏区域和贪吃蛇
self.game_area_surface.fill((0, 0, 0))
for pos in self.snake:
pygame.draw.rect(self.game_area_surface, SNAKE_COLOR, (pos[0]-BLOCK_SIZE, pos[1]-BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE))
self.game_area_surface.blit(self.food_surface, (self.food_pos[0]-BLOCK_SIZE, self.food_pos[1]-BLOCK_SIZE))
# 绘制分数
font = pygame.font.SysFont(None, 36)
score_text = font.render(f'Score: {self.score}', True, SCORE_COLOR)
score_rect = score_text.get_rect()
score_rect.centerx = WINDOW_WIDTH // 2
score_rect.top = BLOCK_SIZE // 2
self.game_area_surface.blit(score_text, score_rect)
# 将游戏区域表面绘制到游戏窗口中央位置
window_centerx = WINDOW_WIDTH // 2
window_centery = WINDOW_HEIGHT // 2
game_area_centerx = BLOCK_SIZE + GAME_AREA_WIDTH // 2
game_area_centery = BLOCK_SIZE + GAME_AREA_HEIGHT // 2
x_offset = window_centerx - game_area_centerx
y_offset = window_centery - game_area_centery
self.window.fill((0, 0, 0))
self.window.blit(self.game_area_surface, (x_offset, y_offset))
# 刷新屏幕并控制帧率
pygame.display.update()
clock.tick(10)
def get_random_pos(self):
x = random.randint(BLOCK_SIZE, GAME_AREA_WIDTH - BLOCK_SIZE)
y = random.randint(BLOCK_SIZE, GAME_AREA_HEIGHT - BLOCK_SIZE)
return (x // BLOCK_SIZE * BLOCK_SIZE, y // BLOCK_SIZE * BLOCK_SIZE)
def game_over(self):
print('Game over!')
pygame.quit()
sys.exit()
class SnakeWindow(QMainWindow):
def __init__(self):
super().__init__()
# 设置窗口标题和大小
self.setWindowTitle('Snake Game')
self.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
# 设置窗口居中显示
screen_rect = QDesktopWidget().availableGeometry(self)
window_rect = self.frameGeometry()
window_rect.moveCenter(screen_rect.center())
self.move(window_rect.topLeft())
# 创建游戏场景和视图
scene = QGraphicsScene()
view = QGraphicsView(scene)
view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
view.setRenderHint(QPainter.Antialiasing)
view.setViewportUpdateMode(QGraphicsView.FullViewportUpdate)
view.setFixedSize(WINDOW_WIDTH, WINDOW_HEIGHT)
# 创建游戏标签和按钮
label = QLabel('Snake Game', view)
label.setAlignment(Qt.AlignCenter)
label.setGeometry(0, 50, WINDOW_WIDTH, 100)
button_start = QPushButton('Start', view)
button_start.setGeometry(150, 200, 100, 50)
button_start.clicked.connect(self.start_game)
button_exit = QPushButton('Exit', view)
button_exit.setGeometry(550, 200, 100, 50)
button_exit.clicked.connect(self.close)
# 将视图设置为主窗口的中心部件
self.setCentralWidget(view)
def start_game(self):
# 创建SnakeGame对象并开始游戏循环
game = SnakeGame()
game.start()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = SnakeWindow()
window.show()
sys.exit(app.exec_())我们运行测试一下:


这里食物在窗口内随机生成,当蛇吃入食物以后自己的身长会增加一格,随之分数会增加。当蛇自己碰撞到自己身体或者撞到窗口边缘则会游戏结束。感兴趣的同学在pycharm里尝试一下吧,有不理解的欢迎在评论区留言讨论。
