哪个梦塔防神箭碎片游戏开始是箭塔后面就是人主人公可以打完一波移动一步

- 最好的系统光盘下载网站!
当前位置:
推荐理由:
《死或生塔防 Dead Or Live》是一款生存类防守游戏,死或生塔防游戏中你需要扮演一个保护圣灵石的英雄,在五大地域的五十个关卡内守住怪物对圣灵石的进攻,可以获得佣金来提升英雄的等级和技能并通过完成副本小任务来更新英雄的装备,还有十六种各不相同的技
推荐理由:
《塔防三国志》是上游网络自主研发的一款三国题材3D策略塔防手机网游。本作由《塔防三国志》原班人马倾力打造,承袭累计1.4亿注册用户的塔防三国志自有IP。
推荐理由:
魔兽争霸塔防是一款高品质的塔防游戏。 游戏讲述了混沌初开之后,人类建立了文明城市,贪婪的兽人试图打破世界和平,占领人类的家园。它们开始攻击人类,人族被步步逼退到古城。在那里,人类魔法师发现了古老的魔法书,发现了元素的神秘力量。
推荐理由:
天天爱塔防是一款非常贴切生活的塔防游戏,天天爱塔防简直就是厨房大战和生活大爆炸啊,米饭、刀叉、盘子、搓衣板、烟酒、美女等各种利器和障碍物,让你边玩游戏边大开眼界还能开怀大笑,原来最终的boss竟然是。。。没想到吧! 天天爱塔防的玩法很简单,找准
推荐理由:
三国塔防是一款以三国故事为背景的塔防类游戏,最具特色的是游戏中敌兵的行进路线是由玩家自己进行规划的,玩家可以在游戏中培养自己喜欢的武将,通过完成关卡发展新的关卡和故事情节,挑战更高级别的关卡。
推荐理由:
《猴子塔防 对战版 Bloons TD Battles》是一款既经典又有趣的策略塔防游戏。游戏一如既往的保持了前作可爱卡通的风格,同时游戏加入了全新的塔防系统和武器系统,游戏还支持在线PK,和自己的好友较量一下吧 ,看看谁的城防更坚固。 游戏有进攻和防守两大模式
推荐理由:
三国武将塔防是一款以三国为主题的塔防游戏,除了有精美的画面、丰富的关卡设置、多兵种的敌人,还独具匠心的在其中加入的武将系统,同时还兼备了RPG游戏的剧情、升级等元素在内,并且蜀魏吴三国可以任意选择,每个国家都有自己特有的武将,每个武将都有自己
推荐理由:
致敬经典动漫,创新塔防玩法!2014年度创新动漫塔防游戏《塔防海贼王》已经扬帆起航!全球首款动漫题材塔防类手游;地图/关卡/任务全部完美还原动漫剧情,同时集伙伴召集、探险掠夺、海贼大战、伟大航路、出海护航等创新玩法于一体。快来召集小伙伴,跟路飞
推荐理由:
主角被困在冰之岛,给怪物围攻了,主角最后的命运如何?撑握在你的手中。 1、操作建冰:阻止怪物前进,射击:攻击怪物; 2、冰之封印:大绝招,消灭怪物,吸收怪物生命,但对BOSS无效;
推荐理由:
EVO塔防 towers defense EVO,和其他所有塔防游戏一样,他有三个难度三个不同的关卡,而玩家们则需要不断挑战难度才能获得更高的分数,画面细腻,值得大家一玩,已经完整汉化。 1、通过反编译,所有的英文都已经汉化为中文。(有些专业术语可能翻译不当,请
推荐理由:
坦克-现代防卫(Tank ON - Modern Defender)这款游戏来自Ino-Co Plus。上线短短时间国内外下载量即冲破百万!!迄今为止最火爆最好玩的坦克射击塔防游戏! 这是一款充满RPG元素的塔防游戏。玩家必须守卫基地,阻止来自敌军吉普车,坦克和直升机的进攻。游戏
推荐理由:
《银河塔防 Galaxy Defense》是一款策略塔防游戏。游戏虽然不大,但是画面精美。神秘的机器人军队入侵我们的星球。作为一名指挥官,你需要保持最后一道防线。现在,所有的力量都在等待您的调遣!安置防御塔,形成完美的防守,让我们消灭它们!
推荐理由:
Lich Defense(巫妖塔防)是一款来自韩国的带有RPG风格的塔防游戏新型大作。游戏的画面相当的华丽,但是带有韩文的界面可能会引起某些人的反感,很是无奈
推荐理由:
星战塔防(Galaxy Wars Tower Defense)一款以星战为背景的塔防游戏,画面超精致,绚丽的炮弹飞行轨迹。 支持5张超大型地图(20x1080),另外支持游戏支持多点触控伸缩,总体不错! 六种塔炮,可进行三次升级。 三种模式:经典、加强版、无尽模
推荐理由:
非常棒的集塔防射击策略于一身的一个休闲益智游戏,游戏免费提供,完美支持主流手机和平板。 正如你所看到的游戏游戏是与生化为背景的,游戏关卡丰富,难度越来越难,每一关卡又分为多个回合制,回合结束后游戏暂停,里面的融入塔防思想也添加了很多抢滩的元
推荐理由:
《皇家塔防 Royal Defense Saga》是一款塔防游戏,矮人王国和巨魔部落一直发生这战争,那些巨魔想占领矮人的土地,并驱逐他们,为了击败这些成群结队的巨魔,你必须建造强大的防御塔和学习使用强大的魔法。 游戏不大,每一关卡的地图不同,巨魔来袭的通道不
推荐理由:
太空塔防TD是一款像素风格塔防类游戏。虽然是像素风格,但是看上去不会有丝毫不舒服的感觉,同样的音效也很好。游戏玩法上面也稍微有一些创新,游戏有两种模式,闯关模式和生存模式,生存模式必须在完成所有闯关模式才给开放。
推荐理由:
天天塔防游戏实现了ARPG与塔防的完美结合。剑圣,奥法,熊猫人,多达三个独特英雄。VIP礼包领不停,紫色符文天天送。全AI自动战斗,简单操作,只需控制英雄,以PVP般的游戏平衡性,践踏敌方首领。战场英雄?策略大师?一玩见分晓! 1、简化购买装备的繁琐操
推荐理由:
《萌塔防》是一款由杭州电魂自主研发运营的集竞技、养成、策略一体的休闲类塔防端游。游戏画面主打Q版卡通风格,以竞技、多人组队塔防为主要战斗形式,结合时下流行的各种玩法元素,开创全新竞技塔防网游模式!
推荐理由:
《塔防群侠传》是一款Q版仙侠策略类塔防手游,塔防群侠传游戏采用卡牌的视觉盛宴,是收集癖患者必备之选,囊括众多名家大作,百余张风格各异的精制英雄卡牌;防守时变身战斗塔,自由搭配布阵、策略挑战体验,快和你的小伙伴们一起通关集卡吧!
推荐理由:
魔Q塔防是一款以人族和魔族之间的战争为背景的全新史诗级塔防大作。玩家需要在游戏中帮助人类获得战争的胜利,合理布阵人族士兵防御魔族大军。 多达15张的游戏地图、特殊的BOSS战、全新的升级系统、钱币和宝箱掉落系统,带给你不一样的塔防体验!
推荐理由:
《神灵塔防 Gods and Towers》这款游戏继承了传统塔防游戏的风格,稍加改进的地方在于你能够破坏敌人的防御能力。高清3D画面的风格使其显得与众不同。 游戏特色: 1、可以与其它人联机对战; 2、4种不同的游戏模式; 3、3中地图,42种攻击能力生物; 4、36座
推荐理由:
《塔防江湖》是一款Q版武侠题材的横版塔防类手机网游。《塔防江湖》炫丽的武功招式、紧张刺激的战斗,布阵御敌,横版PK,带你领略塔防武侠的刀光剑影,演绎不一样的塔防游戏。
推荐理由:
《水瓶座塔防 Aquarius TD》是一款传统的塔防战争游戏,游戏中的需要你保卫水瓶座上面五颗行星并击退怪物,它有三个故事模式的难度。你有定义的波过程中抵御怪物,游戏中断再进去也还可以继续比赛,每捍卫一个阶段都可以拿到一定的星级,想知道你能拿到多少
推荐理由:
《橄榄球塔防 Score Defence》是一款集策略,体育为一体的塔防游戏。橄榄球员组成的火力走廊等待敌人的进攻。敌人很聪明,他们可以智能的调整行进的路线,这样防守方也要调整防守的位置。游戏的角色都设置都非常奇葩,都是各种各样的运动员,快来下载试试吧
推荐理由:
《彩虹塔防》是一款策略塔防游戏。彩虹塔防的故事是一百年前,与恶魔之王之间的战争,使得精灵王国变为废墟。彩虹之王在击退恶魔之王之后,离奇消失。而剩下的三位英雄则为重建精灵王国而奋不顾身。而有一天,不料恶魔们再一次袭击精灵王国!原来是恶魔之王
推荐理由:
《妖姬塔防》全新竞技塔防手游,重新定义塔防游戏! 上手简单、由浅到深,可玩性极高的塔防对战手游! 场景精美雅致,特效炫丽多彩,梦幻般的视觉享受! 仙女与妖姬,天神与魔王,再现神魔之间的史诗之战! 触屏释放技能,妖姬技能组合,英雄职业搭配,带来
推荐理由:
《钢铁塔防 Iron Defense Pro》是一款策略塔防游戏。游戏采用最经典的塔防玩法,玩家需要根据地形,在合适的地方建造合适的防御塔,以此来抵御敌人的入侵。游戏一共有12副不同的地图,还有一个特殊的挑战关卡。
推荐理由:
《三国志塔防2 Three Kingdoms Defense2》乱世的英雄豪杰汇聚一堂! 终极防守策略游戏! 《三国志塔防2》这是一个相聚在桃园的三国英雄人物共同努力,一统天下的故事! 《三国志塔防2》是以统一三国作为故事背景,在游戏中会出现各种三国时期的著名武将和历史事件
推荐理由:
塔防36计通过充满中国元素的Q版卡通画面,向玩家生动有趣的展现战国时期的历史风貌。 战斗中地图塔位设计更加合理,路径设计更具变化性,您必须充分合理的使用每一个位置,您将真正感受到塔防玩法的精髓。从步兵 枪兵 盾兵 战车 神隐到各种骑兵 御剑仙人 风
推荐理由:
《TD塔防 TD++ Battle for Hugeon》是一款策略游戏。TD塔防为您提供的是纯粹的塔防战役模式。游戏中你建立起实验室,研究各种不同的武器、还可以升级塔,提供更强大的攻击模式。
推荐理由:
《混沌塔防》是一款战争策略类COC游戏,混沌塔防游戏里你需要建立村庄,与成千上万的网友训练你的军队和战斗,你也可以对各种武器进行升级,游戏还增加了众多社交互动,让你游戏中体验到不一样的战争乐趣。
推荐理由:
《塔防萌主》是一款萌系塔防策略手游。游戏在剧情设置以及画面的表现上,都极力贴合轻松愉快的萌系基调。3D的画质搭配激萌的画风,力求为广大萌系手游爱好者,提供全新的萌系塔防。
推荐理由:
虫虫塔防是款可爱的塔防游戏。一波强大的敌人入侵虫虫家园,它们凶猛狡猾,诡计多端,更有强大的BOSS来势汹汹! 那就开战吧!8种兼具美貌与强大战斗力的塔虫,用它们特殊的能力帮你坚守阵地,千变万化的塔虫技能组合挑战你的策略极限! 华丽丽的主动技能不仅
推荐理由:
超级几何塔防Defensoid包含了所有的经典元素,画面简单清新,但不失华丽的战斗。每个防御塔都有三次升级的机会。攻击范围和视觉效果越来越华丽。
推荐理由:
你必须保卫你的基地,抵挡住敌人的吉普车,坦克和直升机的袭击,在游戏中你控制在你的炮塔在基地前移动并射击。 1、使用 轨道离子炮一次摧毁多个目标 2、保护整个基地 3、核炸弹爆炸,涵盖整个战
推荐理由:
《异形塔防 Aliens Defense》是一款未来感十足的策略塔防游戏。开发外星土地的军队为了阻止外星异形妨碍开发而建设炮塔防御,如果异形摧毁了军队基地则游戏结束。与一般塔防游戏有所不同的是,本游戏中建设炮塔的资源并不来自射杀异形,而产生于建设炮塔列表
推荐理由:
《僵尸塔防 Zombies TD》是一款画风可爱的射击塔防游戏。游戏中讲述了一男一女在沙漠中的生存故事,游戏有两个模式,故事模式和生存模式,故事模式中有20个关卡供你选择。游戏第一关是教学关卡,无论谁来玩这个游戏都可以从头学习游戏操作方式。游戏操作主要
推荐理由:
Z度塔防 - 极限塔防体验! 在这儿,敌人来自四面八方,而你没有任何屏障!挑战你的智力极限! 在这儿,敌人一拥而上,250秒50波!挑战你的速度极限! 在这儿,敌人无穷无尽而且越来越强大,而你需要坚守阵地,支撑100波!挑战你的耐力极限! 在这儿,你会失
推荐理由:
指挥官! 敌人开过来了。他们要摧毁我们的家园。盗走我们的能源。 比你军衔高的都死光了。现在你就是最高指挥官了。 下面都乱成一团,请你发布任务!
推荐理由:
这是一款画面华丽并且游戏非常流畅的极品战略型塔防游戏,你的任务就是要阻止魔物不断地侵蚀神圣的水晶之前,用自己的智慧在地图上放置炮塔,最后消灭它们!而且游戏非常讲究战略部署,如果不能合理的设防,游戏就会很快结束!游戏整体风格都极具魔幻色彩,
推荐理由:
一款非常好玩的魔幻题材防守类游戏,你需要通过各种不同的武器组合来守卫自己的城堡,抵御各种怪物对城堡的攻击。 游戏的另外一大特色就是丰富的元素和绚丽的动画效果,你能够使用多达11种武器的同时,还能够释放9种不同的魔法,而且魔法的效果还非常炫目,
推荐理由:
Crystallight Defense作为魔法水晶之主,你回到了面目全非的家乡,你必须施展你所拥有的魔法,重新夺回属于自己的城堡。通过触屏操作,建造各类水晶塔,设置通道障碍,在敌人入侵城堡前将其消灭。和星际塔防一样经典耐玩的游戏,挺考验智慧,非常有意思。
推荐理由:
一款以忍者为题材的塔防游戏,玩家需要不断的在游戏中铺设将领和士兵,对抗叛徒明智光秀的偷袭。游戏采用卡通的设计,多种角色和武器可供选择,让你更好的挑战个个等级。
推荐理由:
Medieval Castle Defense(中世纪城堡防御)是Android平台上的一款经典的塔防游戏,与城堡塔防(Castle Defense)一样,都是以中世纪的欧洲为时代背景的。不过,这两款游戏虽然只是一个多了Medieval单词,但是两者的风格完全不一样,Medieval Castle Defense
推荐理由:
合金塔防是一款集合射击和塔防元素的策略游戏。玩家可以使用武器攻击入侵敌军,同时可以生产派遣士兵和机甲帮助防守,玩家保护城堡击杀所有敌军即可获得胜利。游戏包含大量兵种,武器以及技能,不同兵种的搭配打造最强战队。即使是敌军强大的BOSS超级战舰,
推荐理由:
这是一款以三国题材的策略防守游戏!雷人!搞笑!快乐不断! 扮演三国时期的君主刘备,守在城墙上,抵挡敌人一波又一波的进攻,最终获得胜利。 通过击退敌人可以获得金币与分数,并可以不断的提升士兵与技术的等级,使游戏变得更加轻松。 在三国时期的50多个
推荐理由:
【注意】 该款游戏需要另100M数据包,下载链接在描述最后面。 《猴子塔防5 Bloons TD 5》是一款塔防游戏,最流行的塔防游戏又回来了!建造合适的炮塔,选择你喜欢的升级,雇佣新的特工,消灭每一个敌人!新的炮塔和特工,享受华丽的铁托,原创的音效和特殊任
推荐理由:
《机枪塔防 Defense Gear》是一款塔防游戏,游戏对操作的要求较高,你不仅需要根据地形和敌人来放置不同的炮塔,还要手动给炮塔设定攻击方向,敌人漏掉了还要手动攻击,不然可是打不到敌人的哦~
推荐理由:
一款以大炮为题材的塔防游戏,制作精良,玩法特别,相当有战争的厚重感。 玩家需要不断的通过搭建大炮和巨型机械昆虫的军队来保卫你的卡车车队,你可以搭建路障,毁灭一切,阻止进攻!
本站发布的系统与软件仅为个人学习测试使用,请在下载后24小时内删除,不得用于任何商业用途,否则后果自负,请支持购买微软正版软件!如侵犯到您的权益,请及时通知我们,我们会及时处理。
Copyright&2011 系统之家(www.xitongzhijia.net) 版权所有 闽ICP备号-134520人阅读
3.1 Cocos2d-x(22)
&&&&& 本文实践自 Pablo Ruiz 的文章《》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.0.4进行学习和移植。在这篇文章,将会学习到如何制作一个塔防游戏。在这当中,学习如何在设定的时间内出现一波波的敌人,使这些敌人沿着指定的路点前进,如何在地图上指定的位置创建炮塔,如何使炮塔射击敌人,如何可视化调试路点和炮塔的攻击范围。
步骤如下:
1.新建Cocos2d-win32工程,工程名为&TowerDefense&,去除&Box2D&选项,勾选&Simple Audio Engine in Cocos Denshion&选项;
2.下载本游戏所需的资源,将资源放置&Resources&目录下;
3.为场景添加背景图片。打开HelloWorldScene.cpp文件,修改init函数,如下:
bool&HelloWorld::init()
&&&&bool&bRet&=&false;
&&&&&&&&CC_BREAK_IF(!&CCLayer::init());
&&&&&&&&this-&setTouchEnabled(true);
&&&&&&&&CCSize&wins&=&CCDirector::sharedDirector()-&getWinSize();
&&&&&&&&CCSprite&*background&=&CCSprite::create(&Bg.png&);
&&&&&&&&this-&addChild(background);
&&&&&&&&background-&setPosition(ccp(wins.width&/&2,&wins.height&/&2));
&&&&&&&&bRet&=&true;
&&&&}&while&(0);
&&&&return&bR
通过放置的背景图片,可以直观的看出哪些地方允许玩家放置炮塔。编译运行,如下图所示:
4.接着,需要沿路设置一些点,在这些点上能够让玩家触摸和建立炮塔。为了方便管理,使用.plist文件来存储炮塔的放置点,这样就可以很容易的改变它们。TowersPosition.plist已经在资源文件夹中,其中已经有了一些炮塔的位置。查看这个文件,可以看到一个字典数组,字典只包含两个键&x&和&y&。每个字典条目代表一个炮塔位置的x和y坐标。现在需要读取这个文件,并且放置塔基到地图上。打开HelloWorldScene.h文件,添加以下变量:
cocos2d::CCArray*&towerB
打开HelloWorldScene.cpp文件,添加如下方法:
void&HelloWorld::loadTowerPositions()
&&&&CCArray*&towerPositions&=&CCArray::createWithContentsOfFile(&TowersPosition.plist&);
&&&&towerBases&=&CCArray::createWithCapacity(10);
&&&&towerBases-&retain();
&&&&CCObject&*pObject&=&NULL;
&&&&CCARRAY_FOREACH(towerPositions,&pObject)
&&&&&&&&CCDictionary*&towerPos&=&(CCDictionary*)pO
&&&&&&&&CCSprite*&towerBase&=&CCSprite::create(&open_spot.png&);
&&&&&&&&this-&addChild(towerBase);
&&&&&&&&towerBase-&setPosition(ccp(((CCString*)towerPos-&objectForKey(&x&))-&intValue(),
&&&&&&&&&&&&((CCString*)towerPos-&objectForKey(&y&))-&intValue()));
&&&&&&&&towerBases-&addObject(towerBase);
在init函数里面,添加背景图片代码之后,添加如下代码:
this-&loadTowerPositions();
在析构函数里面,添加如下代码:
towerBases-&release();
编译运行,就可以看到道路两侧的方块,这些是做为玩家炮塔的基座。如下图所示:
5.开始建立炮塔。打开HelloWorldScene.h文件,添加如下代码:
CC_SYNTHESIZE_RETAIN(cocos2d::CCArray*,&_towers,&Towers);
添加Tower类,派生自CCNode类,Tower.h文件代码如下:
#ifndef&__TOWER_H__
#define&__TOWER_H__
#include&&cocos2d.h&
#include&&HelloWorldScene.h&
#define&kTOWER_COST&<span style="color:#ff
class&Tower&:&public&cocos2d::CCNode
&&&&Tower(void);
&&&&~Tower(void);
&&&&static&Tower*&nodeWithTheGame(HelloWorld*&game,&cocos2d::CCPoint&location);
&&&&bool&initWithTheGame(HelloWorld*&game,&cocos2d::CCPoint&location);
&&&&void&update(float&dt);
&&&&void&draw(void);
&&&&CC_SYNTHESIZE(HelloWorld*,&_theGame,&TheGame);
&&&&CC_SYNTHESIZE(cocos2d::CCSprite*,&_mySprite,&MySprite);
&&&&int&attackR
&&&&float&fireR
#endif&&//&__TOWER_H__
打开Tower.cpp文件,代码如下:
#include&&Tower.h&
using&namespace&cocos2d;
Tower::Tower(void)
Tower::~Tower(void)
Tower*&Tower::nodeWithTheGame(HelloWorld*&game,&CCPoint&location)
&&&&Tower&*pRet&=&new&Tower();
&&&&if&(pRet&&&&pRet-&initWithTheGame(game,&location))
&&&&&&&&return&pR
&&&&&&&&delete&pR
&&&&&&&&pRet&=&NULL;
&&&&&&&&return&NULL;
bool&Tower::initWithTheGame(HelloWorld*&game,&CCPoint&location)
&&&&bool&bRet&=&false;
&&&&&&&&attackRange&=&70;
&&&&&&&&damage&=&10;
&&&&&&&&fireRate&=&1;
&&&&&&&&_mySprite&=&CCSprite::create(&tower.png&);
&&&&&&&&this-&addChild(_mySprite);
&&&&&&&&_mySprite-&setPosition(location);
&&&&&&&&_theGame&=&
&&&&&&&&_theGame-&addChild(this);
&&&&&&&&this-&scheduleUpdate();
&&&&&&&&bRet&=&true;
&&&&}&while&(0);
&&&&return&bR
void&Tower::update(float&dt)
void&Tower::draw(void)
#ifdef&COCOS2D_DEBUG
&&&&ccDrawColor4F(<span style="color:#ff,&<span style="color:#ff,&<span style="color:#ff,&<span style="color:#ff);
&&&&ccDrawCircle(_mySprite-&getPosition(),&attackRange,&<span style="color:#ff,&30,&false);
&&&&CCNode::draw();
这个Tower类包含几个属性:一个精灵对象,这是炮塔的可视化表现;一个父层的引用,方便访问父层;还有三个变量:
attackRange: 炮塔可以攻击敌人的距离。damage: 炮塔对敌人造成的伤害&#20540;。fireRate: 炮塔再次攻击敌人的时间间隔。
有了这三个变量,就可以创建各种不同攻击属性的炮塔,比如需要很长时间来重新加载的远程重击,或者范围有限的快速攻击。最后,代码中的draw方法,用于在炮塔周围绘制一个圆,以显示出它的攻击范围,这将方便调试。
6.让玩家添加炮塔。打开HelloWorldScene.cpp文件,加入以下头文件声明:
#include&&Tower.h&
在析构函数中添加如下代码:
_towers-&release();
在init函数,添加如下代码:
_towers&=&CCArray::create();
_towers-&retain();
添加如下两个方法,代码如下:
bool&HelloWorld::canBuyTower()
&&&&return&true;
void&HelloWorld::ccTouchesBegan(CCSet&*pTouches,&CCEvent&*pEvent)
&&&&CCSetIterator&iter&=&pTouches-&begin();
&&&&for&(;&iter&!=&pTouches-&end();&iter&#43;&#43;)
&&&&&&&&CCTouch*&pTouch&=&(CCTouch*)(*iter);
&&&&&&&&CCPoint&location&=&pTouch-&getLocation();
&&&&&&&&CCObject&*pObject&=&NULL;
&&&&&&&&CCARRAY_FOREACH(towerBases,&pObject)
&&&&&&&&&&&&CCSprite&*tb&=&(CCSprite*)pO
&&&&&&&&&&&&if&(this-&canBuyTower()&&&&tb-&boundingBox().containsPoint(location)&&&&!tb-&getUserData())
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&//We&will&spend&our&gold&later.
&&&&&&&&&&&&&&&&Tower*&tower&=&Tower::nodeWithTheGame(this,&tb-&getPosition());
&&&&&&&&&&&&&&&&_towers-&addObject(tower);
&&&&&&&&&&&&&&&&tb-&setUserData(tower);
&&&&&&&&&&&&}&&&&&&&&&&&
方法ccTouchesBegan检测当用户触摸屏幕上任何点时,遍历towerBases数组,检查触摸点是否包含在任何一个塔基上。不过在创建炮塔前,还有两件事需要检查:
①玩家是否买得起炮塔?canBuyTower方法用来检查玩家是否有足够的金币来购买炮塔。在这里先假设玩家有很多金币,方法返回true。
②玩家是否违法了建筑规则?如果tb的UserData已经设置了,那么这个塔基已经有了炮塔,不能再添加一个新的了。
如果一切检查都通过,那么就创建一个新的炮塔,放置在塔基上,并将它添加到炮塔数组中。编译运行,触摸塔基,就可以看到炮塔放置上去了,并且它的周围还有白色的圆圈显示攻击范围,如下图所示:
7.添加路点。敌人将会沿着一系列的路点前进,这些简单相互连接的点构成了一条路径,敌人在这条路径上进行行走。敌人会出现在第一个路点,搜寻列表中的下一个路点,移动到那个位置,重复这个过程,直到他们到达列表中的最后一个路点——玩家基地。如果被敌人到达基地,那么玩家就会受到损害。添加Waypoint类,派生自CCNode类,Waypoint.h文件代码如下:
#ifndef&__WAYPOINT_H__
#define&__WAYPOINT_H__
#include&&cocos2d.h&
#include&&HelloWorldScene.h&
class&Waypoint&:&public&cocos2d::CCNode
&&&&Waypoint(void);
&&&&~Waypoint(void);
&&&&static&Waypoint*&nodeWithTheGame(HelloWorld*&game,&cocos2d::CCPoint&location);
&&&&bool&initWithTheGame(HelloWorld*&game,&cocos2d::CCPoint&location);
&&&&void&draw(void);
&&&&CC_SYNTHESIZE(cocos2d::CCPoint,&_myPosition,&MyPosition);
&&&&CC_SYNTHESIZE(Waypoint*,&_nextWaypoint,&NextWaypoint);
&&&&HelloWorld*&theG
#endif&&//&__WAYPOINT_H__
打开Waypoint.cpp文件,代码如下:
#include&&Waypoint.h&
using&namespace&cocos2d;
Waypoint::Waypoint(void)
&&&&_nextWaypoint&=&NULL;
Waypoint::~Waypoint(void)
Waypoint*&Waypoint::nodeWithTheGame(HelloWorld*&game,&CCPoint&location)
&&&&Waypoint&*pRet&=&new&Waypoint();
&&&&if&(pRet&&&&pRet-&initWithTheGame(game,&location))
&&&&&&&&return&pR
&&&&&&&&delete&pR
&&&&&&&&pRet&=&NULL;
&&&&&&&&return&NULL;
bool&Waypoint::initWithTheGame(HelloWorld*&game,&CCPoint&location)
&&&&bool&bRet&=&false;
&&&&&&&&theGame&=&
&&&&&&&&_myPosition&=&
&&&&&&&&this-&setPosition(CCPointZero);
&&&&&&&&theGame-&addChild(this);
&&&&&&&&bRet&=&true;
&&&&}&while&(0);
&&&&return&bR
void&Waypoint::draw(void)
#ifdef&COCOS2D_DEBUG
&&&&ccDrawColor4F(0,&<span style="color:#ff,&0,&<span style="color:#ff);
&&&&ccDrawCircle(_myPosition,&6,&<span style="color:#ff,&30,&false);
&&&&ccDrawCircle(_myPosition,&2,&<span style="color:#ff,&30,&false);
&&&&if&(_nextWaypoint)
&&&&&&&&ccDrawLine(_myPosition,&_nextWaypoint-&_myPosition);
&&&&CCNode::draw();
首先,通过传入的HelloWorld对象引用和路点位置坐标,进行初始化一个waypoint对象。每个路点都包含下一个路点的引用,这将会创建一个路点链接列表。每个路点知道列表中的下一个路点。通过这种方式,可以引导敌人沿着链表上的路点到达他们的最终目的地。最后,draw方法绘制显示路点的位置,并且绘制一条直线将其与下一个路点进行连接,这仅仅用于调试目的。
8.创建路点列表。打开HelloWorldScene.h文件,添加以下代码:
CC_SYNTHESIZE_RETAIN(cocos2d::CCArray*,&_waypoints,&Waypoints);
打开HelloWorldScene.cpp文件,加入以下头文件声明:
#include&&Waypoint.h&
在析构函数中添加如下代码:
_waypoints-&release();
添加以下方法:
void&HelloWorld::addWaypoints()
&&&&_waypoints&=&CCArray::create();
&&&&_waypoints-&retain();
&&&&Waypoint&*waypoint1&=&Waypoint::nodeWithTheGame(this,&ccp(<span style="color:#ff,&35));
&&&&_waypoints-&addObject(waypoint1);
&&&&Waypoint&*waypoint2&=&Waypoint::nodeWithTheGame(this,&ccp(35,&35));
&&&&_waypoints-&addObject(waypoint2);
&&&&waypoint2-&setNextWaypoint(waypoint1);
&&&&Waypoint&*waypoint3&=&Waypoint::nodeWithTheGame(this,&ccp(35,&<span style="color:#ff));
&&&&_waypoints-&addObject(waypoint3);
&&&&waypoint3-&setNextWaypoint(waypoint2);
&&&&Waypoint&*waypoint4&=&Waypoint::nodeWithTheGame(this,&ccp(<span style="color:#ff,&<span style="color:#ff));
&&&&_waypoints-&addObject(waypoint4);
&&&&waypoint4-&setNextWaypoint(waypoint3);
&&&&Waypoint&*waypoint5&=&Waypoint::nodeWithTheGame(this,&ccp(<span style="color:#ff,&<span style="color:#ff));
&&&&_waypoints-&addObject(waypoint5);
&&&&waypoint5-&setNextWaypoint(waypoint4);
&&&&Waypoint&*waypoint6&=&Waypoint::nodeWithTheGame(this,&ccp(-40,&<span style="color:#ff));
&&&&_waypoints-&addObject(waypoint6);
&&&&waypoint6-&setNextWaypoint(waypoint5);
在init函数,添加如下代码:
this-&addWaypoints();
编译运行,效果如下图所示:
在地图上有6个路点,这是敌人的行走路线。在让敌人出现在游戏中前,还需要添加一个辅助方法。打开HelloWorldScene.cpp文件,添加方法如下:
bool&HelloWorld::collisionWithCircle(CCPoint&circlePoint,&float&radius,&CCPoint&circlePointTwo,&float&radiusTwo)
&&&&float&xdif&=&circlePoint.x&-&circlePointTwo.x;
&&&&float&ydif&=&circlePoint.y&-&circlePointTwo.y;
&&&&float&distance&=&sqrt(xdif&*&xdif&&#43;&ydif&*&ydif);
&&&&if(distance&&=&radius&&#43;&radiusTwo)&
&&&&&&&&return&true;
&&&&return&false;
方法collisionWithCircle用于判断两个圆是否碰撞或者相交。这将用于判断敌人是否到达一个路点,同时也可以检测敌人是否在炮塔的攻击范围之内。
9.添加敌人。打开HelloWorldScene.h文件,添加以下代码:
CC_SYNTHESIZE_RETAIN(cocos2d::CCArray*,&_enemies,&Enemies);
cocos2d::CCLabelBMFont*&ui_wave_
打开HelloWorldScene.cpp文件,在析构函数里,添加如下代码:
_enemies-&release();
添加Enemy类,派生自CCNode类,Enemy.h文件代码如下:
#ifndef&__ENEMY_H__
#define&__ENEMY_H__
#include&&cocos2d.h&
#include&&HelloWorldScene.h&
#include&&Waypoint.h&
class&Enemy&:&public&cocos2d::CCNode
&&&&Enemy(void);
&&&&~Enemy(void);
&&&&static&Enemy*&nodeWithTheGame(HelloWorld*&game);
&&&&bool&initWithTheGame(HelloWorld*&game);
&&&&void&doActivate(float&dt);
&&&&void&getRemoved();
&&&&void&update(float&dt);
&&&&void&draw(void);
&&&&CC_SYNTHESIZE(HelloWorld*,&_theGame,&TheGame);
&&&&CC_SYNTHESIZE(cocos2d::CCSprite*,&_mySprite,&MySprite);
&&&&cocos2d::CCPoint&myP
&&&&int&maxHp;
&&&&int&currentHp;
&&&&float&walkingS
&&&&Waypoint&*destinationW
#endif&&//&__ENEMY_H__
打开Enemy.cpp文件,代码如下:
#include&&Enemy.h&
using&namespace&cocos2d;
#define&HEALTH_BAR_WIDTH&20
#define&HEALTH_BAR_ORIGIN&-10
Enemy::Enemy(void)
Enemy::~Enemy(void)
Enemy*&Enemy::nodeWithTheGame(HelloWorld*&game)
&&&&Enemy&*pRet&=&new&Enemy();
&&&&if&(pRet&&&&pRet-&initWithTheGame(game))
&&&&&&&&return&pR
&&&&&&&&delete&pR
&&&&&&&&pRet&=&NULL;
&&&&&&&&return&NULL;
bool&Enemy::initWithTheGame(HelloWorld*&game)
&&&&bool&bRet&=&false;
&&&&&&&&maxHp&=&40;
&&&&&&&&currentHp&=&maxHp;
&&&&&&&&active&=&false;
&&&&&&&&walkingSpeed&=&0.5;
&&&&&&&&_theGame&=&
&&&&&&&&_mySprite&=&CCSprite::create(&enemy.png&);
&&&&&&&&this-&addChild(_mySprite);
&&&&&&&&Waypoint&*waypoint&=&(Waypoint*)_theGame-&getWaypoints()-&objectAtIndex(_theGame-&getWaypoints()-&count()&-&1);
&&&&&&&&destinationWaypoint&=&waypoint-&getNextWaypoint();
&&&&&&&&CCPoint&pos&=&waypoint-&getMyPosition();
&&&&&&&&myPosition&=&
&&&&&&&&_mySprite-&setPosition(pos);
&&&&&&&&_theGame-&addChild(this);
&&&&&&&&this-&scheduleUpdate();
&&&&&&&&bRet&=&true;
&&&&}&while&(0);
&&&&return&bR
void&Enemy::doActivate(float&dt)
&&&&active&=&true;
void&Enemy::getRemoved()
&&&&this-&getParent()-&removeChild(this,&true);
&&&&_theGame-&getEnemies()-&removeObject(this);
&&&&//Notify&the&game&that&we&killed&an&enemy&so&we&can&check&if&we&can&send&another&wave
&&&&_theGame-&enemyGotKilled();
void&Enemy::update(float&dt)
&&&&if&(!active)
&&&&&&&&return;
&&&&if&(_theGame-&collisionWithCircle(myPosition,&1,&destinationWaypoint-&getMyPosition(),&1))
&&&&&&&&if&(destinationWaypoint-&getNextWaypoint())
&&&&&&&&&&&&destinationWaypoint&=&destinationWaypoint-&getNextWaypoint();
&&&&&&&&}&
&&&&&&&&else
&&&&&&&&&&&&//Reached&the&end&of&the&road.&Damage&the&player
&&&&&&&&&&&&_theGame-&getHpDamage();
&&&&&&&&&&&&this-&getRemoved();
&&&&CCPoint&targetPoint&=&&destinationWaypoint-&getMyPosition();
&&&&float&movementSpeed&=&walkingS
&&&&CCPoint&normalized&=&ccpNormalize(ccp(targetPoint.x&-&myPosition.x,&targetPoint.y&-&myPosition.y));
&&&&_mySprite-&setRotation(CC_RADIANS_TO_DEGREES(atan2(normalized.y,&-&normalized.x)));
&&&&myPosition&=&ccp(myPosition.x&&#43;&normalized.x&*&movementSpeed,&myPosition.y&&#43;&normalized.y&*&movementSpeed);
&&&&_mySprite-&setPosition(myPosition);
void&Enemy::draw(void)
&&&&CCPoint&healthBarBack[]&=&{
&&&&&&&&ccp(_mySprite-&getPosition().x&-&10,&_mySprite-&getPosition().y&&#43;&16),
&&&&&&&&ccp(_mySprite-&getPosition().x&&#43;&10,&_mySprite-&getPosition().y&&#43;&16),
&&&&&&&&ccp(_mySprite-&getPosition().x&&#43;&10,&_mySprite-&getPosition().y&&#43;&14),
&&&&&&&&ccp(_mySprite-&getPosition().x&-&10,&_mySprite-&getPosition().y&&#43;&14)
&&&&ccDrawSolidPoly(healthBarBack,&4,&ccc4f(<span style="color:#ff,&0,&0,&<span style="color:#ff));
&&&&CCPoint&healthBar[]&=&{
&&&&&&&&ccp(_mySprite-&getPosition().x&&#43;&HEALTH_BAR_ORIGIN,&_mySprite-&getPosition().y&&#43;&16),
&&&&&&&&ccp(_mySprite-&getPosition().x&&#43;&HEALTH_BAR_ORIGIN&&#43;&(float)(currentHp&*&HEALTH_BAR_WIDTH)&/&maxHp,&_mySprite-&getPosition().y&&#43;&16),
&&&&&&&&ccp(_mySprite-&getPosition().x&&#43;&HEALTH_BAR_ORIGIN&&#43;&(float)(currentHp&*&HEALTH_BAR_WIDTH)&/&maxHp,&_mySprite-&getPosition().y&&#43;&14),
&&&&&&&&ccp(_mySprite-&getPosition().x&&#43;&HEALTH_BAR_ORIGIN,&_mySprite-&getPosition().y&&#43;&14)
&&&&ccDrawSolidPoly(healthBar,&4,&ccc4f(0,&<span style="color:#ff,&0,&<span style="color:#ff));
&&&&CCNode::draw();
首先,通过传递一个HelloWorld对象引用进行初始化。在初始化函数里面,对一些重要的变量进行设置:
maxHP: 敌人的生命&#20540;。walkingSpeed: 敌人的移动速度。mySprite: 存储敌人的可视化表现。destinationWaypoint: 存储下一个路点的引用。
update方法每帧都会被调用,它首先通过collisionWithCircle方法检查是否到达了目的路点。如果到达了,则前进到下一个路点,直到敌人到达终点,玩家也就受到伤害。接着,它根据敌人的行走速度,沿着一条直线移动精灵到达下一个路点。它通过以下算法:
①计算出从当前位置到目标位置的向量,然后将其长度设置为1(向量标准化)
②将移动速度乘以标准化向量,得到移动的距离,将它与当前坐标进行相加,得到新的坐标位置。
最后,draw方法在精灵上面简单的实现了一条血量条。它首先绘制一个红色背景,然后根据敌人的当前生命&#20540;用绿色进行覆盖血量条。
10.显示敌人。打开HelloWorldScene.cpp文件,添加头文件声明:
#include&&Enemy.h&
添加如下方法:
bool&HelloWorld::loadWave()
&&&&CCArray&*waveData&=&CCArray::createWithContentsOfFile(&Waves.plist&);
&&&&if&(wave&&=&waveData-&count())
&&&&&&&&return&false;
&&&&CCArray&*currentWaveData&=&(CCArray*)waveData-&objectAtIndex(wave);
&&&&CCObject&*pObject&=&NULL;
&&&&CCARRAY_FOREACH(currentWaveData,&pObject)
&&&&&&&&CCDictionary*&enemyData&=&(CCDictionary*)pO
&&&&&&&&Enemy&*enemy&=&Enemy::nodeWithTheGame(this);
&&&&&&&&_enemies-&addObject(enemy);
&&&&&&&&enemy-&schedule(schedule_selector(Enemy::doActivate),&((CCString*)enemyData-&objectForKey(&spawnTime&))-&floatValue());
&&&&wave&#43;&#43;;
&&&&ui_wave_lbl-&setString(CCString::createWithFormat(&WAVE:&%d&,&wave)-&getCString());
&&&&return&true;
void&HelloWorld::enemyGotKilled()
&&&&//If&there&are&no&more&enemies.
&&&&if&(_enemies-&count()&&=&0)
&&&&&&&&if&(!this-&loadWave())
&&&&&&&&&&&&CCLog(&You&win!&);
&&&&&&&&&&&&CCDirector::sharedDirector()-&replaceScene(CCTransitionSplitCols::create(1,&HelloWorld::scene()));
&&&&&&&&}&&&&&&&
void&HelloWorld::getHpDamage()
在init函数里面,添加如下代码:
ui_wave_lbl&=&CCLabelBMFont::create(CCString::createWithFormat(&WAVE:&%d&,&wave)-&getCString(),&&font_red_14.fnt&);
this-&addChild(ui_wave_lbl,&10);
ui_wave_lbl-&setPosition(ccp(<span style="color:#ff,&wins.height&-&12));
ui_wave_lbl-&setAnchorPoint(ccp(0,&0.5));
_enemies&=&CCArray::create();
_enemies-&retain();
this-&loadWave();
现在对上面的代码进行一些解释。最重要的部分是loadWave方法,它从Waves.plist文件读取数据。查看这个文件,可以看到它包含了3个数组,每个数组代表着一波敌人。第一个数组包含6个字典,每个字典定义了一个敌人。在本篇文章中,这个字典仅存储敌人的出现时间,但是也可用于定义敌人类型或者其他特殊属性,以区分不同的敌人。loadWave方法检查下一波应出现的敌人,根据波信息创建相应的敌人,并安排它们在规定的时间出现在屏幕上。enemyGotKilled方法检查当前屏幕上的敌人数量,如果已经没有敌人的话,那么就让下一波敌人出现。之后,还使用这个方法来判断玩家是否赢得了游戏。编译运行,敌人正向玩家基地前进,如下图所示:
10.炮塔攻击。每座塔进行检查是否有敌人出现在攻击范围之内,如果有的话,对敌人进行开火,直到以下两种情况之一发生:敌人移动出范围;敌人被消灭。那么炮塔就会寻找下一个敌人。打开Tower.h文件,添加以下代码:
添加以下变量:
Enemy&*chosenE
打开Tower.cpp文件,添加头文件声明:
#include&&Enemy.h&
在initWithTheGame函数开头if条件之后,添加如下代码:
chosenEnemy&=&NULL;
添加以下方法:
void&Tower::attackEnemy()
&&&&this-&schedule(schedule_selector(Tower::shootWeapon),&fireRate);
void&Tower::chosenEnemyForAttack(Enemy&*enemy)
&&&&chosenEnemy&=&NULL;
&&&&chosenEnemy&=&
&&&&this-&attackEnemy();
&&&&enemy-&getAttacked(this);
void&Tower::shootWeapon(float&dt)
&&&&CCSprite&*bullet&=&CCSprite::create(&bullet.png&);
&&&&_theGame-&addChild(bullet);
&&&&bullet-&setPosition(_mySprite-&getPosition());
&&&&bullet-&runAction(CCSequence::create(
&&&&&&&&CCMoveTo::create(0.1,&chosenEnemy-&getMySprite()-&getPosition()),
&&&&&&&&CCCallFunc::create(this,&callfunc_selector(Tower::damageEnemy)),
&&&&&&&&CCCallFuncN::create(this,&callfuncN_selector(Tower::removeBullet)),
&&&&&&&&NULL));
void&Tower::removeBullet(CCSprite&*bullet)
&&&&bullet-&getParent()-&removeChild(bullet,&true);
void&Tower::damageEnemy()
&&&&if&(chosenEnemy)
&&&&&&&&chosenEnemy-&getDamaged(damage);
void&Tower::targetKilled()
&&&&if&(chosenEnemy)
&&&&&&&&chosenEnemy&=&NULL;
&&&&this-&unschedule(schedule_selector(Tower::shootWeapon));
void&Tower::lostSightOfEnemy()
&&&&chosenEnemy-&gotLostSight(this);
&&&&if&(chosenEnemy)
&&&&&&&&chosenEnemy&=&NULL;
&&&&this-&unschedule(schedule_selector(Tower::shootWeapon));
最后,更新update方法为如下:
void&Tower::update(float&dt)
&&&&if&(chosenEnemy)
&&&&&&&&//We&make&it&turn&to&target&the&enemy&chosen
&&&&&&&&CCPoint&normalized&=&ccpNormalize(ccp(chosenEnemy-&getMySprite()-&getPosition().x&-&_mySprite-&getPosition().x,
&&&&&&&&&&&&chosenEnemy-&getMySprite()-&getPosition().y&-&_mySprite-&getPosition().y));
&&&&&&&&_mySprite-&setRotation(CC_RADIANS_TO_DEGREES(atan2(normalized.y,&-&normalized.x))&&#43;&90);
&&&&&&&&if&(!_theGame-&collisionWithCircle(_mySprite-&getPosition(),&attackRange,&chosenEnemy-&getMySprite()-&getPosition(),&1))
&&&&&&&&&&&&this-&lostSightOfEnemy();
&&&&&&&&CCObject&*pObject&=&NULL;
&&&&&&&&CCARRAY_FOREACH(_theGame-&getEnemies(),&pObject)
&&&&&&&&&&&&Enemy&*enemy&=&(Enemy*)pO
&&&&&&&&&&&&if&(_theGame-&collisionWithCircle(_mySprite-&getPosition(),&attackRange,&enemy-&getMySprite()-&getPosition(),&1))
&&&&&&&&&&&&{
&&&&&&&&&&&&&&&&this-&chosenEnemyForAttack(enemy);
&&&&&&&&&&&&&&&&break;
&&&&&&&&&&&&}&&&&&&&&&&&
打开Enemy.h文件,添加以下代码:
cocos2d::CCArray&*attackedBy;
打开Enemy.cpp文件,在initWithTheGame函数开头if条件之后,添加如下代码:
attackedBy&=&CCArray::createWithCapacity(5);
attackedBy-&retain();
在getRemoved函数开头,添加如下代码:
CCObject&*pObject&=&NULL;
CCARRAY_FOREACH(attackedBy,&pObject)
&&&&Tower&*attacker&=&(Tower*)pO
&&&&attacker-&targetKilled();
添加如下方法:
void&Enemy::getAttacked(Tower*&attacker)
&&&&attackedBy-&addObject(attacker);
void&Enemy::gotLostSight(Tower*&attacker)
&&&&attackedBy-&removeObject(attacker);
void&Enemy::getDamaged(int&damage)
&&&&currentHp&-=&
&&&&if&(currentHp&&=&0)
&&&&&&&&this-&getRemoved();
代码中最重要的部分是在Tower类的update方法。炮塔不断检查敌人是否在攻击范围内,如果是的话,炮塔将旋转朝向敌人,开火攻击。一个敌人一旦被标记为被攻击,将会调用方法让炮塔以攻击间隔发射子弹。反过来,每个敌人都存储有向其攻击的炮塔列表,所以如果敌人被杀死了,那么炮塔就会被通知停止攻击。编译运行,放置几个炮塔在地图上,将会看到一旦敌人进入炮塔的攻击范围,炮塔就会向它们开火攻击,敌人的血量条就会减少,直到被消灭。如下图所示:
11.显示玩家血量。打开HelloWorldScene.h文件,添加以下代码:
int&playerHp;
cocos2d::CCLabelBMFont&*ui_hp_
bool&gameE
变量playerHp表示玩家的生命&#20540;,CCLabelBMFont对象是一个标签,用来显示生命数&#20540;。gameEnded用来表示游戏是否结束。打开HelloWorldScene.cpp文件,在init函数里面,添加如下代码:
gameEnded&=&false;
playerHp&=&5;
ui_hp_lbl&=&CCLabelBMFont::create(CCString::createWithFormat(&HP:&%d&,&playerHp)-&getCString(),&&font_red_14.fnt&);
this-&addChild(ui_hp_lbl,&10);
ui_hp_lbl-&setPosition(ccp(35,&wins.height&-&12));
添加如下方法:
void&HelloWorld::getHpDamage()
&&&&playerHp--;
&&&&ui_hp_lbl-&setString(CCString::createWithFormat(&HP:&%d&,&playerHp)-&getCString());
&&&&if&(playerHp&&=&0)
&&&&&&&&this-&doGameOver();
void&HelloWorld::doGameOver()
&&&&if&(!gameEnded)
&&&&&&&&gameEnded&=&true;
&&&&&&&&CCDirector::sharedDirector()-&replaceScene(CCTransitionRotoZoom::create(1,&HelloWorld::scene()));
添加的方法为减少玩家生命&#20540;,更新标签,并检查玩家生命是否耗尽,如果是的话,游戏就结束了。当敌人到达基地的时候,getHpDamage方法被调用。编译运行,让敌人到达基地,你将会看到玩家的生命在减少,直到游戏失败。如下图所示:
12.限制金币供应量。大多数游戏都实现了“零和”功能,建造每座炮塔需要一定的资源,并给玩家有限的资源进行分配。打开HelloWorldScene.h文件,添加如下代码:
int&playerG
cocos2d::CCLabelBMFont&*ui_gold_
就像显示生命数&#20540;一样,一个变量表示玩家的金币数,一个标签对象显示金币数&#20540;。打开HelloWorldScene.cpp文件,在init函数里面,添加如下代码:
playerGold&=&<span style="color:#ff;
ui_gold_lbl&=&CCLabelBMFont::create(CCString::createWithFormat(&GOLD:&%d&,&playerGold)-&getCString(),&&font_red_14.fnt&);
this-&addChild(ui_gold_lbl,&10);
ui_gold_lbl-&setPosition(ccp(<span style="color:#ff,&wins.height&-&12));
ui_gold_lbl-&setAnchorPoint(ccp(0,&0.5));
添加如下方法:
void&HelloWorld::awardGold(int&gold)
&&&&playerGold&&#43;=&
&&&&ui_gold_lbl-&setString(CCString::createWithFormat(&GOLD:&%d&,&playerGold)-&getCString());
替换canBuyTower方法,代码如下:
bool&HelloWorld::canBuyTower()
&&&&if&(playerGold&-&kTOWER_COST&&=&0)
&&&&&&&&return&true;
&&&&return&false;
在ccTouchesBegan函数里面,语句//We will spend our gold later.的后面,添加如下代码:
playerGold&-=&kTOWER_COST;
ui_gold_lbl-&setString(CCString::createWithFormat(&GOLD:&%d&,&playerGold)-&getCString());
上述的代码在玩家尝试放置炮塔时,检查是否有足够的金币。如果足够的话,炮塔就会放置上去,并从玩家的金币数中减去炮塔的费用。每次杀死敌人的时候也应该奖励玩家一些金币。打开Enemy.cpp文件,在getDamaged函数里面,if条件后面,添加如下语句:
_theGame-&awardGold(<span style="color:#ff);
编译运行,会看到不能随意的放置炮塔了,因为每个炮塔都要花费金币。当然,杀死敌人就可以获得金币奖励,这样就可以继续购买炮塔。这是一个很好的系统。如下图所示:
13.加入背景音乐和音效。打开HelloWorldScene.cpp文件,添加头文件声明:
#include&&SimpleAudioEngine.h&
在init函数,if条件之后,添加如下代码:
CocosDenshion::SimpleAudioEngine::sharedEngine()-&playBackgroundMusic(&8bitDungeonLevel.mp3&,&true);
在ccTouchesBegan函数,添加一个新的Tower对象前,添加如下代码:
CocosDenshion::SimpleAudioEngine::sharedEngine()-&playEffect(&tower_place.wav&);
在getHpDamage函数里,添加如下代码:
CocosDenshion::SimpleAudioEngine::sharedEngine()-&playEffect(&life_lose.wav&);
打开Enemy.cpp文件,添加头文件声明:
#include&&SimpleAudioEngine.h&
在getDamaged函数里,添加如下代码:
CocosDenshion::SimpleAudioEngine::sharedEngine()-&playEffect(&laser_shoot.wav&);
编译运行,现在游戏将有配乐,关闭掉调试绘制后,效果图:
参考资料:
1.How To Make a Tower Defense Game&
2.钓龟岛保卫战-如何从零开始制作一款iOS塔防游戏(新)&
非常感谢以上资料,本例子源代码附加资源下载地址:
如文章存在错误之处,欢迎指出,以便改正。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3287420次
积分:33856
积分:33856
排名:第134名
原创:394篇
转载:88篇
评论:3371条
联系方式:
(1)(1)(1)(2)(1)(1)(1)(1)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(1)(1)(1)(2)(1)(1)(1)(1)(1)(3)(1)(1)(1)(1)(2)(1)(3)(3)(3)(1)(1)(3)(1)(1)(8)(1)(3)(2)(2)(3)(2)(3)(2)(1)(1)(2)(3)(6)(1)(4)(3)(1)(3)(5)(5)(5)(5)(1)(3)(5)(4)(4)(4)(5)(5)(1)(13)(11)(7)(5)(2)(5)(4)(5)(2)(7)(14)(18)(23)(19)(5)(35)(22)(21)(8)(10)(42)(49)}

我要回帖

更多关于 梦塔防 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信