PyQt5 – 彩色游戏

  • Post category:Python

下面我详细讲解一下Python的PyQt5 – 彩色游戏的完整使用攻略。

1. 环境搭建

在开始使用PyQt5 – 彩色游戏之前,需要先安装Python和PyQt5这两个环境。具体安装方法可以参考以下链接:

  • Python官网:https://www.python.org/downloads/
  • PyQt5官网:https://pypi.org/project/PyQt5/

除此之外,还需要安装colorama模块,可以通过以下命令进行安装:

pip install colorama

2. 游戏介绍

这个彩色游戏的规则很简单,场上有多个圆形,每个圆形上有不同的颜色。游戏的目标是将所有圆形连成一条不间断的线,线的颜色需要和所经过的圆形颜色匹配,最后将所有圆形都连上线即可过关。

3. 游戏代码说明

下面是一份基于PyQt5实现的彩色游戏代码,我逐步解释一下代码的作用。

import sys
import random
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPainter, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox


class Circle:
    color_dict = {
        0: QColor(255, 0, 0),  # 红色
        1: QColor(0, 255, 0),  # 绿色
        2: QColor(0, 0, 255),  # 蓝色
        3: QColor(255, 255, 0),  # 黄色
        4: QColor(255, 0, 255),  # 紫色
        5: QColor(0, 255, 255)  # 青色
    }

    def __init__(self, x, y, radius, color=None):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color if color is not None else random.choice(list(self.color_dict.values()))

    def draw(self, painter):
        painter.setPen(Qt.NoPen)
        painter.setBrush(self.color)
        painter.drawEllipse(self.x - self.radius, self.y - self.radius, self.radius * 2, self.radius * 2)


class Game:
    def __init__(self, level=1):
        self.level = level
        self.width = 800
        self.height = 600
        self.circles = self.generate_circles()

    def generate_circles(self):
        colors = list(Circle.color_dict.values())
        count = self.level * 5
        radius = min(self.width, self.height) // (count * 4)
        margin = 2 * radius
        circle_pos = [(x, y) for y in range(margin, self.height - margin, 2 * margin) for x in range(margin, self.width - margin, 2 * margin)]
        circle_pos = random.sample(circle_pos, count)
        circles = [Circle(x, y, radius, random.choice(colors)) for (x, y) in circle_pos]
        return circles

    def draw(self, painter):
        painter.fillRect(0, 0, self.width, self.height, QColor(255, 255, 255))
        for i, circle in enumerate(self.circles):
            circle.draw(painter)

    def check_line(self, line):
        if len(line) != len(self.circles):
            return False
        color_dict = {circle.color: circle for circle in self.circles}
        for i in range(len(line)-1):
            v1 = line[i]
            v2 = line[i+1]
            if v1.color != v2.color:
                return False
            if not self.is_neighbor(color_dict[v1.color], color_dict[v2.color]):
                return False
        return True

    @staticmethod
    def is_neighbor(circle1, circle2):
        return abs(circle1.x - circle2.x) <= circle1.radius * 2 and abs(circle1.y - circle2.y) <= circle1.radius * 2


class MainWindow(QMainWindow):
    def __init__(self, game):
        super().__init__()
        self.game = game
        self.init_gui()

    def init_gui(self):
        self.setGeometry(50, 50, self.game.width, self.game.height)
        self.setWindowTitle("彩色游戏")
        self.show()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        self.game.draw(painter)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            pos = event.pos()
            circle = self.get_clicked_circle(pos)
            if circle is not None and circle not in self.selected_circles():
                circle.color = QColor(0, 0, 0)
                self.update()
                self.check_win()

    def get_clicked_circle(self, pos):
        for circle in self.game.circles:
            if self.check_circle_clicked(circle, pos):
                return circle
        return None

    @staticmethod
    def check_circle_clicked(circle, pos):
        x, y = circle.x, circle.y
        r = circle.radius
        return (pos.x() - x) ** 2 + (pos.y() - y) ** 2 < r ** 2

    def selected_circles(self):
        return [circle for circle in self.game.circles if circle.color == QColor(0, 0, 0)]

    def check_win(self):
        line = self.selected_circles()
        if self.game.check_line(line):
            QMessageBox.information(self, "通关提示", "恭喜你,通关了!")
            self.game = Game(self.game.level + 1)
            self.update()

这份代码主要分为三部分:

  1. Circle类:圆形类,包括位置、大小、颜色等属性,能够绘制自身。
  2. Game类:游戏类,包括随机生成若干个圆形、绘制场景、检测胜利条件等方法。
  3. MainWindow类:主窗口类,用于绘制游戏场景、绑定事件、判断胜利等。

4. 游戏使用示例

示例一:

下面是一个PyQt5 – 彩色游戏的使用示例。运行以下代码,即可开始游戏:

import sys
from PyQt5.QtWidgets import QApplication
from game import Game, MainWindow

app = QApplication(sys.argv)
game = Game()
window = MainWindow(game)
sys.exit(app.exec_())

在程序中,我们创建了一个Game对象和一个MainWindow对象,然后使用QApplication进行初始化,并运行主循环。

示例二:

你也可以在命令行中直接运行游戏:

python game.py

这样就可以从命令行启动游戏了。注意,在运行游戏前需要先安装PyQt5和colorama模块。