塔防游戏,类似于保卫萝卜的一种。

需要注意的是几点问题是:

  • 游戏地图是瓦片地图,设置特定的标记,用来标记哪些点是地图点,哪些是塔点。
  • 游戏关卡选择:需要在两个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的更多相关文章

  1. Cocos2D:塔防游戏制作之旅(十八)

    在Enemy.m的getDamaged:方法只给你添加如下1行(在if条件内): [theGame awardGold:200]; 现在运行游戏你将注意到你不能放置超出你资源金币的炮塔了.当然杀死敌人 ...

  2. Cocos2D:塔防游戏制作之旅(一)

    原文地址:http://www.raywenderlich.com/37701/how-to-make-a-tower-defense-game-tutorial 由Pablo Ruiz写的入门教程, ...

  3. Cocos2D:塔防游戏制作之旅(十六)

    编译运行你的app,放置一些炮塔在你的地图上吧!你将看到炮塔在敌人移动如攻击范围时如何立即开始攻击,并且敌人的血条将随着攻击不断减少知道它们被人道毁灭!胜利即将来临了! 哦!Okay,这里只有少数细节 ...

  4. Cocos2D:塔防游戏制作之旅(二)

    一个象牙塔的视图 如果你并不熟悉此类型的游戏,塔防游戏是一个战略游戏,你需要购买和将武装塔放置在战略位置,去阻止一波又一波的敌人到达并摧毁你的基地 每一波敌人都更强,这些更强的对手有着更快的速度和对于 ...

  5. Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(三)

    一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)篇 二.本篇目标: l  说说游戏中各种角色的动作.属性以及重构思路 l  进行代码重构让色狼大叔和 ...

  6. Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(二)

    一.前提: 完成前一篇的内容. 具体参考:Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)篇 二.本篇目标: l  说说关于cocos2dx手机分辨率适配 l  对前一篇完成的塔防游戏原型进 ...

  7. Cocos2d-x3.x塔防游戏(保卫萝卜)从零开始(一)

    一.前提: 完成Hello Game项目的创建编译. 具体参考:Cocos2dx.3x_Hello Game项目创建篇 二.本篇目标: l  说说关于塔防游戏的想法和思路 l  实现一个简单的塔防游戏 ...

  8. 制作一个塔防游戏 Cocos2d-x 2.1.4 (一)

    在这篇文章,将会学习到怎样制作一个塔防游戏.在这其中,学习怎样在设定的时间内出现一波波的敌人,使这些敌人沿着指定的路点前进.怎样在地图上指定的位置创建炮塔.怎样使炮塔射击敌人,怎样可视化调试路点和炮塔 ...

  9. 魔兽塔防游戏android源码

    魔兽塔防是一款经典的游戏,当年在pc机器上玩过魔兽的人应该都玩过类似的游戏,他仿照魔兽,建塔拦截敌人入侵,发挥你的智慧让敌人走最远的路,将他们消灭在路上.... 源码下载:http://code.66 ...

随机推荐

  1. PIE SDK元素位置和显示样式的修改

    1功能简介 在数据的处理中会出现根据需求进行元素的位置和显示样式的修改,使元素的形状,空间位置得到改变,下面将介绍基于PIE SDK的元素位置和显示样式的修改. 2功能实现说明 2.1.1 实现思路及 ...

  2. PIE SDK聚类

    1.算法功能简介 聚类处理时运用形态学算子将临近的类似分类区域聚类并合并. PIE SDK支持算法功能的执行,下面对聚类算法功能进行介绍. 2.算法功能实现说明 2.1. 实现步骤 第一步 算法参数设 ...

  3. Python学习 day06

    一.== 和 is ==  比较的是值 is   比较的是地址 id()  --  返回对象的内存地址 例: 赋值操作是将地址赋给变量 Python 中会实现创建一个小型的整形池,范围为 [-5,25 ...

  4. spring对异步的支持

    spring中异步方法的配置 1.在web.xml文件中设置org.springframework.web.servlet.DispatcherServlet的async-supported属性为tr ...

  5. Django_Xadmin 修改后台

      admin组件使用 Django 提供了基于 web页面的管理工具. Django 自动管理工具是 django.contrib 的一部分.你可以在项目的 settings.py 中的 INSTA ...

  6. pyspark 读写csv、json文件

    from pyspark import SparkContext,SparkConf import os from pyspark.sql.session import SparkSession de ...

  7. 里氏替换原则(Liskov Substitution Principle) LSP

    using System; using System.Collections.Generic; using System.Text; namespace LiskovSubstitutionPrinc ...

  8. C# 服务端控件 asp:RadioButton 选择选中值

    1.服务端控件RadioButton <asp:RadioButton ID="rbNewUser" runat="server" GroupName=& ...

  9. 项目搭建系列之二:SpringMVC框架下配置MyBatis

    1.什么是MyBatis? MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis ...

  10. 【阿里云产品公测】PTS压力测试服务器性能

    作者:阿里云用户xsnjxjj 在PTS服务之前,经常使用webbench来对服务器进行压力测试,在看到阿里云PTS服务的介绍以后,深深的被PTS强大的功能所吸引     非常感谢阿里云团队给予的测试 ...