COCOS2D-X自带的DEMO解析和理解
头文件 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
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
//角色的绘制区域
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
//获取小怪绘制区域
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
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
//从数组中移除子弹
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
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();
}
上一篇: mysql浮点型输出格式问题
下一篇: ACCESS数据库连接字符串
推荐阅读
-
Android MeasureSpec的理解和源码的解析
-
Python编程中对super函数的正确理解和用法解析
-
CmakeLists.txt和makefiles的关系及原理解析
-
Python编程中对super函数的正确理解和用法解析
-
spring5 源码深度解析----- 事务的回滚和提交(100%理解事务)
-
Google和Facebook不使用Docker的原理解析
-
rem布局完成响应式开发,通俗且详细的原理解析和代码实现
-
JavaScript中的return布尔值的用法和原理解析
-
详解vue数组遍历方法forEach和map的原理解析和实际应用
-
一直分不清选择排序和冒泡排序,网上也好多都是模棱两可的,按自己的理解,总结了个小demo以作记录,希望批评指正