[转注自官网]Cocos2d-x Tutorial 5 - 碰撞检测(Glede Edition for 2.0.3)

2023-05-16

Chapter5 – 碰撞检测

主人公能够放子弹了,虽然子弹看起来很美,但是怎么样来打到妖怪?

在这一章我们介绍一下最简单的碰撞检测方法去实现它。

首先第一个,我们有必要保存每个妖怪和子弹的指针,来够追踪他们的位置。

在这个游戏中我们增加两个tag标志去辨别CCNode对象是子弹还是妖怪。tag == 1表示他是一个妖怪,tag == 2 表示他是一个子弹。CCNode有一个m_nTag属性,我们可以使用getTag()/setTag()来访问它,CCSprite是CCNode的子类,我们可以利用这个。

先在HellowWorld类中添加两个成员变量来存储,在HelloWorldScene.h里声明一下。


    // cpp with cocos2d-x
protected:
    cocos2d::CCArray *_targets;
    cocos2d::CCArray *_projectiles;      

译注:原文中使用的CCMutableArray……但是在新版本中已经被直接废弃了,我们现在使用CCArray,他也是可变长数组,没有模板功能,使用时需要强制转换。

同时,在HelloWorldScene.h里声明HelloWorld的构造函数和析构函数,在HelloWorldScene.cpp里进行初始化:


HelloWorld::~HelloWorld()
{
    //cocos2d定义的宏,它等价于以下代码
    //if (_targets)
    //{
    //  _targets->release();
    //  _targets = NULL;
    //}
    CC_SAFE_RELEASE_NULL(_targets);
    CC_SAFE_RELEASE_NULL(_projectiles);

    // 记得把析构函数声明为虚函数
}

HelloWorld::HelloWorld():_targets(NULL)
    ,_projectiles(NULL)
{
    _targets = new CCArray();
    _projectiles = new CCArray(); 
}      

 

然后修改一下addTarget方法,在方法的最后,设置妖怪的tag,并且加入到数组里:


    // cpp with cocos2d-x
    // Add to targets array
    target->setTag(1);
    _targets->addObject(target);     

 

同理在 ccTouchesEnded 方法最后,设置子弹的tag并且加入到数组


    // cpp with cocos2d-x
    // 设置tag并且加入到数组
    projectile->setTag(2);
    _projectiles->addObject(projectile);    

 

然后还要修改一下spriteMoveFinished方法,因为在他们被从父节点中移除的同时,也需要将他们从数组中移除。


// cpp with cocos2d-x
void HelloWorld::spriteMoveFinished(CCNode* sender)
{
    CCSprite *sprite = (CCSprite *)sender;
    this->removeChild(sprite, true); 

    // 从 tag 判断类型从对应的数组中移除
    if (sprite->getTag() == 1)  
    {
        _targets->removeObject(sprite);
    }
    else if (sprite->getTag() == 2) 
    {
        _projectiles->removeObject(sprite);
    }
}  

 

下面的update方法将检查碰撞,并且移除碰撞的子弹和妖怪。


// cpp with cocos2d-x
void HelloWorld::update(float dt)
{
    CCArray* projectilesToDelete = new CCArray();
    CCObject* pobject;

    // cocos2d定义的宏,提供方便的只读遍历CCARRAY写法
    CCARRAY_FOREACH(_projectiles, pobject)
    {
        CCSprite* projectile = (CCSprite*)pobject;
        CCRect pRect = CCRect(projectile->getPosition().x - projectile->getContentSize().width/2, 
                              projectile->getPosition().y - projectile->getContentSize().height/2, 
                              projectile->getContentSize().width, 
                              projectile->getContentSize().height);     

        CCArray* targetsToDelete = new CCArray();
        CCObject* tobject;
        CCARRAY_FOREACH(_targets, tobject)
        {
            CCSprite* target = (CCSprite*)tobject;
            CCRect tRect = CCRect(target->getPosition().x - target->getContentSize().width/2, 
                                  target->getPosition().y - target->getContentSize().height/2, 
                                  target->getContentSize().width, 
                                  target->getContentSize().height);
            
            // 碰撞测试
            if( pRect.intersectsRect( tRect ) )
            {
                targetsToDelete->addObject( target );
            }
        }

        // 移除被击中的目标
        CCARRAY_FOREACH(targetsToDelete, tobject)
        {
            CCSprite* target = (CCSprite*)tobject;
            _targets->removeObject(target);
            this->removeChild(target, true);
        }

        // 记录击中目标的子弹
        if(targetsToDelete->count() > 0)
        {
            targetsToDelete->addObject(projectile);
        }
        
        /* 由于我们是用的 new CCArray() 而非 CCArray::create()
        获得的数组对象,所以需要手动调用release */
        targetsToDelete->release();
    }

    // 移除击中目标的子弹
    CCARRAY_FOREACH(projectilesToDelete, pobject)
    {
        CCSprite* projectile = (CCSprite*)pobject;
        _projectiles->removeObject(projectile, true);
        this->removeChild(projectile, true);
    }

    projectilesToDelete->release();
}      

 

OK~最后我们在HelloWorld::init方法最后添加一行代码,让游戏在每秒钟60次的刷新画面时调用HelloWorld::update方法


        this->scheduleUpdate();  

 

大功告成!生成运行一下,看看是不是一打一个准!

转载于:https://www.cnblogs.com/buaashine/archive/2012/10/23/2735315.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[转注自官网]Cocos2d-x Tutorial 5 - 碰撞检测(Glede Edition for 2.0.3) 的相关文章

随机推荐