游戏界面(1)
游戏界面(2)
游戏界面(3)
游戏界面(4)
游戏界面(5)
游戏主逻辑
HWorld.h
#pragma once #include <sstream> #include "cocos2d.h" using namespace cocos2d; using namespace std; //标签 enum { //敌人的波数 tag_wave, //生命值 tag_HP, //金钱 tag_gold, }; //将值转换为String template<typename T> string Conver2String(const T &value) { stringstream ss; ss<<value; return ss.str(); } class HWorld : public cocos2d::CCLayer { public: // Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer) virtual bool init(); // there's no 'id' in cpp, so we recommend to return the class instance pointer static cocos2d::CCScene* scene(); // preprocessor macro for "static create()" constructor ( node() deprecated ) CREATE_FUNC(HWorld); virtual ~HWorld(); //加载炮塔位置信息 void loadTowerPositions(); //加载敌人攻击进行路径信息 void addWayPoints(); //加载敌人攻击波数的信息 bool loadWaves(); //塔基座 cocos2d::CCArray *towerBases; //塔 cocos2d::CCArray *towers; //路径点 cocos2d::CCArray *wayPoints; //敌怪 cocos2d::CCArray *enemies; //每波怪 cocos2d::CCArray *waveData; //返回敌人攻击进行路径信息 cocos2d::CCArray * returnWayPoints(); //返回敌人信息 cocos2d::CCArray * returnEnemies(); //判断是否冲突 bool collisionWithCircle(CCPoint pt1,float radius1,CCPoint pt2,float radius2); //判断是不是一波敌怪都死了,如果都死了,放下波敌怪 void enmeyGotKilled(); //生命值减少 void getHpDamage(); //增加金钱 void addGold(int golden); private: //金线 int gold; //敌人的波数 int wave; //生命值 int hp; //是否可以买炮塔 bool isCanBuy(); //生命周期相关函数 virtual void onEnter(); virtual void onExit(); //处理触摸事件 virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent); virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent); };
HWorld.cpp
#include "HWorld.h" #include "SimpleAudioEngine.h" #include "HTower.h" #include "HWayPoint.h" #include "HEnemy.h" #include "stdio.h" #include "SimpleAudioEngine.h" #include "HWin.h" #include "HLose.h" using namespace cocos2d; using namespace CocosDenshion; //塔所花费的钱 #define TOWERCAST 300 CCScene* HWorld::scene() { CCLog("HWorld::scene "); // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HWorld *layer = HWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool HWorld::init() { CCLog("HWorld::init "); ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } CCSize winSize=CCDirector::sharedDirector()->getWinSize(); CCSprite *background=CCSprite::create("Bg.png"); background->setPosition(ccp(winSize.width/2, winSize.height/2)); addChild(background); towerBases=CCArray::create(); CC_SAFE_RETAIN(towerBases); towers=CCArray::create(); CC_SAFE_RETAIN(towers); wayPoints=CCArray::create(); CC_SAFE_RETAIN(wayPoints); //加载炮塔位置 loadTowerPositions(); //添加敌人行进路径 addWayPoints(); enemies=CCArray::create(); CC_SAFE_RETAIN(enemies); waveData=CCArray::createWithContentsOfFile("Waves.plist"); CC_SAFE_RETAIN(waveData); //当前波数 wave = 0; CCLog(" wave: %d", wave); CCString *strWave=CCString::create(""); strWave->initWithFormat("waves: %d",wave); CCLabelBMFont *pFont=CCLabelBMFont::create(strWave->getCString(), "font_red_14.fnt"); pFont->setPosition(400,winSize.height-12); addChild(pFont,0,tag_wave); //加载波数 loadWaves(); //当前血量 hp=5; CCString *strHP=CCString::create(""); strHP->initWithFormat("HP: %d",hp); CCLabelBMFont *pHPFont=CCLabelBMFont::create(strHP->getCString(), "font_red_14.fnt"); pHPFont->setPosition(300,winSize.height-12); addChild(pHPFont,0,tag_HP); //当前黄金 gold=10000; CCString *strGold=CCString::create(""); strGold->initWithFormat("gold: %d",gold); CCLabelBMFont *pGoldFont=CCLabelBMFont::create(strGold->getCString(), "font_red_14.fnt"); pGoldFont->setPosition(200,winSize.height-12); addChild(pGoldFont,0,tag_gold); //背景音乐 SimpleAudioEngine::sharedEngine()->playBackgroundMusic("8bitDungeonLevel.mp3", true); return true; } //判断黄金储备 bool HWorld::isCanBuy() { if (gold-TOWERCAST>0) { return true; } return false; } //敌怪顺利到达终点 void HWorld::getHpDamage() { if (hp<=0) { CCDirector::sharedDirector()->replaceScene(CCTransitionFade::create(1.5, HLose::scene())); } hp-=1; CCString *strHP=CCString::create(""); strHP->initWithFormat("HP: %d",hp); CCLabelBMFont *pHPFont=(CCLabelBMFont *) getChildByTag(tag_HP); pHPFont->setString(strHP->getCString()); SimpleAudioEngine::sharedEngine()->playEffect("life_lose.wav"); } //加载波数 bool HWorld::loadWaves() { if (wave>=waveData->count()) { //if (wave>=20) { CCLog(" wave: %d",wave); CCLog(" waveData->count(): %d",waveData->count()); CCLog(" wave>=waveData->count()"); return false; } CCArray *currenWaveData=(CCArray *)waveData->objectAtIndex(wave); for (int i=0; i<currenWaveData->count(); i++) { CCDictionary *pDic=(CCDictionary*)currenWaveData->objectAtIndex(i); CCString* delay=(CCString *)pDic->valueForKey("spawnTime"); HEnemy *enmey=HEnemy::initGame(this); enemies->addObject(enmey); enmey->scheduleOnce(schedule_selector(HEnemy::doActive), delay->floatValue()); } wave++; CCLabelBMFont *pFont=(CCLabelBMFont*) getChildByTag(tag_wave); CCString *strWave=CCString::create(""); strWave->initWithFormat("waves: %d",wave); pFont->setString(strWave->getCString()); return true; } //判断是不是一波敌怪都死了,如果都死了,放下波敌怪 void HWorld::enmeyGotKilled() { if (enemies->count()<=0) { if (!loadWaves()) { CCLog("成功 "); CCDirector::sharedDirector()->replaceScene(CCTransitionJumpZoom::create(1.5,HWin::scene())); } } } //设置敌怪活动路径 void HWorld::addWayPoints() { HWayPoint *wayPoint1=HWayPoint::initGame(this, ccp(420,35)); wayPoints->addObject(wayPoint1); wayPoint1->nextWayPoint=NULL; HWayPoint *wayPoint2=HWayPoint::initGame(this, ccp(35,35)); wayPoints->addObject(wayPoint2); wayPoint2->nextWayPoint=wayPoint1; HWayPoint *wayPoint3=HWayPoint::initGame(this, ccp(35,130)); wayPoints->addObject(wayPoint3); wayPoint3->nextWayPoint=wayPoint2; HWayPoint *wayPoint4=HWayPoint::initGame(this, ccp(445,130)); wayPoints->addObject(wayPoint4); wayPoint4->nextWayPoint=wayPoint3; HWayPoint *wayPoint5=HWayPoint::initGame(this, ccp(445,220)); wayPoints->addObject(wayPoint5); wayPoint5->nextWayPoint=wayPoint4; HWayPoint *wayPoint6=HWayPoint::initGame(this, ccp(-40,220)); wayPoints->addObject(wayPoint6); wayPoint6->nextWayPoint=wayPoint5; } //加载塔基座 void HWorld::loadTowerPositions() { CCArray *towerPositions=CCArray::createWithContentsOfFile("TowersPosition.plist"); for (int i=0;i<towerPositions->count();i++) { CCDictionary *pDic=(CCDictionary *) towerPositions->objectAtIndex(i); CCSprite *towerBase=CCSprite::create("open_spot.png"); const CCString *strX=pDic->valueForKey("x"); const CCString *strY=pDic->valueForKey("y"); int x=strX->intValue(); int y=strY->intValue(); towerBase->setPosition(ccp(x,y)); addChild(towerBase); towerBases->addObject(towerBase); } } //杀了一个怪,玩家得到金钱 void HWorld::addGold(int golden) { gold+=golden; CCLabelBMFont *pGoldFont=(CCLabelBMFont *)getChildByTag(tag_gold); CCString *strGold=CCString::create(""); strGold->initWithFormat("gold: %d",gold); pGoldFont->setString(strGold->getCString()); CCUserDefault::sharedUserDefault()->setStringForKey("user_score", Conver2String(gold)); CCUserDefault::sharedUserDefault()->flush(); } //圆形碰撞 bool HWorld::collisionWithCircle(CCPoint pt1,float radius1,CCPoint pt2,float radius2) { float xdif=pt1.x-pt2.x; float ydif=pt1.y-pt2.y; float distande=sqrt(xdif*xdif+ydif*ydif); if (distande<=radius1+radius2) { return true; } return false; } CCArray *HWorld::returnEnemies() { return enemies; } CCArray * HWorld::returnWayPoints() { return wayPoints; } HWorld::~HWorld() { CC_SAFE_RELEASE(towerBases); CC_SAFE_RELEASE(towers); CC_SAFE_RELEASE(wayPoints); CC_SAFE_RELEASE(enemies); CC_SAFE_RELEASE(waveData); } //生命周期相关函数 void HWorld::onEnter() { CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true); CCNode::onEnter(); } void HWorld::onExit() { CCDirector::sharedDirector()->getTouchDispatcher()->removeDelegate(this); CCNode::onExit(); } //判断触摸点是否需要放置炮塔 bool HWorld::ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent) { CCPoint location=pTouch->getLocation(); for (int i=0; i<towerBases->count(); i++) { CCSprite* towerBase=(CCSprite*) towerBases->objectAtIndex(i); CCRect rect=towerBase->boundingBox(); //如果触摸点是塔的基座,触摸点没有塔,金线足够 if(rect.containsPoint(location) && (towerBase->getUserData()==NULL)&&(isCanBuy())) { gold-=TOWERCAST; CCLabelBMFont *pGoldFont=(CCLabelBMFont *)getChildByTag(tag_gold); CCString *strGold=CCString::create(""); strGold->initWithFormat("gold: %d",gold); pGoldFont->setString(strGold->getCString()); CCUserDefault::sharedUserDefault()->setStringForKey("user_score", Conver2String(gold)); CCUserDefault::sharedUserDefault()->flush(); HTower *tower=HTower::initGame(this, towerBase->getPosition()); towers->addObject(tower); towerBase->setUserData(tower); SimpleAudioEngine::sharedEngine()->playEffect("tower_place.wav"); } } return true; } void HWorld::ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent) { } void HWorld::ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) { }
HWayPoint.h
#pragma once #include "HWorld.h" #include "cocos2d.h" class HWayPoint:public CCNode { public: static HWayPoint * initGame(HWorld *game,CCPoint location); //下一个路径信息 HWayPoint* nextWayPoint; //自己的位置 CCPoint myPostion; private: //变量HWorld HWorld *theGame; virtual void draw(); void initWithGame(HWorld *game,CCPoint location); };
HWayPoint.cpp
#include "HWayPoint.h" HWayPoint * HWayPoint::initGame(HWorld *game,CCPoint location) { CCLog("HWayPoint::initGame"); HWayPoint *wayPoint=new HWayPoint(); if (wayPoint) { wayPoint->autorelease(); wayPoint->initWithGame(game, location); return wayPoint; } CC_SAFE_DELETE(wayPoint); return NULL; } void HWayPoint::initWithGame(HWorld *game,CCPoint location) { CCLog("HWayPoint::initWithGame"); theGame=game; myPostion=location; theGame->addChild(this); } void HWayPoint::draw() { #ifdef TESTDebug ccDrawColor4F(0, 255, 0, 255); ccDrawCircle(myPostion, 6, 360, 30, false); ccDrawCircle(myPostion, 2, 360, 30, false); if (nextWayPoint) { ccDrawLine(myPostion, nextWayPoint->myPostion); } #endif }
HTower.h
#pragma once #include "HWorld.h" #include "cocos2d.h" #include "HEnemy.h" //炮台类 class HTower:public cocos2d::CCNode { public: static HTower* initGame(HWorld *game,cocos2d::CCPoint loc); //选择攻击的敌怪 HEnemy *chosenEnemy; void targetKilled(); private: void initWithTheGame(HWorld * game,cocos2d::CCPoint location); //攻击范围 int attackRange; //伤害 int damage; //攻击速度 float fireRate; bool attacking; //HWorld 成员 HWorld *theGame; //炮塔图片 cocos2d::CCSprite *mySprite; void update(float time); virtual void draw(); void attackEnemy(); void shootWeapon(); void chosenEnemyForAttack(HEnemy* enemy); void lastSightOfEnemy(); void removeBullet(CCSprite *bullet); void damageEnemy(); };
HTower.cpp
#include "SimpleAudioEngine.h" #include "HTower.h" using namespace cocos2d; using namespace CocosDenshion; HTower* HTower::initGame(HWorld *game,cocos2d::CCPoint loc) { HTower *tower=new HTower(); if (tower) { tower->autorelease(); tower->initWithTheGame(game, loc); return tower; } CC_SAFE_DELETE(tower); return NULL; } void HTower::initWithTheGame(HWorld * game,cocos2d::CCPoint location) { chosenEnemy = NULL; theGame=game; //炮塔攻击范围 attackRange=70; //伤害 damage=10; //攻击速度 fireRate=1; mySprite = CCSprite::create("tower.png"); mySprite->setPosition(location); addChild(mySprite); game->addChild(this); scheduleUpdate(); } void HTower::update(float time) { if (chosenEnemy) //if (chosenEnemy != NULL) { CCLog("HTower::update---if"); //炮口转向敌怪 CCPoint targetPostion=chosenEnemy->mySprite->getPosition(); CCPoint myPt=mySprite->getPosition(); CCPoint normalized=ccpNormalize(ccp(targetPostion.x-myPt.x,targetPostion.y-myPt.y)); mySprite->setRotation(CC_RADIANS_TO_DEGREES(atan2(normalized.y, -normalized.x))+90); if (!theGame->collisionWithCircle(targetPostion, attackRange, myPt, 1)) { //敌怪离开攻击范围 lastSightOfEnemy(); } } else { CCLog("HTower::update---else"); //找到一个敌怪来攻击 CCArray *enemies=theGame->returnEnemies(); for (int i=0; i<enemies->count(); i++) { HEnemy *enemy=(HEnemy*) enemies->objectAtIndex(i); if (theGame->collisionWithCircle(mySprite->getPosition(), attackRange, enemy->mySprite->getPosition(), 1)) { chosenEnemyForAttack(enemy); break; } } } } //选择一个敌怪攻击 void HTower::chosenEnemyForAttack(HEnemy* enemy) { chosenEnemy=NULL; chosenEnemy=enemy; chosenEnemy->addActby(this); //敌人受伤害 attackEnemy(); } //攻击敌怪 void HTower::attackEnemy() { schedule(schedule_selector(HTower::shootWeapon),fireRate); } //敌怪离开攻击范围 void HTower::lastSightOfEnemy() { if (chosenEnemy) { chosenEnemy->removeActby(this); chosenEnemy=NULL; } unschedule(schedule_selector(HTower::shootWeapon)); } //开炮 void HTower::shootWeapon() { SimpleAudioEngine::sharedEngine()->playEffect("laser_shoot.wav"); CCSprite *bullet=CCSprite::create("bullet.png"); theGame->addChild(bullet); bullet->setPosition(mySprite->getPosition()); CCCallFuncN *funCall=CCCallFuncN::create(this, callfuncN_selector(HTower::removeBullet)); CCCallFunc *funAct=CCCallFunc::create(this, callfunc_selector(HTower::damageEnemy)); bullet->runAction(CCSequence::create(CCMoveTo::create(0.1, chosenEnemy->mySprite->getPosition()),funAct,funCall,NULL)); } //敌怪掉血 void HTower::damageEnemy() { if (chosenEnemy) { chosenEnemy->getDamage(damage); } } //移除子弹 void HTower::removeBullet(CCSprite *bullet) { theGame->removeChild(bullet, true); } void HTower::draw() { #ifdef TESTDebug ccDrawColor4F(255, 255, 255, 255); ccDrawCircle(mySprite->getPosition(), attackRange, 360, 30, false); #endif } //目标被击毁后,不再开炮 void HTower::targetKilled() { chosenEnemy=NULL; unschedule(schedule_selector(HTower::shootWeapon)); }
怪物类:
HEnemy.h
#pragma once #include "HWayPoint.h" #include "cocos2d.h" #include "HTower.h" extern class HTower; using namespace cocos2d; class HEnemy:public CCNode { //void initWithGame(HWorld *game void initWithGame(HWorld *game); //位置 CCPoint myPostion; //最大生命值 int maxHp; //当前生命值 int currentHp; //移动速度 float walkingSpeed; //敌人目的点位置 HWayPoint *destnationWaypoint; //是否激活 bool active; //变量HWorld HWorld* theGame; //刷新界面 void update(float time); void removeSelf(); virtual void draw(); //敌怪被消灭了 void getRemoved(); //攻击敌人的炮塔的集合 CCArray *actby; virtual ~HEnemy(); public: static HEnemy*initGame(HWorld* game); void removeActby(HTower* tower); void addActby(HTower* tower); void doActive(); void getDamage(int damage); //敌人图片 CCSprite *mySprite; };
HEnemy.cpp
#include "HTower.h" #include "HEnemy.h" #include "SimpleAudioEngine.h" using namespace CocosDenshion; HEnemy *HEnemy::initGame(HWorld* game) { HEnemy *enmey=new HEnemy(); if (enmey) { enmey->autorelease(); enmey->initWithGame(game); return enmey; } CC_SAFE_DELETE(enmey); return NULL; } void HEnemy::initWithGame(HWorld *game) { actby=CCArray::create(); CC_SAFE_RETAIN(actby); theGame=game; maxHp=40; currentHp=maxHp; active=false; walkingSpeed=0.5f; //walkingSpeed=2.0f; mySprite=CCSprite::create("enemy.png"); addChild(mySprite); CCArray *wayPoints=theGame->returnWayPoints(); int nIndex=wayPoints->count()-1; CCLog(" nIndex: %d", nIndex); if (nIndex>=0) { HWayPoint* wayPoint=(HWayPoint*) wayPoints->objectAtIndex(nIndex); destnationWaypoint=wayPoint->nextWayPoint; myPostion=wayPoint->myPostion; mySprite->setPosition(myPostion); } theGame->addChild(this); scheduleUpdate(); } void HEnemy::update(float time) { if (!active) { return; } if (theGame->collisionWithCircle(myPostion, 1, destnationWaypoint->myPostion, 1))//到了一个路径点,就走下一个路径点 { if (destnationWaypoint->nextWayPoint) { destnationWaypoint=destnationWaypoint->nextWayPoint; } else { //玩家掉血 theGame->getHpDamage(); removeSelf(); } } CCPoint targetPoint=destnationWaypoint->myPostion; float movementSpeed=walkingSpeed; CCPoint normalized=ccpNormalize(ccp(targetPoint.x-myPostion.x,targetPoint.y-myPostion.y)); double angle=atan2(normalized.y, -normalized.x); float rotation=CC_RADIANS_TO_DEGREES(angle); //旋转方向 mySprite->setRotation(rotation); //移动距离 myPostion=ccp(myPostion.x+normalized.x*movementSpeed,myPostion.y+normalized.y*movementSpeed); mySprite->setPosition(myPostion); } //敌怪掉血 void HEnemy::getDamage(int damage) { currentHp-=damage; if (currentHp<=0) { //敌怪被消灭了,告诉炮塔别开炮了 for (int i=0;i<actby->count(); i++) { HTower *tower=(HTower*) actby->objectAtIndex(i); tower->targetKilled(); } getRemoved(); SimpleAudioEngine::sharedEngine()->playEffect("enemy_destroy.wav"); } } //敌怪开始活动 void HEnemy::doActive() { active=true; } //清空自己 void HEnemy::removeSelf() { theGame->removeChild(this, true); CCArray *enemies=theGame->returnEnemies(); enemies->removeObject(this); theGame->enmeyGotKilled(); } //画血条 void HEnemy::draw() { //画血条 CCPoint postion=mySprite->getPosition(); CCPoint orgin; CCPoint endpt; orgin.x=postion.x-10; orgin.y=postion.y+16; endpt.x=postion.x+10; endpt.y=postion.y+14; ccDrawSolidRect(orgin, endpt, ccc4f(255, 0, 0, 255)); float cuthp=currentHp; cuthp=cuthp/maxHp*20; //血条总长20 endpt.x=postion.x-10+cuthp; ccDrawSolidRect(orgin, endpt, ccc4f(0, 255, 0, 255)); } //敌怪被消灭了 void HEnemy::getRemoved() { //爆炸粒子效果 CCParticleSystemQuad *particle=CCParticleSystemQuad::create("particle_boom.plist"); particle->setPosition(mySprite->getPosition()); particle->setAutoRemoveOnFinish(true); theGame->addChild(particle); //消灭一个敌怪,增加200金钱 theGame->addGold(200); removeSelf(); } //被炮塔攻击 void HEnemy::addActby(HTower* tower) { actby->addObject(tower); } //离开炮塔攻击 void HEnemy::removeActby(HTower* tower) { actby->removeObject(tower); } HEnemy::~HEnemy() { CC_SAFE_RELEASE(actby); }
参考资料:
1.http://download.csdn.net/download/szulee/4711058
下载地址: