欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

COCOS2D-X自带的DEMO解析和理解

程序员文章站 2022-05-12 09:47:39
...

头文件 class GameScene : public cocos2d::CCLayerColor{ public: GameScene(void); ~GameScene(void); virtual bool init();//继承多态,可重写 static cocos2d::CCScene* scene();//返回一个场景 virtual void menuClose(cocos2d::CCObject *obj);//退出

头文件

class GameScene : public cocos2d::CCLayerColor{

public:


GameScene(void);


~GameScene(void);


virtual bool init();//继承多态,可重写


static cocos2d::CCScene* scene();//返回一个场景


virtual void menuClose(cocos2d::CCObject *obj);//退出按钮回调的处理函数


CREATE_FUNC(GameScene);//创建create()函数,并返回当前类的一个实列指针


void spriteMoveFinished(cocos2d::CCNode *node);//游戏状态:1、表示失败,进入失败场景,2:表示删除小子弹和小怪


void gameLogic(float dt);//增加子小怪,游戏的逻辑


void updateGame(float dt);//更新游戏,增加角色发射的子弹


//重写父类的点击方法
void registerWithTouchDispatcher();//注册触控事件接收




//点击事件
virtual void ccTouchesBegan(cocos2d::CCSet *pTouches, cocos2d::CCEvent *pEvent);
virtual void ccTouchesEnded(cocos2d::CCSet *touches,cocos2d::CCEvent *event);


protected:
cocos2d::CCArray *_targets;//小怪
cocos2d::CCArray *_projectiles;//子弹
int _projectilesDestoryed;//打死小怪的数量
void addTarget();//增加子弹

};


GameScene::GameScene()
:_targets(NULL),
_projectiles(NULL),
_projectilesDestoryed(0){


}


GameScene::~GameScene(){
//敌人
if(this->_targets){


this->_targets->release();


this->_targets=NULL;
}


if(this->_projectiles){

this->_projectiles->release();


this->_projectiles = NULL;

}
}




CCScene* GameScene::scene(){


CCScene *scene = NULL;


do{

scene = CCScene::create();//创建场景
CC_BREAK_IF(!scene);//没有创建成功,就break

GameScene *layer = GameScene::create();//创建图层
CC_BREAK_IF(!layer);//没有创建成功,就break


scene->addChild(layer);//把图层增加到场景
}while(0);


return scene;
}


bool GameScene::init(){


bool flag = false;


do{

//先初始化父类
if(!CCLayerColor::initWithColor(ccc4(255,255,255,255)))return false;

CCDirector *director = CCDirector::sharedDirector();
CCSize size = director->getVisibleSize();
CCPoint origin = director->getVisibleOrigin();


CCMenuItemImage *closeItem = CCMenuItemImage::create(
"CloseNormal.png",
"CloseSelected.png",
this,
menu_selector(GameScene::menuClose));
CC_BREAK_IF(!closeItem);


closeItem->setPosition(ccp(size.width-closeItem->getContentSize().width/2,
closeItem->getContentSize().height/2));




CCMenu *menu = CCMenu::create(closeItem,NULL);
CC_BREAK_IF(!menu);
menu->setPosition(CCPointZero);


this->addChild(menu,1);
CCSprite *player = CCSprite::create("Player.png",CCRectMake(0,0,27,40));
//CCSprite *player = CCSprite::create("hd/Player.png");
//居中最左边
player->setPosition(ccp(player->getContentSize().width/2,
size.height/2));
this->addChild(player);
//更新精灵的发射子弹状态
this->schedule(schedule_selector(GameScene::gameLogic),1.0);

//开启点击控制
this->setTouchEnabled(true);


//创建小怪的数组
_targets = new CCArray;
//创建角色所发射的子弹的数组
_projectiles = new CCArray;

//增加怪物
this->schedule(schedule_selector(GameScene::updateGame));

//播放指定文件,并循环播放
CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav", true);

flag = true;


}while(0);
return flag;
}


void GameScene::registerWithTouchDispatcher(){
CCLog("GameScene::registerWithTouchDispatcher");
CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);
//CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);
}


void GameScene::gameLogic(float dt){
//增加敌人
this->addTarget();
}


void GameScene::addTarget(){
CCLog("GameScene::addTarget");
//小怪
CCSprite *target = CCSprite::create("Target.png",
CCRectMake(0,0,27,40));
//场景大小
CCSize size = CCDirector::sharedDirector()->getVisibleSize();


//出现小怪,在场景中去区域
float minY = target->getContentSize().height/2;
float maxY = size.height - target->getContentSize().height/2;
//只能强转指针类型的dynamic_cast(maxY-minY);
int rangeY = (int)(maxY-minY);


//获得在场景中的一个位置
int actualY = rand() % rangeY + (int)minY;
//设置当前小怪在场景中的位置
target->setPosition(ccp(
size.width + (target->getContentSize().width/2),
actualY
));
//增加到场景
this->addChild(target);


//增加到事件动画
int minDuration = 2;
int maxDuration = 4;
int rangeDur = maxDuration - minDuration;


//移动的速度
int actualDur = rand()%rangeDur + minDuration;


//CCFiniteTimeAction是CCMoveTo的父类,父类的指针,指向子类
CCFiniteTimeAction *move = CCMoveTo::create((float)actualDur,
ccp(0-target->getContentSize().width/2,actualY));//第一个参数:时间,目标位置
//运行目标点时,要回调的函数
CCFiniteTimeAction *moveDone = CCCallFuncN::create(
this,
callfuncN_selector(GameScene::spriteMoveFinished)
);
//激活事件
target->runAction(CCSequence::create(move,moveDone,NULL));


target->setTag(1);//设置标记
//增加到数组中
this->_targets->addObject(target);
}


void GameScene::updateGame(float dt){
//CCLog("GameScene::updateGame(float dt)");


//CCLog("_projectiles:count=%d",_projectiles->count());
//CCLog("_targets:count=%d",_targets->count());


//______________________迭代子弹____________________________
//要删除的子弹的数组
CCArray *bulletDelete = new CCArray;
CCObject *obj1 = NULL;
CCObject *obj2 = NULL;
//迭代数组中存放的子弹
CCARRAY_FOREACH(this->_projectiles,obj1){
//CCLog("_projectiles:obj=%p",obj1);
//动态类型转换把CCObject * 转换成CCSprite*
CCSprite *bullet = dynamic_cast(obj1);
//角色的绘制区域
CCRect bulletRect = CCRectMake(
bullet->getPosition().x-(bullet->getContentSize().width/2),
bullet->getPosition().y-(bullet->getContentSize().height/2),
bullet->getContentSize().width,
bullet->getContentSize().height );


//______________________迭代小怪____________________________


//要删除的小怪数组
CCArray *monsterDelete = new CCArray;
//迭代数组中存放的小怪
CCARRAY_FOREACH(this->_targets,obj2){
//CCLog("_targets:obj=%p",obj2);
//获取小怪的一个对象指针
CCSprite *target = dynamic_cast(obj2);
//获取小怪绘制区域
CCRect targetRect = CCRectMake(
target->getPosition().x-(target->getContentSize().width/2),
target->getPosition().y-(target->getContentSize().height/2),
target->getContentSize().width,
target->getContentSize().height );


//判断两块区域是否相交(碰撞)
if(bulletRect.intersectsRect(targetRect)){
//把当前小怪对象,增加到碰撞小怪数组中
monsterDelete->addObject(target);
}
}


//___________________打够5个小怪,胜利__________________________
obj2 = NULL;
//把碰撞过的小怪,从目标小怪数组中删除
CCARRAY_FOREACH(monsterDelete,obj2){
//CCLog("monsterDelete:obj=%p",obj2);
CCSprite *target = dynamic_cast(obj2);
this->_targets->removeObject(target);//从小怪数组中移除当前对象
this->removeChild(target);//从场景中移除当前小怪

//打死小怪数++
this->_projectilesDestoryed++;


//打死5个小怪后,进入胜利场景
if(this->_projectilesDestoryed>=5){

GameOverScene *scene = GameOverScene::create();
scene->getLayer()->getLabel()->setString("You win");
CCDirector::sharedDirector()->replaceScene(scene);

}
}


//___________________清空碰撞过的小怪__________________________


//把当前子弹对象也放到待删除的子弹数组中
if(monsterDelete->count()>0){
bulletDelete->addObject(bullet);
}
//删除存放待删除的小怪数组
monsterDelete->release();
}


//______________________清空碰撞的子弹____________________________
obj1 = NULL;
//把待删除的子弹,从子弹数组中移除
CCARRAY_FOREACH(bulletDelete,obj1){
//CCLog("bulletDelete:obj=%p",obj1);
CCSprite *bullet = dynamic_cast(obj1);
//从数组中移除子弹
this->_projectiles->removeObject(bullet);
//从场景中移除,子弹
this->removeChild(bullet,true);
}
//释放待删除子弹数组
bulletDelete->release();
}


void GameScene::spriteMoveFinished(cocos2d::CCNode *obj){
CCLog("GameScene::spriteMoveFinished");
CCSprite *sprite = (CCSprite *)obj;


this->removeChild(sprite,true);


//怪物
if(sprite->getTag()==1){
CCLog("GameScene::spriteMoveFinished:monster delete");
//从数组中移除
this->_targets->removeObject(sprite);


GameOverScene *scene = GameOverScene::create();


scene->getLayer()->getLabel()->setString("You Lose");
//等于上面一句
//GameOverLayer *layer = scene->getLayer();
//layer->getLabel()->setString("You Lose");


CCDirector::sharedDirector()->replaceScene(scene);


}else if(sprite->getTag()==2){
CCLog("GameScene::spriteMoveFinished:bullet delete");
_projectiles->removeObject(sprite);
}

}


void GameScene::ccTouchesBegan(CCSet *touches,CCEvent *event){


CCLog("GameScene::ccTouchesBegan:%p",touches->anyObject());


}
void GameScene::ccTouchesEnded(CCSet *touches,CCEvent *event){
CCLog("GameScene::ccTouchesEnded");
//CCTouch *touch = dynamic_cast(touches->anyObject);
CCTouch *touch = (CCTouch *)(touches->anyObject());
//获到当前位置
CCPoint location = touch->getLocation();


CCLog("location:x=%.2f,y=%.2f",location.x,location.y);


CCSize size = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();


CCLog("size:width=%.2f,height=%.2f",size.width,size.height);
CCLog("origin:x=%.2f,y=%.2f",origin.x,origin.y);




CCSprite *bullet = CCSprite::create("Projectile.png",CCRectMake(0,0,20,20));
bullet->setPosition(ccp(origin.x+20,origin.y+size.height/2));
CCLog("bullet->setPosition(x=%.2f,y=%.2f)",bullet->getPosition().x,bullet->getPosition().y);
//角色与点击的点之间的距离(偏移量)
float offX = location.x - bullet->getPosition().x;
float offY = location.y - bullet->getPosition().y;
CCLog("offX=%.2f,offY=%.2f",offX,offY);


//最小点击区域不能小于20
if(offX

this->addChild(bullet);//增加到场景中


//子弹的射程区域
float realX = origin.x+size.width+(bullet->getContentSize().width/2);
float ratio = offY/offX;//弧度(比率)
float realY = (realX*ratio)+bullet->getPosition().y;


CCLog("realX=%.2f,realY=%.2f,ratio=%.2f,sum = %.2f",realX,realY,ratio,realX*ratio);


//最大射程
CCPoint realDest = ccp(realX,realY);
float length = sqrtf((realX*realX)+(realY*realY));//
float velocity = 480/1;
float realMoveDuration = length/velocity;//距离/速度=时间


CCLog("length=%.2f,velocity=%.2f,realMoveDuration=%.2f",length,velocity,realMoveDuration);

CCFiniteTimeAction *move = CCMoveTo::create(realMoveDuration
,realDest);//移动事件
CCFiniteTimeAction *moveDone = CCCallFuncN::create(this,
callfuncN_selector(GameScene::spriteMoveFinished));//到达目标后,回调函数
bullet->runAction(CCSequence::create(move,moveDone,NULL));//激活事件


bullet->setTag(2);//设置标记


this->_projectiles->addObject(bullet);//增加到子弹数组中


//播放发射子弹的声音
CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pew-pew-lei.wav");
}


void GameScene::menuClose(cocos2d::CCObject *obj){
//退出游戏
CCDirector::sharedDirector()->end();
}