更多精彩内容,欢迎关注:

视频号
视频号

抖音
抖音

快手
快手

微博
微博

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实现消消乐小游戏的文章就介绍到这了,希望大家以后多多支持好二三四!

为你推荐
资讯专栏
热门视频
相关推荐
学习python的while循环嵌套 提升Python运行速度的5个小技巧 Python按键或值对字典进行排序 图像检索之基于vlfeat实现SIFT特征 python绘图中的四个绘图技巧 js中toString方法3个作用 信息系统项目管理师报考条件 信息系统项目管理师报考时间 信息系统项目管理师报名时间 信息系统项目管理师考试时间 pmp与信息系统项目管理师 信息系统项目管理师报考要求 信息系统项目管理师有效期 信息系统项目管理师考什么论文 信息系统项目管理师是什么类别 软考信息系统项目管理师怎么备考 备考流程有哪些 考信息系统项目管理师需要考几门 信息系统项目管理师考试几门 信息系统项目管理师初中能考吗 信息系统项目管理师英语简称 python实现新年倒计时实例代码 详解python的循环 基于Python实现PDF区域文本提取工具 Python数据分析处理(三)--运动员信息的分组与聚合 Python实现城市公交网络分析与可视化 Python&nbsp;垃圾回收机制详解 python正则表达式语法学习笔记 一文秒懂python正则表达式常用函数 Python常用的正则表达式处理函数详解 JS截取字符串的三种方法详解 PHP遍历数组的6种方式总结 php两种基本的输出方及实例详解 php生成唯一uid的解决方法详解 PHP7中对十六进制字符串处理的问题详解 PHP对接抖音开发平台接口的详细教程 php7安装mysqli实例讲解 php去掉一维数组的键值的实例方法 PHP中empty()和isset()的区别介绍 PHP实现JWT的Token登录认证 php判断时间戳是否为今天实例讲解
Top