Python加Qt实现贪吃蛇

如果没有安装Python和Qt6是运行不了的,先用cmd检查

python --version

输出Python版本则证明已经安装了

如果没有则要提前安装Python,这里就不赘述了

同样cmd,安装Qt6

pip install PyQt6

我这里用的Qt6,当然也可以用其它版本 

安装完成就可以运行了

新建一个py文件,把代码保存到文件中,例如snake.py

cmd打开到文件所在的文件夹,我这里文件放在下面的路径中

cd D:\myFile

用以下命令就可以运行了

python snake.py

 代码:

import sys
import random
from PyQt6.QtWidgets import QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel
from PyQt6.QtGui import QPainter, QColor, QFont, QPen
from PyQt6.QtCore import Qt, QTimer, pyqtSignal


class SnakeGame(QWidget):
    score_updated = pyqtSignal(int)  # 新增信号

    def __init__(self, parent=None):
        super().__init__(parent)
        self.grid_size = 10
        self.grid_width = 100
        self.grid_height = 80
        self.border_width = 2

        self.snake = [(50, 40), (49, 40), (48, 40)]
        self.direction = "right"
        self.food = self.generate_food()
        self.score = 0
        self.game_over_flag = False

        self.timer = QTimer(self)
        self.timer.timeout.connect(self.update_game)

        self.init_ui()
        self.set_speed(150)  # 初始速度
        self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)

    def init_ui(self):
        self.setFixedSize(
            self.grid_width * self.grid_size + 2 * self.border_width,
            self.grid_height * self.grid_size + 2 * self.border_width,
        )
        self.setStyleSheet("background-color: white;")

    def set_speed(self, speed):
        self.timer.stop()
        self.timer.start(speed)

    def generate_food(self):
        while True:
            x = random.randint(0, self.grid_width - 1)
            y = random.randint(0, self.grid_height - 1)
            if (x, y) not in self.snake:
                return x, y

    def update_game(self):
        if self.game_over_flag:
            return

        head = self.snake[0]
        if self.direction == "right":
            new_head = (head[0] + 1, head[1])
        elif self.direction == "left":
            new_head = (head[0] - 1, head[1])
        elif self.direction == "up":
            new_head = (head[0], head[1] - 1)
        else:
            new_head = (head[0], head[1] + 1)

        if (
            new_head[0] < 0
            or new_head[0] >= self.grid_width
            or new_head[1] < 0
            or new_head[1] >= self.grid_height
            or new_head in self.snake[1:]
        ):
            self.game_over()
            return

        self.snake.insert(0, new_head)

        if new_head == self.food:
            self.food = self.generate_food()
            self.score += 1
            self.score_updated.emit(self.score)  # 发射信号
        else:
            self.snake.pop()

        self.update()

    def game_over(self):
        self.timer.stop()
        self.game_over_flag = True
        self.update()

    def keyPressEvent(self, event):
        if self.game_over_flag:
            QApplication.instance().quit()
            return

        key = event.key()
        if key == Qt.Key.Key_Left and self.direction != "right":
            self.direction = "left"
        elif key == Qt.Key.Key_Right and self.direction != "left":
            self.direction = "right"
        elif key == Qt.Key.Key_Up and self.direction != "down":
            self.direction = "up"
        elif key == Qt.Key.Key_Down and self.direction != "up":
            self.direction = "down"
        elif key == Qt.Key.Key_1:
            self.set_speed(200)  # 慢速
        elif key == Qt.Key.Key_2:
            self.set_speed(150)  # 中速
        elif key == Qt.Key.Key_3:
            self.set_speed(100)  # 快速
        elif key == Qt.Key.Key_4:
            self.set_speed(50)  # 超快速

    def paintEvent(self, event):
        painter = QPainter(self)

        # 画边框
        painter.setPen(QPen(QColor(0, 0, 0), self.border_width))
        painter.drawRect(
            self.border_width // 2,
            self.border_width // 2,
            self.width() - self.border_width,
            self.height() - self.border_width,
        )

        painter.setPen(Qt.PenStyle.NoPen)

        # 画蛇身
        painter.setBrush(QColor(0, 200, 0))
        for segment in self.snake[1:]:
            painter.drawRect(
                segment[0] * self.grid_size + self.border_width,
                segment[1] * self.grid_size + self.border_width,
                self.grid_size,
                self.grid_size,
            )

        # 画蛇头(黑色)
        painter.setBrush(QColor(0, 0, 0))
        head = self.snake[0]
        painter.drawRect(
            head[0] * self.grid_size + self.border_width,
            head[1] * self.grid_size + self.border_width,
            self.grid_size,
            self.grid_size,
        )

        # 画食物
        painter.setBrush(QColor(255, 0, 0))
        painter.drawRect(
            self.food[0] * self.grid_size + self.border_width,
            self.food[1] * self.grid_size + self.border_width,
            self.grid_size,
            self.grid_size,
        )

        # 如果游戏结束,显示"GAME OVER"
        if self.game_over_flag:
            painter.setPen(QPen(QColor(255, 0, 0)))
            painter.setFont(QFont("Arial", 30))
            painter.drawText(self.rect(), Qt.AlignmentFlag.AlignCenter, "GAME OVER")


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Snake Game")

        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        layout = QVBoxLayout()
        central_widget.setLayout(layout)

        self.game_widget = SnakeGame(self)
        layout.addWidget(self.game_widget)

        self.score_label = QLabel("Score: 0")
        self.score_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.score_label.setFont(QFont("Arial", 16))
        layout.addWidget(self.score_label)

        self.speed_label = QLabel("Press 1-4 to change speed (1: Slow, 4: Fast)")
        self.speed_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(self.speed_label)

        self.game_over_label = QLabel("Press any key to exit when game is over")
        self.game_over_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(self.game_over_label)

        self.adjustSize()
        self.center_on_screen()

        # 连接信号和槽
        self.game_widget.score_updated.connect(self.update_score)

    def update_score(self, score):
        self.score_label.setText(f"Score: {score}")

    def center_on_screen(self):
        screen = QApplication.primaryScreen().availableGeometry()
        size = self.geometry()
        self.move(
            (screen.width() - size.width()) // 2, 
            (screen.height() - size.height()) // 2
        )


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

附:运行的时候可以按1 ~ 4来调节速度,快慢尽在掌控 ~

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个简单的贪吃实现思路和部分代码。 首先,您需要使用 Qt 框架创建一个新的 C++ 项目。然后,您需要创建一个 Snake 类来表示贪吃的状态和行为。这个类应该包含以下属性: - 当前的长度 - 当前的位置 - 当前的方向 - 当前的速度 - 当前的身体部分 贪吃的主要行为包括: - 移动:根据当前方向和速度移动的位置 - 改变方向:根据用户输入改变的方向 - 吃食物:如果的头部碰到了食物,就将其入到的身体中,并增的长度 - 碰撞检测:检测是否与边界或自己的身体碰撞,如果是,则游戏结束 下面是一个简单的 Snake 类的实现: ```cpp class Snake { public: Snake(int x, int y, int length, int speed){ // 初始化的位置、长度和速度 } void move(){ // 根据当前方向和速度移动的位置 } void changeDirection(Direction direction){ // 根据用户输入改变的方向 } void eatFood(Food food){ // 如果的头部碰到了食物,就将其入到的身体中,并增的长度 } bool isGameOver(){ // 检测是否与边界或自己的身体碰撞,如果是,则游戏结束 } private: int m_x; int m_y; int m_length; int m_speed; Direction m_direction; QList<QPoint> m_body; }; ``` 在主窗口中,您需要创建一个 QTimer 对象来定期更新游戏状态。在每次定时器超时时,您需要更新的位置、检测是否吃到了食物、检测是否游戏结束等。您还需要在窗口中绘制和食物的位置。下面是一个简单的 MainWindow 类的实现: ```cpp class MainWindow : public QMainWindow { public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { // 设置窗口大小、标题等 // 创建游戏场景和对象 // 创建定时器,设置定时器超时信号的槽函数 } private slots: void updateGame(){ // 更新的位置、检测是否吃到了食物、检测是否游戏结束等 // 绘制和食物的位置 } private: QGraphicsScene *m_scene; Snake *m_snake; QTimer *m_timer; }; ``` 这只是一个简单的贪吃实现思路,您可以根据需要进行修改和扩展。希望对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值