我给你们一个射击类游戏游戏,赢了我采纳。赢了...

【小燕文学】二五二 我赢给你们看【10月18号第二更】_寂灭天骄吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:2,281贴子:
【小燕文学】二五二 我赢给你们看【10月18号第二更】收藏
请下次直接百度搜索:小燕文学
无广告&&无弹窗&&【小燕文学】
1楼 22:58&|
相关的贴子1446950170相关的图贴
&&&&他的参赛新兵,脸色更是一片的黑暗。
&&&&大家都是新兵中玩枪的好手,刚刚林零做到的事情,自己能不能做到,都很清楚。
&&&&在那纸牌模型满天飞的战场上,做到被击中次数零,已经是奇迹。再保持命中率百分百都难如上青天,更不要提像林零一样,保持着要害命中率百分之百的惊人准确度,那几乎是非人类的表现了。
&&&&的脸色比一般新兵还要难看,白种人的他,如今脸色都有些菜绿了。
&&&&作为新兵枪手中顶尖的存在之一,刚刚的战场之上,不论是被击中次数为零,还是要害命中率百分之百,在他看来都不是最重要可怕的。
&&&&真正可怕的,是林零的预判!
&&&&每一名优秀的射击手,都要学习预判,判断敌人可能出现的位置,判断敌人出现的姿势跟角度,做到提前准备,抢先出手的重要要素。
&&&&一直对自己的预判非常自豪,就连教他枪的师傅,那位当今联邦射击手前五十名的顶尖枪手,就对他的预判称赞异常,甚至夸奖他有资格向联邦军界枪王发起挑战。
&&&&林零的预判,彻底摧毁了他的自豪。特别是那一枪打死人质,人质竟然变成悍匪的一刻,自信也随之遭到了巨大的冲击。
&&&&不少观众在怀疑那一枪是瞎蒙上的,却知道,那一枪是真材实料的一枪,开枪地稳健程度丝毫没有一点犹豫,充满了果断自信的一枪!
&&&&就是这种强大地预判。促成地抢先出手。才是真正可怕致命地地方。
&&&&不中弹。要害命中率百分百。自信也能做到。但时间。恐怕不止需要六百秒。
&&&&当两名选手都是不中弹。要害命中率百分百时。比地就是时间地快慢了。
&&&&对于枪手来说。一秒。不!零点零一秒!就是生死。天堂跟地狱地差别。
&&&&除了预判之外。林零那找通道地速度。也让人感到太过惊人。从头到尾。她就没有走过一次错误地死路。百分百全对地方向。更是节约了大把地时间。
&&&&一名射击手。在杂乱地环境下。找到准确地道路。这也是一项重要地考核。
&&&&电梯快速的上升着,很快到了最高层地位置。连续做了几个深呼吸,等待着的打开。
&&&&巨大地投影屏幕中,高楼大厦中的墙壁快速的变化着位置,楼梯也在同样变化着位置。
&&&&为了公平,每一名参赛者的路线都是程序随机制丨作,防止出现某些人背景太硬,导致作弊的情况出现。
&&&&虽然,这种可能性因为大洲军区的竞争,几乎为零。
&&&&但,组委会依然没有掉以轻心。
&&&&大门缓缓地打开,带着一种“风萧萧兮易水寒,壮士一去兮不复还”的背影,走进了那黑洞洞地高楼大厦。
&&&&枪响,命中要害!
&&&&进入战斗状态的,完全忘记了之前林零地表现,全心投入到了自己的战斗之中。
&&&&安迪盯着投影地眼睛绽放着一丝佩服,这才是一名王牌射击手应有的心理素质。不论面前有多么艰难的事情发生,用枪!轰碎一切!直到胜利!
&&&&看台上不少的观众都紧张了起来,联邦军界开出的赔率中,来自欧洲的新兵赔率最低,而且他们也有着光荣的数届冠军头衔,绝对的夺冠大热门。
2楼 22:59&|
&&&&很多人,都在博彩中,把钱押在欧洲新兵的身上。
&&&&没有令押宝在他身上的观众失望,来自林零那巨大的压力,统统转化成为了,超越一切的动力。
&&&&他的手速,比任何时间快,他的出枪比任何时间都果断,他的预判比任何时间都要迅速。
&&&&挡住道路的纸板模型,就像是豆腐在阻挡坦克一样,瞬间被轰的粉碎。
&&&&快快快!冲冲冲!
&&&&宛如狂龙风虎,埋头杀出了高楼大厦。
&&&&命中率百分之百,命中要害率百分之百,误伤零,被击中次数零,完成时间六百秒,完美度S级!
&&&&完全相同的成绩!观众席上哗然一片,坐在地上,双手撑着地面大口大口的喘着粗气,汗水像是下雨一样的从脸颊上滴向地面,穿在身上的军服,仿佛被丢入了湖水中,刚刚捞上来的一样。
&&&&看着屏幕上的成绩,先是一笑,随即无力的倒在地上,脸上尽是绝望的神情。
&&&&平局?不!输了!
&&&&很满意自己超越极限的成绩,同时也知道自己已经输了。
&&&&东亚的女兵林零,也是六百秒,但她神态自如,脸上没有任何的汗水,轻松自如的完成了这一切,仿佛还有余力的样子。
&&&&相比,集中了百分之二百的精神,将所有的精神都在那一战中消耗的干干净净。
&&&&当战斗结束时,他整个人都垮了,累垮了!
&&&&军中的比赛,没有并列第一这种说法。
&&&&第一,只有一个。
&&&&所以,如果两人最后是并列第一,就需要再加赛一场。
&&&&很清楚自己,现在让他拿枪打死靶子,二十五米的距离,都不见得可以百分百中了。
&&&&再来一场刚刚那种战斗?结局不是一般的惨,可能最后的分数会是中枪几千次,命中率百分之十五?误伤率???还有那可恶的时间。都可能创造新兵大赛开赛以来,最烂成绩。
&&&&平局,就是输!躺在选手的入口处,看着从他身旁走过的美洲新兵,安迪。
&&&&“加油!一定要赢啊。
&&&&有气无力的说着,话语中充满了诚恳。
&&&&苦练这么久,结果遇到这样一个变态级别地女人,很不甘心的他,希望能有人出来,击败这个女人,哪怕只是领先一秒也好。
&&&&“我……尽量……”
&&&&安迪回答的很没有底气,六百秒他推算过很多次,这几乎是真正的极限速度。能做到这个速度,除了实力之外,确实还包含着一定的好运气。
&&&&安迪不敢保证,自己也有一样的好运。
&&&&入平台,上高楼,命运的大门再次打开,安迪提着枪昂然步入其中。
&&&&一如一样,进入战场的安迪同样是一副拼命三郎的样子,看台上的部分观众更是齐声呐喊着。
&&&&这些年来,美洲从来都是综合实力最强地新兵部队。
&&&&手丨枪射击比赛,这几年也都是以极其微弱地劣势败北而已。
3楼 22:59&|
&&&&人们都在期待着安迪创造奇迹,虽然他们的脑海被隔音的墙壁完全挡住,但这一点都不能够减弱他们的兴奋。
&&&&这个时间,军事发烧友们,也有经过各种的测算,模糊地计算出了一个数值。六百秒,可以说是这次的极限时间,不可突破地时间锁。
&&&&最专业的军事发烧友,已经开始沉默了,他们通过即时的测算,已经在其他观众之前,得到了安迪这次大约的成绩。
&&&&不可能是六百秒,安迪的速度比斯塔克豪斯慢。
&&&&两人之间本就有些微的差距,斯塔克豪斯地超水平极限发挥,打出了极限的数据,安迪是无论如何也无法超越地。
&&&&六百六十五秒。
&&&&很不错的成绩,若是放在以前地新兵大赛中,估计有机会夺冠了。
&&&&然而,今天。
&&&&这个本应该惊艳的成绩,因为之前两名新兵地发挥,变得没有丝毫吸引力。甚至,不少观众都在对美洲的新兵发出了鄙视的起哄嘘声。
&&&&安迪额头也同样满是汗水,无力的坐在了斯塔克豪斯身旁,神态沮丧的叹息说道:“我……尽力了……”
&&&&“看出来了。”斯塔克豪斯靠着围墙苦笑:“六百秒,就算是鹏来,恐怕也只是这样的成绩。最终,很可能还会败给那个女人。”
&&&&安迪很是认同的点着头,眉宇间更多的也是苦笑:“东亚,真是个神奇的地方。要么,连冠军都拿不到。要么就出这么一个可怕的射击手,她的表现能让其他任何射击手精神崩溃。”
&&&&“没错。”斯塔克豪斯也连连点头:“她再训练一段时间,或许真的可以挑战枪王了。”
&&&&“枪王?”安迪眼中尽是崇拜:“这个女人,不会是枪王的徒弟吧?”
&&&&“不是。”斯塔克豪斯很果断的答道:“枪王也有自己的风格,那是无视一切的战斗方式。这个女人,果断,干脆,利落。却并非真正无视一切,那种气质是装不来的。”
&&&&“是吗?”安迪歪头看着斯塔克豪斯问道:“你说,这次的冠军会是那个女人吗?”
&&&&“当然了!”斯塔克豪斯白了安迪一眼:“你看她那轻松的样子,估计再来三次六百秒都不是问题。”
&&&&“另外那个东方人……”
&&&&“不可能。”斯塔克豪斯连连摇头:“他的手确实好,但远远不够成为超越那女人的条件。六百秒是极限,他能达到这个极限也没用。那个女人的状态明摆着告诉所有人,她可以跟任何挑战者打持久战。”
&&&&比赛不停的进行着,后面参赛的新兵,远不如最初的三人,不但再也没有要害命中率百分之百的出现,甚至出现了误伤,还有被打中的情况。
&&&&这种情况并不出乎众人的意料,毕竟最初的三人表现太出色了。观众们也开始明白,安迪的表现非常精彩,并非像他们想的那样差劲。
&&&&比赛终于走到了最后一人,秦奋缓缓的起身,离开了选首席。
&&&&“嘿,东方人,加油啊。”安迪半开玩笑的打气。
&&&&秦奋停住脚步,回头看着坐在地上的两人说道:“我来赢给你们看。”
&&&&如果觉得还爽,来点推荐票吧,过了凌晨又是新的一周了,需要点推荐票上分类周推榜。好歹也是宣传啊。还有月票,如果觉得爽,也给点吧,谢谢了(未完待续,如欲知后事如何,请登陆www**,章节更多,支持作者,支持正版阅读!)
&&&&发首发
4楼 22:59&|
登录百度帐号我的游戏推荐游戏
后查看最近玩过的游戏
内&&容:使用签名档&&
想了解更多关于 ”寂灭天骄“的信息,请&或免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作!
  原文链接地址:
程序截图:
  在这个教程里面,你将会学习到如何为iPhone开发一个太空射击游戏!
  你可以使用加速计(重力感应)来控制飞船的移动,并且可以点击屏幕来发射激光武器。
  如果你对于如何制作iphone游戏完全陌生的话,这个教程可以帮助你!你将会学习到,如何从头至尾构建一个完整的游戏,不需要任何的经验!
  假如你对cocos2d编程完全陌生的话,那么你可能需要先学习一下。
  这个教程对于中级开发者来说也非常好,因为它覆盖了一些比较高级的主题,比如视差滚动(parallax scrolling),预分配CCNode,加速计移动以及粒子系统的使用。
  话不多说,直入主题!
安装cocos2d
  为了制作这个游戏,你需要成为 &的一员(这样的话,你的程序就能够安装到你的iPhone上面去,不过听说网上有人越狱也可以安装,知道的朋友麻烦给个链接,谢谢!)同时,需要安装和框架。
  如果你之前已经安装过cocos2d了,那接下来这部分就不要看了。(如果想使用新的cocos2d版本,只需要把之前安装的目录下面的模板文件全部删除,再按照下面的指令重新安装即可)。如果你重来没有安装过cocos2d的话,那么只需要按照下面的指令序列,一步步地安装到你的mac上面就行了。
首先下载&.确定获得最新版本--作者写这篇文章的时候是1.0.0-rc2版本,目前是1.0.0-rc3版本。虽然不是稳定版本,但是,没关系,其实很稳定啦!:)双击下载下来的文件,并且解压缩到一个安全的位置。打开Terminal (Applications\Utilities\Terminal), 然后使用cd命令定位到刚刚解压缩的cocos2d文件夹下面去。然后运行./install-templates.sh来安装xcode模板,如下面所示:
$ cd Downloads
$ cd cocos2d-iphone-1.0.0-rc2
$ ./install-templates.sh&-f&-u
  如果一切顺利的话,你应该会看到终端里面一系列的输出语句:“ Installing xxx template”。
  然后重新启动Xcode,祝贺你,您已成功安装cocos2d了!
Hello, Cocos2D!
  让我们首先创建一个“Hello World”cocos2d工程。
  打开Xcode,选择 File\New\New Project,然后选 iOS\cocos2d template,接下来点Next,并且把工程命名为SpaceGame,再点Next并选择一个文件夹作为你的工程的保存路径,最后点Create。
  编译并运行工程,你将会看到一个“Hello World”出现在屏幕的正中间。
添加相关资源文件
  为了做这样一个iphone游戏,你将需要一些跟太空主题相关的图片资源和声音资源。
  你可以直接下载我老婆制作的。
  因此,请直接下载吧,并且把它解压到你的硬盘的某个目录下面去。
  一旦你解压完这些资源以后,把Backgrounds,Fonts,Particles,Sounds和Spritesheets文件夹拖到Resouces分组下面去。(基本上,除了Classes文件夹以外,其它所有的文件压都拖到Resource目录下面去)
  确保 “Copy items into destination group’s folder (if needed)”被复选中,然后点击Finish。
  当你做完这些事之后,你的工程的分组看起来会是下图所示的样子:
  如果你很好奇,你可以随便看看你刚刚向工程里面添加进去了一些什么东西。下面是完整的内容列表:
Backgrounds: 一些背景图片,你等下会使用它们来制作一个滚动背景。里面包含星系,太阳,和空间异常(它移动速度比较慢),还有一组空间尘埃图片(它们会出现在背景前面,而且会移动地稍微快一点)Fonts: 使用&制作的位图字体,我们将使用这些字体来在游戏中显示文字。Particles: 使用 &制作的一些特殊的粒子效果。 在这里,我们用来创建星星飞动的效果。Sounds: 一些与太空相关的背景音乐和音效。使用&&和&制作的。Spritesheets: 一张格式为pvr.ccz的大图片,里面包含了游戏中将要用到的许多小图片,比如陨石,太空船等。这个文件使用制作的---如果你想使用pvr.ccz文件格式的话,你可能就需要使用这个工具。当然pvr.ccz格式的优点就是文件小,加载速度快。
  如果你还没安装上面任何一款工具的话,也不用担心!对于这个教程来说,你完全不需要他们,你可以使用我已经制作好的这些资源就够了。以后,如果有条件,你可以再去试试上面提到的工具。
  下面就是Sprites.pvr.ccz文件,它看起来如下图所示:
  你可能会奇怪,为什么要把所有的这些图片都弄成这样一张大图呢?因为,首先,它可以帮助节省内存,同时还可以提高性能。
  接下来,让我们开始coding吧!:)
添加一个太空船
  首先,让我们在屏幕上添加一艘太空船吧!
  打开HelloWorldLayer.h文件,然后在@interface里面添加两个实例变量:
CCSpriteBatchNode&*_batchN
CCSprite&*_
  第一个变量 (_batchNode)是必须的,因为我们将把所有的图片存储在一张图片里面,然后使用这个BatchNode就可以仅使用一次opengl调用来做所有的绘图操作。
  第二个变量(_ship)代表屏幕上的太空飞船。
  接下来,打开HelloWorldLayer.m,并且把init方法改成下面的样子:
-(id) init
if( (self=[super init])) {
_batchNode&=&[CCSpriteBatchNode batchNodeWithFile:@&Sprites.pvr.ccz&];&//&1
[self addChild:_batchNode];&//&2
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@&Sprites.plist&];&//&3
_ship&=&[CCSprite spriteWithSpriteFrameName:@&SpaceFlier_sm_1.png&];&//&4
CGSize winSize&=&[CCDirector sharedDirector].winS&//&5
_ship.position&=&ccp(winSize.width&*0.1,
winSize.height&*0.5);&//&6
[_batchNode addChild:_ship z:1];&//&7
让我们一句一句地解释上面的代码:
使用一张大的图片创建一个CCSpriteBatchNode对象来批处理所有的对象的描绘操作。接收的参数是Sprites.pvr.ccz。把CCSpriteBatchNode添加到当前层里面去,这样就可以绘制它的所有的孩子对象。加载Sprites.plist文件,它里面包含了这张大图里面的所有的小图的位置坐标信息。这样,你以后可以非常方便地使用 spriteWithSpriteFrameName来提取一张张小图片来初使化一些精灵。使用 SpaceFlier_sm_1.png图片来创建一个精灵,注意这张图片是大图里的一个子图。使用CCDirector来获得屏幕的大小---我们接下来会用到这个大小。设置飞船的位置在屏幕宽度的10%,高度的50处。注意,飞船的中心点位置默认是飞船的中心。把ship当作batchNode的一个孩子添加进去,这样的话,这些精灵就会被批处理显示出来。
  编译并运行工程,你将会看到你的飞船图片出现在屏幕上面啦!
添加视差滚动
  我们已经有一个很酷的飞船在屏幕上了,但是,它看起来就好像坐在那里一样,毫无生气!我们可以通过往里面添加视差滚动背景来解决这个问题。
  但是,等一下,到底什么是视差滚动了?
  视差滚动,简单来说,就是“移动背景中的一些图片比其它图片慢一点点”,打个比方,一个背景中的物体有远有近,近的背景移动地快(比如地面),远的背景移动地慢(比如天空),这样子就会形成景深不一样的视差效果出来。
  想要在cocos2d里面使用视差滚动效果非常简单。你只需要做3步就ok了:
创建一个CCParallaxNode,然后把它加到层中去。创建你想要滚动的元素,然后通过调用CCParallaxNode的 addChild:parallaxRatio:positionOffset方法把这些元素添加进去。移动CCParallaxNode来滚动背景。这样的话,CCParallaxNode就会根据parallaxRatio的不同,或快或慢地移动它里面添加的元素了。
  让我们看看这个过程具体是怎样的。打开HelloWorldLayer.h,然后在@interface里面加入下面代码:
CCParallaxNode&*_backgroundN
CCSprite&*_spacedust1;
CCSprite&*_spacedust2;
CCSprite&*_
CCSprite&*_
CCSprite&*_
CCSprite&*_spacialanomaly2;
  然后,转到HelloWorldLayer.m文件,在init方法的底部加入下面的代码:
//&1) Create the CCParallaxNode
_backgroundNode&=&[CCParallaxNode node];
[self addChild:_backgroundNode z:-1];
//&2) Create the sprites we'll add to the CCParallaxNode
_spacedust1&=&[CCSprite spriteWithFile:@&bg_front_spacedust.png&];
_spacedust2&=&[CCSprite spriteWithFile:@&bg_front_spacedust.png&];
_planetsunrise&=&[CCSprite spriteWithFile:@&bg_planetsunrise.png&];
_galaxy&=&[CCSprite spriteWithFile:@&bg_galaxy.png&];
_spacialanomaly&=&[CCSprite spriteWithFile:@&bg_spacialanomaly.png&];
_spacialanomaly2&=&[CCSprite spriteWithFile:@&bg_spacialanomaly2.png&];
//&3) Determine relative movement speeds for space dust and background
CGPoint dustSpeed&=&ccp(0.1,&0.1);
CGPoint bgSpeed&=&ccp(0.05,&0.05);
//&4) Add children to CCParallaxNode
[_backgroundNode addChild:_spacedust1 z:0&parallaxRatio:dustSpeed positionOffset:ccp(0,winSize.height/2)];
[_backgroundNode addChild:_spacedust2 z:0&parallaxRatio:dustSpeed positionOffset:ccp(_spacedust1.contentSize.width,winSize.height/2)];&
[_backgroundNode addChild:_galaxy z:-1&parallaxRatio:bgSpeed positionOffset:ccp(0,winSize.height&*0.7)];
[_backgroundNode addChild:_planetsunrise z:-1&parallaxRatio:bgSpeed positionOffset:ccp(600,winSize.height&*0)];&
[_backgroundNode addChild:_spacialanomaly z:-1&parallaxRatio:bgSpeed positionOffset:ccp(900,winSize.height&*0.3)];&
[_backgroundNode addChild:_spacialanomaly2 z:-1&parallaxRatio:bgSpeed positionOffset:ccp(1500,winSize.height&*0.9)];
  编译并运行工程,你将会看到飞船背景了。
  然而,这还不是很有趣,因为还没有任何东西在动!
  为了移动太空尘埃和相关背景层,你只需要移动一样东西就可以了,那就是parallaxNode。对于移动parallax node的每一个y值,灰尘就会移动0.1y值,同时背景会移动0.05y值。
  为了移动parallax节点,你只需要飞一帧更新一下它的位置就可以了。打开HelloWorldLayer.m文件,加入下列的代码:(添加位置注意看注释)
//&Add to end of init method
[self scheduleUpdate];
//&Add new update method
-&(void)update:(ccTime)dt {
CGPoint backgroundScrollVel&=&ccp(-1000,&0);
_backgroundNode.position&=&ccpAdd(_backgroundNode.position, ccpMult(backgroundScrollVel, dt));
  编译并运行工程,你会看到,使用parallax来做视差滚动效果真是太简洁了!
  然后,运行几秒钟之后,你会发现一个问题:背景滚动完之后没有了!我们只得到了一个黑色的屏幕!那真是太糟糕了!好,接下来,看看我是怎么解决的吧!
连续地滚动
  我们想要背景保持无限地连续滚动效果。我们的做法就是,当背景移出屏幕的左边的时候,就马上把它移动到屏幕右边的适当的位置上去。
  这里有一个小小的问题,目前CCParallaxNode并不支持直接修改它的每个孩子的offset。你不能够简单地更新它的孩子的坐标点,因为CCParallaxNode每次更新的时候会覆盖那些改变。
  不过没关系,我已经制作了一个CCParallaxNode的分类,它可以用来解决这个问题,这个Category可以在下面的Classes文件夹中找到。把 CCParallaxNode-Extras.h 和 CCParallaxNode-Extras.m拖到工程中去,同时确保
“Copy items into destination group’s folder”被复选中,然后点击Finish。
  然后,在HelloWorldLayer.m中做下列改变来实现连续滚动的效果:  
//&Add to top of file
#import&CCParallaxNode-Extras.h&
//&Add at end of your update method
NSArray&*spaceDusts&=&[NSArray arrayWithObjects:_spacedust1, _spacedust2,
for&(CCSprite&*spaceDust&in&spaceDusts)
if&([_backgroundNode convertToWorldSpace:spaceDust.position].x&&-spaceDust.contentSize.width)
[_backgroundNode incrementOffset:ccp(2*spaceDust.contentSize.width,0)
forChild:spaceDust];
NSArray&*backgrounds&=&[NSArray arrayWithObjects:_planetsunrise, _galaxy, _spacialanomaly, _spacialanomaly2,
for&(CCSprite&*background&in&backgrounds)
if&([_backgroundNode convertToWorldSpace:background.position].x&&-background.contentSize.width)
[_backgroundNode incrementOffset:ccp(2000,0) forChild:background];
  编译并运行工程,这时你可以看到有一个无限连续滚动的背景了!
  没有哪一个太空射击游戏是没有星星在旁边飞的!
  同样的,我们也可以创建相应的星星图片,并且把它当作paralla节点的一个孩子添加进去。但是,这里我们不想这么做,因为星星是一个非常好的介绍粒子系统的例子。
  粒子系统能够让你使用同样的精灵创建大量的小对象,并且非常高效。cocos2d给了你很多配置粒子系统的参数,&这个工具可以使这些参数的配置可视化。
  但是,这个教程里面,我们不会涉及如何调整粒子系统的各项参数,我们使用已经做好的星星的粒子效果。只需要在init方法中把它简单地添加进来即可:
NSArray&*starsArray&=&[NSArray arrayWithObjects:@&Stars1.plist&,&@&Stars2.plist&,&@&Stars3.plist&,
for(NSString&*stars&in&starsArray)
CCParticleSystemQuad&*starsEffect&=&[CCParticleSystemQuad particleWithFile:stars];&
[self addChild:starsEffect z:1];
  通过把粒子系统加到层中去,接着它会自动运行起来。编译并运行代码,你现在可以看到好多星星在屏幕上飞过了!:)
使用加速计来移动飞船
  到目前为止,还是很好,但是,如果我们不能控制飞船的移动的话,那就不是一个完整的游戏!
  这里,我们将采用加速计来移动太空飞船。当用户沿着x轴方向倾斜设备的时候,飞船就会上下移动。
  这个功能实际上非常容易实现。首先,在HelloWorldLayer.h里面的@interface里面添加一个成员变量,用来记录飞船沿着y轴方向每秒移动的点的个数。(这个点不一定等于一个实际的像素点,如果是Retina的设备,一个点=2个像素)
float&_shipPointsPerSecY;
  然后,在HelloWorldLayer.m中做如下修改:
//&1) Add to bottom of init
self.isAccelerometerEnabled&=&YES;
//&2) Add new method
-&(void)accelerometer:(UIAccelerometer&*)accelerometer
didAccelerate:(UIAcceleration&*)acceleration {
#define&kFilteringFactor 0.1
#define&kRestAccelX -0.6
#define&kShipMaxPointsPerSec (winSize.height*0.5)&
#define&kMaxDiffX 0.2
UIAccelerationValue rollingX, rollingY, rollingZ;
rollingX&=&(acceleration.x&*&kFilteringFactor)&+&(rollingX&*&(1.0-&kFilteringFactor));&
rollingY&=&(acceleration.y&*&kFilteringFactor)&+&(rollingY&*&(1.0-&kFilteringFactor));&
rollingZ&=&(acceleration.z&*&kFilteringFactor)&+&(rollingZ&*&(1.0-&kFilteringFactor));
float&accelX&=&acceleration.x&-&rollingX;
float&accelY&=&acceleration.y&-&rollingY;
float&accelZ&=&acceleration.z&-&rollingZ;
CGSize winSize&=&[CCDirector sharedDirector].winS
float&accelDiff&=&accelX&-&kRestAccelX;
float&accelFraction&=&accelDiff&/&kMaxDiffX;
float&pointsPerSec&=&kShipMaxPointsPerSec&*&accelF
_shipPointsPerSecY&=&pointsPerS
//&4) Add to bottom of update
CGSize winSize&=&[CCDirector sharedDirector].winS
float&maxY&=&winSize.height&-&_ship.contentSize.height/2;
float&minY&=&_ship.contentSize.height/2;
float&newY&=&_ship.position.y&+&(_shipPointsPerSecY&*&dt);
newY&=&MIN(MAX(newY, minY), maxY);
_ship.position&=&ccp(_ship.position.x, newY);
让我们一点点剖析一下这段代码:
添加这行代码的作用是让当前的层可以接收到加速计移动事件,当有事件发生的时候,会回调 accelerometer:didAcccelerate这个方法。这个方法的前面一部分是直接从Apple的样例代码中copy过来的,所做的事情其实是某种意义上的“滤波”。其实你也不用理解它的原理,基本上就是为了让飞船的移动更加平滑。如果你实在是对此非常感兴趣,可以查看来获得一些信息。不管怎么说,在运行完这个滤波之后,我们可以测试下看看,到底有哪些改进。通过实现证明,这种方法确实感觉不错!基于每秒沿y轴方向移动的点数,来更新飞船的位置。同时要注意边界值的判断。
  编译并运行工程(一定要编译到真机上面,否则模拟器是没有加速计效果的,你不可能抱着电脑摇吧:))。这时,上下晃动真机,你可以操作你的飞船移动了!
  这个游戏目前看起来还不错,但是,危险和激情在哪里呢?让我们往场景中添加一些陨石吧!
  我们接下来将要采纳的方法其实是非常普遍的做法,我们在右边屏幕之后创建一些陨石,然后利用cocos2d的action把它移动到屏幕的左边去。
  我们可以在每次需要一个陨石的时候,马上创建一个对象,但是,分配内存的操作是非常慢的!所以你最好不要这样做!因此,我们可以预先分配好一堆陨石对象,这样当需要一个陨石对象的时候,就从中抓取一个就ok了。
  好,我们看看具体该怎么做吧。打开HelloWorldLayer.h,然后往类中添加下列成员变量:
CCArray&*_
int&_nextA
double&_nextAsteroidS
  接下来在HelloWorldLayer.m里面做如下修改:
//&Add to top of file
#define&kNumAsteroids 15
//&Add to bottom of init
_asteroids&=&[[CCArray alloc] initWithCapacity:kNumAsteroids];
for(int&i&=0;
i&&&kNumA&++i) {
CCSprite&*asteroid&=&[CCSprite spriteWithSpriteFrameName:@&asteroid.png&];
asteroid.visible&=&NO;
[_batchNode addChild:asteroid];
[_asteroids addObject:asteroid];
//&Add new method, above update loop
-&(float)randomValueBetween:(float)low
andValue:(float)high {
return&(((float) arc4random()&/0xFFFFFFFFu)&*&(high&-&low))&+&
//&Add to bottom of update loop
double&curTime&=&CACurrentMediaTime();
if&(curTime&&&_nextAsteroidSpawn) {
float&randSecs&=&[self randomValueBetween:0.20&andValue:1.0];
_nextAsteroidSpawn&=&randSecs&+&curT
float&randY&=&[self randomValueBetween:0.0&andValue:winSize.height];
float&randDuration&=&[self randomValueBetween:2.0&andValue:10.0];
CCSprite&*asteroid&=&[_asteroids objectAtIndex:_nextAsteroid];
_nextAsteroid++;
if&(_nextAsteroid&&=&_asteroids.count) _nextAsteroid&=0;
[asteroid stopAllActions];
asteroid.position&=&ccp(winSize.width+asteroid.contentSize.width/2,
asteroid.visible&=&YES;
[asteroid runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:randDuration position:ccp(-winSize.width-asteroid.contentSize.width,&0)],
[CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)],
//&Add new method
-&(void)setInvisible:(CCNode&*)node
node.visible&=&NO;
关于上面的代码,有几点需要说明一下:
CCArray 和NSArray差不多,但是做了速度方面的优化。所以如果可以的话,尽可能多地使用CCArray。注意,我们添加了15个陨石到batchNode中去了。但是,把它们都设置成了不可见。如果是不可见的,就把它当前是未激活的。我们使用一个实例变量 &(_nextAsteroidSpawn) 来指示下一个陨石出现的时间点。我们会在update循环中一直检测这个变量的值。如果你对cocos2d的action还很陌生的话,其实action就是一种很简单的,可以让精灵在一段时间做一些事情的对象。比如,你可以让精灵在指定的一段时间内,让它旋转、缩放、移动等等。这里,我们执行了2个action的序列:一个从右边移动到左边的action,还有一个是当前一个action结束时,调用另一个函数把陨石设置为不可见的action。这两个action的顺序是固定的。
  编译并运行代码,这时候你可以看见一些陨石在屏幕上飞过啦!
  我不清楚你是怎么想的,当我看到屏幕上有陨石在飞的时候,我的第一感觉就是,把它们干掉!
  因此,让我们给飞船添加发射激光武器的功能吧!这段代码和我们之前添加陨石的代码有点类似,因为我们会创建一组可以重用的激光束,同时使用action来移动这些激光束。
  主要的区别就是,我们将使用touch事件来发射激光。
  首先打开HelloWorldLayer.h,然后在类中添加下面成员变量:
CCArray&*_shipL
int&_nextShipL
  然后在HelloWorldLayer.m做如下修改:
//&Add to top of file
#define&kNumLasers 5
//&Add to bottom of init
_shipLasers&=&[[CCArray alloc] initWithCapacity:kNumLasers];
for(int&i&=0;
i&&&kNumL&++i) {
CCSprite&*shipLaser&=&[CCSprite spriteWithSpriteFrameName:@&laserbeam_blue.png&];
shipLaser.visible&=&NO;
[_batchNode addChild:shipLaser];
[_shipLasers addObject:shipLaser];
self.isTouchEnabled&=&YES;
//&Add new method
-&(void)ccTouchesBegan:(NSSet&*)touches
withEvent:(UIEvent&*)event&{
CGSize winSize&=&[CCDirector sharedDirector].winS
CCSprite&*shipLaser&=&[_shipLasers objectAtIndex:_nextShipLaser];
_nextShipLaser++;
if&(_nextShipLaser&&=&_shipLasers.count) _nextShipLaser&=0;
shipLaser.position&=&ccpAdd(_ship.position, ccp(shipLaser.contentSize.width/2,&0));
shipLaser.visible&=&YES;
[shipLaser stopAllActions];
[shipLaser runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:0.5&position:ccp(winSize.width,&0)],
[CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)],
  这个例子也向你展示了,在cocos2d里面接收touch事件是多么容易啊---仅需要把isTouchEnabled设置为yes就ok了。然后你需要实现ccTouchesBeban(或者ccTouchesMoved,ccTouchesEnded等等)。
  编译并运行代码,现在你可以发射激光武器了。
基本的碰撞检测
  恩,到目前为止,这看起来有点像一个游戏了,但是,还不够完整,因为没有爆炸!
  而且我天性不听话,喜欢搞破坏,所以是时候往游戏里面添加一些破坏啦!:)
  打开HelloWorldLayer.h,然后添加下面的实例变量:
  然后update方法的最后面添加下面代码:
for&(CCSprite&*asteroid&in&_asteroids)
if&(!asteroid.visible)&continue;
for&(CCSprite&*shipLaser&in&_shipLasers)
if&(!shipLaser.visible)&continue;
if&(CGRectIntersectsRect(shipLaser.boundingBox, asteroid.boundingBox)) {&
shipLaser.visible&=&NO;
asteroid.visible&=&NO;&
if&(CGRectIntersectsRect(_ship.boundingBox, asteroid.boundingBox)) {
asteroid.visible&=&NO;
[_ship runAction:[CCBlink actionWithDuration:1.0&blinks:9]];&
  这里使用了最最简单的方式,只是判断两个精灵的边界矩形是否有交集。注意,边界部分可能有透明,而且边界矩形不能反应精灵实例的轮廓,所以最好的做法是使用前面介绍的box2d的方法。不过没关系,这个游戏,我们这样做就可以了。
  对于更好的使用box2d的方法,请查看。
  编译并运行代码,现在你会看到有东西爆炸啦!
胜利/失败条件检测
  我们差不多快做完了---现在只需要往游戏中添加判断游戏胜利或者失败的条件就可以了。
  我是这样考虑的,只要玩家存活了30秒,就是胜利;如果被陨石打中了3次,那么就是失败。
  因此,在HelloWorldLayer.h中做如下修改:
//&Add before @interface
typedef&enum&{
kEndReasonWin,
kEndReasonLose
//&Add inside @interface
double&_gameOverT
bool&_gameO
  同时,相应地修改HelloWorldLayer.m:
//&Add at end of init
_lives&=3;
double&curTime&=&CACurrentMediaTime();
_gameOverTime&=&curTime&+30.0;
//&Add at end of update loop
if&(_lives&&=0) {
[_ship stopAllActions];
_ship.visible&=&FALSE;
[self endScene:kEndReasonLose];
}&elseif&(curTime&&=&_gameOverTime)
[self endScene:kEndReasonWin];
//&Add new methods above update
-&(void)restartTapped:(id)sender
[[CCDirector sharedDirector] replaceScene:[CCTransitionZoomFlipX transitionWithDuration:0.5&scene:[HelloWorldLayer scene]]];&
-&(void)endScene:(EndReason)endReason {
if&(_gameOver)&return;
_gameOver&=true;
CGSize winSize&=&[CCDirector sharedDirector].winS
NSString&*
if&(endReason&==&kEndReasonWin) {
message&=@&You win!&;
}&elseif&(endReason&==&kEndReasonLose)
message&=@&You lose!&;
CCLabelBMFont&*
if&(UI_USER_INTERFACE_IDIOM()&==&UIUserInterfaceIdiomPad) {
label&=&[CCLabelBMFont labelWithString:message fntFile:@&Arial-hd.fnt&];
label&=&[CCLabelBMFont labelWithString:message fntFile:@&Arial.fnt&];
label.scale&=0.1;
label.position&=&ccp(winSize.width/2, winSize.height&*0.6);
[self addChild:label];
CCLabelBMFont&*restartL
if&(UI_USER_INTERFACE_IDIOM()&==&UIUserInterfaceIdiomPad) {
restartLabel&=&[CCLabelBMFont labelWithString:@&Restart&&fntFile:@&Arial-hd.fnt&];&
restartLabel&=&[CCLabelBMFont labelWithString:@&Restart&&fntFile:@&Arial.fnt&];&
CCMenuItemLabel&*restartItem&=&[CCMenuItemLabel itemWithLabel:restartLabel target:self selector:@selector(restartTapped:)];
restartItem.scale&=0.1;
restartItem.position&=&ccp(winSize.width/2, winSize.height&*0.4);
CCMenu&*menu&=&[CCMenu menuWithItems:restartItem, nil];
menu.position&=&CGPointZ
[self addChild:menu];
[restartItem runAction:[CCScaleTo actionWithDuration:0.5&scale:1.0]];
[label runAction:[CCScaleTo actionWithDuration:0.5&scale:1.0]];
  如果你不理解endScene方法的话,也没关系---那些代码是我过去用来快速地判断游戏胜利或失败的方式。
  真正重要的是,你要理解其它部分的代码---在每一个update循环中,你只检测玩家是否胜利或失败,然后相应地调那个方法就可以了。
  编译并运行代码,看看你会不会输?
免费的音乐和音效
  你懂的,我怎么可能不给你们提供一些很棒的音效和音效呢?
  之前,你已经把相关的音乐和音效加到工程里面来了,因此,我们只需要在HelloWorldLayer.m中做如下修改即可:
//&Add to top of file
#import&SimpleAudioEngine.h&
//&Add to bottom of init
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@&SpaceGame.caf&&loop:YES];
[[SimpleAudioEngine sharedEngine] preloadEffect:@&explosion_large.caf&];
[[SimpleAudioEngine sharedEngine] preloadEffect:@&laser_ship.caf&];
//&Add inside BOTH CGRectIntersectsRect tests
[[SimpleAudioEngine sharedEngine] playEffect:@&explosion_large.caf&];
//&Add inside ccTouchBegan
[[SimpleAudioEngine sharedEngine] playEffect:@&laser_ship.caf&];
  好了!编译并运行,这就是一个我们从头至尾一步步开发出来的完整的游戏啦!:)
  这里有本项目的。
  到目前为止,除了网络编程的教程没有翻译外,其它的cocos2d和box2d相关的教程全部翻译完了。:)以后,随着原作者的博客更新,我也会相应地更新。当然时间上肯定会落后不少,所以我希望大家没事的时候,还是多看看e文版。google,金山词霸等工具都用上,看着看着,就能看懂了。
  最后还是那句话,本人水平有限,翻译不准确的地方,请见谅!
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:148677次
积分:1968
积分:1968
排名:第8110名
原创:22篇
转载:87篇
评论:137条
(1)(1)(1)(1)(2)(1)(8)(74)(1)(5)(5)(1)(3)(1)(1)(3)

我要回帖

更多关于 射击类游戏 的文章

 

随机推荐