您的位置:首页 > 移动开发 > Cocos引擎

结合物理引擎的cocos2dx游戏(保卫果树)

2014-12-09 14:24 351 查看
physic是coco2dx3.0自带的物理引擎,应付一般的需求已经足够啦。

项目地址:
https://github.com/frank1982/Fruits
核心代码:

_arrowArray=Array::create();
    _arrowArray->retain();
    _birdArray=Array::create();
    _birdArray->retain();
设置小鸟和弓箭的存贮array;

 auto layer = GameScene::create();
    layer->setPhyWorld(scene->getPhysicsWorld());
设置物理世界;

 
    auto listener =
EventListenerTouchOneByOne::create();
    listener->setSwallowTouches(true);
    
    auto contactListener=EventListenerPhysicsContact::create();
    //设置监听器的碰撞开始函数
    contactListener->onContactBegin =
CC_CALLBACK_1(GameScene::onContactBegin,
this);
    //添加到事件分发器中
    _eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener,
this);
设置物理碰撞(小鸟和弓箭)和触摸检测;

auto str=String::createWithFormat("SCORE: %d",SCORE);
    _scoreLabel=LabelTTF::create(str->getCString(),
"Arial", 40);
    _scoreLabel->setPosition(visibleSize.width/2,visibleSize.height-_scoreLabel->getContentSize().height);
    _scoreLabel->setColor(Color3B::GREEN);
    addChild(_scoreLabel,2);
//计算得分;

 auto str2=String::createWithFormat("X %d",FRUITS_NUM);
    _fruitNum=LabelTTF::create(str2->getCString(),
"Arial", 40);
    _fruitNum->setPosition(fruit->getPosition()+Point(50,0));
    _fruitNum->setColor(Color3B::RED);
    addChild(_fruitNum,2);
//计算剩余果实的数量;

    listener->onTouchBegan=[&](Touch* touch,
Event* event){
        
        struct  timeval tv;
        gettimeofday(&tv,NULL);
        _curTouchTime=tv.tv_sec *
1000 + tv.tv_usec /
1000;
        
        if(_curTouchTime-_preTouchTime>=500){
            
            _pointTouch=touch->getLocation();
            Point shootVector =
_pointTouch-_bowl->getPosition();
            Point normalizedVector =
ccpNormalize(shootVector) ;
            float radians =
atan2(normalizedVector.y, - normalizedVector.x);
            float degree =
CC_RADIANS_TO_DEGREES(radians);
            _bowl->setRotation(degree);
            _preTouchTime=_curTouchTime;
            return true;
            
        }else{
            
            CCLOG("too much touch");
            return false;
        }
    };
//当检测到触摸时,旋转弓箭的角度,并且500毫秒内只允许点击一次;

listener->onTouchEnded=[&](Touch* touch,
Event* event){
        
        //shoot the arrow
        SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
        SimpleAudioEngine::sharedEngine()->playEffect("music/shoot.mp3");

//播放射击音效;
        Point shootVector =
_pointTouch-_bowl->getPosition();
        Point normalizedVector =
ccpNormalize(shootVector) ;
        CCLog("x speed is: %f, y speed is: %f",shootVector.x,shootVector.y);
        _arrow=Sprite::create("Arrow.png");
        _arrow->setTag(1);
        addChild(_arrow);
        //加载弓箭精灵;
        
        _arrow->setPosition(_bowl->getPosition());
        _arrow->setScale(arrow_scale);
        _arrow->setRotation(_bowl->getRotation());
        auto body=PhysicsBody::createBox(_arrow->getContentSize()*arrow_scale);
        body->setMass(1.0f);
        body->setCategoryBitmask(0x00000010);
        body->setContactTestBitmask(0x00000001);
        body->setCollisionBitmask(0x00000001);
//设置物理检测参数,弓箭和小鸟会发生碰撞;
        _arrow->setPhysicsBody(body);
        _arrow->getPhysicsBody()->setVelocity(Vect(normalizedVector.x*_arrowSpeed,normalizedVector.y*_arrowSpeed));
        _arrow->getPhysicsBody()->setGravityEnable(true);
        //设置初速度,和弓箭的旋转方向一致;
        //_arrowArray=Array::create();
        _arrowArray->addObject(_arrow);
        CCLog("_arrowArray length is %zd",_arrowArray->count());
     };
    
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);

void GameScene::loadBirds(float dt){
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    enum
birdType type[7]={Blue,Yellow,Green,Grey,Red,Orange,Coffee};
    int index=(int)(CCRANDOM_0_1()*7);
    auto birdSp=Bird::createBird(type[index]);
    
    //random enter position;
    float PY=(float)(CCRANDOM_0_1()*visibleSize.height);
    birdSp->setPosition(0,PY);
    
    
    addChild(birdSp,1);
    _birdArray->addObject(birdSp);
    auto fruit=this->getChildByTag(21);
    
    //random speed;
    float Speed=(float)(CCRANDOM_0_1()*2.5+3);
    auto seq=Sequence::create(MoveTo::create(Speed, fruit->getPosition()),
DelayTime::create(1.2),CallFunc::create(CC_CALLBACK_0(GameScene::eatApple,
this)),
                              MoveTo::create(2,
Point(visibleSize.width,fruit->getPosition().y)),NULL);
    birdSp->runAction(seq);
    CCLOG("bird number is %zd",_birdArray->count());

}
//这里随机会出现一只小鸟,速度和位置都不确定,小鸟会飞到树上停留一下,吃掉苹果;

void GameScene::update(float dt){
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    auto rectWin=CCRectMake(0,
0, visibleSize.width, visibleSize.height);

    for(int i=0;i<_arrowArray->count();i++){
        
        auto sp=dynamic_cast<Sprite *>(_arrowArray->getObjectAtIndex(i));
        
        //check if out of window;
        if(sp->getPosition().x<=0||sp->getPosition().y>=visibleSize.height||sp->getPosition().x>=visibleSize.width||sp->getPosition().y<=0){
            
            //sp->setVisible(false);
            sp->removeAllChildren();
            this->removeChild(sp);
            _arrowArray->removeObjectAtIndex(i);
            CCLog("_arrowArray length is %zd",_arrowArray->count());
        }
    }
    for(int j=0;j<_birdArray->count();j++){
        
        auto sp2=dynamic_cast<Sprite *>(_birdArray->getObjectAtIndex(j));
        
        //check if out of window;
        if(sp2->getPosition().x>=visibleSize.width||sp2->getPosition().y<=0){
            
            sp2->removeAllChildren();
            this->removeChild(sp2);
            _birdArray->removeObjectAtIndex(j);
            CCLog("_birdArray length is %zd",_birdArray->count());
        }
    }
    
}
//检测小鸟和弓箭是否越出边界;

bool GameScene::onContactBegin(const
PhysicsContact& contact){
    
    CCLOG("get bound");
    auto cnt = const_cast<PhysicsContact*>(&contact);
    auto spA = cnt->getShapeA()->getBody()->getNode();
    auto spB = cnt->getShapeB()->getBody()->getNode();
    int tagA = spA->getTag();
    int tagB = spB->getTag();
    if(tagA == 2) {
        
        spA->getPhysicsBody()->setGravityEnable(true);
        spA->getPhysicsBody()->setVelocity(Point(0,-300));
        spB->removeAllChildren();
        this->removeChild(spB);
        _arrowArray->removeObject(spB);
        CCLog("_arrowArray length is %zd",_arrowArray->count());
        
    }else if(tagB ==
2){
        
        spB->getPhysicsBody()->setGravityEnable(true);
        spB->getPhysicsBody()->setVelocity(Point(0,-300));
        this->removeChild(spA);
        _arrowArray->removeObject(spA);
        CCLog("_arrowArray length is %zd",_arrowArray->count());
        
    }
    SCORE+=5;
    auto str=String::createWithFormat("SCORE: %d",SCORE)-
aac7
>getCString();
    _scoreLabel->setString(str);

    return true;
}
//射中小鸟后,小鸟落地,得分;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cocos2dx xcode 手游 苹果