如何用cocos2d-x来开发简单的Uphone游戏:(三) 射击子弹 碰撞检测
五、射击子弹
首先,我们先让这游戏里唯一的图层可以支持触摸。添加下面一行到init方法:
// cpp with cocos2d-x
this->setIsTouchEnabled(true); |
// objc with cocos2d-iphone
self.isTouchEnabled = YES; |
因为图层已经支持触摸,所以我们可以收到触摸事件的回调。现在我们实现ccTouchesEnded方法,只要用户完成触摸,该方法就会被调用。
先在HelloWorldScene.h里增加函数声明 void ccTouchesEnded(cocos2d::NSSet* touches, cocos2d::UIEvent* event);
然后到HelloWorldScene.cpp里增加函数实现
// cpp with cocos2d-x
void HelloWorld::ccTouchesEnded(NSSet* touches, UIEvent* event) { // Choose one of the touches to work with CCTouch* touch = (CCTouch*)( touches->anyObject() ); CGPoint location = touch->locationInView(touch->view()); location = CCDirector::getSharedDirector()->convertToGL(location); // Set up initial location of projectile // Determinie offset of location to projectile // Bail out if we are shooting down or backwards // Ok to add now - we've double checked position // Determine where we wish to shoot the projectile to // Determine the length of how far we're shooting // Move projectile to actual endpoint callfuncN_selector(HelloWorld::spriteMoveFinished)), |
// objc with cocos2d-iphone
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // Choose one of the touches to work with UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:[touch view]]; location = [[CCDirector sharedDirector] convertToGL:location]; // Set up initial location of projectile CGSize winSize = [[CCDirector sharedDirector] winSize]; CCSprite *projectile = [CCSprite spriteWithFile:@"Projectile.png" rect:CGRectMake(0, 0, 20, 20)]; projectile.position = ccp(20, winSize.height/2); // Determine offset of location to projectile int offX = location.x - projectile.position.x; int offY = location.y - projectile.position.y; // Bail out if we are shooting down or backwards if (offX <= 0) return; // Ok to add now - we've double checked position [self addChild:projectile]; // Determine where we wish to shoot the projectile to selector:@selector(spriteMoveFinished:)], |
编译后,带头大哥就可以BIU~BIU~地扔飞镖出去了。这里会产生一些float和int隐式转换导致的warning,我们为了和objc代码保持一致而在坐标计算里使用了不少int变量,实际上全部用float会更合适。
六、碰撞检测
光扔飞镖是杀不死人的,我们还需要加入碰撞检测。要做到这一点,首先得在场景中更好地跟踪目标和子弹。
在这个游戏中,我们得为小怪和飞镖两种sprite加入一个tag成员变量,以区分两种不同的游戏物体。tag=1的时候这个CCSprite对象为小怪,tag=2的时候则为飞镖。由于在CCNode里面有m_nTag这个成员变量,并且有setTag和getTag方法,因此CCSprite就继承了这些方法,我们可以利用之。
修改完毕,现在可以专心地跟踪小怪和飞镖了。把以下代码添加到class HelloWorld的声明中
// cpp with cocos2d-x
protected: cocos2d::NSMutableArray<cocos2d::CCSprite*> *_targets; cocos2d::NSMutableArray<cocos2d::CCSprite*> *_projectiles; |
// objc with cocos2d-iphone
NSMutableArray *_targets; |
在这里,cocos2d-x模拟iOS的SDK实现了NSMutableArray,里面只能放NSObject及其子类。但不同的是,你必须告诉他里面要放的是哪种具体类型。
然后在init方法中初始化这两个数组
// cpp with cocos2d-x
// Initialize arrays _targets = new NSMutableArray<CCSprite*>; _projectiles = new NSMutableArray<CCSprite*>; |
// objc with cocos2d-iphone
// Initialize arrays _targets = [[NSMutableArray alloc] init]; _projectiles = [[NSMutableArray alloc] init]; |
同时在类的析构函数里释放之. 严谨地说,我们还应在class HelloWorld的构造函数里初始化_targets和_projectiles两个指针为NULL
// cpp with cocos2d-x
HelloWorld::~HelloWorld() { if (_targets) { _targets->release(); _targets = NULL; } if (_projectiles) HelloWorld::HelloWorld() |
// objc with cocos2d-iphone
- (void) dealloc { [_targets release]; _targets = nil; [_projectiles release]; // don't forget to call "super dealloc" |
现在修改addTarget方法,添加新目标到目标数组中,并给它设置Tag标记以和飞镖sprite区分开来
// cpp with cocos2d-x
// Add to targets array taget->setTag(1); _targets->addObject(target); |
// objc with cocos2d-iphone
// Add to targets array target.tag = 1; [_targets addObject:target]; |
然后,修改spriteMoveFinished方法,根据标记的不同,在对应的数组中移除精灵
// cpp with cocos2d-x
void HelloWorld::spriteMoveFinished(CCNode* sender) { CCSprite *sprite = (CCSprite *)sender; this->removeChild(sprite, true); if (sprite->getTag() == 1) // target |
// objc with cocos2d-iphone
-(void)spriteMoveFinished:(id)sender { CCSprite *sprite = (CCSprite *)sender; [self removeChild:sprite cleanup:YES]; if (sprite.tag == 1) // target { [_targets removeObject:sprite]; } else if (sprite.tag == 2) // projectile { [_projectiles removeObject:sprite]; } } |
编译并运行项目以确保一切正常。此时还看不出什么明显不同,但我们可以利用前面加的tag标记来实现碰撞检测
现在往class HelloWorld里添加一个update方法,计算碰撞,并让碰撞了的飞镖和小杂兵同时从屏幕消失
// cpp with cocos2d-x
void HelloWorld::update(ccTime dt) { NSMutableArray<CCSprite*> *projectilesToDelete = new NSMutableArray<CCSprite*>; for (it = _projectiles->begin(); it != _projectiles->end(); it++) NSMutableArray<CCSprite*>*targetsToDelete =new NSMutableArray<CCSprite*>; for (jt = targetsToDelete->begin(); jt != targetsToDelete->end(); jt++) if (targetsToDelete->count() >0) for (it = projectilesToDelete->begin(); it != projectilesToDelete->end(); it++) |
// objc with cocos2d-iphone
- (void)update:(ccTime)dt { NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init]; for (CCSprite *projectile in _projectiles) CGRect projectileRect = CGRectMake( NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init]; for (CCSprite *target in _targets) [_targets removeObject:target]; [_projectiles removeObject:projectile]; |
上面有个注意点,我们用来检查矩形交叉的函数。实际上各平台都有用来检查矩形相交的函数,我们这里为了方便iphone开发者转换代码,实现了静态的CGRect::CGRectInterestcRect方法。上面的代码大致就是,遍历小怪和飞镖数组,一旦发现有矩形相交(碰撞),就把他们分别添加到targetsToDelete和projectileToDelete数组中,然后删除之
在运行之前,你还需要让这个update方法不断地被调用,可以在init方法中添加如下代码达成这个目的
// cpp with cocos2d-x
this->schedule( schedule_selector(HelloWorld::update) ); |
// objc with cocos2d-iphone
[self schedule:@selector(update:)]; |
编译运行,你就可以看到飞镖和小怪碰撞时,它们同时从屏幕消失了。
至此,一个简单cocos2d游戏的雏形就已经完成了。在下一篇里,我们会对这个游戏进行最后的润色,添加背景音乐和音效,已经过关和GAME OVER的提示界面。
本文转自Walzer博客园博客,原文链接:http://www.cnblogs.com/walzer/archive/2010/10/11/1848106.html,如需转载请自行联系原作者
如何用cocos2d-x来开发简单的Uphone游戏:(三) 射击子弹 碰撞检测相关推荐
- 如何用cocos2d-x来开发简单的Uphone游戏:(二) 移动的精灵
三.添加一个精灵 我们先用个简单的方式,把player, projectile, target三个PNG文件拷贝到 D:\Work7\NEWPLUS\TDA_DATA\UserData 目录下,这使其 ...
- [20110209]Cocos2dSimpleGame入门系列《如何用cocos2d-x来开发简单的Uphone游戏》学习小记
原文: http://www.cnblogs.com/walzer/archive/2010/10/10/1847089.html 拜读王哲王总的cocos2d-x入门教程,将学习过程中对C++或co ...
- 翻译:如何用Cocos2d来开发简单的IPhone游戏教程
这一周接触到Cocos2D开发,在它的官网上看到Ray Wenderlic写的关于cocos2d开发的文章,感觉写的挺好,翻译了一下. 原文链接地址大家可以在上面看到作者的更多内容 初次翻译文章,望 ...
- Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 2
本文是"使用Cocos2D 3.x开发横版动作游戏"系列教程的第二篇,同时也是最后一篇.是对How To Make A Side-Scrolling Beat Em Up Game ...
- Cocos2D教程:使用SpriteBuilder和Cocos2D 3.x开发横版动作游戏——Part 1
本文是对教程How To Make A Side-Scrolling Beat Em Up Game Like Scott Pilgrim with Cocos2D – Part 1的部分翻译,加上个 ...
- 如何使用cocos2d-x 3.0来做一个简单的iphone游戏教程(第一部分)
游戏截图: cocos2d-x 是一个支持多平台的开源框架,用于构建游戏.应用程序和其他图形界面交互应用.Cocos2d-x项目可以很容易地建立和运行在iOS,Android的三星Bada,黑莓Bla ...
- HiLink LiteOS IoT芯片 让IoT开发简单高效
HiLink & LiteOS & IoT芯片 让IoT开发简单高效 华为HiLink & LiteOS & IoT芯片使能三件套,让IoT开发更简单高效.下一代智能手 ...
- Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏
Unity 2D游戏开发快速入门第1章创建一个简单的2D游戏 即使是现在,很多初学游戏开发的同学,在谈到Unity的时候,依然会认为Unity只能用于制作3D游戏的.实际上,Unity在2013年发布 ...
- 记事本写python怎么运行-Python开发简单记事本
摘要: 本文是使用Python,结合Tkinter开发简单记事本. 本文的操作环境:ubuntu,Python2.7,采用的是Pycharm进行代码编辑,个人很喜欢它的代码自动补齐功能. 最近很想对p ...
- python一般用来开发什么-python主要用来做什么?Python开发简单吗?
python主要用来做什么?Python开发简单吗?Python技术可做web开发.Python技术可做数据分析.Python技术可做人工智能.将Python用于机器学习,流行的Python机器学习库 ...
最新文章
- 硬科技凭什么产业化?
- 问得最多的十个JavaScript前端面试问题
- 牛顿迭代法(Newton's Method)
- MySQL数据库Innodb储存引擎----储存页的结构
- OpenCASCADE:形状愈合之用于修复、分析和升级的辅助工具
- 政企边缘安全,如何助您提升企业免疫力?
- Android异步处理:Handler+Looper+MessageQueue深入详解
- python里如何计算大文件的md5
- Linux 5.10 LTS 发布,支持到 2026 年
- JavaWab项目1 ---- 技术架构
- 信么?PrintDemon 漏洞影响自1996年起发布的所有 Windows 版本
- 鸿蒙os2.0官网公测报名,鸿蒙OS2.0公测版测试资格报名-鸿蒙OS2.0公测版测试资格报名官网地址预约 -友情手机站...
- 烧录工具Android Tool的使用
- 微信小程序tab切换,可滑动切换,导航栏跟随页面滚动
- QOne、QData开关机操作
- maven Web项目中POM的配置信息
- 【缓存】@CacheEvict
- Redis之EXPIRE
- 如何查看.o和.exe文件
- Windows 源码编译 nginx (加入nginx-http-flv-module)