查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!
游戏么,得有胜负、朋友。
地图编辑的一些方法,传送门:http://www.cnblogs.com/andyque/archive/2011/05/07/2039481.html
上面入加朋友:
void HelloWorld::addEnemy(int x,int y) { CCSprite* enemy = CCSprite::create("enemy1.png"); enemy->setPosition(ccp(x,y)); addChild(enemy); //moveEnemy(enemy); m_enemies->addObject(enemy); }
接下来使朋友动移,这里跟官方的不太一样。我用采的是在屏幕上表现的怪能动移。
做出来的有点小问题:isRunning数函乎似有问题,不能用。嫌费事自己没写类。
所以有个小Bug,有兴致的读者可以改改,自己写个子类,然后设置个动没动的标记。
void HelloWorld::moveEnemy(CCSprite* enemy) { CCPoint diff = ccpSub(m_player->getPosition(),enemy->getPosition()); float angleRadians = atanf((float)diff.y / (float)diff.x); float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians); float cocosAngle =-1* angleDegrees; if (diff.x <0) { cocosAngle +=180; } enemy->setRotation(cocosAngle); int x = m_player->getPosition().x; int y = m_player->getPosition().y; CCActionInterval* move = CCMoveBy::create(3.0f, ccpSub(m_player->getPosition(),enemy->getPosition())); enemy->runAction(CCSequence::create(move, CCCallFuncN::create(this,callfuncN_selector(HelloWorld::enemyMoveFinished)),NULL)); }
环循的调回是要必的,因为玩家的置位会改更,目标标坐会变改。
//此处如此计划因为玩家置位会发生变化,须要复重获得 void HelloWorld::enemyMoveFinished(CCNode* node) { CCSprite* enemy = (CCSprite*)node; moveEnemy(enemy); }
void HelloWorld::checkMoveEnemy(CCPoint center) { CCSize winSize = CCDirector::sharedDirector()->getWinSize(); center = convertToNodeSpace(center); CCRect screen = CCRectMake(center.x-winSize.width/2,center.y-winSize.height/2,winSize.width,winSize.height); CCObject* e = NULL; CCARRAY_FOREACH(m_enemies,e) { CCSprite* enemy = dynamic_cast<CCSprite*>(e); CCPoint temp = enemy->getPosition(); CCPoint pos = convertToNodeSpace(temp); if(screen.containsPoint(pos)) { //此处会有复重调用的问题,即对已动移的怪调用runAction //if(enemy->isRunning()) //这个数函不能用? moveEnemy(enemy); } } }
有怪了就得打,接下来是发射飞镖。
因为是触控,没法用键盘那么高端,这里用采切换模式的方法,即动移和发射飞镖两种模式切换。
切换的表现要用CCMenuItemToggle来做,把它放在CCMenu中,再放在ScoreLayer中。
发射飞镖就用之前那个最易简的忍者游戏的代码就行。
void HelloWorld::sendProjectile(CCSprite* projectile,CCPoint pos) { int realX; CCPoint diff = ccpSub(pos, m_player->getPosition()); if (diff.x >0) { realX = (m_tileMap->getContentSize().width) + (projectile->getContentSize().width/2); } else { realX =-(m_tileMap->getContentSize().width) - (projectile->getContentSize().width/2); } float ratio = (float) diff.y / (float) diff.x; int realY = ((realX - projectile->getPositionX()) * ratio) + projectile->getPositionY(); CCPoint realDest = ccp(realX, realY); // Determine the length of how far we're shooting int offRealX = realX - projectile->getPositionX(); int offRealY = realY - projectile->getPositionY(); float length = sqrtf((offRealX*offRealX) + (offRealY*offRealY)); float velocity =480/1; // 480pixels/1sec float realMoveDuration = length/velocity; CCActionInterval* throwProjectile = CCMoveTo::create(realMoveDuration,realDest); projectile->runAction(CCSequence::create(throwProjectile, CCCallFuncN::create(this,callfuncN_selector(HelloWorld::projectileMoveFinished)),NULL)); }
void HelloWorld::projectileMoveFinished(CCNode* object) { CCSprite* p = (CCSprite* )object; if(p) { removeChild(p,true); m_projectiles->removeObject(p); } }
碰撞检测也一样,查检飞镖与朋友否是相遇,另外要入加朋友与玩家相遇的逻辑。
void HelloWorld::checkHit(float dt) { CCArray* projectilesToDelete = new CCArray; CCArray* targetToDelete = new CCArray; CCObject* it = NULL; CCObject* jt = NULL; CCRect playerRect = CCRectMake( m_player->getPositionX() - m_player->getContentSize().width/2, m_player->getPositionY() - m_player->getContentSize().height/2, m_player->getContentSize().width, m_player->getContentSize().height); CCARRAY_FOREACH(m_projectiles,it) { CCSprite * projectile = dynamic_cast<CCSprite*>(it); CCRect projectileRect = CCRectMake( projectile->getPositionX() - projectile->getContentSize().width/2, projectile->getPositionY() - projectile->getContentSize().height/2, projectile->getContentSize().width, projectile->getContentSize().height); CCARRAY_FOREACH(m_enemies,jt) { CCSprite* target = dynamic_cast<CCSprite*>(jt); CCRect targetRect = CCRectMake( target->getPositionX() - target->getContentSize().width/2, target->getPositionY() - target->getContentSize().height/2, target->getContentSize().width, target->getContentSize().height); if(projectileRect.intersectsRect(targetRect)) { targetToDelete->addObject(target); } } CCARRAY_FOREACH(targetToDelete,jt) { CCSprite* delTarget = dynamic_cast<CCSprite*>(jt); m_enemies->removeObject(delTarget,true); this->removeChild(delTarget,true); } if(targetToDelete->count() >0) { projectilesToDelete->addObject(projectile); } targetToDelete->removeAllObjects(); } CCARRAY_FOREACH(projectilesToDelete,it) { CCSprite* delProject = dynamic_cast<CCSprite*>(it); m_projectiles->removeObject(delProject); this->removeChild(delProject,true); } CCARRAY_FOREACH(m_enemies,jt) { CCSprite* target = dynamic_cast<CCSprite*>(jt); CCRect targetRect = CCRectMake( target->getPositionX() - target->getContentSize().width/2, target->getPositionY() - target->getContentSize().height/2, target->getContentSize().width, target->getContentSize().height); if(playerRect.intersectsRect(targetRect)) { GameOverSecne *gameOverScene = GameOverSecne::create(); gameOverScene->getLayer()->getLabel()->setString("You Lose!"); CCDirector::sharedDirector()->replaceScene(gameOverScene); } } targetToDelete->release(); projectilesToDelete->release(); }
最后加上胜负界面:吃掉西瓜就赢,遇到怪物就输。
用的之前易简忍者游戏的那个GameOverScene。体具可以看我的码源。
编译运行吧,少年。
我觉感我这版游戏,关卡计划还是有点难的,打了半天才赢...
等过CSDN审核,上码源:
文章结束给大家分享下程序员的一些笑话语录: 看到有人回帖“不顶不是中国人”,他的本意是想让帖子沉了。