用Python写个开心消消乐小游戏
本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理
提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 Python 来做个简单的消消乐小游戏。
实现
消消乐的构成主要包括三部分:游戏主体、计分器、计时器,下面来看一下具体实现。
先来看一下游戏所需 Python 库。
import os
import sys
import time
import pygame
import random
定义一些常量,比如:窗口宽高、网格行列数等,代码如下:
WIDTH = 400
HEIGHT = 400
NUMGRID = 8
GRIDSIZE = 36
XMARGIN = (WIDTH - GRIDSIZE * NUMGRID) // 2
YMARGIN = (HEIGHT - GRIDSIZE * NUMGRID) // 2
ROOTDIR = os.getcwd()
FPS = 30
接着创建一个主窗口,代码如下:
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('消消乐')
看一下效果:

再接着在窗口中画一个 8 x 8 的网格,代码如下:
screen.fill((255, 255, 220))
# 游戏界面的网格绘制
def drawGrids(self):
for x in range(NUMGRID):
for y in range(NUMGRID):
rect = pygame.Rect((XMARGIN+x*GRIDSIZE, YMARGIN+y*GRIDSIZE, GRIDSIZE, GRIDSIZE))
self.drawBlock(rect, color=(255, 165, 0), size=1
# 画矩形 block 框
def drawBlock(self, block, color=(255, 0, 0), size=2):
pygame.draw.rect(self.screen, color, block, size)
看一下效果:

再接着在网格中随机放入各种拼图块,代码如下:
while True:
self.all_gems = []
self.gems_group = pygame.sprite.Group()
for x in range(NUMGRID):
self.all_gems.append([])
for y in range(NUMGRID):
gem = Puzzle(img_path=random.choice(self.gem_imgs), size=(GRIDSIZE, GRIDSIZE), position=[XMARGIN+x*GRIDSIZE, YMARGIN+y*GRIDSIZE-NUMGRID*GRIDSIZE], downlen=NUMGRID*GRIDSIZE)
self.all_gems[x].append(gem)
self.gems_group.add(gem)
if self.isMatch()[0] == 0:
break
看一下效果:

再接着加入计分器和计时器,代码如下:
# 显示得分
def drawScore(self):
score_render = self.font.render('分数:'+str(self.score), 1, (85, 65, 0))
rect = score_render.get_rect()
rect.left, rect.top = (55, 15)
self.screen.blit(score_render, rect)
# 显示加分
def drawAddScore(self, add_score):
score_render = self.font.render('+'+str(add_score), 1, (255, 100, 100))
rect = score_render.get_rect()
rect.left, rect.top = (250, 250)
self.screen.blit(score_render, rect)
# 显示剩余时间
def showRemainingTime(self):
remaining_time_render = self.font.render('倒计时: %ss' % str(self.remaining_time), 1, (85, 65, 0))
rect = remaining_time_render.get_rect()
rect.left, rect.top = (WIDTH-190, 15)
self.screen.blit(remaining_time_render, rect)
看一下效果:

当设置的游戏时间用尽时,我们可以生成一些提示信息,代码如下:
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYUP and event.key == pygame.K_r:
flag = True
if flag:
break
screen.fill((255, 255, 220))
text0 = '最终得分: %s' % score
text1 = '按 R 键重新开始'
y = 140
for idx, text in enumerate([text0, text1]):
text_render = font.render(text, 1, (85, 65, 0))
rect = text_render.get_rect()
if idx == 0:
rect.left, rect.top = (100, y)
elif idx == 1:
rect.left, rect.top = (100, y)
y += 60
screen.blit(text_render, rect)
pygame.display.update()
看一下效果:

说完了游戏图形化界面相关的部分,我们再看一下游戏的主要处理逻辑。
我们通过鼠标来操纵拼图块,因此程序需要检查有无拼图块被选中,代码实现如下:
def checkSelected(self, position):
for x in range(NUMGRID):
for y in range(NUMGRID):
if self.getGemByPos(x, y).rect.collidepoint(*position):
return [x, y]
return None
我们需要将鼠标连续选择的拼图块进行位置交换,代码实现如下:
def swapGem(self, gem1_pos, gem2_pos):
margin = gem1_pos[0] - gem2_pos[0] + gem1_pos[1] - gem2_pos[1]
if abs(margin) != 1:
return False
gem1 = self.getGemByPos(*gem1_pos)
gem2 = self.getGemByPos(*gem2_pos)
if gem1_pos[0] - gem2_pos[0] == 1:
gem1.direction = 'left'
gem2.direction = 'right'
elif gem1_pos[0] - gem2_pos[0] == -1:
gem2.direction = 'left'
gem1.direction = 'right'
elif gem1_pos[1] - gem2_pos[1] == 1:
gem1.direction = 'up'
gem2.direction = 'down'
elif gem1_pos[1] - gem2_pos[1] == -1:
gem2.direction = 'up'
gem1.direction = 'down'
gem1.target_x = gem2.rect.left
gem1.target_y = gem2.rect.top
gem1.fixed = False
gem2.target_x = gem1.rect.left
gem2.target_y = gem1.rect.top
gem2.fixed = False
self.all_gems[gem2_pos[0]][gem2_pos[1]] = gem1
self.all_gems[gem1_pos[0]][gem1_pos[1]] = gem2
return True
每一次交换拼图块时,我们需要判断是否有连续一样的三个及以上拼图块,代码实现如下:
def isMatch(self):
for x in range(NUMGRID):
for y in range(NUMGRID):
if x + 2 < NUMGRID:
if self.getGemByPos(x, y).type == self.getGemByPos(x+1, y).type == self.getGemByPos(x+2, y).type:
return [1, x, y]
if y + 2 < NUMGRID:
if self.getGemByPos(x, y).type == self.getGemByPos(x, y+1).type == self.getGemByPos(x, y+2).type:
return [2, x, y]
return [0, x, y]
当出现三个及以上拼图块时,需要将这些拼图块消除,代码实现如下:
def removeMatched(self, res_match):
if res_match[0] > 0:
self.generateNewGems(res_match)
self.score += self.reward
return self.reward
return 0
将匹配的拼图块消除之后,我们还需要随机生成新的拼图块,代码实现如下:
def generateNewGems(self, res_match):
if res_match[0] == 1:
start = res_match[2]
while start > -2:
for each in [res_match[1], res_match[1]+1, res_match[1]+2]:
gem = self.getGemByPos(*[each, start])
if start == res_match[2]:
self.gems_group.remove(gem)
self.all_gems[each][start] = None
elif start >= 0:
gem.target_y += GRIDSIZE
gem.fixed = False
gem.direction = 'down'
self.all_gems[each][start+1] = gem
else:
gem = Puzzle(img_path=random.choice(self.gem_imgs), size=(GRIDSIZE, GRIDSIZE), position=[XMARGIN+each*GRIDSIZE, YMARGIN-GRIDSIZE], downlen=GRIDSIZE)
self.gems_group.add(gem)
self.all_gems[each][start+1] = gem
start -= 1
elif res_match[0] == 2:
start = res_match[2]
while start > -4:
if start == res_match[2]:
for each in range(0, 3):
gem = self.getGemByPos(*[res_match[1], start+each])
self.gems_group.remove(gem)
self.all_gems[res_match[1]][start+each] = None
elif start >= 0:
gem = self.getGemByPos(*[res_match[1], start])
gem.target_y += GRIDSIZE * 3
gem.fixed = False
gem.direction = 'down'
self.all_gems[res_match[1]][start+3] = gem
else:
gem = Puzzle(img_path=random.choice(self.gem_imgs), size=(GRIDSIZE, GRIDSIZE), position=[XMARGIN+res_match[1]*GRIDSIZE, YMARGIN+start*GRIDSIZE], downlen=GRIDSIZE*3)
self.gems_group.add(gem)
self.all_gems[res_match[1]][start+3] = gem
start -= 1
之后反复执行这个过程,直至耗尽游戏时间,游戏结束。
最后,我们动态看一下游戏效果。

总结
本文我们使用 Python 实现了一个简单的消消乐游戏,有兴趣的可以对游戏做进一步扩展,比如增加关卡等。
想要获取更多Python学习资料可以加
QQ:2955637827私聊
或加Q群630390733
大家一起来学习讨论吧!
用Python写个开心消消乐小游戏的更多相关文章
- 用 Python 写个消消乐小游戏
提到开心消消乐这款小游戏,相信大家都不陌生,其曾在 2015 年获得过玩家最喜爱的移动单机游戏奖,受欢迎程度可见一斑,本文我们使用 Python 来做个简单的消消乐小游戏. 很多人学习python,不 ...
- qml自学笔记------自己写相似于劲舞团的按键小游戏(中)
接上篇<qml自学笔记------自己写类似于劲舞团的按键小游戏(上)> 第三部分DisplayPart.qml 代码的其它部分都是渣,就这里花了点时间,整个小游戏就靠这个文件. 首先,屏 ...
- 我用数据结构花了一夜给女朋友写了个h5走迷宫小游戏
目录 起因 分析 画线(棋盘) 画迷宫 方块移动 结语 @(文章目录) 先看效果图(在线电脑尝试地址http://biggsai.com/maze.html): 起因 又到深夜了,我按照以往在公众号写 ...
- 零基础自学Python十天,写了一款猜数字小游戏,附源码和软件下载链接!
自学一门语言最重要的是要及时给自己反馈,那么经常写一些小程序培养语感很重要,写完可以总结一下程序中运用到了哪些零散的知识点. 本程序中运用到的知识点有: 1.输入输出函数 (input.print) ...
- 零基础自学Python十天的时候,写的一款猜数字小游戏,附源码和软件下载链接!
自学一门语言最重要的是要及时给自己反馈,那么经常写一些小程序培养语感很重要,写完可以总结一下程序中运用到了哪些零散的知识点. 本程序中运用到的知识点有: 1.输入输出函数 (input.print) ...
- 用python写一个爬虫——爬取性感小姐姐
忍着鼻血写代码 今天写一个简单的网上爬虫,爬取一个叫妹子图的网站里面所有妹子的图片. 然后试着先爬取了三页,大概有七百多张图片吧!各个诱人的很,有兴趣的同学可以一起来爬一下,大佬级程序员勿喷,简单爬虫 ...
- 如何用python写个人专属群聊提醒小助手?
前言 大家还记得教会父母玩微信是什么时候吗?父母学会后,我们的生活就发生了「质」的变化,父母也许会吐槽你的微信头像不好,要你换一个头像. 最近 pk哥 又被母后大人吐槽了,原因是亲戚微信群里某个亲戚生 ...
- python写的的简单的爬虫小程序
import re import urllib def getHtml(url): page=urllib.urlopen(url) html=page.read() return html def ...
- python开发_自己开发的一个小游戏
先看看游戏的运行效果: 看完游戏的运行情况,你可能对游戏有了一定了了解: #运行游戏后,玩家首先要进行语音的选择,1选择英语,2选择汉语,其他则默认选择英语 #根据玩家选择的语音,进入不同的语音环境 ...
随机推荐
- Spring 事件监听机制及原理分析
简介 在JAVA体系中,有支持实现事件监听机制,在Spring 中也专门提供了一套事件机制的接口,方便我们实现.比如我们可以实现当用户注册后,给他发送一封邮件告诉他注册成功的一些信息,比如用户订阅的主 ...
- 从数据仓库双集群系统模式探讨,看GaussDB(DWS)的容灾设计
摘要:本文主要是探讨OLAP关系型数据库框架的数据仓库平台如何设计双集群系统,即增强系统高可用的保障水准,然后讨论一下GaussDB(DWS)的容灾应该如何设计. 当前社会.企业运行当中,大数据分析. ...
- input[type=file] 样式美化,input上传按钮美化
<style>.file { position: relative; display: inline-block; background: #D0EEFF; border: 1px sol ...
- iPhone/iOS开启个人热点的相关位置调整小结
冬至已到,圣诞将近,最近公司项目实在太多,三四个项目反复的切换真的让人焦头烂额,趁今天有点空,把维护的三个项目顺利送出,刚好可以缕缕思路,记录一下最近遇到的问题.说不着急那是假的,客户一天天的催的确实 ...
- 经典算法—BF算法(字符串匹配)
前言 字符串的匹配算法也是很经典的一个算法,在面试的时候常常会遇到,而BF算法是字符串模式匹配中的一个简单的算法 1,什么是BF算法 BF算法,即暴力(Brute Force)算法,是普通的模式匹配算 ...
- LeetCode 038 Count and Say
题目要求:Count and Say The count-and-say sequence is the sequence of integers beginning as follows:1, 11 ...
- java41
2019.8.7全部回顾完毕 收获:搞懂了以前不理解的内容 学会了Markdown语法 1. 将首字母变大写 public class _02将首字母变大写 { public static void ...
- 2、Spring Cloud和dubbo简介
1.Spring Cloud简介 (1).Spring Cloud简介 SpringCloud,基于SpringBoot提供了一套微服务解决方案,包括服务注册与发现,配置中心,全链路监控,服务网关,负 ...
- Django----短信验证接口
1.注册荣联云账号 1.1注册账号 1.2 登录即可看到开发者账号信息 1.3 添加测试账号 2.使用容联云发送代码测试 '''1. 安装容联云sdk''' pip install ronglian_ ...
- Spring Cloud 学习 (七) Spring Cloud Sleuth
微服务架构是一个分布式架构,微服务系统按业务划分服务单元,一个微服务系统往往有很多个服务单元.由于服务单元数量众多,业务的复杂性较高,如果出现了错误和异常,很难去定位.主要体现在一个请求可能需要调用很 ...