四、游戏交互实现

1、前面已经介绍在 Block 类实现了每个block的触碰监听,block 实现触碰监听,当按下时,调起在GameScene中实现的touchBlock方法。下面来看改方法的实.

  1. /**

  2. * 点击到Block时进行的逻辑处理

  3. *

  4. * @param pBlock

  5. *            所点击的block

  6. */

  7. public void touchBlock(Block pBlock) {

  8. if (gameStatus == ConstantUtil.GAME_START) {

  9. if (pBlock.getRow() == moveNum + 2) {// 表示是在底部往上数的倒数第三行

  10. // 判断是不是点击了该点击的黑块的上一格,如果是,我们也判定这是正确点击了,做出相应移动

  11. upBlockTouch(pBlock);

  12. } else if (pBlock.getRow() == moveNum + 1) {// 表示是在底部往上数的倒数第二行

  13. if (pBlock.getColorType() == ConstantUtil.COLOR_BLACK) {

  14. if (linesLength == moveNum + 2) {

  15. // 游戏胜利

  16. gameSucc(pBlock);

  17. } else {

  18. // 整体blocks下移

  19. moveDown(pBlock, 1);

  20. }

  21. } else if (pBlock.getColorType() == ConstantUtil.COLOR_WHITE) {

  22. // 误点了白块,游戏失败

  23. gameFail();

  24. // 失败时pBlock的一个闪红效果

  25. LoopEntityModifier loop = failAction();

  26. // 播放效果

  27. pBlock.registerEntityModifier(loop);

  28. }

  29. }

  30. }

  31. }

复制代码

上面的代码已经有所注释,这里再简单解析一下。

①理论上可以点击的一行为倒数第二行,如果点击到该行的黑块,则所有block向下移动一格,如果点击到该行的白块,则游戏失败,弹出失败界面。

②为了体验上的优化,如果点击到倒数第二行黑块所在列正对上的一个block(不管是黑块还是白块)也视为正确点击了黑块。因为在快速点击黑块的同时整体的block也迅速向下移动,很容易点击到上一格,此时我们认为这也是正确的点。

2、判断是不是点击了该点击的黑块的上一格,如果是,我们也判定这是正确点击了,做出相应移动

  1. /**

  2. * 判断是不是点击了该点击的黑块的上一格,如果是,我们也判定这是正确点击了,做出相应移动

  3. *

  4. * @param pBlock

  5. *            所被点击的块

  6. */

  7. private void upBlockTouch(Block pBlock) {

  8. int touchColumn = pBlock.getColumn();

  9. for (Block[] blocks : blockList) {

  10. for (Block block : blocks) {

  11. if (block.getRow() == moveNum + 1

  12. && block.getColorType() == ConstantUtil.COLOR_BLACK) {

  13. if (block.getColumn() == touchColumn) {

  14. // 整体blocks下移

  15. moveDown(block, 1);

  16. }

  17. return;

  18. }

  19. }

  20. }

  21. }

复制代码

3、方块下移等相关逻辑moveDown方法的实现。

  1. // 正确点击该点击的黑块,或者上一行的块,整体向下移动、创建新的一样块,改变黑块        private void moveDown(Block pBlock, int stepNum) {

  2. if(moveNum == 0){

  3. // 开始计时

  4. mTimerTool.start();

  5. // 隐藏提示文字

  6. game_tip.setVisible(false);

  7. }

  8. if (moveNum < ConstantUtil.LINES_LEN) {

  9. // 创建添加新的一行

  10. createNewRowBolcks();

  11. } else if (moveNum == ConstantUtil.LINES_LEN) {

  12. // 开始显示绿色胜利界面,即将胜利,但还没有胜利

  13. showSuccGroup();

  14. }

  15. // 被点击的黑块变灰

  16. pBlock.setColor(0.63f, 0.63f, 0.63f);

  17. pBlock.registerEntityModifier(new ScaleModifier(0.1f, 0.5f, 1.0f));

  18. // 移动步数加1

  19. moveNum++;

  20. // 需要移动的距离

  21. float moveDistance = this.getCameraHeight() - blockHight * stepNum

  22. - pBlock.getY();

  23. for (Block[] rowBlocks : blockList) {

  24. for (Block block : rowBlocks) {

  25. // 遍历,所有block向下移动指定距离

  26. moveToY(block, moveDistance);

  27. }

  28. }

  29. // 快到胜利出现绿色胜利界面时,胜利界面跟着移动

  30. if (mSuccGroup.isVisible()) {

  31. moveToY(mSuccGroup, moveDistance);

  32. }

  33. }

复制代码

①moveNum用来记录移动了多少步,第一次开始下移时,我们开始计时以及隐藏下边的提示文字。

②如果还没有达到预设的总行数就创建添加新的一行blocks,如果到了则开始显示绿色胜利界面。

③被点击的黑块变灰色,加点小小的动作效果。

④计算出需要向下移动的距离,遍历所有blocks,向下移动指定距离。

⑤快到胜利出现绿色胜利界面时,胜利界面跟着移动。

4、创建添加新的一行createNewRowBolcks()方法的实现。

  1. //创建添加新的一行

  2. private void createNewRowBolcks() {

  3. // 超出屏幕没用的部分移除掉

  4. if (blockList.size() > 5) {

  5. Block[] rowBolcks = blockList.get(0);

  6. for (Block block : rowBolcks) {

  7. block.detachSelf();

  8. }

  9. blockList.remove(0);

  10. }

  11. // 目前顶部的一行块的Y坐标

  12. float topBlocksY = blockList.get(blockList.size() - 1)[0].getY();

  13. // 一行块

  14. Block[] rowBolcks = new Block[4];

  15. int blackIndex = new Random().nextInt(4);

  16. for (int column = 0; column < 4; column++) {

  17. // 新创建 Block

  18. rowBolcks[column] = new Block(this, column, blockWidth, blockHight,

  19. blackIndex, getVertexBufferObjectManager());

  20. // 设置Y坐标

  21. rowBolcks[column].setBottomPositionY(topBlocksY - 1);

  22. // 设置已经是第几行

  23. rowBolcks[column].setRow(linesLength);

  24. this.attachChild(rowBolcks[column]);

  25. }

  26. blockList.add(rowBolcks);

  27. // 按Z索引排序一下上下层顺序

  28. this.sortChildren();

  29. // 当前生成的块的行数增加

  30. linesLength++;

  31. }

复制代码

① 先把超出屏幕没用的部分移除掉,把新增的一行blocks的位置设在最顶端,设置已经是第几行。

5、游戏成功或者游戏失败

  1. /**

  2. * 最后一个移动,游戏胜利

  3. *

  4. * @param pBlock

  5. */

  6. private void gameSucc(Block pBlock) {

  7. gameStatus = ConstantUtil.GAME_OVER;

  8. // 最后一个移动,游戏胜利

  9. moveDown(pBlock, 0);

  10. // 停止计时

  11. mTimerTool.stop();

  12. // 显示游戏胜利画面

  13. mSuccGroup.showItems(true);

  14. // 隐藏显示时间的Text

  15. timerText.setVisible(false);

  16. }

  17. /**

  18. * 点击错误后弹出红色的失败界面,游戏失败

  19. */

  20. private void gameFail() {

  21. gameStatus = ConstantUtil.GAME_OVER;

  22. // 游戏失败,停止计时

  23. mTimerTool.stop();

  24. // 隐藏显示时间的Text

  25. timerText.setVisible(false);

  26. }

复制代码

五、计时控制类TimerTool 的实现。

我们知道游戏一开始就会有时间的计时,完成指定任务后,时间越短越厉害,玩家通过不断刷新记录来提高对游戏的成就感,所以计时、显示历史最佳记录必不可少。下面我们就来看看如何实现计时。

我们使用OGEngine引擎中的TimerHandler来实现计时,我们先来了解一下TimerHandler。从源码我们发现它实现IUpdateHandler接口。

  1. public class TimerHandler implements IUpdateHandler{

复制代码

再来看一下它的构造器

  1. /**

  2. * @param pTimerSeconds 经过多少秒后执行 pTimerCallback 中的回调

  3. * @param pAutoReset 是否循环执行

  4. * @param pTimerCallback 回调函数

  5. */

  6. public TimerHandler(final float pTimerSeconds, final boolean pAutoReset, final ITimerCallback pTimerCallback) {

  7. if(pTimerSeconds <= 0){

  8. throw new IllegalStateException("pTimerSeconds must be > 0!");

  9. }

  10. this.mTimerSeconds = pTimerSeconds;

  11. this.mAutoReset = pAutoReset;

  12. this.mTimerCallback = pTimerCallback;

  13. }

复制代码

下面来看TimerTool 的具体实现。

①所定义的成员变量,构造器实现。

  1. public class TimerTool {

  2. private GameScene mGameScene;

  3. private TimerHandler mTimerHandler;

  4. /**当前经过的总毫秒数**/

  5. private long millisPass = 0;

  6. /**是否计时中**/

  7. private boolean isCountDowning = false;

  8. /**多少毫秒累加一次计时**/

  9. private static long stepMillis = 83;

  10. public TimerTool(GameScene pGameScene) {

  11. this.mGameScene = pGameScene;

  12. initTimerHandler();

  13. }

复制代码

②初始化TimerHandler

  1. // 初始化TimerHandler,设置为每隔stepMillis * 0.001f秒循环回调onTimePassed方法

  2. private void initTimerHandler() {

  3. mTimerHandler = new TimerHandler(stepMillis * 0.001f, true,

  4. new ITimerCallback() {

  5. @Override

  6. public void onTimePassed(TimerHandler pTimerHandler) {

  7. // 累加所经过的时间,并在界面上更新显示当前时间

  8. addMillisPass();

  9. }

  10. });

  11. }

复制代码

③相关时间的逻辑实现

  1. // 重置时间

  2. public void resetTimer() {

  3. millisPass = 0;

  4. isCountDowning = false;

  5. }

  6. // 累加所经过的时间,并在界面上更新显示当前时间

  7. private void addMillisPass() {

  8. millisPass += stepMillis;

  9. mGameScene.getTimerText().setText(millisToTimer(millisPass));

  10. }

  11. // 获取当前经过的总毫秒数

  12. public long getMillisPass() {

  13. return millisPass;

  14. }

  15. // 把毫秒转化为一种分、秒、毫秒的文本显示模式字符串

  16. public String millisToTimer(long pMillisPass) {

  17. String timer = "";

  18. long min = pMillisPass / 60000;

  19. long sec = (pMillisPass - min * 60000) / 1000;

  20. String secStr = sec < 10 ? "0" + sec : String.valueOf(sec);

  21. long millisec = pMillisPass % 1000;

  22. if (min > 0) {

  23. timer += min + ":";

  24. }

  25. timer += secStr + "." + millisec + "\"";

  26. return timer;

  27. }

复制代码

④开始计时和结束计时

  1. // 注册mTimerHandler开始计时

  2. public void start() {

  3. if (!isCountDowning) {

  4. isCountDowning = true;

  5. mGameScene.registerUpdateHandler(mTimerHandler);

  6. }

  7. }

  8. // 反注册mTimerHandler停止计时

  9. public void stop() {

  10. mGameScene.unregisterUpdateHandler(mTimerHandler);

  11. }

复制代码

在正确点击第一块黑块的时候开始计时,游戏失败或者游戏完成时停止计时,保存好记录的时间,在胜利界面或失败界面根据实际情况实现所用时间跟最佳记录的显示。

本游戏就介绍到这里,更多细节请看游戏源码。。。。。。

×××地址

http://www.eoeandroid.com/forum-863-1.html

www.ogengine.com

转载于:https://blog.51cto.com/9165326/1439338

别踩白块儿游戏源代码分析和下载(二)相关推荐

  1. python+opencv别踩白块儿游戏辅助,一天一个opencv小项目(已开源)

    python+opencv别踩白块儿游戏辅助,一天一个opencv小项目(已开源) 见链接

  2. 使用js实现“别踩白块儿”游戏

    界面如下: 点击"开始游戏","白格"将开始向下移动,此后再每一行上开始出现一个"黑格",对应列上按下对应的键即可消除黑格,但不可跨行消除( ...

  3. 傅小森的游戏制作之路-别踩白块儿

    项目前言 别踩白块儿 这- 还用开发吗? 别人已经制作了呀 触屏版本多的是 是挺多的 但是 你见过按键版本的嘛? 没见过吧 这就是需要开发出来 , 进入项目需求环节 项目需求 别踩白块儿 顾名思义:不 ...

  4. 团队项目代码分析(Android游戏:别踩白块儿)

    代码组成部分: 关键代码主要分为三大部分,如下图所示(用思维导图的形式展示): 代码调用关系 通过MainActivity调用其他类❤,具体见核心代码分析! 核心代码分析 public class P ...

  5. QT 小游戏 : 别踩白块儿~

    一.实现思路 QPainter 绘制 游戏界面 PS:根据方块坐标链表绘制所有方块 支持两种操作方式 PS:鼠标事件 和 键盘事件(Q,W,E,R,T) 定时器(10ms) 刷新 方块坐标数据 根据得 ...

  6. 初学JS——利用JS制作的别踩白块儿(街机模式) 小游戏

    初学JS--利用JS制作的别踩白块儿(街机模式) 小游戏 这个是上个星期5写的了,当时是突然想写个游戏,就想到了别踩白块儿,当时的想法是 可能普通模式的别踩白块儿因为他的"块儿"是 ...

  7. C语言项目实战:《别踩白块游戏》零基础项目,137 行源代码示例

    这篇文章主要为大家详细介绍了C语言实现--<别踩白块游戏>,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下! 游戏介绍: <别踩白块儿 Don't Ta ...

  8. 基于Linux、QT、C++的“别踩白块儿”小游戏

    基于Linux.QT.C++的"别踩白块儿"小游戏 源码链接 一.功能实现 完善的游戏界面.游戏倒计时.得分记录.历史最高分显示 二.功能描述 1.界面为4*4,一行中只有一个黑块 ...

  9. Cocos别踩白块儿案列1

    Cocos  版本3.10 1.游戏介绍: <别踩白块儿>是由 Umoni Studio (Umoni Entertainment Limited 的前身)"制作的一款休闲益智游 ...

最新文章

  1. 二进制安装MariaDB 5.5.41
  2. fastjson异常问题
  3. shell基础之if语句
  4. Maven精选系列--发布jar包到Nexus私库
  5. netty java开发文档_Netty简明教学文档
  6. java设计一个立方体类box_实例1: 设计一个立方体类Box,定义三个属性,分别是长,宽,高。定义二个方法,分别计算并输出立方体的体积和表面积。_学小易找答案...
  7. 设计模式(4)----抽象工厂模式
  8. 机器学习笔记(十二):随机梯度下降
  9. 给大家赠送一个我最近写的鼠标连点器的源代码!
  10. 揭阳市计算机考证报名点在哪里
  11. Win10使用Windows照片查看器(Windows Photo Viewer)来打开图片
  12. 网上车市通过聆讯:营收单一,上半年减员15%,徐翀持股80%
  13. GSWiFi校园网路由器设置方法最新版
  14. 肖sir__出现无法连接仓库的情况:Error performing git command: git ls-remote -h
  15. 乱码问题-Quoted-printable编码
  16. 樱花动漫视频数据表分析樱花动漫
  17. Ali-Perseus(擎天):统一深度学习分布式通信框架 [弹性人工智能]
  18. CountDownLatch和CyclicBarrier的爱恨情仇
  19. UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 的解决方法
  20. 求助:matlab报错:位置 2 处的索引超出数组边界(1)

热门文章

  1. c语言自动按次序创建文件,读取文件建立顺序表实现增,删,查,取(C语言)...
  2. java api 获取jvm实例_JVMTI那些事——和Java相互调用
  3. 执行环境,作用域链,闭包
  4. 为什么ES模块比CommonJS更好?
  5. v8的垃圾回收机制(二)
  6. android串口service,Android串口操作库:EZ-SerialPort
  7. 外接鼠标键盘无反应处理
  8. VB 创建快捷方式函数(可带参数)
  9. 批处理写的关机小程序--bat
  10. Linux系统初学者的常见问题解决集结