python作业-2048小游戏
需了解的知识
Pygame中的各个模块及其功能:
Pygame.init():初始化所有导入的模块
pygame.display:
pygame.display.init() — 初始化 display 模块
pygame.display.set_mode() — 初始化一个准备显示的窗口或屏幕
pygame.display.set_caption() — 设置当前窗口标题
pygame.mixer.music:
pygame.mixer.music.load() — 加载音乐进行播放
pygame.mixer.music.play() — 开始播放音乐(参数:int播放次数,-1为无限重复。。)
pygame.time,Clock(创建一个对象帮助跟踪时间):
pygame.time.Clock.tick(): — 更新时钟
pygame.event(用户事件和队列进行交互):
pygame.event.get(): — 在队列中获取事件
pygame.key(与键盘使用的关系):
常用列表:
pygame
Constant ASCII Description
---------------------------------
K_BACKSPACE \b backspace
K_TAB \t tab
K_CLEAR clear
K_RETURN \r return
K_PAUSE pause
K_ESCAPE ^[ escape
K_SPACE space
K_EXCLAIM ! exclaim
K_QUOTEDBL " quotedbl
K_HASH # hash
K_DOLLAR $ dollar
K_AMPERSAND & ampersand
K_QUOTE quote
K_LEFTPAREN ( left parenthesis
K_RIGHTPAREN ) right parenthesis
K_ASTERISK * asterisk
K_PLUS + plus sign
K_COMMA , comma
K_MINUS - minus sign
K_PERIOD . period
K_SLASH / forward slash
K_0 0 0
。。。
K_COLON : colon
K_SEMICOLON ; semicolon
K_LESS < less-than sign
K_EQUALS = equals sign
K_GREATER > greater-than sign
K_QUESTION ? question mark
K_AT @ at
K_LEFTBRACKET [ left bracket
K_BACKSLASH \ backslash
K_RIGHTBRACKET ] right bracket
K_CARET ^ caret
K_UNDERSCORE _ underscore
K_BACKQUOTE ` grave
K_a a a
。。。
K_DELETE delete
K_KP0 keypad 0
。。。
K_KP_PERIOD . keypad period
K_KP_DIVIDE / keypad divide
K_KP_MULTIPLY * keypad multiply
K_KP_MINUS - keypad minus
K_KP_PLUS + keypad plus
K_KP_ENTER \r keypad enter
K_KP_EQUALS = keypad equals
K_UP up arrow
K_DOWN down arrow
K_RIGHT right arrow
K_LEFT left arrow
K_INSERT insert
K_HOME home
K_END end
K_PAGEUP page up
K_PAGEDOWN page down
K_F1 F1
。。。
K_NUMLOCK numlock
K_CAPSLOCK capslock
K_SCROLLOCK scrollock
K_RSHIFT right shift
K_LSHIFT left shift
K_RCTRL right control
K_LCTRL left control
K_RALT right alt
K_LALT left alt
K_RMETA right meta
K_LMETA left meta
K_LSUPER left Windows key
K_RSUPER right Windows key
K_MODE mode shift
K_HELP help
K_PRINT print screen
K_SYSREQ sysrq
K_BREAK break
K_MENU menu
K_POWER power
K_EURO Euro
系统结构
Modules存放实现的模块
Resources存放游戏资源文件
cfg.py存放配置文件
实现代码
cfg.py配置文件:
import os '''FPS'''
FPS = 60
'''背景颜色'''
BG_COLOR = '#92877d'
'''屏幕大小'''
SCREENSIZE = (650, 370)
'''保存当前最高分的文件'''
MAX_SCORE_FILEPATH = 'score'
'''字体路径'''
FONTPATH = os.path.join(os.getcwd(), 'resources/font/Gabriola.ttf')
'''背景音乐路径'''
BGMPATH = os.path.join(os.getcwd(), 'resources/audio/bgm.mp3')
'''其他一些必要的常量'''
MARGIN_SIZE = 10
BLOCK_SIZE = 80
GAME_MATRIX_SIZE = (4, 4)
执行文件2048Game.py
# 游戏初始化
pygame.init() screen = pygame.display.set_mode(cfg.SCREENSIZE) pygame.display.set_caption('——2048——')
# 播放背景音乐
pygame.mixer.music.load(cfg.BGMPATH) pygame.mixer.music.play(-1)
# 实例化2048游戏
game_2048 = Game2048(matrix_size=cfg.GAME_MATRIX_SIZE, max_score_filepath=cfg.MAX_SCORE_FILEPATH)
# 游戏主循环
clock = pygame.time.Clock() is_running = True while is_running: screen.fill(pygame.Color(cfg.BG_COLOR)) # --按键检测 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key in [pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT]: game_2048.setDirection({pygame.K_UP: 'up', pygame.K_DOWN: 'down', pygame.K_LEFT: 'left', pygame.K_RIGHT: 'right'}[event.key]) # --更新游戏状态 game_2048.update() if game_2048.isgameover: game_2048.saveMaxScore() is_running = False # --将必要的游戏元素画到屏幕上 drawGameMatrix(screen, game_2048.game_matrix, cfg) start_x, start_y = drawScore(screen, game_2048.score, game_2048.max_score, cfg) drawGameIntro(screen, start_x, start_y, cfg) # --屏幕更新 pygame.display.update() clock.tick(cfg.FPS) return endInterface(screen, cfg)
在modules中定义一个Game2048的类(里面主要负责实现2048的各种游戏规则):
class Game2048(object): def __init__(self, matrix_size=(4, 4), max_score_filepath=None): # matrix_size: (num_rows, num_cols) self.matrix_size = matrix_size # 游戏最高分保存路径 self.max_score_filepath = max_score_filepath # 初始化 self.initialize()
游戏开始时需要随机的在二维列表里随机选择两个位置生成2或者4:
在新的位置随机生成数字
def randomGenerateNumber(self): empty_pos = [] for i in range(self.matrix_size[0]): for j in range(self.matrix_size[1]): if self.game_matrix[i][j] == 'null': empty_pos.append([i, j]) i, j = random.choice(empty_pos) self.game_matrix[i][j] = 2 if random.random() > 0.1 else 4
然后,当玩家按下方向键(↑↓← →)时,这个二维列表要根据玩家的操作指令进行更新,主要分为两个部分:
移动所有的数字块并进行必要的合并和记分;
随机地在一个还没有数字的位置上生成一个数字。
更新游戏状态
def update(self):
game_matrix_before = copy.deepcopy(self.game_matrix)
self.move()
if game_matrix_before != self.game_matrix: self.randomGenerateNumber()
if self.score > self.max_score: self.max_score = self.score
移动所有的数字并进行必要的合并的代码实现如下:
def move(self):
# 提取非空数字
def extract(array):
array_new = []
for item in array:
if item != 'null': array_new.append(item)
return array_new
# 合并非空数字
def merge(array):
score = 0
if len(array) < 2: return array, score
for i in range(len(array)-1):
if array[i] == 'null':
break
if array[i] == array[i+1]:
array[i] *= 2
array.pop(i+1)
array.append('null')
score += array[i]
return extract(array), score
# 不需要移动的话直接return
if self.move_direction is None: return
# 向上
if self.move_direction == 'up':
for j in range(self.matrix_size[1]):
col = []
for i in range(self.matrix_size[0]):
col.append(self.game_matrix[i][j])
col = extract(col)
col.reverse()
col, score = merge(col)
self.score += score
col.reverse()
col = col + ['null',] * (self.matrix_size[0] - len(col))
for i in range(self.matrix_size[0]):
self.game_matrix[i][j] = col[i]
# 向下
elif self.move_direction == 'down':
for j in range(self.matrix_size[1]):
col = []
for i in range(self.matrix_size[0]):
col.append(self.game_matrix[i][j])
col = extract(col)
col, score = merge(col)
self.score += score
col = ['null',] * (self.matrix_size[0] - len(col)) + col
for i in range(self.matrix_size[0]):
self.game_matrix[i][j] = col[i]
# 向左
elif self.move_direction == 'left':
for idx, row in enumerate(copy.deepcopy(self.game_matrix)):
row = extract(row)
row.reverse()
row, score = merge(row)
self.score += score
row.reverse()
row = row + ['null',] * (self.matrix_size[1] - len(row))
self.game_matrix[idx] = row
# 向右
elif self.move_direction == 'right':
for idx, row in enumerate(copy.deepcopy(self.game_matrix)):
row = extract(row)
row, score = merge(row)
self.score += score
row = ['null',] * (self.matrix_size[1] - len(row)) + row
self.game_matrix[idx] = row
self.move_direction = None
判断游戏是否结束:
游戏是否结束
@property
def isgameover(self):
for i in range(self.matrix_size[0]):
for j in range(self.matrix_size[1]):
if self.game_matrix[i][j] == 'null': return False
if (i == self.matrix_size[0] - 1) and (j == self.matrix_size[1] - 1):
continue
elif (i == self.matrix_size[0] - 1):
if (self.game_matrix[i][j] == self.game_matrix[i][j+1]):
return False
elif (j == self.matrix_size[1] - 1):
if (self.game_matrix[i][j] == self.game_matrix[i+1][j]):
return False
else:
if (self.game_matrix[i][j] == self.game_matrix[i+1][j]) or (self.game_matrix[i][j] == self.game_matrix[i][j+1]):
return False
return True
在游戏主循环里根据用户操作来更新当前的游戏状态并将游戏里所有必要的元素显示在屏幕:
# 游戏主循环
clock = pygame.time.Clock()
is_running = True
while is_running:
screen.fill(pygame.Color(cfg.BG_COLOR))
# --按键检测
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key in [pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT]:
game_2048.setDirection({pygame.K_UP: 'up', pygame.K_DOWN: 'down', pygame.K_LEFT: 'left', pygame.K_RIGHT: 'right'}[event.key])
# --更新游戏状态
game_2048.update()
if game_2048.isgameover:
game_2048.saveMaxScore()
is_running = False
# --将必要的游戏元素画到屏幕上
drawGameMatrix(screen, game_2048.game_matrix, cfg)
start_x, start_y = drawScore(screen, game_2048.score, game_2048.max_score, cfg)
drawGameIntro(screen, start_x, start_y, cfg)
# --屏幕更新
pygame.display.update()
clock.tick(cfg.FPS)
return endInterface(screen, cfg)
实验
使用python ./Game2048来执行:
总结和展望
通过此次学习,我了解了python的灵活性以及代码的可阅读性比一般的语言要强,并且如今python社区有许多活跃的用户可以在网络上找到许多相关的资料资源。通过此次学习深刻理解了python中的面向对象思想,也了解了一些游戏的设计想法和可供实现的模块。现如今正在学习其他东西,如果未来有更多充裕的时间可以加深python的理解,学习更多的内容,自己做出更好的项目。
参考:https://mp.weixin.qq.com/s/WJhg4J0MuuEcmDasRzuE9Q
python作业-2048小游戏的更多相关文章
- python写2048小游戏
#!/usr/bin/env python # coding=utf-8 #******************************************************** # > ...
- jQuery实践-网页版2048小游戏
▓▓▓▓▓▓ 大致介绍 看了一个实现网页版2048小游戏的视频,觉得能做出自己以前喜欢玩的小游戏很有意思便自己动手试了试,真正的验证了这句话-不要以为你以为的就是你以为的,看视频时觉得看懂了,会写了, ...
- C# 开发2048小游戏
这应该是几个月前,闲的手痒,敲了一上午代码搞出来的,随之就把它丢弃了,当时让别人玩过,提过几条更改建议,但是时至今日,我也没有进行过优化和更改(本人只会作案,不会收场,嘎嘎),下面的建议要给代码爱好的 ...
- Swift实战之2048小游戏
上周在图书馆借了一本Swift语言实战入门,入个门玩一玩^_^正好这本书的后面有一个2048小游戏的实例,笔者跟着实战了一把. 差不多一周的时间,到今天,游戏的基本功能已基本实现,细节我已不打算继续完 ...
- 如何在CentOS上安装一个2048小游戏
如何在centos上安装一个2048小游戏 最近在学习CentOS系统,就琢磨着玩点什么,然后我看到有人在玩2048小游戏,所有我就在想,为啥不装一个2048小游戏搞一下嘞,于是乎,我就开始工作啦 由 ...
- js、jQuery实现2048小游戏
2048小游戏 一.游戏简介: 2048是一款休闲益智类的数字叠加小游戏 二. 游戏玩法: 在4*4的16宫格中,您可以选择上.下.左.右四个方向进行操作,数字会按方向移动,相邻的两个数字相同就会合 ...
- 用js实现2048小游戏
用js实现2048小游戏 笔记仓库:https://github.com/nnngu/LearningNotes 1.游戏简介 2048是一款休闲益智类的数字叠加小游戏.(文末给出源代码和演示地址) ...
- 2048小游戏代码解析 C语言版
2048小游戏,也算是风靡一时的益智游戏.其背后实现的逻辑比较简单,代码量不算多,而且趣味性强,适合作为有语言基础的童鞋来加强编程训练.本篇分析2048小游戏的C语言实现代码. 前言 游戏截图: 游 ...
- Docker从0开始之部署一套2048小游戏
本文记录一下在docker部署一套2048小游戏的过程,在娱乐中熟悉docker的应用部署.docker 安装不在本文讲述之中,参考我的其它博客. 1.获取image镜像. 方法一:daocloud. ...
随机推荐
- powertool
powertool简介 PowerTool 一款免费强大的进程管理器,支持进程强制结束,可以Unlock占用文件的进程,查看文件/文件夹被占用的情况,内核模块和驱动的查看和管理,进程模块的内存的dum ...
- 用MindManager做完思维导图后怎么加密
使用MindManager我们可以制作出很多简洁明了的思维导图,然而,不论是分享还是查看这些导图,我们往往需要对导图进行加密操作,尤其是制定公司或企业的下一步发展计划时,加密导图就显得很有必要了. M ...
- js 实现textarea剩余字数统计
1 针对textarea剩余字数统计 2 <div class="fankui-textarea"> 3 <span>留言:</span> &l ...
- 推荐系统实践 0x07 基于邻域的算法(2)
基于邻域的算法(2) 上一篇我们讲了基于用户的协同过滤算法,基本流程就是寻找与目标用户兴趣相似的用户,按照他们对物品喜好的对目标用户进行推荐,其中哪些相似用户的评分要带上目标用户与相似用户的相似度作为 ...
- C语言讲义——冒泡排序(bubble sort)
冒泡排序三步走: 循环 交换 回一手 一个数和其它数比较(循环) 每个数都要做这种比较(再一层循环) 准备工作 #include <stdio.h> void sort(int arr[] ...
- JQuery案例:购物车编辑
购物车编辑 实现了:商品的加减,总价的变动 实现了:全选/全不选(使用prop而不是attr) 实现了:删除(遮罩层) <html> <head> <meta chars ...
- 微服务手册:API接口9个生命节点,构建全生命周期管理
互联网应用架构:专注编程教学,架构,JAVA,Python,微服务,机器学习等领域,欢迎关注,一起学习. 对于API,在日常的工作中是接触最多的东西,特别是我们软件这一行,基本就是家常便饭了,在百度百 ...
- 一枚程序猿的MacBook M1详细体验报告
前言 2020年11月11日双十一上午,苹果发布了M1芯片的新款Mac,其最大的变化就是将处理器从Intel换成了苹果自研的ARM芯片M1. 上一次苹果更换Mac芯片要追溯到2006年,14年前,苹果 ...
- 2020.11最新JAVA环境安装配置
Windows10下java环境配置 更新:2020年11月25日 电脑环境: windows10 64位 一.下载jdk 首先到Oracle网站下载对应操作系统的jdk安装包. https://ww ...
- linq 查询的结果会开辟新的内存吗?
一:背景 1. 讲故事 昨天群里有位朋友问:linq 查询的结果会开辟新的内存吗?如果开了,那是对原序列集里面元素的深拷贝还是仅仅拷贝其引用? 其实这个问题我觉得问的挺好,很多初学 C# 的朋友或多或 ...