#include "HelloWorldScene.h" #include "GameOverScene.h" #include "SimpleAudioEngine.h" using namespace cocos2d; extern float g_scaleRatio; HelloWorld::~HelloWorld() { if (_targets) { _targets->release(); _targets = NULL; } if (_projectiles) { _projectiles->release(); _projectiles = NULL; } // cpp don't need to call super dealloc // virtual destructor will do this } HelloWorld::HelloWorld() :_targets(NULL) ,_projectiles(NULL) ,_projectilesDestroyed(0) ,_scaleRatio(1.0) { if ( 0 == strcmp(CCFileUtils::sharedFileUtils()->getResourceDirectory(), "hd/") ) { // AppDelegate.cpp used hd resource & 960x640 design resolution _scaleRatio = 2.0; } else { // sd _scaleRatio = 1.0; } } CCScene* HelloWorld::scene() { CCScene * scene = NULL; do { // 'scene' is an autorelease object scene = CCScene::create(); CC_BREAK_IF(! scene); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); CC_BREAK_IF(! layer); // add layer as a child to scene scene->addChild(layer); } while (0); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { bool bRet = false; do { ////////////////////////////////////////////////////////////////////////// // super init first ////////////////////////////////////////////////////////////////////////// CC_BREAK_IF(! CCLayerColor::initWithColor( ccc4(255,255,255,255) ) ); ////////////////////////////////////////////////////////////////////////// // add your codes below... ////////////////////////////////////////////////////////////////////////// // 1. Add a menu item with "X" image, which is clicked to quit the program. // Create a "close" menu item with close icon, it's an auto release object. CCMenuItemImage *pCloseItem = CCMenuItemImage::create( "CloseNormal.png", "CloseSelected.png", this, menu_selector(HelloWorld::menuCloseCallback)); CC_BREAK_IF(! pCloseItem); // Place the menu item bottom-right conner. CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin(); pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2, origin.y + pCloseItem->getContentSize().height/2)); // Create a menu with the "close" menu item, it's an auto release object. CCMenu* pMenu = CCMenu::create(pCloseItem, NULL); pMenu->setPosition(CCPointZero); CC_BREAK_IF(! pMenu); // Add the menu to HelloWorld layer as a child layer. this->addChild(pMenu, 1); ///////////////////////////// // 2. add your codes below... CCSprite *player = CCSprite::create("Player.png", CCRectMake(0, 0, 27*_scaleRatio, 40*_scaleRatio) ); player->setPosition( ccp(origin.x + player->getContentSize().width/2, origin.y + visibleSize.height/2) ); this->addChild(player); this->schedule( schedule_selector(HelloWorld::gameLogic), 1.0 ); this->setTouchEnabled(true); _targets = new CCArray; _projectiles = new CCArray; // use updateGame instead of update, otherwise it will conflit with SelectorProtocol::update // see http://www.cocos2d-x.org/boards/6/topics/1478 this->schedule( schedule_selector(HelloWorld::updateGame) ); CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("background-music-aac.wav", true); bRet = true; } while (0); return bRet; } void HelloWorld::menuCloseCallback(CCObject* pSender) { // "close" menu item clicked CCDirector::sharedDirector()->end(); } // cpp with cocos2d-x void HelloWorld::addTarget() { CCSprite *target = CCSprite::create("Target.png", CCRectMake(0,0,27*_scaleRatio,40*_scaleRatio) ); // Determine where to spawn the target along the Y axis CCSize winSize = CCDirector::sharedDirector()->getVisibleSize(); float minY = target->getContentSize().height/2; float maxY = winSize.height - target->getContentSize().height/2; int rangeY = (int)(maxY - minY); // srand( TimGetTicks() ); int actualY = ( rand() % rangeY ) + (int)minY; // Create the target slightly off-screen along the right edge, // and along a random position along the Y axis as calculated target->setPosition( ccp(winSize.width + (target->getContentSize().width/2), CCDirector::sharedDirector()->getVisibleOrigin().y + actualY) ); this->addChild(target); // Determine speed of the target int minDuration = (int)2.0; int maxDuration = (int)4.0; int rangeDuration = maxDuration - minDuration; // srand( TimGetTicks() ); int actualDuration = ( rand() % rangeDuration ) + minDuration; // Create the actions CCFiniteTimeAction* actionMove = CCMoveTo::create( (float)actualDuration, ccp(0 - target->getContentSize().width/2, actualY) ); CCFiniteTimeAction* actionMoveDone = CCCallFuncN::create( this, callfuncN_selector(HelloWorld::spriteMoveFinished)); target->runAction( CCSequence::create(actionMove, actionMoveDone, NULL) ); // Add to targets array target->setTag(1); _targets->addObject(target); } void HelloWorld::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 HelloWorld::gameLogic(float dt) { this->addTarget(); } // cpp with cocos2d-x void HelloWorld::ccTouchesEnded(CCSet* touches, CCEvent* event) { // Choose one of the touches to work with CCTouch* touch = (CCTouch*)( touches->anyObject() ); CCPoint location = touch->getLocation(); CCLog("++++++++after x:%f, y:%f", location.x, location.y); // Set up initial location of projectile CCSize winSize = CCDirector::sharedDirector()->getVisibleSize(); CCSprite *projectile = CCSprite::create("Projectile.png", CCRectMake(0, 0, 20*_scaleRatio, 20*_scaleRatio)); projectile->setPosition( ccp(20, winSize.height/2) ); // Determinie offset of location to projectile float offX = location.x - projectile->getPosition().x; float offY = location.y - projectile->getPosition().y; // Bail out if we are shooting down or backwards if (offX <= 0) return; // Ok to add now - we've double checked position this->addChild(projectile); // Determine where we wish to shoot the projectile to float realX = 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 shooting float offRealX = realX - projectile->getPosition().x; float offRealY = realY - projectile->getPosition().y; float length = sqrtf((offRealX * offRealX) + (offRealY*offRealY)); float velocity = 480/1; // 480pixels/1sec float realMoveDuration = length/velocity; // Move projectile to actual endpoint projectile->runAction( CCSequence::create( CCMoveTo::create(realMoveDuration, realDest), CCCallFuncN::create(this, callfuncN_selector(HelloWorld::spriteMoveFinished)), NULL) ); // Add to projectiles array projectile->setTag(2); _projectiles->addObject(projectile); CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("pew-pew-lei.wav"); } void HelloWorld::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) { CCSprite *projectile = dynamic_cast(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(jt); CCRect targetRect = CCRectMake( target->getPosition().x - (target->getContentSize().width/2), target->getPosition().y - (target->getContentSize().height/2), target->getContentSize().width, target->getContentSize().height); // if (CCRect::CCRectIntersectsRect(projectileRect, targetRect)) if (projectileRect.intersectsRect(targetRect)) { targetsToDelete->addObject(target); } } // for (jt = targetsToDelete->begin(); jt != targetsToDelete->end(); jt++) CCARRAY_FOREACH(targetsToDelete, jt) { CCSprite *target = dynamic_cast(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(it); _projectiles->removeObject(projectile); this->removeChild(projectile, true); } projectilesToDelete->release(); } void HelloWorld::registerWithTouchDispatcher() { // CCTouchDispatcher::sharedDispatcher()->addTargetedDelegate(this,0,true); CCDirector::sharedDirector()->getTouchDispatcher()->addStandardDelegate(this,0); }