之前制作的简单的一个小游戏,整理之后分享一下,只是最初的版本,后续完善版本不方便公布。
先看看最终示意图吧
如图所示,怪物由上至下移动,有五条道路,底部有一塔在攻击。
首先就是加载地图了
//=========加载背景图========
CCTMXTiledMap* tmxmap = CCTMXTiledMap::create("bg.tmx");
tmxmap->setPosition(ccp(0,0));
this->addChild(tmxmap,-1);
怪物类的实现Enemy.h
#pragma once
#include "cocos2d.h"
#include "Box2D/Box2D.h"
#include "SimpleAudioEngine.h"
#include "cocos-ext.h"
using namespace cocos2d;
using namespace extension;
class Enemy : public cocos2d::CCSprite
{
public:
CCControlSlider* slider;
float speed;
float hp;
static Enemy* create();
void run();
void showHP();
};
Enemy.cpp
#include "Enemy.h"
USING_NS_CC;
Enemy* Enemy::create()
{
Enemy *pobSprite = new Enemy();
if (pobSprite && pobSprite->initWithFile("Enemy1.png"))
{
pobSprite->speed = 1.0f;
pobSprite->hp = 100.0f;
pobSprite->showHP();
pobSprite->autorelease();
return pobSprite;
}
CC_SAFE_DELETE(pobSprite);
return NULL;
}
void Enemy::run()
{
float y0 = this->getPositionY();
y0 -= this->speed*1;
this->setPositionY(y0);
}
void Enemy::showHP()
{
slider = CCControlSlider::create("background.png", "progress.png", "fire.png");
slider->setPosition(ccp(this->getContentSize().width/2*this->getScale(),
this->getContentSize().height*this->getScale()+5));
//slider->setPosition(ccp(0,0));
slider->setScale(1.0/this->getScale());
slider->setMinimumValue(0);
slider->setMaximumValue(this->hp);
slider->setValue(this->hp);
slider->setTouchEnabled(false);
this->addChild(slider,2);
//slider->setVisible(false);
}
此时在主场景中可以添加怪物了
Enemy* enemy = Enemy::create();
int j=(int)(5.0*rand()/(RAND_MAX+1.0));
enemy->setPosition(p[j]);
this->addChild(enemy);
DataManage::sharedDataManage()->v_enemy.push_back(enemy);
主场景开启全局定时器以实现怪物的移动
this->scheduleUpdate();
定时器函数的实现
void GameScene::update( float dt )
{
//==========enemy run================
vector<Enemy*>::iterator it=DataManage::sharedDataManage()->v_enemy.begin();
while(it!=DataManage::sharedDataManage()->v_enemy.end())
{
if((*it)->hp<=0||(*it)->getPositionY()<100)
{
if ((*it)->hp<=0)
{
numKill++;
char s[10];
sprintf(s,"%d",numKill);
pLabel->setString(s);
}
(*it)->removeFromParentAndCleanup(true);
it = DataManage::sharedDataManage()->v_enemy.erase(it);
}else
{
(*it)->run();
it++;
}
}
}
这样,第一只怪物就会随机出现在五条道路中的一条,并向下移动
在定时器中加段代码,过一秒增加一只怪物
//===========add enemy=======
if (time>=60)
{
time=0;
Enemy* enemy = Enemy::create();
int j=(int)(5.0*rand()/(RAND_MAX+1.0));
enemy->setPosition(p[j]);
this->addChild(enemy);
DataManage::sharedDataManage()->v_enemy.push_back(enemy);
}else
time++;
怪物出现并跑动起来了,就是时候加塔进行攻击了
塔的类的实现Tower.h
#pragma once
#include "cocos2d.h"
#include "Box2D/Box2D.h"
#include "SimpleAudioEngine.h"
#include "Enemy.h"
#include "Fire.h"
using namespace cocos2d;
class Tower : public cocos2d::CCSprite
{
public:
Enemy* target;
Fire* bullet;
public:
static Tower* create();
virtual bool init(void);
//========左右移动========
void attack2();
};
Tower.cpp
#include "Tower.h"
#include "DataManage.h"
#include "GameScene.h"
USING_NS_CC;
Tower* Tower::create()
{
Tower *pobSprite = new Tower();
if (pobSprite && pobSprite->initWithFile("Tower.png"))
{
pobSprite->target = NULL;
pobSprite->autorelease();
return pobSprite;
}
CC_SAFE_DELETE(pobSprite);
return NULL;
}
bool Tower::init(void)
{
return true;
}
void Tower::attack2()
{
Fire* fire = Fire::create();
fire->setPosition(this->getPosition());
GameScene::sharedGameScene()->batchNode->addChild(fire,1);
DataManage::sharedDataManage()->v_fire.push_back(fire);
}
如上代码,我并没有在塔的类中去攻击,只是增加了子弹的出现,子弹的攻击也在主场景的定时器中去实现,整个游戏将只有开启一个定时器,实现实时刷新并增加怪物,怪物的跑动,塔的攻击
//==========fire run================
vector<Fire*>::iterator it0=DataManage::sharedDataManage()->v_fire.begin();
while(it0!=DataManage::sharedDataManage()->v_fire.end())
{
if((*it0)->getPositionY()>(origin.y+visibleSize.height))
{
(*it0)->removeFromParentAndCleanup(true);
it0 = DataManage::sharedDataManage()->v_fire.erase(it0);
}else
{
int i = (*it0)->run();
if (i==1)
{
(*it0)->removeFromParentAndCleanup(true);
it0 = DataManage::sharedDataManage()->v_fire.erase(it0);
}else
it0++;
}
}
//===========add fire=======
if (fireTime>=10)
{
fireTime=0;
tower->attack2();
}else
fireTime++;
塔是可以左右移动的,开启触摸代理
//=========开启点击事件============
CCDirector* pDirector = CCDirector::sharedDirector();
pDirector->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
//setTouchEnabled(true);
移动的实现
bool GameScene::ccTouchBegan( CCTouch *pTouch, CCEvent *pEvent )
{
CCPoint touchPoint = pTouch->getLocationInView();
touchPoint = CCDirector::sharedDirector()->convertToGL( touchPoint );
CCRect rc1 = tower->boundingBox();
if (rc1.containsPoint(touchPoint))
{
return true;
}
return false;
}
void GameScene::ccTouchMoved( CCTouch *pTouch, CCEvent *pEvent )
{
CCPoint beginPoint=pTouch->getLocationInView();
beginPoint=CCDirector::sharedDirector()->convertToGL(beginPoint);
CCPoint endPoint=pTouch->getPreviousLocationInView();
endPoint=CCDirector::sharedDirector()->convertToGL(endPoint);
CCPoint offSet =ccpSub(beginPoint,endPoint);
CCPoint toPoint=ccpAdd(tower->getPosition(),offSet);
CCPoint p = tower->getPosition();
p.x = toPoint.x;
if (p.x<=origin.x)
p.x = origin.x;
if (p.x>=(origin.x+visibleSize.width))
p.x = (origin.x+visibleSize.width);
tower->setPosition(p);
}
最后介绍一下一个单例,DataManage.h,保存全局数据,包括怪物,子弹
#pragma once
#include "cocos2d.h"
#include <vector>
#include "Enemy.h"
#include "Fire.h"
USING_NS_CC;
class DataManage : public cocos2d::CCObject
{
public:
vector<Enemy*>v_enemy;
vector<Fire*>v_fire;
public:
void init();
protected:
~DataManage();
public:
static DataManage* s_sharedDataManage;
static DataManage* sharedDataManage();
};
实现方法
#include "DataManage.h"
USING_NS_CC;
DataManage* DataManage::s_sharedDataManage = NULL;
DataManage* DataManage::sharedDataManage()
{
if (!s_sharedDataManage)
{
s_sharedDataManage = new DataManage();
s_sharedDataManage->init();
}
return s_sharedDataManage;
}
void DataManage::init()
{
v_enemy.clear();
v_fire.clear();
}
DataManage::~DataManage()
{
s_sharedDataManage = NULL;
}
好了,基本到这里,游戏就可以玩起来了,只是一个简易的小游戏,希望大家不要见怪。
本例子源代码附加资源下载地址:http://download.csdn.net/detail/nat_myron/7161837
资源纯属随意使用,如有版权问题,请不要见怪。
如文章有错误之处,欢迎指出,以便改正。