coco2d-x 2.0学习系列(一):SimpleGame(2)
#ifndef __SIMPLE_GAME_H__#define __SIMPLE_GAME_H__#include "cocos2d.h"class SimpleGame:public cocos2d::CCLayerColor{public:SimpleGame();~SimpleGame();//初始化函数virtual bool init(); static cocos2d::CCScene* scene();// 菜单响应函数virtual void menuCloseCallback(cocos2d::CCObject* pSender);CREATE_FUNC(SimpleGame);//精灵移动结束回调函数void spriteMoveFinished(cocos2d::CCNode* sender);//定时添加精灵回调函数void gameLogic(float dt);//碰撞检测void updateGame(float dt);void registerWithTouchDispatcher();//触摸事件void ccTouchesEnded(cocos2d::CCSet* touches, cocos2d::CCEvent* event);protected:cocos2d::CCArray *_targets;//敌人精灵集合cocos2d::CCArray *_projectiles;//子弹精灵集合int _projectilesDestroyed;//void addTarget();//添加敌人精灵};#endif
?
#include "SimpleGameScene.h"#include "GameOverScene.h"#include "SimpleAudioEngine.h"using namespace cocos2d;SimpleGame::SimpleGame(): _targets(NULL),_projectiles(NULL),_projectilesDestroyed(0){}SimpleGame::~SimpleGame(){if(_targets){_targets->release();_targets=NULL;}if(_projectiles){_projectiles->release();_projectiles=NULL;}}//创建场景并且添加层CCScene* SimpleGame::scene(){CCScene * scene = NULL;do {scene = CCScene::create();CC_BREAK_IF(! scene);SimpleGame *layer = SimpleGame::create();CC_BREAK_IF(! layer);scene->addChild(layer);} while (0);return scene;}//初始化bool SimpleGame::init(){bool bRet = false;do {//初始化带颜色的层CC_BREAK_IF(! CCLayerColor::initWithColor( ccc4(255,255,255,255) ) ); //创建图片菜单item,并设置响应回调函数CCMenuItemImage *pCloseItem = CCMenuItemImage::create("CloseNormal.png","CloseSelected.png",this,menu_selector(SimpleGame::menuCloseCallback));CC_BREAK_IF(! pCloseItem);// OpenGL view sizeCCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();// visible origin of the OpenGL view in pointsCCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();//设置pCloseItem位置//#define ccp(__X__,__Y__) cocos2d::CCPointMake((float)(__X__), (float)(__Y__))//宏ccp 返回point /************************************************************************//*这个地方关联到coco2d-x坐标系 基本的两个坐标系:屏幕坐标系和GL坐标系。屏幕坐标系x轴朝右,y轴朝下。默认原点在左上角。 O---------------->x | | | | yGL坐标系x轴朝右,y轴朝上。默认原点在左下角。 opengl y| | | | | O-------------------->x setPosition设置的是GL坐标 setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2, origin.y + pCloseItem->getContentSize().height/2)); 这句实际上是把关闭按钮设置到到屏幕的右下角 y | | | | ____ | |__*_| origin(x,y)---------------------------->x*//************************************************************************/pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2,origin.y + pCloseItem->getContentSize().height/2));CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);pMenu->setPosition(CCPointZero);//这里必须设置才能显示菜单CC_BREAK_IF(! pMenu);//菜单添加到层this->addChild(pMenu, 1); //创建英雄精灵 CCSprite *player = CCSprite::create("Player.png", CCRectMake(0, 0, 27, 40) );//创建精灵player->setPosition( ccp(origin.x + player->getContentSize().width/2,origin.y + visibleSize.height/2) );this->addChild(player);//定时增加敌人精灵,每一秒新增一个this->schedule( schedule_selector(SimpleGame::gameLogic), 1.0 );//设置可触摸this->setTouchEnabled(true);_targets = new CCArray;_projectiles = new CCArray;//检测碰撞this->schedule( schedule_selector(SimpleGame::updateGame) );//播放背景音乐CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav", true);bRet = true;} while (0);return bRet;}// 新增敌人精灵void SimpleGame::addTarget(){ CCSprite *target = CCSprite::create("Target.png", CCRectMake(0,0,27,40) );CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();float minY = target->getContentSize().height/2;float maxY = winSize.height - target->getContentSize().height/2;int rangeY = (int)(maxY - minY);int actualY = ( rand() % rangeY ) + (int)minY;target->setPosition( ccp(winSize.width + (target->getContentSize().width/2), CCDirector::sharedDirector()->getVisibleOrigin().y + actualY) );this->addChild(target);// Determine speed of the targetint minDuration = (int)2.0;int maxDuration = (int)4.0;int rangeDuration = maxDuration - minDuration;// srand( TimGetTicks() );int actualDuration = ( rand() % rangeDuration ) + minDuration;// 精灵移动actionCCFiniteTimeAction* actionMove = CCMoveTo::create( (float)actualDuration,ccp(0 - target->getContentSize().width/2, actualY) );CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create( this, callfuncN_selector(SimpleGame::spriteMoveFinished));target->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) );// 敌人精灵加入ccarraytarget->setTag(1);_targets->addObject(target);}void SimpleGame::spriteMoveFinished(CCNode *sender){CCSprite *sprite = (CCSprite *)sender;this->removeChild(sprite, true);if (sprite->getTag() == 1) // target{_targets->removeObject(sprite);//游戏失败切换场景GameOverScene *gameOverScene = GameOverScene::create();gameOverScene->getLayer()->getLabel()->setString("You Lose :[");CCDirector::sharedDirector()->replaceScene(gameOverScene);}else if (sprite->getTag() == 2) // projectile{_projectiles->removeObject(sprite);}}void SimpleGame::gameLogic(float dt){this->addTarget();//添加敌人精灵}void SimpleGame::menuCloseCallback(CCObject* pSender){// 响应menu时间CCDirector::sharedDirector()->end();}// 触摸屏幕 添加子弹void SimpleGame::ccTouchesEnded(CCSet* touches, CCEvent* event){// Choose one of the touches to work withCCTouch* touch = (CCTouch*)( touches->anyObject() );CCPoint location = touch->getLocation();//触摸按下的坐标CCLog("++++++++after x:%f, y:%f", location.x, location.y);CCSize winSize = CCDirector::sharedDirector()->getVisibleSize();CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();CCSprite *projectile = CCSprite::create("Projectile.png", CCRectMake(0, 0, 20, 20));projectile->setPosition( ccp(origin.x+20, origin.y+winSize.height/2) );// Determinie offset of location to projectilefloat offX = location.x - projectile->getPosition().x;float offY = location.y - projectile->getPosition().y;// Bail out if we are shooting down or backwardsif (offX <= 0) return;// Ok to add now - we've double checked positionthis->addChild(projectile);// Determine where we wish to shoot the projectile tofloat realX = origin.x+winSize.width + (projectile->getContentSize().width/2);float ratio = offY / offX;float realY = (realX * ratio) + projectile->getPosition().y;CCPoint realDest = ccp(realX, realY);// Determine the length of how far we're shootingfloat offRealX = realX - projectile->getPosition().x;float offRealY = realY - projectile->getPosition().y;float length = sqrtf((offRealX * offRealX) + (offRealY*offRealY));float velocity = 480/1; // 480pixels/1secfloat realMoveDuration = length/velocity;// 移动子弹actionprojectile->runAction( CCSequence::create(CCMoveTo::create(realMoveDuration, realDest),CCCallFuncN::create(this, callfuncN_selector(SimpleGame::spriteMoveFinished)), NULL) );// Add to projectiles arrayprojectile->setTag(2);_projectiles->addObject(projectile);CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pew-pew-lei.wav");}//碰撞检测void SimpleGame::updateGame(float dt){CCArray *projectilesToDelete = new CCArray;CCObject* it = NULL;CCObject* jt = NULL;// for (it = _projectiles->begin(); it != _projectiles->end(); it++)CCARRAY_FOREACH(_projectiles, it)//遍历ccarray{CCSprite *projectile = dynamic_cast<CCSprite*>(it);//动态转换类类型//飞镖矩形区域CCRect projectileRect = CCRectMake(projectile->getPosition().x - (projectile->getContentSize().width/2),projectile->getPosition().y - (projectile->getContentSize().height/2),projectile->getContentSize().width,projectile->getContentSize().height);CCArray* targetsToDelete =new CCArray;// for (jt = _targets->begin(); jt != _targets->end(); jt++)CCARRAY_FOREACH(_targets, jt){CCSprite *target = dynamic_cast<CCSprite*>(jt);CCRect targetRect = CCRectMake(target->getPosition().x - (target->getContentSize().width/2),target->getPosition().y - (target->getContentSize().height/2),target->getContentSize().width,target->getContentSize().height);// 碰撞检测,2个精灵区域相交,即为碰撞。if (projectileRect.intersectsRect(targetRect)){targetsToDelete->addObject(target);}}// for (jt = targetsToDelete->begin(); jt != targetsToDelete->end(); jt++)CCARRAY_FOREACH(targetsToDelete, jt){CCSprite *target = dynamic_cast<CCSprite*>(jt);_targets->removeObject(target);this->removeChild(target, true);_projectilesDestroyed++;if (_projectilesDestroyed >= 5){GameOverScene *gameOverScene = GameOverScene::create();gameOverScene->getLayer()->getLabel()->setString("You Win!");CCDirector::sharedDirector()->replaceScene(gameOverScene);}}if (targetsToDelete->count() > 0){projectilesToDelete->addObject(projectile);}targetsToDelete->release();}// for (it = projectilesToDelete->begin(); it != projectilesToDelete->end(); it++)CCARRAY_FOREACH(projectilesToDelete, it){CCSprite* projectile = dynamic_cast<CCSprite*>(it);_projectiles->removeObject(projectile);this->removeChild(projectile, true);}projectilesToDelete->release();}void SimpleGame::registerWithTouchDispatcher(){// CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this,0,true);CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0);}
?