时间:2021-07-01 10:21:17 帮助过:25人阅读
头文件 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::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 <= 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();
}