游戏界面(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
下载地址: