cocos2d滚屏射击游戏

第7章 滚屏射击游戏(上)
7.1 高级视差滚屏
7.1.1 将背景创建为底纹
将背景条纹分成单独的文件保存并不只是为了保持正确的Z轴次序,这么做还可以节省空间。
将背景条纹分成单独的文件保存还有助于保持高帧率。iOS设备的填充能力(每一帧可以画的像素个数)非常有限。由于图像经常会互相覆盖,iOS设备不得不在同一帧多次绘制相同的像素。最极端的情况是一幅全屏图像覆盖在另一幅全屏图像上,虽然你只看到其中一幅,但设备将会绘制两幅,这在技术上叫做overdraw。将背景分为独立的条纹可以减少覆盖部分,从而减少绘画的像素点数量,以提高帧率。
7.1.2 在代码中重建背景
因为所有的图像都已经保存在一个全屏图像中,Zwoptex会记住这些图像的的偏移值。你唯一要做的就是将这些图像放在画布中它们各自的中心位置上,然后它们就会在正确的位置上。
提示:
由于Zwoptex保存了图像的偏移值,因此在cocos2d中重建背景会非常简单。对于创建游戏界面布局来说,这也是一个非常棒的方式。可以将界面上不同的UI元素设计为独立的层。然后将每一层作为独立的包含透明信息的全屏文件单独输出,并根据输出的文件生成一个纹理相册。这样一来,不必费心对各个图层进行定位就能轻松实现最初的设计,也不会造成内存浪费。
7.1.3 移动ParallaxBackground
7.14 视差滚动的速度因素
关于CCArray和iPhone SDK中所有容器的关键问题:它们只能存储对象,不能存储整数或浮点数之类的数值。解决这个问题的方法是将数值封装到NSNumber对象中。
7.15 实现背景的无限滚动
在每一个条纹的游标将该条纹重复一遍,这样一来,背景条纹的宽度变为原来的两倍,可以满足无限滚屏的需求。
我们仅仅需要检查条纹的横坐标,判断它是否小于负的屏幕的宽度。如果是,就加上屏幕宽度的两倍。这样就使原来在屏幕左边的条纹移动到了屏幕右边,正好在屏幕右边,正好在屏幕外面。通过对两个精灵不断重复这个动作,就有了无限滚动的效果。
7.1.6 取消闪烁
如果仔细观察,可能会注意到在条纹的接缝处,会不时地有垂直的黑线出现。出现黑线的原因是四舍五入有误差,因此不时地会出现宽度为1像素的黑色线条。
最简单的解决方法是让左右两个条纹间有1个像素发生重叠。
7.1.7 重复贴图
你可以在指定大小的矩形区域里让任意纹理重复出现。
这里用到了OpenGL支持的GL_REPEAT纹理参数。但它只对边长为2的方幂的正方形区域有效,就像32*32或128*128那样的区域。
7.2 虚拟手柄
不同于传统的移动游戏设备,iOS设备上没有按钮、十字按钮,更没有手柄,所有的输入操作都使用触控屏接收。
7.2.1 引入SneakyInput
在编写任意一个看起来十分普通的程序之前,总是应该先搜索一下是否存在可以直接使用的解决方案,而不要花大量时间去自己写。
SneakyInput的源代码保存在github上,这是一个公开的代码管理网站,地址如下:http://github.com/sneakyness/SneakyInput。
7.2.2 集成SneakyInput
下面5个类是SneakyInput的核心:
1)SneakyButton和 SneakyButtonSkinnedBase
2)SneakyJoystick和SneakJoystickSkinnedBase
3)ColoredCircleSprite
7.2.3 触摸按钮产生射击
7.2.4 为按钮添加皮肤
计算机图形学中的皮肤是指给一个普通的对象添加一个纹理或是一个不同的外观。
7.2.5 控制动作
7.2.5 数字控制
如果虚拟手柄不适合你的游戏怎么办?你可以把SneakyJoystick类变成一个数字控制器,就像D-pad一样。
joystick.isDPad=YES;
joystick.numberOfDirections=8;
将isDPad属性设为YES,于是摇杆就成了数字控制器。D-pads有4个方向键,在许多游戏中,你可以同时按住两个方向键,这样就能让较色沿着对角线方向移动。为了得到这样的效果,可将numberOfDirectors属性设置为8。SneakyJoystick自动确保这些方向被均衡地分配到拇指控制器中。
7.2.6 另一个选择
GPJoystick是一个商业软件。网址:http://wrensation.com/?p=36
7.4 本章小结
第8章 滚屏设计游戏(下)
8.1 添加BulletCache类
注意:
虽然添加一个像BulletCache这样的CCNode会增加场景层次体系的深度,但这样的变化不会造成太大的影响。如果你很介意场景层次体系的继承深度,一个替代的方案是像往常那样在GameScene类中添加精灵节点,然后在BulletCache类中使用存取器方法得到精灵节点。不过这样会导致额外的函数调用,可能对性能产生影响。我的原则是:首先应该保持代码良好的可读性,然后只在必要时才进行重构来提高性能。
8.2 关于敌人
对于程序设计,并没有一种所谓的最好的方法。我们所做的选择都完全处于主观喜好和个人经验。如果你愿意在对所制作的游戏有更深入的理解之后再重构代码,那么在移开时,一份可以工作的代码会比一份简洁、完美的代码更值得推崇。
8.3 Entity类的继承体系
8.3.1 EnemyEntity
只要不忘记调用[super init...]这个方法,我们就可以在数值赋给self之前运行一下代码,不然的话,super类无法初始化,将会出现奇怪的错误和导致崩溃。
在Objective-C中,你向nil对象发送任何消息都没有问题,因为它们都将被忽略掉。
8.3.2 EnemyCache类
8.3.3 组件类
组件类是用来扩展游戏逻辑的插件。如果给一个实体添加了一个组件,那么这个实体就会执行组件的逻辑行为:移动、开火、动画、显示生命条,等等。
8.4 射击开火
8.5 大怪物的生命条
大怪物不可能是一个很简单、可以被一下就消灭的敌人。所以我们需要一个生命条来给玩家反馈一些信息:即大怪物每被击中一次,它的生命条就会缩短。
8.6 本章小结

猜你喜欢

转载自bsr1983.iteye.com/blog/1672020