原文链接:
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 keyW, 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)//2sound1, 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, hself.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 = Nonedef show(self):self.arc.batch = self.cir.batch = batchdef on_mouse_over(self, x, y):return self.x<=x<=self.x+self.w and self.y<=y<=self.y+self.hclass 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 = Falsedef __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 0def 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 0def adjacent(self, point1, point2):return point1*point2def 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 Truedef 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]) orself.inline(p[i],(p1,p2)[i]))and self.diagonal(p[i], (p2,p1)[i]):self.point.append(p[i])return Truedef connect(self, p1, p2):if (ret := self.connect1(p1, p2) or self.connect2(p1, p2)):self.showlines(p1, p2)return retdef getxy(self, row, col):return x0+col*(w+space)+w//2, y0+row*(h+space)+h//2def 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 = Truedef 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, point2self.drawline(*points)self.point.clear()def hidelines(self):for line in self.lines: line.visible = Falsedef linevisible(self):return self.lines[0].visibledef initMatrix(row, col):global matrix, Array, Boxesmatrix = Matrix(row+2, col+2)Array, Boxes = matrix.array, Matrix().arrayfor i in range(row):for j in range(col):Array[i+1][j+1] = 0COLOR = 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 = 0self.rc, self.rc2 = Point(), Point()self.array, self.arces = Array, Boxesself.last1, self.last2, self.lastz = None, None, Noneself.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(): returnif 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').rgbaelif 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').rgbaif self.rc == self.rc2:self.last1.arc.color = Color('WHITE').rgbaself.last1, self.last2 = None, Noneelse: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).namedef 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 += 10window.set_caption(window.caption.split('分数:')[0] + f'分数:{self.score}')else:sound2.play()self.last1.arc.color = self.last2.arc.color = Color('WHITE').rgbaself.lastz = self.last1, self.last2self.last1, self.last2 = None, Nonematrix.hidelines()if game.success():window.set_caption('彩色方块连连看——任务完成!')game.label1.batch = game.label2.batch = batch2clock.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] = 1def 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] = 0def success(self):return sum(sum(self.array,[]))==(row+2)*(col+2) def main(event):global gamegame = Game()game.label1.batch = game.label2.batch = Nonewindow.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 scoreif (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, batchelif symbol == key.F and modifiers & key.MOD_CTRL:if sum(sum(game.array,[]))%2: returnboxsample = []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类的修改
点击事件的修改
部分代码的替代
完整代码
完