塔防cocos2d
塔防游戏,类似于保卫萝卜的一种。
需要注意的是几点问题是:
- 游戏地图是瓦片地图,设置特定的标记,用来标记哪些点是地图点,哪些是塔点。
- 游戏关卡选择:需要在两个cpp文件传参,用的是静态成员变量。
- 每一关的不同点是地图的不一样,根据关卡使用不同地图,无需写重复的game1.cpp,game2.cpp。
- 每个塔对于在它范围内的物体进行攻击,一个双重循环。
展示一下效果吧:
公司Logo:
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__ #include "cocos2d.h"
using namespace cocos2d; class HelloWorld : public cocos2d::CCLayer
{
private:
CCSprite* LG;
public:
virtual bool init();
void BG(); virtual void registerWithTouchDispatcher(void);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); static cocos2d::CCScene* scene(); void menuCloseCallback(CCObject* pSender); CREATE_FUNC(HelloWorld);
}; #endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.h
#include "HelloWorldScene.h"
#include "hall.h" USING_NS_CC; CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create(); // 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene
scene->addChild(layer); // return the scene
return scene;
} void HelloWorld::BG() {
CCPoint _center = ccp(/, /);
CCSprite* bg = CCSprite::create("bg.png");
this->addChild(bg);
bg->setPosition(_center);
LG = CCSprite::create("logo.png");
this->addChild(LG);
LG->setPosition(ccp(/,)); LG->runAction(
CCMoveTo::create(,_center)
); } // on "init" you need to initialize your instance
bool HelloWorld::init()
{ if ( !CCLayer::init() )
{
return false;
}
BG(); this->setTouchEnabled(true);
return true;
} void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
#else
CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit();
#endif
#endif
} void HelloWorld::registerWithTouchDispatcher(void) {
//参数:作用范围,优先级,是否被吞噬
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,,true);
}
bool HelloWorld::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
return true;
}
void HelloWorld::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) { }
void HelloWorld::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
// 切换场景
CCScene* pGameScene = hall::scene();
pGameScene = CCTransitionFade::create(1.0f,pGameScene);
CCDirector::sharedDirector()->replaceScene(pGameScene); }
HelloWorldScene.cpp
开始界面(游戏大厅):
#ifndef _hall_H_
#endif #define _hall_H_
#include "cocos2d.h" using namespace cocos2d;
class hall : public CCLayer
{
private:
CCSprite* start;
public:
virtual bool init();
void BG();
static CCScene* scene(); virtual void registerWithTouchDispatcher(void);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); CREATE_FUNC(hall);
};
hall.h
#include "hall.h"
#include "Customs.h" USING_NS_CC; CCScene* hall::scene()
{
CCScene* pScene = CCScene::create();
hall* pLayer = hall::create();
pScene->addChild(pLayer);
return pScene;
} void hall::BG() {
CCPoint _center = ccp(*0.5f, *0.5f);
CCSprite* bg = CCSprite::create("background/start.png");
this->addChild(bg);
bg->setPosition(_center); start = CCSprite::create("start.png");
this->addChild(start);
start->setPosition(ccp(*0.5f,*0.5f-)); CCSprite* fish = CCSprite::create("fish/hall.png");
this->addChild(fish);
fish->setScale(0.2f);
fish->setPosition(ccp(,/)); fish->runAction(
CCRepeatForever::create(
CCSequence::create(
CCMoveTo::create(,ccp(,/)),
CCFlipX::create(true),
CCMoveTo::create(,ccp(,/)),
CCFlipX::create(false),
NULL
)
)
); } bool hall::init()
{
if (!CCLayer::init())
{
return true;
}
BG();
this->setTouchEnabled(true);
return true;
} void hall::registerWithTouchDispatcher(void) {
//参数:作用范围,优先级,是否被吞噬
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,,true);
}
bool hall::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
CCPoint touchPoint = pTouch->getLocation();
float minx = start->getPositionX() - / 2.0f;
float maxx = start->getPositionX() + / 2.0f;
float miny = start->getPositionY() - / 2.0f;
float maxy = start->getPositionY() + / 2.0f;
if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
start->setScale(2.0f); } return true;
}
void hall::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) { }
void hall::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
// 切换场景
CCPoint touchPoint = pTouch->getLocation();
float minx = start->getPositionX() - / 2.0f;
float maxx = start->getPositionX() + / 2.0f;
float miny = start->getPositionY() - / 2.0f;
float maxy = start->getPositionY() + / 2.0f;
if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
start->setScale(1.0f);
CCScene* pGameScene = Customs::scene();
pGameScene = CCTransitionFade::create(1.0f,pGameScene);
CCDirector::sharedDirector()->replaceScene(pGameScene); } }
hall.cpp
关卡选择:
#ifndef _Customs_H_
#endif #define _Customs_H_
#include "cocos2d.h" using namespace cocos2d;
class Customs : public CCLayer
{
private:
CCSprite* customs[];
public:
virtual bool init();
void BG();
static CCScene* scene();
static int lv; virtual void registerWithTouchDispatcher(void);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); CREATE_FUNC(Customs);
};
Customs.h
#include "Customs.h"
#include "game1.h" USING_NS_CC; CCScene* Customs::scene()
{
CCScene* pScene = CCScene::create();
Customs* pLayer = Customs::create();
pScene->addChild(pLayer);
return pScene;
} void Customs::BG() {
CCPoint _center = ccp(/, /);
CCSprite* bg = CCSprite::create("choice.png");
this->addChild(bg);
bg->setPosition(_center); int k=-;
char tmp[];
for(int i=; i<; i++){
sprintf(tmp,"customs/%d.png",i+);
customs[i] = CCSprite::create(tmp);
this->addChild(customs[i]);
customs[i]->setPosition(ccp(k, ));
k+=;
} } int Customs::lv = ; bool Customs::init()
{
if (!CCLayer::init())
{
return true;
} BG();
this->setTouchEnabled(true);
return true;
} void Customs::registerWithTouchDispatcher(void) {
//参数:作用范围,优先级,是否被吞噬
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,,true);
}
bool Customs::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) { return true;
}
void Customs::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) { }
void Customs::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
// 切换场景 CCPoint touchPoint = pTouch->getLocation(); for(int i = ; i < ; i ++) {
float minx = customs[i]->getPositionX() - / 2.0f;
float maxx = customs[i]->getPositionX() + / 2.0f;
float miny = customs[i]->getPositionY() - / 2.0f;
float maxy = customs[i]->getPositionY() + / 2.0f; if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
customs[i]->setScale(1.6f);
Customs::lv = i+;
CCScene* pGameScene = game1::scene(); pGameScene = CCTransitionFade::create(1.0f,pGameScene);
CCDirector::sharedDirector()->replaceScene(pGameScene); }
} }
Customs.cpp
游戏界面:
#ifndef _game1_H_
#endif #define _game1_H_
#include "cocos2d.h" using namespace cocos2d;
using namespace std; struct WayPoint {
CCPoint pos;
int index;
bool operator < (const WayPoint & rhs) const {
return index < rhs.index;
}
}; //塔
struct Cannon {
CCPoint pos;
int width,hight;
bool flag;
int kind;
}; //怪物
struct Monster {
CCSprite * sp;
int flag;
}; class game1 : public CCLayer
{
private:
void findPath(CCTMXTiledMap* tmxMap);
//A关节点
list<WayPoint> _listPoint_; //炮塔
Cannon cannon[];
//炮塔个数
int cnt; Monster spEnemy[];
int cntMonster; int wave;
int wave_cnt; int FlagVic;
//返回键
CCSprite * back;
public:
virtual bool init();
static CCScene* scene(); //背景
void BG();
//运动序列
CCSequence* createMoveAction();
virtual void registerWithTouchDispatcher(void);
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent); //默认调度器
//void update(float dt);
void shoot(float dt); CREATE_FUNC(game1);
};
game1.h
#include "game1.h"
#include "Customs.h" USING_NS_CC; #include "SimpleAudioEngine.h"
using namespace CocosDenshion; CCScene* game1::scene()
{
CCScene* pScene = CCScene::create();
game1* pLayer = game1::create();
pScene->addChild(pLayer);
return pScene;
} void game1::findPath(CCTMXTiledMap* tmxMap) {
this->cnt = ;
CCTMXObjectGroup* object = tmxMap->objectGroupNamed("object");
CCArray* objectsArray = object->getObjects();
for(int i = ; i < (int)objectsArray->count(); i++) {
// 字典 map key-value
CCDictionary* item = (CCDictionary*)objectsArray->objectAtIndex(i);
CCString* strX = (CCString*)item->valueForKey("x");
CCString* strY = (CCString*)item->valueForKey("y");
CCString* strWidth = (CCString*)item->valueForKey("width");
CCString* strHeight = (CCString*)item->valueForKey("height");
CCString* strWayPoint = (CCString*)item->valueForKey("waypointA");
int index = strWayPoint->intValue(); if(index!=) {
float x = strX->floatValue()+;
float y = strY->floatValue()+;
WayPoint wayPoint;
wayPoint.pos = CCPoint(x,y);
wayPoint.index = index;
_listPoint_.push_back(wayPoint);
} CCString *strBuild = (CCString*)item->valueForKey("build");
int build = strBuild->intValue();
if(build!=) {
float x = strX->floatValue()+;
float y = strY->floatValue()+;
cannon[this->cnt].pos = CCPoint(x,y);
cannon[this->cnt].width = strWidth->intValue();
cannon[this->cnt].hight = strHeight->intValue();
cannon[this->cnt].flag = false;
this->cnt++;
} } _listPoint_.sort();
//放房子 CCSprite* start_Point = CCSprite::create("house/house1.png");
CCSprite* end_Point = CCSprite::create("house/house2.png");
this->addChild(start_Point);
start_Point->setScale(0.2);
this->addChild(end_Point);
end_Point->setScale(0.2);
start_Point->setPosition(_listPoint_.begin()->pos);
end_Point->setPosition((--_listPoint_.end())->pos);
} // 创建寻路动作
CCSequence* game1::createMoveAction()
{
// 临时链表
list<WayPoint> _listPoint = this->_listPoint_;
// 动作数组
CCArray* actionArray = CCArray::create();
while (_listPoint.size() > )
{
WayPoint frontPoint = _listPoint.front();
// 删除第一个点
_listPoint.pop_front();
// 创建动作
float speed = ;
// 计算两点之间的距离
WayPoint nextPoint = _listPoint.front();
float x = (frontPoint.pos.x - nextPoint.pos.x);
float y = (frontPoint.pos.y - nextPoint.pos.y);
float dis = sqrt(x*x + y*y);
float t = dis / speed;
// 创建动作
CCMoveTo* moveTo = CCMoveTo::create(t, nextPoint.pos);
// 将动作添加到数组
actionArray->addObject(moveTo);
}
return CCSequence::create(actionArray);
} void game1::BG() {
CCPoint _center = ccp(*0.5f,*0.5f);
char bgtmp[];
sprintf(bgtmp,"background/level%d.png",Customs::lv);
CCSprite* bg = CCSprite::create(bgtmp);
this->addChild(bg);
bg->setPosition(_center);
//1.创建地图对象
char tmp[];
sprintf(tmp,"tmx/map%d.tmx",Customs::lv);
CCTMXTiledMap* tmxMap = CCTMXTiledMap::create(tmp);
//2.绘制地图
this->addChild(tmxMap);
findPath(tmxMap); //音乐
// 播放背景音乐
SimpleAudioEngine::sharedEngine()
->playBackgroundMusic("music/backgroundmusic1.mp3",true); back = CCSprite::create("back.png");
this->addChild(back);
back->setPosition(ccp(-,-)); wave = ;
wave_cnt = ;
FlagVic = ; } bool game1::init()
{
if (!CCLayer::init())
{
return true;
} BG(); WayPoint wayPoint = _listPoint_.front();
char fishtmp[];
cntMonster = ;
for(int j = ; j < wave; j++) {
for (int i = ; i < wave_cnt; i++)
{
// 创建一个怪物
sprintf(fishtmp,"fish/%d.png",(i+j)%+);
spEnemy[cntMonster].sp = CCSprite::create(fishtmp);
spEnemy[cntMonster].sp->setFlipX(true);
this->addChild(spEnemy[cntMonster].sp);
spEnemy[cntMonster].sp->setVisible(false);
spEnemy[cntMonster].sp->setPosition(wayPoint.pos);
spEnemy[cntMonster].flag = ;
spEnemy[cntMonster].sp->runAction(CCSequence::create(
CCDelayTime::create(i*0.8f+j*),
CCShow::create(),
createMoveAction(),
CCHide::create(),
NULL));
cntMonster++;
}
} this->setTouchEnabled(true);
this->schedule(schedule_selector(game1::shoot),0.5f);
return true;
} void game1::registerWithTouchDispatcher(void) {
//参数:作用范围,优先级,是否被吞噬
CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,,true);
}
bool game1::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent) {
return true;
}
void game1::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent) { }
void game1::ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent) {
CCPoint touchPoint = pTouch->getLocation(); for(int i = ; i < this->cnt; i++) {
CCPoint center = cannon[i].pos;
int wight = cannon[i].width/;
int hight = cannon[i].hight/;
if(touchPoint.x>center.x-wight&&touchPoint.x<center.x+wight&&touchPoint.y>center.y-hight&&touchPoint.y<center.y+hight) {
CCSprite* town = CCSprite::create("cannon.png");
this->addChild(town);
town->setScale(0.5);
town->setPosition(center);
//标记该炮塔有塔了
cannon[i].flag = true;
//音效
SimpleAudioEngine::sharedEngine()->playEffect("music/di.mp3");
}
}
//返回选择关卡
float minx = back->getPositionX() - ;
float maxx = back->getPositionX() + ;
float miny = back->getPositionY() - ;
float maxy = back->getPositionY() + ;
if(touchPoint.x>minx && touchPoint.x<maxx && touchPoint.y > miny && touchPoint.y < maxy) {
back->setScale(1.1f);
CCScene* pGameScene = Customs::scene();
pGameScene = CCTransitionFade::create(1.0f,pGameScene);
CCDirector::sharedDirector()->replaceScene(pGameScene);
FlagVic = ;
//关闭背景音乐
SimpleAudioEngine::sharedEngine()->stopBackgroundMusic(true);
}
} void game1::shoot(float dt) { for(int i = ; i < cntMonster; i++) {
if(spEnemy[i].flag) {
for(int j = ; j < cnt; j++) {
if(cannon[j].flag) { CCPoint Cannon_center = cannon[j].pos;
int hight = cannon[j].hight;
int wight = cannon[j].width;
//在射程范围内
if(cannon[j].pos.getDistance(spEnemy[i].sp->getPosition())<) {
CCSprite* tmp = CCSprite::create("bullet/BulletLizi_0.png");
this->addChild(tmp);
tmp->setPosition(cannon[j].pos);
SimpleAudioEngine::sharedEngine()->playEffect("music/bumm1.mp3");
tmp->runAction(CCSequence::create(CCMoveTo::create(0.1f,spEnemy[i].sp->getPosition()),CCHide::create(),NULL
));
spEnemy[i].flag--;
if(!spEnemy[i].flag) {
SimpleAudioEngine::sharedEngine()->playEffect("music/bumm2.mp3");
FlagVic++;
spEnemy[i].sp->setVisible(false);
}
if(FlagVic==wave*wave_cnt) {
CCSprite* k = CCSprite::create("congratulate.png");
this->addChild(k);
k->setPosition(ccp(/, /));
}
//CCLOG("dist = %d",spEnemy[i].sp->getPosition().getDistance(cannon[j].pos));
}
}
}
}
} }
game1.cpp
塔防cocos2d的更多相关文章
- Cocos2D:塔防游戏制作之旅(十八)
在Enemy.m的getDamaged:方法只给你添加如下1行(在if条件内): [theGame awardGold:200]; 现在运行游戏你将注意到你不能放置超出你资源金币的炮塔了.当然杀死敌人 ...
- Cocos2D:塔防游戏制作之旅(一)
原文地址:http://www.raywenderlich.com/37701/how-to-make-a-tower-defense-game-tutorial 由Pablo Ruiz写的入门教程, ...
- Cocos2D:塔防游戏制作之旅(十六)
编译运行你的app,放置一些炮塔在你的地图上吧!你将看到炮塔在敌人移动如攻击范围时如何立即开始攻击,并且敌人的血条将随着攻击不断减少知道它们被人道毁灭!胜利即将来临了! 哦!Okay,这里只有少数细节 ...
- Cocos2D:塔防游戏制作之旅(二)
一个象牙塔的视图 如果你并不熟悉此类型的游戏,塔防游戏是一个战略游戏,你需要购买和将武装塔放置在战略位置,去阻止一波又一波的敌人到达并摧毁你的基地 每一波敌人都更强,这些更强的对手有着更快的速度和对于 ...
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(三)
一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)篇 二.本篇目标: l 说说游戏中各种角色的动作.属性以及重构思路 l 进行代码重构让色狼大叔和 ...
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)
一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)篇 二.本篇目标: l 说说关于cocos2dx手机分辨率适配 l 对前一篇完成的塔防游戏原型进 ...
- Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)
一.前提: 完成Hello Game项目的创建编译. 具体参考:Cocos2dx.3x_Hello Game项目创建篇 二.本篇目标: l 说说关于塔防游戏的想法和思路 l 实现一个简单的塔防游戏 ...
- 制作一个塔防游戏 Cocos2d-x 2.1.4 (一)
在这篇文章,将会学习到怎样制作一个塔防游戏.在这其中,学习怎样在设定的时间内出现一波波的敌人,使这些敌人沿着指定的路点前进.怎样在地图上指定的位置创建炮塔.怎样使炮塔射击敌人,怎样可视化调试路点和炮塔 ...
- 魔兽塔防游戏android源码
魔兽塔防是一款经典的游戏,当年在pc机器上玩过魔兽的人应该都玩过类似的游戏,他仿照魔兽,建塔拦截敌人入侵,发挥你的智慧让敌人走最远的路,将他们消灭在路上.... 源码下载:http://code.66 ...
随机推荐
- 转 Oracle]如何在Oracle中设置Event
https://www.cnblogs.com/gaojian/p/7619960.html 为了调查Oracle 的故障,可以通过设置event ,来了解详细的状况.方法如下: ■ 如果使用 SPF ...
- Java调度线程池ScheduleExecutorService(续)
链接 Java线程池详解(一) Java线程池详解(二) Java调度线程池ScheduleExecutorService 上面列出了最近写的关于java线程池ScheduleExecutorServ ...
- rancher初级(搭建+基本操作+web应用部署)
Rancher搭建 首先rancher需要安装了docker的linux环境,我的系统版本为 在docker的基础上启动rancher服务器,Rancher 服务器是一个 Docker image,所 ...
- UI设计师与VI设计师的区别
企业视觉形象(CorporateVisualImage)与企业视觉形象识别(VI)并不是一个概念.前者是企业与生俱来的客观存在要素,也就是说一个企业无论是否制定了它的VI,也无论其所制定的VI是否成功 ...
- java集合常用操作
收集一些常用集合操作的代码,用于治疗健忘症,:) set转list //构造Map数据 Map<String, String> map = new HashMap<String, S ...
- unet知识点
https://www.bilibili.com/video/av8483444/?from=search&seid=17755425906400905363 https://www.jian ...
- [openStack]使用Fuel安装OpenStack juno的fuel_master
安装OpenStack是一件很复杂的事情,特别是在想目中,如果一个组件一个组件,一台一台的coding部署,估计太消耗时间,而且出错的概率很高,所以使用工具推送部署的效率就很高了,而且必须得可靠.mi ...
- SpringSecurity 3.2入门(5)自定义登录页面
增加spring-security.xml文件配置如下 <!-- 配置SpringSecurity的http安全服务 --> <security:http auto-config=& ...
- 数据库mysql中编码自动生成
call PrGetRuleCodeNoDate('Table_Name'); call PrGetRuleCode('Table_Name');
- Google Kickstart在线测试规则以及注意事项
谷歌招聘在如火如荼的进行中,进谷歌都需要经过谷歌kickstart在线测试,然后过了之后还有五轮的面试- -.好吧毕竟你待遇高,你强你有理.. 下面介绍一下进谷歌的第一关google kickstar ...