搜索
您的当前位置:首页正文

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

2020-11-09 来源:欧得旅游网

头文件 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 <= 0 )return;


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();
}

Top