Android 别踩白块 源码分析
文章目录
- 一、项目下载
- 二、项目分析
- 三、源码分析
- 1、实体层(Entity)
- (1).Block类
- [1].属性
- [2].方法
- (2).SuccGroup类
- [1].属性
- [2].方法
- (3).FailGroup类
- [1].属性
- [2].方法
- 2、资源层(Res)
- (1).Res类
- 3、控制层(Control)
- (1).TimeTool类
- [1].属性
- [2].方法
- 4、工具层(Util)
- (1).ConstantUtil类
- (2).LogUtil类
- [1].属性
- [2].方法
- (3).SharedUtil类
- [1].属性
- [2].方法
- 5、场景层(Scene)
- (1).GameScene类
- [1].属性
- [2].方法
- 6、活动层(Activity)
- (1).MainActivity类
- 四、整体实现流程
- 1、资源加载、信息获取
- 2、界面、数据初始化
- 3、游戏开始
- 4、游戏进行
- 5、游戏结束
- 6、游戏记录
- 7、游戏结束后的选择
一、项目下载
【CSDN下载】
链接:https://download.csdn.net/download/qq_44220418/12701065
【百度云下载】
链接:https://pan.baidu.com/s/13P72shFSuku8zfDvBQX-hQ
提取码:742m
Tips:如果想在自己的电脑上运行项目,可参考【这篇博客】对项目部分配置文件进行相关修改
二、项目分析
在com.orange.blcok的别踩白块项目中,有一个被引入的名为orangeengine_gles2_v1.4
的jar包,网上查了一下是所谓的OGEngine开源引擎,统计下来将近有800多个类,这里就不去分析了。
项目中的源码,都很好地用适当的包进行了分类:{control包存放游戏中一些用于控制的类entity包存放实体类res包存放一些存储静态资源常量(如:字符串)的类scene包存放游戏场景类util包存放游戏中需要用到的工具类最外层存放MainActivity类\begin{cases} \text{control包} & 存放游戏中一些用于控制的类 \\ \text{entity包} & 存放实体类\\ \text{res包} & 存放一些存储静态资源常量(如:字符串)的类\\ \text{scene包} & 存放游戏场景类\\ \text{util包} & 存放游戏中需要用到的工具类\\ \text{最外层} & 存放\text{MainActivity}类 \end{cases}⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧control包entity包res包scene包util包最外层存放游戏中一些用于控制的类存放实体类存放一些存储静态资源常量(如:字符串)的类存放游戏场景类存放游戏中需要用到的工具类存放MainActivity类
三、源码分析
1、实体层(Entity)
(1).Block类
Block类继承自OGEngine开源引擎封装好的Rectangle类。
[1].属性
属性名 | 介绍 |
---|---|
mGameScene | 所属的游戏场景(GameScene) |
colorType |
用来指示Block是黑色还是白色,用ConstantUtil 中的常量指代
|
row | Block所在行索引 |
column | Block所在列索引 |
[2].方法
方法 | 介绍 |
---|---|
构造函数(带有参数row) | 根据行索引、列索引、游戏场景、块宽、块高、黑块列索引来构造一个Block |
构造函数(不带参数row) | 根据列索引、游戏场景、块宽、块高、黑块列索引来构造下一行中的某一个Block |
initBlockData | 根据Block的列索引和当前行的黑块列索引来给Block设置颜色 |
onAreaTouched | 按下Block后调用GameScene的相关逻辑处理 |
(2).SuccGroup类
SuccGroup类继承自OGEngine开源引擎封装好的EntityGroup类。
[1].属性
属性名 | 介绍 |
---|---|
mGameScene | 成功界面游戏场景 |
bgRect | 成功界面背景矩形(用来设置背景色填充) |
titelSprite | 成功界面右上角标题文字 |
modelSprite | 成功界面中间“经典模式”文字 |
btn_back | 成功界面返回按钮 |
btn_again | 成功界面重来按钮 |
txt_big | 成功界面本次通关用时文字 |
txt_small | 成功界面最佳记录提示文字 |
onClickListener | 成功界面点击事件监听器,用来监听按钮的点击事件 |
[2].方法
方法 | 介绍 |
---|---|
initView | 初始化成功界面的组件元素,但是不进行展示 |
showItems | 展示/隐藏成功界面的元素 |
updateBigText | 设置txt_big要展示的文字 |
updateSmallText | 设置txt_small要展示的文字 |
showDialog | 准备退出游戏时,显示对话框进行询问 |
(3).FailGroup类
FailGroup类继承自OGEngine开源引擎封装好的EntityGroup类。
[1].属性
属性名 | 介绍 |
---|---|
mGameScene | 失败界面游戏场景 |
bgRect | 失败界面背景矩形(用来设置背景色填充) |
titelSprite | 失败界面右上角标题文字 |
modelSprite | 失败界面中间“经典模式”文字 |
btn_back | 失败界面返回按钮 |
btn_again | 失败界面重来按钮 |
txt_big | 失败界面提示文字“失败了” |
txt_small | 失败界面最佳记录提示文字 |
onClickListener | 失败界面点击事件监听器,用来监听按钮的点击事件 |
[2].方法
方法 | 介绍 |
---|---|
initView | 初始化失败界面的组件元素,但是不进行展示 |
showView | 展示失败界面的元素 |
updateBigText | 设置txt_big要展示的文字 |
updateSmallText | 设置txt_small要展示的文字 |
resetView | 隐藏失败界面的元素 |
setBtnEnable | 隐藏失败界面按钮 |
showDialog | 准备退出游戏时,显示对话框进行询问 |
2、资源层(Res)
(1).Res类
可以理解为资源常量类。
资源名 | 资源说明 |
---|---|
XML_GFX_GAME | 存放了游戏game.xml文件的路径,game.xml文件存放了游戏的许多资源以及相关参数设置 |
ALL_XML | 存放了游戏中要用到的所有xml文件的路径 |
BTN_AGAIN | 存放成功/失败界面中重来按钮的名字 |
BTN_BACK | 存放成功/失败界面中返回按钮的名字 |
BTN_START | 存放开始按钮的名字(并未使用到) |
GAME_MODEL | 存放了成功/失败界面中中上部标题文字组件的组件名 |
GAME_TIP | 存放了开始界面中底部提示文字组件的组件名 |
GAME_TITLE | 存放了成功/失败界面中右上角标题文字组件的组件名 |
3、控制层(Control)
(1).TimeTool类
可以理解为计时器类。
[1].属性
属性名 | 介绍 |
---|---|
mGameScene | TimeTool类游戏场景 |
mTimerHandler | TimeTool类时间处理器,用于计时 |
millsPass | 当前经过的总毫秒数 |
isCountDowning | 标明是否正在计时 |
stepMills | 标明多久刷新一次计时 |
[2].方法
方法 | 介绍 |
---|---|
initTimerHandler | 初始化成员mTimerHandler |
resetTimer | 重置计时器计时数 |
addMillisPass | 累加stepMills,并将累加后的计时显示在游戏场景mGameScene中 |
getMillsPass | 获取计时器当前总毫秒数 |
millisToTimer | 将计时器计时数转化成毫秒数 |
start | 注册mTimerHandler,开始计时 |
stop | 反注册mTimerHandler,结束计时 |
4、工具层(Util)
(1).ConstantUtil类
可以理解为公共常量类。
常量名 | 常量说明 |
---|---|
DESIRED_SIZE | 屏幕参考尺寸 |
COLOR_WHITE | 白色块标识 |
COLOR_BLACK | 黑色块标识 |
GAME_START | 游戏开始状态标识 |
GAME_OVER | 游戏结束状态标识 |
LINES_LEN | 别踩白块的白块行数 |
FONT_NAME_TIMER | 游戏进行界面上方计时器文字颜色(红色)的key |
FONT_NAME_RESULT | 游戏结束界面结果文字颜色(黑色)的key |
(2).LogUtil类
可以理解为日志工具类。
[1].属性
属性名 | 介绍 |
---|---|
showLogEnabled | 标识是否允许输出日志信息 |
TAG | 日志标记,便于在LogCat中查找相应日志 |
[2].方法
方法 | 介绍 |
---|---|
out | 根据showLogEnable,决定是否进行在LogCat中进行System.out输出 |
d | 根据showLogEnable,决定是否进行在LogCat中进行Debug级别输出 |
i | 根据showLogEnable,决定是否进行在LogCat中进行Info级别输出 |
v | 根据showLogEnable,决定是否进行在LogCat中进行Verbose级别输出 |
w | 根据showLogEnable,决定是否进行在LogCat中进行Warning级别输出 |
e | 根据showLogEnable,决定是否进行在LogCat中进行Error级别输出 |
(3).SharedUtil类
可以理解为缓存读写类
[1].属性
属性名 | 介绍 |
---|---|
SHARED_OG | 缓存文件名 |
RESULT_RECORD | 在缓存文件中用来存储记录的量 |
[2].方法
方法 | 介绍 |
---|---|
setRecord | 记录(毫秒数)写入 |
getRecord | 记录(毫秒数)获取 |
5、场景层(Scene)
(1).GameScene类
可以理解为游戏场景类。
GameScene类继承自OGEngine开源引擎封装好的Scene类。
[1].属性
属性名 | 介绍 |
---|---|
blockWidth | Block宽度 |
blockHeight | Block高度 |
blockList | 存放一次游戏中要显示的Blcok,可以理解为游戏地图 |
linesLength | 当前生成块的行数 |
gameStatus | 当前游戏的状态 |
moveNum | 移动步数 |
mSuccGroup | 成功界面对象 |
mFailGroup | 失败界面对象 |
mTimeTool | 计时器对象 |
timerText | 计时文本显示 |
game_tip | 游戏开始前的提示文本 |
pZIndex_middle | Z索引排序使用的常量(Z索引应该指的是索引值越高展示在越上层,可能是用于组件覆盖) |
pZIndex_top | Z索引排序使用的常量(Z索引应该指的是索引值越高展示在越上层,可能是用于组件覆盖) |
[2].方法
方法 | 介绍 |
---|---|
onSceneCreate | 游戏场景创建时的回调函数 |
initView | 初始化界面、初始化游戏地图、初始化各组件,准备好界面展示 |
initBlocks | 初始化开始时的游戏地图,也就是生成包括黄色提示行在内的5行Block |
resetGame | 重置游戏相关的内部成员(游戏状态、地图数据、界面显示……) |
createNewRowBolcks | 去除超出屏幕(下界)的Block,生成一行新的Block加入地图列表 |
gameSucc | 游戏胜利后相关处理(停止计时、成功界面显示……) |
gameFail | 游戏胜利后相关处理(停止计时、失败界面显示……) |
showSuccGroup() | 游戏即将结束(地图已经加载完毕,没有新的方块)时,加载顶部标志着即将胜利的绿色界面 |
deletBlocks | 清除Block绘制,移除地图中的所有Block |
touchBlock | Block被点击时的逻辑处理 |
failAction | 加载点击白块(游戏即将失败)时的闪红效果 |
upBlockTouch | 判断是否触碰了应点按钮的上一行,如果点了则进行移动,否则不作处理 |
moveDown | 将地图整体往下移动一格(正确点击黑块或点击黑块上一行后调用) |
moveToY | 将当前界面沿着Y轴方向移动指定距离 |
onKeyUp | 触发键盘输入事件时的回调函数 |
onSceneResume | 触发场景恢复事件时的回调函数 |
onScenePause | 触发场景暂停事件时的回调函数 |
onSceneDestroy | 触发场景销毁事件时的回调函数 |
getCameraRightX | 获取界面最右边的X坐标 |
getCameraCenterX | 获取界面正中间的X坐标 |
getCameraBottomY | 获取界面最底部的Y坐标 |
getCameraCenterY | 获取界面正中间的Y坐标 |
6、活动层(Activity)
(1).MainActivity类
MainActivity类OGEngine开源引擎封装好的GameActivity类。
方法名 | 方法介绍 |
---|---|
onCreate | MainActivity创建时的回调函数 |
onCreatePixelPerfectEngineOptions | 安卓机打开应用后的回调函数(用于设置横竖屏、分辨率等) |
onLoadResources | 加载资源时的回调函数(加载所有XML文件资源、字体资源) |
onLoadComplete | 加载完成时的回调函数(启动游戏场景) |
onPause | 暂停时的回调函数 |
onResume | 恢复时的回调函数 |
onDestroy | 结束时的回调函数 |
四、整体实现流程
1、资源加载、信息获取
先是MainActivity类:
- onReloadResources函数加载了相关的XML资源文件(game.xml),
- onCreatePixelPerfectEngineOptions函数设置了竖屏显示
- onLoadComplete函数启动了游戏场景GameScene
然后是GameScene类:
- onSceneCreate函数根据屏幕宽高的1/4大小设置Blcok元素的宽高
2、界面、数据初始化
在GameScene类中:
- onSceneCreate函数调用initView函数
- initView函数调用initBlocks函数初始化游戏数据,然后将计时器文字、提示文字、失败界面、成功界面统一进行了初始化
- initBlocks函数使用Blcok的构造函数先生成4×54×54×5的地图,加入到地图列表blockList中(其中row=0的一行为提示黄块,其余每行根据一个0-3的索引随机数生成黑块)
至此,整个游戏初始界面,已经加载完毕,游戏状态是游戏已经开始。
3、游戏开始
虽然游戏状态为游戏开始,但是实际上计时器还未开始计时,只有点击了第一块黑块时,计时器才会开始计时,游戏才真正开始。
在GameScene类中,touchBlock函数是Blcok被点击后的逻辑处理函数,当一个Block被按下后,将进行如下的逻辑处理:
- 如果点击的Block在从下往上数第3行(即应点击方块的上一行),则判断点击的是否为黑块:如果是黑块,整体下移,生成下一行;如果不是黑块,不作处理。
- 如果点击的Blcok在从下往上数第2行(即应点击方块的那一行),则判断点击的是否为黑块:如果是黑块,通过当前已经生成行数lineLength和已移动步数moveNum计算是否应该游戏结束,游戏结束则加载成功界面,未结束则整体下移生成下一行;如果是白块,加载游戏失败的Block闪红效果,然后显示游戏失败界面
- 如果点击的Block在其他位置,不作处理
当第一块黑块被正确点击后,touchBlock函数将调用moveDown函数,moveDown函数会将底部提示文字隐藏,并开始计时。
至此,游戏才算真正开始。
4、游戏进行
方块层迭代
当正确点击黑块后,Block点击的回调函数touchBlock会调用moveDown函数。
在地图还没有生成结束时,moveDown函数会调用createNewRowBlocks函数生成一行新的Blcok,生成机制如下:如果当前地图blockList的行数超过5,则清除原来blockList中第一行的绘制、移除blockList中第一个元素,根据一个0-3的随机数,调用4次Block的构造函数,生成一行新的Block,加到地图blockList中,更新已生成的地图层数lineLength.
在地图已经生成结束时,调用showSuccGroup函数加载出成功界面的部分(因为文字、按钮等组件均被隐藏,所以只能看到背景色)。
然后moveDown函数会继续更新已经移动的步数moveNum,将被正确点击的黑块弄成灰色,并且调用moveToY将所有Block向下移动一格单位(如果已经显示出了即将胜利的界面,将胜利界面也往下移动一格单位)
5、游戏结束
失败结束
当点击到了从下往上数第二行的白块时,touchBlock函数将判定游戏结束,调用failAction函数加载失败Block闪红效果,调用gameFail函数,然后显示失败界面。
成功结束
当已生成方块行数lineLength与已点击黑块数moveNum满足lineLength == moveNum + 2
时(相差的2,一个是一开始的第一行黄块不在moveNum计数中,另一个是最后一次点击没有更新moveNum),标志着当前点击的黑块是最后一个黑块,touchBlock函数将判定游戏结束,调用gameSucc函数进行最终移动,加载胜利界面。
6、游戏记录
游戏的记录是用SharedPreference存储在App的缓存里的。
当游戏成功结束后、成功界面被显示(SuccGroup类的showItems方法被调用)时,会读取游戏场景mGameScene里的计时器里的计时,然后和缓存里的计时相比较(如果新记录更厉害会被写入缓存),然后再展示,上方大字展示本次游戏记录,下方小字展示最佳记录(如果是新纪录会显示“新纪录”的提示文字;如果没有记录将不显示)。
当游戏失败结束后、失败界面被显示(SuccGroup类的showView方法被调用)时,会读取缓存里的最佳记录,然后再展示,上方大字展示“失败了”的提示文字,下方小字展示最佳记录(如果没有记录将不显示)。
【记录的读取是通过封装的SharedUtil类实现的】
7、游戏结束后的选择
不论是胜利界面还是失败界面,都有“返回”和“重来”两个按钮。
点击“返回”按钮后,将弹出对话框询问是否退出App:选择“确定”后,将结束MainActivity,然后退出App;选择“取消”后,不进行操作。
点击“重来”按钮后,将调用resetView函数重置成功/失败界面,然后调用resetGame函数重新加载游戏场景。
Android 别踩白块 源码分析相关推荐
- 【微信小程序】别踩白块源码免费分享
微信小程序"别踩白块"源码分享 一.项目目录框架及配置 1.文件框架 (1)pages文件夹: (2)app.js (3)app.json (4)app.wxss (5)app.w ...
- 别踩白块java程序代码_别踩白块源码
[实例简介] 经典游戏别踩白块源码,自己DIY 嘚瑟一下自己的小伙伴吧 ! [实例截图] [核心代码] OGEngine_bcbkym └── OGEngineDeom_block ├── Andro ...
- android别猜白块源码,小白式源码-别踩白块
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 先来一个-- 专门用来画图的,我不敢保证里面的方法都对,这是小白式的源码. import android.view.*; import android.c ...
- 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 )
Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...
- Android shortcut的使用及源码分析
Android shortcut的使用及源码分析 最近遇到了一个切换国家码后部分应用的shortcut未更新的问题,就学习了shortcut的相关知识,在这里分享一下我了解的知识,希望能对大家有帮助. ...
- Android Q 10.1 KeyMaster源码分析(二) - 各家方案的实现
写在之前 这两篇文章是我2021年3月初看KeyMaster的笔记,本来打算等分析完KeyMaster和KeyStore以后再一起做成一系列贴出来,后来KeyStore的分析中断了,这一系列的文章就变 ...
- 【Android 插件化】VirtualApp 源码分析 ( 启动应用源码分析 | HomePresenterImpl 启动应用方法 | VirtualCore 启动插件应用最终方法 )
文章目录 一.启动应用源码分析 1.HomeActivity 启动应用点击方法 2.HomePresenterImpl 启动应用方法 3.VirtualCore 启动插件应用最终方法 一.启动应用源码 ...
- 【Android 插件化】VirtualApp 源码分析 ( 添加应用源码分析 | LaunchpadAdapter 适配器 | 适配器添加元素 | PackageAppData 元素 )
文章目录 一.添加应用源码分析 1.LaunchpadAdapter 适配器 2.适配器添加元素 3.PackageAppData 元素 一.添加应用源码分析 1.LaunchpadAdapter 适 ...
最新文章
- 图形基础 GPU架构(5)并行计算
- 【N版】openstack——认证服务keystone(三)
- oracle导出数据视频教程,Oracle导入导出数据的几种方式
- 易语言 mysql_易语言MySql注册登录
- 计算机组成原理包健百度云,计算机组成原理包健版答案
- 2017.8.26 力 思考记录
- 大众CEO迪斯承认芯片仍短缺
- Python爬取并简单分析2024年普通高校招生专业(专业类)选考科目要求
- oracle迁移至ASM磁盘
- linux获取主板温度电压_主板供电
- charts 画折线图
- tombstone 信息解析
- 基于android的个人收支财务管理,基于Android的个人财务管理系统的设计与实现.doc...
- PC端如何下载B站里面的视频?
- 点阵字python_Python点阵字玩转动态歌词
- 加权黑猩猩优化算法(WChOA)附Matlab代码
- promise.all的用法讲解。
- css实现聊天气泡对话框
- 专注是通向成功的直通车
- android中的蓝牙通信协议,android 蓝牙SPP协议通信
热门文章
- linux 脚本中的push,在Linux系统下实现ServerPush(转)
- commit git 删除文件夹_Git-git删除文件夹/文件(删除/不删除本地文件/文件夹)
- python字典创建,删除,增加,合并等方法的调用
- python写入txt,读取txt,拷贝txt文件
- Android恶意代码分析流程,[原创]恶意代码plankton分析记录(1)
- mysql 函数 数字转字串_mysql中字符串和数字的互转函数
- 导致集群重启_园区网核心交换机S7706异常重启导致无线网络故障
- PyTorch 学习笔记(三):transforms的二十二个方法
- 算法导论 思考题9-2
- PyCharm汉化后无法打开Settings设置