【不是教程的教程】第三弹——小乐教你写fc坦克大战(3.11.1版本c++语言)

呀吼,各位好久不见,你没有看错,就是我,我诈尸了。今天又来发教程了,本来该教程在一年多以前就打算出的,当时3.0版本刚出就想着用新版本写个Demo,但是在写一半的时候,“懒癌”发作了,就这么弃了。前不久,Cocos Creator出了,想想,我也该写个Cocos Creator的教程,不过也不能把之前写一半的东西弃了,所以就又开始接着写了。然后发现Cocos2d-x都已经更新到3.10版本了,然后也出了个Cocos引擎。Cocos引擎可以创建预编译库工程,这是个好东西,为了省点空间和编译时间,就采用Cocos引擎重新创建工程了。

作为一个犯有“懒癌”和“拖延症”的我,又花了好几个月,陆陆续续的把代码给补全了。写完之后,发现Cocos2d-x已经更新到3.11.1版本,而Cocos引擎已经阵亡了,那我就只好用Cocos2d-x 3.11.1再重新创建了工程。在此我就提供这两种版本的源码工程下载,如果谁电脑还装着Cocos引擎的话,就可以用了,顺带提供了不带引擎库的工程,网速差的同学就可以下载这个,然后自己拷贝引擎库到工程里。本来还有点小邪恶的想把源码提交Cocos商店卖个1元钱呢,无奈Cocos商店目前无人管理,所以还是免费提供下载了,反正也并不指望挣多少钱。

当初刚入门的时候,也曾经在网上找各种各样的坦克大战源码,结果都只是简单写写,跟原版差的十万八千里,所以就想自己写一个高还原的。讲真,这Demo实现了八成左右的功能(2P、自定义地图和超最高分的提示场景没做),各种细节地方也尽量跟原版一致,肯定是你网上能找到的最接近原版FC坦克大战的源码了。

好了,现在该言归正传了,介绍下Demo。写之前还真小看了坦克大战,以为三下五除二就能搞定,结果还是花费了相当长的时间,代码量也比前两个Demo多了好些。老惯例,晒Demo截图,看,是不是跟原版一模一样呢,这次就晒一张,反正你们也都知道长啥样呢~~~


首先,还是介绍下Demo的各个类。
AudioM 声音管理类,继承于AudioEngine,并添加游戏所需逻辑
Bomb 爆炸类,子弹、坦克、大本营爆炸的动画
BombM 爆炸管理类
Bonus 奖励道具类,就是打死红色敌人坦克出现的道具
Bullet 子弹类
BulletM 子 弹管理类
DataM 数据管理类,存储数据
EnemyTank 敌人坦克类
GamOverScene 游戏结束场景类
GameScene 游戏场景类
Global 定义了一些全局变量
Joystick 虚拟手柄类,包括物理键盘的事件
LevelScene 关卡过渡场景类,每两关之间显示第几关的场景
LoadingScene 加载场景类,游戏一启动的时候进行资源加载,由于没多少资源,没写界面了
MenuScene 菜单类
PlayerTank 玩家坦克类
SceneM 场景管理类
Score 分数表类,关卡结束后的分数统计
Stage 舞台类,包含地图与右边的信息
Tank 坦克类,玩家坦克和敌人坦克的父类,定义了共有的方法和属性
TankM 坦克管理类
TransitionEx 场景切换效果扩展类,自定义了关卡过渡场景的进入和离开的效果

接下来就对代码的几个核心部分进行讲解:
1、如何消除半块砖。
除了玩家坦克的第四个等级(也就是能打铁的那个形态)可以消除整块转,其余情况下都是只消除半块砖。所以,首先对砖分成左上、右上、左下、右下四个部分,例如子弹从上方射击就是消除左上和右上,从左方射击就是消除左上和左下。如果使用四个bool类型的变量来代表四个部分的话,if的条件表达式就比较长了,故舍弃。用"1111"这样的字符串来表示四个部分的话,if判断就来得简单多了,但是最终我也没采用这种方法,为了不添加额外的变量,我使用了位运算(因为大学学的是电子,所以对位运算还是很钟爱的)。每个地图元素的类型都是个int变量,类型只有0~9,4位就够了,所以就在剩余的位数中又拿出来4位来表示四个部分的状态,代码里所涉及到的位运算如下图所示。


标志位搞定了,接下来就是图片的显示了,分别判断上、下、左、右四个部分是否消除来改变图片的矩阵,然后进行裁剪。由于锚点设置的是左上角点,所以如果左边或上边为空的话,裁剪后还得修改图片坐标。

2、地图的读取
地图配置文件如下,之所以不采用json,是因为解析json有点麻烦,而且也没现在这种配置文件直观,这种格式的文件使用C++的fstream就可以很方便的读取到数组了。

最初的代码如下,在win32上一切完美无缺,然而之后在Android上运行的时候才发现,事情大条了,读取不到配置文件。本来想学学引擎是如何读取文件的,然而看了代码之后,我弃了。难道我该换成json解析了吗,就在我快走投无路的时候,突然灵光一现,想起了以前用过的stringstream,可以使用引擎接口读取配置文件内容,再把字符串传给stringstream,遂改成如下代码,经测试果然能行,真是可喜可贺。

3、坦克的动画
坦克的动画并没有使用Animation创建动画,而只是单纯的在update里设置精灵的图片,毕竟坦克的行走方向频繁的改变,频繁的切换Animation感觉不太好,再加上敌人坦克还有种红色闪烁的动画,使用Animation的话那就复杂多了。敌人坦克的图片格式为"enemy%d_%d_%d_%d.png",第一个数字为坦克的类型(1~4四种类型),第二个数字为等级(除了类型4的敌人有4个等级,其余都只有1),第三个数字为方向(1~4表示四个方向),第四个数字就是动画的哪一帧了。玩家坦克的图片格式为"player1_%d_%d_%d.png",也是一样的。

接着说说如何控制红色闪烁的动画了,其实很简单,首先瞧瞧图片资源,如下。一般行走动画帧数是在1、2之间切换,然后加个定时器和一个标志位,标志位就是在true和false不断切换,标志位为true的时候帧数加2,这样一来动画的行走帧数就是在3、4之间切换,就变成红色了。

最后顺带说下特殊的类型4的敌人,有4个等级,打一下变化一个等级,打4下才会死。起初看资源的时候发现才银、黄、绿三个颜色,以为是不是少了资源,后来才发现真相是这个样子的,等级4是银、绿交替,等级3是银、黄交替,等级2是黄、绿交替,等级1是银。所以类型4的等级2~4的行走动画是4帧,稍微特殊处理下,其实也没多大区别。

其余的功能好像也没有什么需要详细讲解的了,我还真不擅长写教程呢,不过代码里的注释也不少,应该都能看懂的,如果还有啥看不懂的话,欢迎回帖提问哟。最后,希望这教程能帮到那些刚入门的同学们。

源码工程上传到百度网盘了,地址是http://pan.baidu.com/s/1bMyoIq,欢迎喜欢本教程的同学顶下帖哟~~~

3赞

不错,下载学习了。

你好,大佬,我不是很理解你消除半块砖的逻辑。对二进制不是很感冒。大佬有空,可以用if判断来解释一下,应该容易理解一些。看了一些其他的坦克确实都是简单写下,消除就用引擎的碰撞系统简单处理下。哈哈,还望大佬有空帮小白解感,感谢,非常感谢!

位运算多简单粗暴,不然就需要四个变量,根据消除的是哪一边就对对应的变量设为0,判断砖状态就得4个变量的值都判断了。

感谢大佬回复。恩,消除半块砖这块还真还没想好怎么处理,还好有得借鉴,其实还是有点懵懵的,先实现吧。目前有个基地与坦克显示问题,地图的格子是以1/4的块(即1616)作为基础块进行显示的,基地大小(3232)这直接放在地图里不都会有偏移吗,我的偏移。我想是应该把基地图片切成4等份…这好像不太行那基地被被毁图片也要这样。我看大佬的资源图是整块,你的不会偏移吗。坦克也是,说明一下,我用的是cocos creator,难道是坐标问题?不是很理解

,四个位置(9,8,8,8)都放这个位置就这样了。有空帮忙看看

问下,地图元素的锚点是在左上角,坦克的锚点设在中心点?

嗯呀,就是这样。锚点中心但大小不一样那肯定就偏移了,所以就改左上了。

请问一下3.10那个报错了

空指针,找不到图片吧,试试把资源放到跟exe同目录吧[quote=“923088220, post:9, topic:37416, full:true”]
请问一下3.10那个报错了

[/quote]