结合物理引擎的cocos2dx游戏(保卫果树)
physic是coco2dx3.0自带的物理引擎,应付一般的需求已经足够啦。项目地址:https://github.com/frank1982/Fruits核心代码:_arrowArray=Array::create(); _arrowArray->retain(); _birdArray=Array::create(); _birdArray
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)->getCString();
_scoreLabel->setString(str);
return true;
}
//射中小鸟后,小鸟落地,得分;
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)