"别踩白块儿"游戏源代码分析和下载(二)

四、游戏交互实现

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

"别踩白块儿"游戏源代码分析和下载(二)

时间: 2024-11-05 14:35:04

"别踩白块儿"游戏源代码分析和下载(二)的相关文章

“别踩白块儿&quot;游戏源代码分析和下载(一)

本帖最后由 lch123go 于 2014-7-9 17:51 编辑 "别踩白块儿"是目前非常火的一款游戏,游戏非常简单刺激.关于具体怎么火法怎么玩我就不多说了,相信看到本文的朋友们都非常地清楚. 什么游戏火,我们都想知道自己能不能也弄一个玩玩,我也花了点时间弄了一个,游戏代码将会开源,利人利己,大家一起提高,希望各位多多支持. 下面介绍如何用OGEngine游戏引擎完成"别踩白块儿"游戏的经典模式. 源码下载地址 一.最终实现的部分效果截图 1.刚开始时,最下面有

别踩白块儿游戏源码项目

这个项目有带说明文档,大家可以看看源码附件的说明文档吧,"别踩白块儿"是目前非常火的一款游戏,游戏非常简单刺激.关于具体怎么火法怎么玩我就不多说了,相信看到本文的朋友们都非常地清楚. 什么游戏火,我们都想知道自己能不能也弄一个玩玩,我也花了点时间弄了一个,游戏代码将会开源,利人利己,大家一起提高,希望各位多多支持. 下面介绍如何用OGEngine游戏引擎完成"别踩白块儿"游戏的经典模式. 一.最终实现的部分效果截图 1.刚开始时,最下面有一栏为***,紧接着上面每一

别踩白块儿游戏源码Android版

这个项目有带说明文档,大家可以看看源码附件的说明文档吧,“别踩白块儿”是目前非常火的一款游戏,游戏非常简单刺激.关于具体怎么火法怎么玩我就不多说了,相信看到本文的朋友们都非常地清楚. 什么游戏火,我们都想知道自己能不能也弄一个玩玩,我也花了点时间弄了一个,游戏代码将会开源,利人利己,大家一起提高,希望各位多多支持. 下面介绍如何用OGEngine游戏引擎完成“别踩白块儿”游戏的经典模式. 一.最终实现的部分效果截图 1.刚开始时,最下面有一栏为黄色,紧接着上面每一行都是有一个黑色块,其余为白色块

跃居AppStore榜首的游戏&lt;别踩到白块儿&gt;源代码分析和下载(第一篇)----它怎么也能爆红?

AppStore和Android市场情况 莫名其妙爆红的游戏 真的莫名其妙,笔者下这个游戏两次,第一次在豌豆荚排行榜看到这款游戏,名字怪怪的,下载下来尝试一下,没觉得有什么新颖的,还在思虑这是不是刷榜刷上去的,果断卸载了:周末的时候逛逛app store,突然看到排行榜首位是Dont Tap The White Tile(后更名panio tiles ),翻译一下不就是别踩到白块儿,笔者震惊了,太莫名其妙了,这东西是真的火,不是刷榜刷出来的!游戏玩家们心理真的难以捉摸,又捧红了一款游戏: 近期爆

【cocos2d-x制作别踩白块儿】第九期:游戏计时功能(附源代码)

游戏没有计时,不是坑爹吗? 这一期,我们将来加入游戏计时功能. 1. 定义变量和函数 我们先在HelloWorldScene.h中定义几个变量和函数 long startTime; bool timeRunning; startTime用来记录開始的时间,timeRunning用来推断游戏是否在进行中. //開始计时 void startTimer(); //结束计时 void stopTimer(); virtual void update(float dt); startTimer()函数时

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

初学JS--利用JS制作的别踩白块儿(街机模式) 小游戏 这个是上个星期5写的了,当时是突然想写个游戏,就想到了别踩白块儿,当时的想法是 可能普通模式的别踩白块儿因为他的"块儿"是滚动的向上这种,以我目前会的技术想不出怎么写, 但是如果是街机模式,通过你每按一次按键之后他像下跳一格这样的就非常好实现了. 通过我目前会的知识,实现的步骤大概是这样的: 建一个4X4的表格,制作2张150X100的图片,一张全白色,一张全黑色,命名为0.JPG,1.JPG 就是说当文件名为0的时候就是白色的

用Canvas写一个简单的游戏--别踩白块儿

第一次写博客也不知怎么写,反正就按照我自己的想法来吧!怎么说呢?还是不要扯那些多余的话了,直接上正题吧! 第一次用canvas写游戏,所以挑个简单实现点的来干:别踩白块儿,其他那些怎么操作的那些就不用再扯了,大家应该都懂,不懂的看到黑色的就点就是了,扯多了我打字手也累,大概.链接给你们:http://nowtd.cn/white/ 咱不是理论派,所以在这里不会扯多少理论. 首先看看html的结构吧 1 <header class="container"> 2 <art

【cocos2d-x制作别踩白块儿】第一期:游戏介绍

这一系类文章.我们将来分析时下最火的一款游戏 -- 别踩白块儿. 无图无真相,先上图 这就是我们终于要完毕项目的效果图. 游戏刚開始的最以下有一栏为黄色,紧接着上面每一行都是有一个黑色块,其余为白色块 玩家假设按错了.按到了白色块.会出现游戏结束对话框 游戏进行到最后会出现绿色栏.而且在游戏过程中都有一个计时器,显示时间 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGVnZW5kb2YxOTkx/font/5a6L5L2T/fontsize/400

别踩白块儿

相信大家对这个游戏并不陌生.这个游戏可玩性不错,就是有点闹心,一点小错误又得重新来过.可所谓一失足成千古恨啊! 不过我最近在和朋友争论这个游戏里的钢琴音效的问题.我认为那是一首首歌曲的调,他却不这么认为(可能有点笨吧).因为我玩的时候明明可以听到是歌曲的音调,还可以跟着哼出来.这里我搜集了一下这里面的歌曲,有我听出来的,也有我在网上搜的.这些音乐随机出现在一局游戏里,当你足够厉害弹完一首歌曲,它会在随机地出现一首(难道没有尽头?)笔者反正只连续听过两首歌曲.不过随着游戏的进行,节奏越来越快,有些