pyqt5 贪吃蛇

pyqt5 贪吃蛇

通过QPainter绘图实现贪吃蛇
代码原创,如有雷同,定是抄袭!
代码均有注释,方便各位学习
不可转载!

代码源

from PyQt5.QtWidgets import QWidget, QApplication, QMessageBox, QInputDialog
from PyQt5.QtGui import QPainter, QPen, QPalette, QColor
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QBasicTimer
import sys
import random
import os
from collections import deque


class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.message_box_run()  # 消息盒子获取难度信息
        self.init_ui()  # 初始化ui
        self.draw_init()  # 初始化图形
        palette1 = QPalette()  # 背景设置为黑色
        palette1.setColor(self.backgroundRole(), QColor(0, 0, 0))
        self.setPalette(palette1)

    def init_ui(self):

        self.resize(300, 300)
        self.setWindowTitle('贪吃蛇')
        self.timer = QBasicTimer()  # 时钟开启
        self.timer.start(self.global_speed, self)  # 步数为开局获取的步数
        self.show()

    def message_box_run(self):
        int_, ok = QInputDialog().getInt(QWidget(), '选择游戏难度', '输入难度1-10:', 5, 1, 10)
        if not ok:
            os._exit(0)  # 如果获取关闭则关闭游戏
        self.global_speed = (-int_ + 11)*100

    def timerEvent(self, a0) -> None:
        self.update()  # 通过时钟信号更新图像

    def paintEvent(self, e):

        self.qp = QPainter()  # 画图工具继承
        self.qp.begin(self)  # 开启
        self.drawPoints(self.qp)
        self.qp.end()

    def change_foot(self):  # 食物生成
        size = self.size()
        self.point_food = [random.randint(2, size.width() // 10 - 2) * 10,
                           random.randint(2, size.height() // 10 - 2) * 10]

    def drawPoints(self, qp):
        speed = 10  # 运行步距为10像素
        point_temp = self.point
        qp.setPen(QPen(Qt.yellow, 10))  # 设置画笔
        qp.drawPoint(self.point_food[0], self.point_food[1])  # 显示食物

        if point_temp[-1] == self.point_food:  # 对吃下去的食物进行处理
            self.point_temp_food.append(self.point_food)
            self.change_foot()  # 重新创建食物
            while self.point_food in self.point:  # 如果食物和蛇重合就重新创建直到不重合
                self.change_foot()
        # 运动轨迹,尾部减一,头部加一
        if self.key_word == Qt.Key_Right:
            point_temp.popleft()  # 左边,尾巴
            point_temp.append([(point_temp[-1][0] + speed), (point_temp[-1][1])])
            if point_temp[0] in self.point_temp_food:  # 如果发现头部和食物重合就添加在尾部
                self.point_temp_food.remove(point_temp[0])
                point_temp.append(point_temp[-1])

        elif self.key_word == Qt.Key_Left:
            point_temp.popleft()
            point_temp.append([(point_temp[-1][0] - speed), (point_temp[-1][1])])
            if point_temp[0] in self.point_temp_food:
                self.point_temp_food.remove(point_temp[0])
                point_temp.append(point_temp[-1])
        elif self.key_word == Qt.Key_Down:
            point_temp.popleft()
            point_temp.append([(point_temp[-1][0]), (point_temp[-1][1]) + speed])
            if point_temp[0] in self.point_temp_food:
                self.point_temp_food.remove(point_temp[0])
                point_temp.append(point_temp[-1])
        elif self.key_word == Qt.Key_Up:
            point_temp.popleft()
            point_temp.append([(point_temp[-1][0]), (point_temp[-1][1]) - speed])
            if point_temp[0] in self.point_temp_food:
                self.point_temp_food.remove(point_temp[0])
                point_temp.append(point_temp[-1])

        for x, y in point_temp:  # 画出蛇和食物
            qp.drawPoint(x, y)

        self.point = point_temp  # 更新蛇的样子
        self.dead_()  # 判断死亡

    def keyPressEvent(self, event):  # 按键控制
        if event.key() == Qt.Key_Right and self.key_word == Qt.Key_Left:  # 向左不能向右,反之亦然
            return
        elif event.key() == Qt.Key_Left and self.key_word == Qt.Key_Right:
            return
        elif event.key() == Qt.Key_Down and self.key_word == Qt.Key_Up:  # 向上不能向下,反之亦然
            return
        elif event.key() == Qt.Key_Up and self.key_word == Qt.Key_Down:
            return
        elif event.key() == Qt.Key_Escape:  # 如果按到esc就退出
            self.close()

        self.key_word = event.key()  # 将信号储存起来

    def draw_init(self):
        self.point = deque([[130, 150], [140, 150], [150, 150], [160, 150], [170, 150]])  # 初始长度
        self.point_food = [240, 150]  # 初始食物
        self.point_temp_food = deque([])  # 吃下去的食物
        self.key_word = Qt.Key_Right  # 按键数据
        self.qp_init = QPainter()  # 初始化绘图
        self.qp_init.begin(self)
        self.qp_init.setPen(QPen(Qt.yellow, 10))
        for x, y in self.point:
            self.qp_init.drawPoint(x, y)
        self.qp_init.end()

    def dead_(self):
        size = self.size()
        point_temp = self.point.copy()  # 浅复制,如果赋值则认为是指针
        for s in self.point_temp_food:  # 移除干扰的食物
            if s in point_temp:
                point_temp.remove(s)
        point_temp.pop()  # 移除头部
        point_temp.pop()
        if self.point[-1] in point_temp:  # 如果发现头部和身体重合就执行死亡
            self.dead_decide()
        elif self.point[-1][0] == size.width()-0 or self.point[-1][1] == size.height()-0 \
                or self.point[-1][0] == 0 or self.point[-1][1] == 0:  # 如果发现头部碰到四周墙壁就思维
            self.dead_decide()

    def dead_decide(self):
        reply = QMessageBox.question(self, 'Message', f"你死了,游戏结束。得分为{len(self.point)-5}", QMessageBox.Close |
                                     QMessageBox.Retry, QMessageBox.Retry)  # 弹出窗口游戏结算
        if reply == QMessageBox.Close:  # 信号判断
            self.close()  # 选择关闭
        else:
            self.draw_init()  # 选择重新开始


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值