cocos2d 小游戏

今天写了一个小游戏,发现看过的代码自己来写还是会经常出错,还是要多自己动手写写哈。

先上几张游戏界面图

void HelloWorld::addTarget()
{
    //首先初始化精灵
    CCSprite *pTarget = CCSprite::create("Target.png");
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    //计算可绘制的范围
    int minY = pTarget->getContentSize().height/2;
    int maxY = winSize.height - minY;
    //计算可随机基数
    int rangeY = maxY - minY;
    //随机出的数*随机基数+半个身位 = 最后的坐标点
    int actualY = (rand() % rangeY) + minY;
    pTarget->setPosition(ccp(winSize.width + pTarget->getContentSize().width/2 ,actualY));
    this->addChild(pTarget);
    pTarget->setTag(1);
    _targets->addObject(pTarget);

    //计算移动速度 最慢4秒移动横屏 最快2秒
    int minDuration = (int) 2.0;
    int maxDuration = (int) 4.0;
    int rangeDuration = maxDuration - minDuration;
    int actualDuration = (rand() % rangeDuration) +minDuration;

    //初始化耗时动作
    CCFiniteTimeAction* actionMove =
        CCMoveTo::create((float)actualDuration,
        ccp(0 - pTarget->getContentSize().width/2,actualY));
    CCFiniteTimeAction* actionMoveDone =
        CCCallFuncN::create(this,
        callfuncN_selector(HelloWorld::spriteMoveFinished));

    //绑定动作
    pTarget->runAction(CCSequence::create(actionMove,actionMoveDone,NULL));
}

这是怪物随机从右边向左边移动的代码,到左边后回调方法spriteMoveFinished。

void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event)
{
    CCTouch *touch = (CCTouch *)touches->anyObject();
    CCPoint location = touch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
    CCSize size = CCDirector::sharedDirector()->getWinSize();
    CCSprite *pProjectile = CCSprite::create("Projectile.png");
    pProjectile->setPosition(ccp(pHero->getContentSize().width/2,size.height/2));

    int offX = location.x - pProjectile->getPosition().x;
    int offY = location.y - pProjectile->getPosition().y;

    if(offX <= 0) return;
    //添加发子弹声音
    CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect(
                            "pew-pew-lei.wav"); 

    this->addChild(pProjectile);
    pProjectile->setTag(2);
    _projectiles->addObject(pProjectile);

    int realX = size.width +
        (pProjectile->getContentSize().width/2);
    float ratio = (float)offY / (float)offX;
    int realY = (realX * ratio) + pProjectile->getPosition().y;
    CCPoint realDest = ccp(realX,realY);

    int offRealX = realX - pProjectile->getPosition().x;
    int offRealY = realY - pProjectile->getPosition().y;
    float length = sqrtf((offRealX * offRealX) + (offRealY*offRealY));
    
    float velocity = 480/1;
    float realMoveDuration = length/velocity;

    pProjectile->runAction(CCSequence::create(
        CCMoveTo::create(realMoveDuration,realDest)
        ,CCCallFuncN::create(this,callfuncN_selector(HelloWorld::spriteMoveFinished))
        ,NULL));
}

这是触摸后发射子弹,子弹发射后到右边也是回调方法spriteMoveFinished。

void HelloWorld::spriteMoveFinished(CCNode* sender)
{
    CCSprite *pSprite = (CCSprite *)sender;
    this->removeChild(pSprite,true);

    //当怪物走屏幕左边,显示失败界面
    if (pSprite->getTag() == 1)
    {
        _targets->removeObject(pSprite);
        GameOverScene *gameOverScene =(GameOverScene*) GameOverScene::create();
        if(gameOverScene){
            gameOverScene->getLabel()->setString("You Lose!");
            CCScene *pScene = CCScene::create();
            pScene->addChild(gameOverScene);
            CCDirector::sharedDirector()->replaceScene(pScene);
        }
    }else if (pSprite->getTag() == 2)
    {
        _projectiles->removeObject(pSprite);
    }
}

这是怪物和子弹的回调方法,怪物走到左边,remove怪物、从数组中删除并显示失败界面;子弹飞到右边,也是remove掉子弹并从数组中删除。

void HelloWorld::update(float dt)
{
    CCLOG("%f",dt);
    CCArray *projectilesToDelete =
        CCArray::create();
    projectilesToDelete->retain();
    //碰撞算法

    //循环遍历 怪物的数字内的所有对象
    for(int i = 0;i < _projectiles->count();i++)
    {
        //取出第i个对象 转化为精灵对象指针
        CCSprite *projectile = (CCSprite *)_projectiles->objectAtIndex(i);
        //获取这个对象的区域
        CCRect projectileRect = CCRectMake(projectile->getPosition().x -(projectile->getContentSize().width/2),
            projectile->getPosition().y - (projectile->getContentSize().height/2),
            projectile->getContentSize().width,
            projectile->getContentSize().height
            );
        //创建存放子弹的数组
        CCArray *targetsToDelete = CCArray::create();
        targetsToDelete->retain();
        //循环遍历 怪物数组对象
        for(int j = 0;j < _targets->count();j++)
        {
             //取出第j个对象的指针
            CCSprite *target = (CCSprite *)_targets->objectAtIndex(j);
            CCRect targetRect = CCRectMake(target->getPosition().x -(target->getContentSize().width/2),
            target->getPosition().y - (target->getContentSize().height/2),
            target->getContentSize().width,
            target->getContentSize().height);
            //如果两个范围有交集
            if(projectileRect.intersectsRect(targetRect))
            {
                targetsToDelete->addObject(target);
            }
            
        }
        for(int k = 0;k < targetsToDelete->count();k++)
        {
            CCSprite *target =(CCSprite *)targetsToDelete->objectAtIndex(k);
            _targets->removeObject(target);
            this->removeChild(target,true);
            _projectilesDestroyed++;
            //打中超过4个怪物,跳转到获胜界面
            if (_projectilesDestroyed > 4)
            {
                GameOverScene *gameOverScene =(GameOverScene*) GameOverScene::create();
                if(gameOverScene){
                    gameOverScene->getLabel()->setString("You Win!");
                    CCScene *pScene = CCScene::create();
                    pScene->addChild(gameOverScene);
                    CCDirector::sharedDirector()->replaceScene(pScene);
                }
            }
                
        }
        if(targetsToDelete->count() > 0)
        {
            projectilesToDelete->addObject(projectile);
        }
        //循环遍历 移除对象
        for (  int i=0;i< projectilesToDelete->count();i++)
        {
            CCSprite* projectile =(CCSprite *)projectilesToDelete->objectAtIndex(i);
            _projectiles->removeObject(projectile);
            this->removeChild(projectile, true);
        }
    }
}

上面这个是检测子弹跟怪物是否碰撞,有碰撞分别把它们都remove掉。

源码及资源下载链接:http://pan.baidu.com/s/1kTHr5DP

原文地址:https://www.cnblogs.com/ycclmy/p/3971709.html