Python pyglet制作彩色圆圈“连连看”游戏

原文链接: 

Python 一步一步教你用pyglet制作“彩色方块连连看”游戏(续)-CSDN博客文章浏览阅读1.6k次,点赞75次,收藏55次。上期讲到相同的色块连接,链接见: Python 一步一步教你用pyglet制作“彩色方块连连看”游戏-CSDN博客续上期,接下来要实现相邻方块的连线:首先来进一步扩展 行列的类......https://blog.csdn.net/boysoft2002/article/details/137063657

彩色圆圈“连连看”

有个网友留言要把原文中的方块改成圆圈,再要加入消去的分数。大致效果如下: 

以下就把原文的代码作几步简单的修改:

Box类的修改

class Box:
    def __init__(self, x, y, w, h, color, batch=batch):
        self.x, self.y, self.w, self.h = x, y, w, h
        self.rect = shapes.Rectangle(x, y, w, h, color=color, batch=batch)
        self.box = shapes.Box(x, y, w, h, color=Color('WHITE').rgba, thickness=3, batch=batch)

    def hide(self):
        self.box.batch = self.rect.batch = None
    def show(self):
        self.box.batch = self.rect.batch = batch
    def on_mouse_over(self, x, y):
        return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.h

把矩形及方框用圆圈和圆弧来代替:

        self.rect = shapes.Circle(x+w//2, y+h//2, min(w,h)//2, color=color, batch=batch)
        self.box = shapes.Arc(x+w//2, y+h//2, min(w,h)//2, color=Color('WHITE').rgba, batch=batch)

Game类的修改 

Game类中增加分数属性:

class Game:
    def __init__(self):
        initMatrix(row, col)
        self.score = 0
        self.rc, self.rc2 = Point(), Point()
        self.array, self.arces = Array, Boxes

update方法中增加分数和显示

    def update(self, event):
        clock.unschedule(self.update)
        if self.last1.cir.color==self.last2.cir.color and matrix.connect(self.rc, self.rc2):
            self.hide()
            sound1.play()
            self.score += 10
            window.set_caption(window.caption.split('分数:')[0] + f'分数:{self.score}')

        ......

点击事件的修改

在on_mouse_press事件中增加分数的显示:

@window.event
def on_mouse_press(x, y, dx, dy):
    global score
    if (ret := game.on_mouse_click(x, y)):
        window.set_caption(f'彩色方块连连看——坐标:{ret[0]}  颜色:{ret[1]}  分数:{game.score}')

部分代码的替代

在源码全文中搜索并替代: .rect 替换为 .cir ; .box 替换为 .arc

class Box类名也可以修改一下,不作修改也不影响代码的运行。

大致就以上几步就完成了修改:

完整代码 

from pyglet import *
from colorlib import *
from pointlib import Point
from pyglet.window import key
 
W, H = 800, 600
window = window.Window(W, H)
gl.glClearColor(*Color('lightblue3').decimal)
batch, batch2, group = graphics.Batch(), graphics.Batch(), graphics.Group()
 
row, col, space = 8, 10, 5
w, h = W//(col+2), H//(row+2)
x0, y0 = (W-(w+space)*col)//2, (H-(h+space)*row)//2
 
sound1, sound2 = media.load('box.mp3'), media.load('box2.mp3')
 
def randColor():
    COLOR = []
    while len(COLOR)<row*col//4:
        if not ((c:=randcolorTuple()) in COLOR or Color(c).name[-1] in '0123456789'):
            COLOR.append(c)
    return sample(COLOR*4, row*col)
 
class Box:
    def __init__(self, x, y, w, h, color, batch=batch):
        self.x, self.y, self.w, self.h = x, y, w, h
        self.cir = shapes.Circle(x+w//2, y+h//2, min(w,h)//2, color=color, batch=batch)
        self.arc = shapes.Arc(x+w//2, y+h//2, min(w,h)//2, color=Color('WHITE').rgba, batch=batch)
    def hide(self):
        self.arc.batch = self.cir.batch = None
    def show(self):
        self.arc.batch = self.cir.batch = batch
    def on_mouse_over(self, x, y):
        return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.h
 
class Matrix:
    def __init__(self, r=row, c=col):
        self.array = [[1]*c for _ in range(r)]
        self.point = []
        self.lines = [shapes.Line(*[-3]*4, width=5, color=Color('light gold').rgba,
                            batch=batch2, group=group) for _ in range(5)]
        for line in self.lines: line.visible = False
    def __repr__(self):
        return '\n'.join(map(str,self.array))+'\n'
    def true(self, point):
        try: return self.array[point.x+1][point.y+1]
        except: return 0
    def alltrue(self, points):
        if isinstance(points,(tuple,list)) and all(isinstance(p, Point) for p in points):
            try: return all(self.array[p.x+1][p.y+1] for p in points)
            except: return 0
    def adjacent(self, point1, point2):
        return point1*point2
    def inline(self, point1, point2):
        return point1^point2 and self.alltrue(point1**point2)
    def diagonal(self, point1, point2):
        if point1&point2:
            for point in point1%point2:
                state1 = self.adjacent(point, point1) or self.inline(point, point1)
                state2 = self.adjacent(point, point2) or self.inline(point, point2)
                if self.true(point) and state1 and state2:
                    self.point.append(point)
                    return True
    def connect1(self, p1, p2):
        return self.adjacent(p1, p2) or self.inline(p1, p2) or self.diagonal(p1, p2)
    def connect2(self, p1, p2):
        for i in range(1, max(row, col)):
            for p in zip(i+p1, i+p2):
                for i in range(2):
                    if self.true(p[i]) and (self.adjacent(p[i],(p1,p2)[i]) or
                            self.inline(p[i],(p1,p2)[i]))and self.diagonal(p[i], (p2,p1)[i]):
                        self.point.append(p[i])
                        return True
    def connect(self, p1, p2):
        if (ret := self.connect1(p1, p2) or self.connect2(p1, p2)):
            self.showlines(p1, p2)
        return ret
    def getxy(self, row, col):
        return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2
    def drawline(self, *args):
        for i,p in enumerate(args[:-1]):
            self.lines[i].x, self.lines[i].y = self.getxy(*p)
            self.lines[i].x2, self.lines[i].y2 = self.getxy(*args[i+1])
            self.lines[i].visible = True
    def showlines(self, point1, point2):
        if len(self.point)==3: self.point.pop(0)
        if len(self.point)==2 and not self.point[0]^point1: self.point.reverse()
        points = point1, *self.point, point2
        self.drawline(*points)
        self.point.clear()
    def hidelines(self):
        for line in self.lines: line.visible = False
    def linevisible(self):
        return self.lines[0].visible
 
def initMatrix(row, col):
    global matrix, Array, Boxes
    matrix = Matrix(row+2, col+2)
    Array, Boxes = matrix.array, Matrix().array
    for i in range(row):
        for j in range(col):
            Array[i+1][j+1] = 0
    COLOR = randColor()
    for r,arr in enumerate(Boxes):
        for c,_ in enumerate(arr):
            Boxes[r][c] = Box(x0+c*(w+space), y0+r*(h+space), w, h, COLOR[c+r*len(arr)])
 
class Game:
    def __init__(self):
        initMatrix(row, col)
        self.score = 0
        self.rc, self.rc2 = Point(), Point()
        self.array, self.arces = Array, Boxes
        self.last1, self.last2, self.lastz = None, None, None
        self.label1 = text.Label('Congratulations!', color=Color().randcolor().rgba, font_size=50,
                                    x=W//2, y=H//2+80, anchor_x='center', anchor_y='center', bold=True, batch=batch)
        self.label2 = text.Label('Any key to restart...', color=Color().randcolor().rgba, font_size=36,
                                    x=W//2, y=H//2-50, anchor_x='center', anchor_y='center', bold=True, batch=batch)
    def on_mouse_click(self, x, y):
        if matrix.linevisible(): return
        if self.success(): main(event)
        r, c = (y-y0)//(h+space), (x-x0)//(w+space)
        if r in range(row) and c in range(col) and self.arces[r][c].on_mouse_over(x, y) and not self.array[r+1][c+1]:
            if self.last1 is None and self.last2 is None:
                self.rc, self.last1 = Point(r, c), self.arces[r][c]
                self.last1.arc.color = Color('RED').rgba
            elif self.last1 is not None and self.last2 is None:
                self.rc2, self.last2 = Point(r, c), self.arces[r][c]
                self.last2.arc.color = Color('RED').rgba
                if self.rc == self.rc2:
                    self.last1.arc.color = Color('WHITE').rgba
                    self.last1, self.last2 = None, None
                else:
                    if self.last1.cir.color==self.last2.cir.color:
                        matrix.connect(self.rc, self.rc2)
                    clock.schedule_interval(self.update, 0.5)
            return (r, c), Color(self.arces[r][c].cir.color).name
    def update(self, event):
        clock.unschedule(self.update)
        if self.last1.cir.color==self.last2.cir.color and matrix.connect(self.rc, self.rc2):
            self.hide()
            sound1.play()
            self.score += 10
            window.set_caption(window.caption.split('分数:')[0] + f'分数:{self.score}')
        else:
            sound2.play()
        self.last1.arc.color = self.last2.arc.color = Color('WHITE').rgba
        self.lastz = self.last1, self.last2
        self.last1, self.last2 = None, None
        matrix.hidelines()
        if game.success():
            window.set_caption('彩色方块连连看——任务完成!')
            game.label1.batch = game.label2.batch = batch2
            clock.schedule_interval(main, 5) # 5秒后自动开始
    def hide(self):
        self.last1.hide(); self.last2.hide()
        self.array[self.rc.x+1][self.rc.y+1] = self.array[self.rc2.x+1][self.rc2.y+1] = 1
    def unhide(self):
        self.lastz[0].show(); self.lastz[1].show()
        self.array[self.rc.x+1][self.rc.y+1] = self.array[self.rc2.x+1][self.rc2.y+1] = 0
    def success(self):
        return sum(sum(self.array,[]))==(row+2)*(col+2) 
 
def main(event):
    global game
    game = Game()
    game.label1.batch = game.label2.batch = None
    window.set_caption('彩色方块连连看')
    clock.unschedule(main)
 
@window.event
def on_draw():
    window.clear()
    batch.draw()
    batch2.draw()

@window.event
def on_mouse_press(x, y, dx, dy):
    global score
    if (ret := game.on_mouse_click(x, y)):
        window.set_caption(f'彩色方块连连看——坐标:{ret[0]}  颜色:{ret[1]}  分数:{game.score}')
 
@window.event
def on_key_press(symbol, modifiers):
    if game.success(): main(event)
    if symbol == key.S and modifiers & key.MOD_CTRL:
        main(event)
    elif symbol == key.Z and modifiers & key.MOD_CTRL:
        game.unhide()
    elif symbol == key.R and modifiers & key.MOD_CTRL:
        for i in range(row):
            for j in range(col):
                Array[i+1][j+1], Boxes[i][j].arc.batch, Boxes[i][j].cir.batch = 0, batch, batch
    elif symbol == key.F and modifiers & key.MOD_CTRL:
        if sum(sum(game.array,[]))%2: return
        boxsample = []
        for i,arr in enumerate(Array[1:-1]):
            for j,n in enumerate(arr[1:-1]):
                if n==0: boxsample.append(Boxes[i][j].cir.color)
        boxsample = sample(boxsample,len(boxsample))
        for i,arr in enumerate(Array[1:-1]):
            for j,n in enumerate(arr[1:-1]):
                if n==0: Boxes[i][j].cir.color = boxsample.pop()
 
main(event)
app.run()

目录

彩色圆圈“连连看”

Box类的修改

Game类的修改 

点击事件的修改

部分代码的替代

完整代码 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/552801.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python基于Django搜索的目标站点内容监测系统设计,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【Android GUI】FramebufferNativeWindow与Surface

文章目录 显示整体体系FramebufferNativeWindowFramebufferNativeWindow构造函数 dequeueBufferSurface总结参考 显示整体体系 native window为OpenGL与本地窗口系统之间搭建了桥梁。 这个窗口系统中&#xff0c;有两类本地窗口&#xff0c;nativewindow1是能直接显示在屏幕的…

超平实版Pytorch CNN Conv2d

torch.nn.Conv2d 基本参数 in_channels (int) 输入的通道数量。比如一个2D的图片&#xff0c;由R、G、B三个通道的2D数据叠加。 out_channels (int) 输出的通道数量。 kernel_size (int or tuple) kernel&#xff08;也就是卷积核&#xff0c;也可…

selenium反反爬虫,隐藏selenium特征

一、stealth.min.js 使用 用selenium爬网页时&#xff0c;常常碰到被检测到selenium &#xff0c;会被服务器直接判定为非法访问&#xff0c;这个时候就可以用stealth.min.js 来隐藏selenium特征&#xff0c;达到绕过检测的目的 from selenium import webdriver from seleniu…

接口压力测试 jmeter--入门篇(一)

一 压力测试的目的 评估系统的能力识别系统的弱点&#xff1a;瓶颈/弱点检查系统的隐藏的问题检验系统的稳定性和可靠性 二 性能测试指标以及测算 【虚拟用户数】&#xff1a;线程用户【并发数】&#xff1a;指在某一时间&#xff0c;一定数量的虚拟用户同时对系统的某个功…

5.11 mybatis之returnInstanceForEmptyRow作用

文章目录 1. 当returnInstanceForEmptyRowtrue时2 当returnInstanceForEmptyRowfalse时 mybatis的settings配置中有个属性returnInstanceForEmptyRow&#xff0c;该属性新增于mybatis的3.4.2版本&#xff0c;低于此版本不可用。该属性的作用官方解释为&#xff1a;当返回行的所…

如何快速上手:springboot+mongodb

当使用 Java Spring Boot 与 MongoDB 时&#xff0c;可以使用 Spring Data MongoDB 来轻松地进行数据库操作。以下是一个简单的示例&#xff0c;演示如何在 Spring Boot 中使用 MongoDB 进行基本的 CRUD&#xff08;创建、读取、更新、删除&#xff09;操作。 Spring Data for …

代码随想录训练营day39

第九章 动态规划part02 1.LeetCode. 不同路径 1.1题目链接&#xff1a;62.不同路径 文章讲解&#xff1a;代码随想录 视频讲解&#xff1a;B站卡哥视频 1.2思路&#xff1a;采用动态规划算法 想要求dp[i][j]&#xff0c;只能有两个方向来推导出来&#xff0c;即dp[i - 1][…

论文解读:(CoOp)Learning to Prompt for Vision-Language Models

文章汇总 存在的问题 虽然训练类别通常具有文本形式&#xff0c;例如“金鱼”或“卫生纸”&#xff0c;但它们将被转换为离散标签&#xff0c;只是为了简化交叉熵损失的计算&#xff0c;从而使文本中的语义封装在很大程度上未被利用。这样的学习范式将视觉识别系统限制在闭集…

【QOpenGL实践】QOpenGLWidget

目录 一、说明 二、QOpenGLWidget 类对象 2.1 概要 2.1.1 函数功能 2.1. 2 三个虚函数 2.1.3 信号 2.2 详细说明 2.2.1 三个虚函数 2.2.2 绘画技巧 2.2.3 OpenGL 函数调用、标头和 QOpenGLFunctions 三、实现代码示例 3.1 最简模式 3.2 与 QGLWidget 的关系 3.3…

LeetCode———144—— 二叉树的前序遍历

目录 ​编辑 1.题目 2.解答 1.首先计算二叉树的节点个数&#xff1a; 2.以先序遍历&#xff08;Preorder Traversal&#xff09;的方式遍历一个二叉树&#xff0c;并将遍历到的节点的值存储在一个整数数组中 3.最终代码 1.题目 . - 力扣&#xff08;LeetCode&#xff09; 给…

123页|华为项目管理精华-成功的项目管理(免费下载)

【1】关注本公众号&#xff0c;转发当前文章到微信朋友圈 【2】私信发送 华为项目管理精华 【3】获取本方案PDF下载链接&#xff0c;直接下载即可。 如需下载本方案PPT原格式&#xff0c;请加入微信扫描以下方案驿站知识星球&#xff0c;获取上万份PPT解决方案&#xff01;&a…

IDEA Tomcat localhost 日志和 catalina日志乱码(解决)

只需要修改 Tomcat 的 logging.properties D:\work\apache-tomcat-8.5.70-windows-x64\apache-tomcat-8.5.70\conf

SpringMVC 常用注解介绍

Spring MVC 常用注解介绍 文章目录 Spring MVC 常用注解介绍准备1. RequestMapping1.1 介绍2.2 注解使用 2. 请求参数2.1 传递单个参数2.2 传递多个参数2.3 传递对象2.4 传递数组 3. RequestParam3.1 注解使用3.2 传入集合 4. RequestBody5. PathVariable6. RequestPart7. Rest…

Since Maven 3.8.1 http repositories are blocked.

编译maven 项目时候报错提示下面信息&#xff1a; Since Maven 3.8.1 http repositories are blocked.Possible solutions: - Check that Maven settings.xml does not contain http repositories - Check that Maven pom files do not contain http repository http://XXXXXX:…

Mac电脑上有什么好玩的格斗游戏 《真人快打1》可以在苹果电脑上玩吗

你是不是喜欢玩格斗游戏&#xff1f;你是不是想在你的Mac电脑上体验一些刺激和激烈的对战&#xff1f;在这篇文章中&#xff0c;我们将介绍Mac电脑上有什么好玩的格斗游戏&#xff0c;以及《真人快打1》可以在苹果电脑上玩吗。 一、Mac电脑上有什么好玩的格斗游戏 格斗游戏是…

设计循环队列(队列oj)

1.设计循环队列 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。…

如何在原生项目中集成flutter

两个前提条件&#xff1a; 从flutter v1.17版本开始&#xff0c;flutter module仅支持AndroidX的应用在release模式下flutter仅支持一下架构&#xff1a;x84_64、armeabi-v7a、arm6f4-v8a,不支持mips和x86;所以引入flutter前需要在app/build.gradle下配置flutter支持的架构 a…

Jmeter 压测-Jprofiler定位接口相应时间长

1、环境准备 执行压测脚本&#xff0c;分析该接口tps很低&#xff0c;响应时间很长 高频接口在100ms以内&#xff0c;普通接口在200ms以内 2、JProfiler分析响应时间长的方法 ①JProfiler录制数据 压测脚本&#xff0c;执行1-3分钟即可 ②分析接口相应时间长的方法 通过Me…

全国产化无风扇嵌入式车载电脑在车队管理嵌入式车载行业应用

车队管理嵌入式车载行业应用 车队管理方案能有效解决车辆繁多管理困难问题&#xff0c;配合调度系统让命令更加精确有效执行。实时监控车辆状况、行驶路线和位置&#xff0c;指导驾驶员安全有序行驶&#xff0c;有效降低保险成本、事故概率以及轮胎和零部件的磨损与损坏。 方…