找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3881|回复: 14

自己动手写魔塔游戏

[复制链接]
发表于 2014-6-19 22:18:58 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
花了一个礼拜,学了cocos2dx   1000行c++代码的魔塔,麻雀虽小五脏俱全,甚至比原版魔塔有创新的地方。
比如支持直接点选怪物查看其属性,楼层切换动画,,打怪时允许撤离,,等,代码如下,注释已经写得很清楚,自行研究。
里面lambda表达式是我的得意之处,对于动画的过程回调我也着重研究了一番。做什么东西都不是那么容易的,嘴说说就可以做出来的,
这个魔塔也是,因为做的时候,你才会发现哪里要怎么写才好实现。现在仍有bug,不过已经无伤大雅了。现在做了4个关卡,有兴趣的,可以自己在做

AppDelegate.cpp

  1. #include "AppDelegate.h"
  2. #include "MagicTower.h"
  3. USING_NS_CC;
  4. AppDelegate::AppDelegate() {
  5. }
  6. AppDelegate::~AppDelegate()
  7. {
  8. }
  9. bool AppDelegate::applicationDidFinishLaunching() {
  10.     // initialize director
  11.     auto director = Director::getInstance();
  12.     auto glview = director->getOpenGLView();
  13.     if(!glview) {
  14.         glview = GLView::create("My Game");
  15.         director->setOpenGLView(glview);
  16.     }
  17.     // turn on display FPS
  18.     director->setDisplayStats(true);
  19.     // set FPS. the default value is 1.0/60 if you don't call this
  20.     director->setAnimationInterval(1.0 / 60);
  21.     // create a scene. it's an autorelease object
  22.     auto scene = MagicTowerLayerManager::getInstance().getScene();
  23.     // run
  24.     director->runWithScene(scene);
  25.     return true;
  26. }
  27. // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
  28. void AppDelegate::applicationDidEnterBackground() {
  29.     Director::getInstance()->stopAnimation();
  30.     // if you use SimpleAudioEngine, it must be pause
  31.     // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
  32. }
  33. // this function will be called when the app is active again
  34. void AppDelegate::applicationWillEnterForeground() {
  35.     Director::getInstance()->startAnimation();
  36.     // if you use SimpleAudioEngine, it must resume here
  37.     // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
  38. }

复制代码


AppDelegate.h

  1. #ifndef  _APP_DELEGATE_H_
  2. #define  _APP_DELEGATE_H_
  3. #include "cocos2d.h"
  4. /**
  5. @brief    The cocos2d Application.
  6. The reason for implement as private inheritance is to hide some interface call by Director.
  7. */
  8. class  AppDelegate : private cocos2d::Application
  9. {
  10. public:
  11.     AppDelegate();
  12.     virtual ~AppDelegate();
  13.     /**
  14.     @brief    Implement Director and Scene init code here.
  15.     @return true    Initialize success, app continue.
  16.     @return false   Initialize failed, app terminate.
  17.     */
  18.     virtual bool applicationDidFinishLaunching();
  19.     /**
  20.     @brief  The function be called when the application enter background
  21.     @param  the pointer of the application
  22.     */
  23.     virtual void applicationDidEnterBackground();
  24.     /**
  25.     @brief  The function be called when the application enter foreground
  26.     @param  the pointer of the application
  27.     */
  28.     virtual void applicationWillEnterForeground();
  29. };
  30. #endif // _APP_DELEGATE_H_

复制代码


MagicTower.cpp

  1. #include "MagicTower.h"
  2. #include "..\external\win32-specific\icon\include\iconv.h"
  3. #pragma comment(lib,"libiconv.lib")
  4. USING_NS_CC;
  5. using namespace CocosDenshion;
  6. bool IConvConvert(const char *from_charset, const char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen)
  7. {
  8. iconv_t cd = iconv_open(to_charset, from_charset);
  9. if (cd == 0) return false;
  10. const char **pin = &inbuf;
  11. char **pout = &outbuf;
  12. memset(outbuf,0,outlen);
  13. size_t ret = iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
  14. iconv_close(cd);
  15. return ret == (size_t)(-1) ? false : true;
  16. }
  17. std::string IConvConvert_GBKToUTF8(const std::string& str)
  18. {
  19. const char* textIn = str.c_str();
  20. char textOut[256];
  21. bool ret = IConvConvert("gb2312", "utf-8", textIn, strlen(textIn),textOut, 256);
  22. return ret ? std::string(textOut) : std::string();
  23. }
  24. // on "init" you need to initialize your instance
  25. MagicTower::MagicTower(int level)
  26. {
  27. thislevel=level;
  28. auto director=Director::getInstance();
  29. //director->getOpenGLView()->setFrameSize(416,416);
  30.     //////////////////////////////
  31.     // 1. super init first
  32.     Layer::init();
  33.     Size visibleSize = director->getVisibleSize();
  34.     Vec2 origin = director->getVisibleOrigin();
  35.     /////////////////////////////
  36.     // 2. add a menu item with "X" image, which is clicked to quit the program
  37.     //    you may modify it.
  38.     // add a "close" icon to exit the progress. it's an autorelease object
  39.     auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(MagicTower::menuCloseCallback, this));
  40. closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
  41.                                 origin.y + closeItem->getContentSize().height/2));
  42.     // create menu, it's an autorelease object
  43.     auto menuclose = Menu::create(closeItem, NULL);
  44.     menuclose->setPosition(Vec2::ZERO);
  45.     this->addChild(menuclose, 1);
  46.     /////////////////////////////
  47.     // 3. add your codes below...
  48. InitMap();
  49. InitHero();
  50. FlushBoard();
  51. //初始换方向键回调
  52. auto listener=EventListenerKeyboard::create();
  53. listener->onKeyPressed=CC_CALLBACK_2(MagicTower::OnMove,this);
  54. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
  55. }

  56. void MagicTower::InitMap()
  57. {
  58. //加载地图背景
  59. auto director=Director::getInstance();
  60. Size visibleSize = director->getVisibleSize();
  61. char mapname[20];
  62. sprintf(mapname,"%d.tmx",thislevel);
  63. map=TMXTiledMap::create(mapname);
  64. map->setAnchorPoint(Vec2(0.5f,0.5f));
  65. board.board=TMXTiledMap::create("background.tmx");
  66. board.board->setAnchorPoint(Vec2(0.5f,0.5f));
  67. map->setPosition(visibleSize.width/2,visibleSize.height/2+board.board->getContentSize().height/2);
  68. board.board->setPosition(visibleSize.width/2,visibleSize.height/2-map->getContentSize().height/2);
  69. addChild(map);
  70. addChild(board.board);
  71. InitBoard();
  72. //初始化地图元素
  73. Vector<SpriteFrame*> animFrames(4);
  74. auto enemylayer=map->getLayer("enemy");
  75. auto enemyTexture=enemylayer->getTexture();
  76. for(int i=0;i<map->getMapSize().width;i++)
  77. {
  78.   for(int j=0;j<map->getMapSize().height;j++)
  79.   {
  80.    int id=enemylayer->getTileGIDAt(Vec2(i,j));
  81.    if(id)
  82.    {
  83.     int index=(id-ENEMY_BEGIN)/4;
  84.     auto frame0=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*0,blocksize*index,blocksize,blocksize));
  85.     auto frame1=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*1,blocksize*index,blocksize,blocksize));
  86.     auto frame2=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*2,blocksize*index,blocksize,blocksize));
  87.     auto frame3=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*3,blocksize*index,blocksize,blocksize));
  88.     animFrames.pushBack(frame0);
  89.     animFrames.pushBack(frame1);
  90.     animFrames.pushBack(frame2);
  91.     animFrames.pushBack(frame3);
  92.     auto animation=Animation::createWithSpriteFrames(animFrames,0.1f);
  93.     animFrames.clear();
  94.     auto cursprite=enemylayer->getTileAt(Vec2(i,j));
  95.     if(!cursprite)
  96.      return;
  97.     cursprite->runAction(RepeatForever::create(Animate::create(animation)));
  98.     cursprite->setUserData(ObjManager::getInstance().InitEnemyByType(id));
  99.    }
  100.   }
  101. }
  102. //初始化点击事件
  103. auto listener=EventListenerTouchOneByOne::create();
  104. listener->onTouchBegan=[this,enemylayer](Touch* touch,Event* event)
  105. {
  106.   Vec2 tilepos;
  107.   WorldPosToTilePos(Vec2(touch->getLocation().x-blocksize/2,touch->getLocation().y-blocksize/2),tilepos);
  108.   if(tilepos.x >= 0 && tilepos.y >=0 &&
  109.    tilepos.x < enemylayer->getLayerSize().width && tilepos.y < enemylayer->getLayerSize().height)
  110.   {
  111.    Sprite* node=enemylayer->getTileAt(tilepos);
  112.    if(node)
  113.    {
  114.     SelectSprite(node);
  115.    }
  116.   }
  117.   //根据位置获取单元格,设置为选中状态并刷新数据到面板
  118.   return true;
  119. };
  120. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,enemylayer);
  121. auto itemlayer=map->getLayer("item");
  122. for(int i=0;i<map->getMapSize().width;i++)
  123. {
  124.   for(int j=0;j<map->getMapSize().height;j++)
  125.   {
  126.    int id=itemlayer->getTileGIDAt(Vec2(i,j));
  127.    auto cursprite=enemylayer->getTileAt(Vec2(i,j));
  128.    //if(id && cursprite)
  129.    //{
  130.    // cursprite->setUserData(ObjManager::getInstance().InitItemByType(id));
  131.    //}
  132.   }
  133. }
  134. //初始化门动画
  135. auto doorTexture=map->getLayer("door")->getTexture();
  136. int doordata[]={0,1,2,3};
  137. char* doorname[]={"DOOR_YELLOW","DOOR_BLUE","DOOR_RED","DOOR_GREEN"};
  138. for(int i=0;i<getNum(doordata);i++)
  139. {
  140.   doordata[i];
  141.   auto frame0=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*0,blocksize,blocksize));
  142.   auto frame1=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*1,blocksize,blocksize));
  143.   auto frame2=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*2,blocksize,blocksize));
  144.   auto frame3=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*3,blocksize,blocksize));
  145.   animFrames.pushBack(frame0);
  146.   animFrames.pushBack(frame1);
  147.   animFrames.pushBack(frame2);
  148.   animFrames.pushBack(frame3);
  149.   auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
  150.   animFrames.clear();
  151.   AnimationCache::getInstance()->addAnimation(animation,doorname[i]);
  152. }
  153. }
  154. void MagicTower::InitBoard()
  155. {
  156. //初始化面板
  157. char title[20];
  158. sprintf(title,"魔塔 第%d层",thislevel);
  159. board.maintitle=Label::createWithSystemFont(IConvConvert_GBKToUTF8(title),"黑体",30);
  160. board.maintitle->setColor(Color3B::GREEN);
  161. board.maintitle->setAnchorPoint(Vec2(0.5f,0.5f));
  162. board.maintitle->setPosition(board.board->getContentSize().width/2,blocksize*5+16);
  163. board.board->addChild(board.maintitle);
  164. board.heroname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("英雄"),"黑体",24);
  165. board.heroname->setColor(Color3B::RED);
  166. board.heroname->setAnchorPoint(Vec2(0.5f,0.5f));
  167. board.heroname->setPosition(board.board->getContentSize().width/4,blocksize*5-16);
  168. board.board->addChild(board.heroname);
  169. board.enemyname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("敌方"),"黑体",24);
  170. board.enemyname->setColor(Color3B::RED);
  171. board.enemyname->setAnchorPoint(Vec2(0.5f,0.5f));
  172. board.enemyname->setPosition(board.board->getContentSize().width*7/8,blocksize*5-16);
  173. board.board->addChild(board.enemyname);
  174. board.life_hero=Label::createWithBMFont("myfont.fnt","life");
  175. board.life_hero->setAnchorPoint(Vec2(0,0));
  176. board.life_hero->setScale(0.4f);
  177. board.life_hero->setPosition(blocksize*1,blocksize*3+5);
  178. board.board->addChild(board.life_hero);
  179. board.offense_hero=Label::createWithBMFont("myfont.fnt","offense");
  180. board.offense_hero->setAnchorPoint(Vec2(0,0));
  181. board.offense_hero->setScale(0.4f);
  182. board.offense_hero->setPosition(blocksize*1,blocksize*2+5);
  183. board.board->addChild(board.offense_hero);
  184. board.defense_hero=Label::createWithBMFont("myfont.fnt","defense");
  185. board.defense_hero->setAnchorPoint(Vec2(0,0));
  186. board.defense_hero->setScale(0.4f);
  187. board.defense_hero->setPosition(blocksize*1,blocksize*1+5);
  188. board.board->addChild(board.defense_hero);
  189. board.money_hero=Label::createWithBMFont("myfont.fnt","money");
  190. board.money_hero->setAnchorPoint(Vec2(0,0));
  191. board.money_hero->setScale(0.4f);
  192. board.money_hero->setPosition(blocksize*1,blocksize*0+5);
  193. board.board->addChild(board.money_hero);
  194. board.yellowkey=Label::createWithBMFont("myfont.fnt","yellowkey");
  195. board.yellowkey->setAnchorPoint(Vec2(0,0));
  196. board.yellowkey->setScale(0.4f);
  197. board.yellowkey->setPosition(blocksize*4,blocksize*3+5);
  198. board.board->addChild(board.yellowkey);
  199. board.bluekey=Label::createWithBMFont("myfont.fnt","bluekey");
  200. board.bluekey->setAnchorPoint(Vec2(0,0));
  201. board.bluekey->setScale(0.4f);
  202. board.bluekey->setPosition(blocksize*4,blocksize*2+5);
  203. board.board->addChild(board.bluekey);
  204. board.redkey=Label::createWithBMFont("myfont.fnt","redkey");
  205. board.redkey->setAnchorPoint(Vec2(0,0));
  206. board.redkey->setScale(0.4f);
  207. board.redkey->setPosition(blocksize*4,blocksize*1+5);
  208. board.board->addChild(board.redkey);
  209. board.life_enemy=Label::createWithBMFont("myfont.fnt","life");
  210. board.life_enemy->setAnchorPoint(Vec2(0,0));
  211. board.life_enemy->setScale(0.4f);
  212. board.life_enemy->setPosition(blocksize*11,blocksize*3+5);
  213. board.board->addChild(board.life_enemy);
  214. board.offense_enemy=Label::createWithBMFont("myfont.fnt","offense");
  215. board.offense_enemy->setAnchorPoint(Vec2(0,0));
  216. board.offense_enemy->setScale(0.4f);
  217. board.offense_enemy->setPosition(blocksize*11,blocksize*2+5);
  218. board.board->addChild(board.offense_enemy);
  219. board.defense_enemy=Label::createWithBMFont("myfont.fnt","defense");
  220. board.defense_enemy->setAnchorPoint(Vec2(0,0));
  221. board.defense_enemy->setScale(0.4f);
  222. board.defense_enemy->setPosition(blocksize*11,blocksize*1+5);
  223. board.board->addChild(board.defense_enemy);
  224. }
  225. void MagicTower::InitHero()
  226. {
  227. ismoving=false;
  228. //加载英雄图片
  229. auto director=Director::getInstance();
  230. Size visibleSize = director->getVisibleSize();
  231. auto heroTexture=Director::getInstance()->getTextureCache()->addImage("hero.png");
  232. auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*1,blocksize,blocksize));
  233. hero.heroSprite=Sprite::createWithSpriteFrame(frame0);
  234. hero.heroSprite->setAnchorPoint(Vec2(0,0));
  235. MoveUnitInTile(hero.nexttilepos,hero.heroSprite);
  236. addChild(hero.heroSprite);
  237. //存储英雄移动动画
  238. std::string dirname[]={"down","left","right","up"};
  239. Vector<SpriteFrame*> animFrames(4);
  240. for(int i=0;i<4;i++)
  241. {
  242.   auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*i,blocksize,blocksize));
  243.   auto frame1=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*1,blocksize*i,blocksize,blocksize));
  244.   auto frame2=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*2,blocksize*i,blocksize,blocksize));
  245.   auto frame3=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*3,blocksize*i,blocksize,blocksize));
  246.   animFrames.pushBack(frame0);
  247.   animFrames.pushBack(frame1);
  248.   animFrames.pushBack(frame2);
  249.   animFrames.pushBack(frame3);
  250.   auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
  251.   animation->setRestoreOriginalFrame(false);
  252.   AnimationCache::getInstance()->addAnimation(animation,dirname[i]);
  253.   animFrames.clear();
  254. }
  255. //初始化攻击动画
  256. auto attackTexture= Director::getInstance()->getTextureCache()->addImage("attack.png");
  257. Size unitsize=attackTexture->getContentSizeInPixels();
  258. for(int i=0;i<25;i++)
  259. {
  260.   auto frame0=SpriteFrame::createWithTexture(attackTexture,
  261.    Rect(i/5*unitsize.width/5,i%5*unitsize.height/5,unitsize.width/5,unitsize.height/5));
  262.   animFrames.pushBack(frame0);
  263. }
  264. AnimationCache::getInstance()->addAnimation(Animation::createWithSpriteFrames(animFrames,0.05f),"attack");
  265. animFrames.clear();
  266. }
  267. void MagicTower::menuCloseCallback(Ref* pSender)
  268. {
  269. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
  270. MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
  271.     return;
  272. #endif
  273.     Director::getInstance()->end();
  274. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
  275.     exit(0);
  276. #endif
  277. }
  278. void MagicTower::OnMove(EventKeyboard::KeyCode keyCode, Event* event)
  279. {
  280. auto animCache=AnimationCache::getInstance();
  281. Animation* curanimation=NULL;
  282. Vec2 delta;
  283. switch(keyCode)
  284. {
  285.   case EventKeyboard::KeyCode::KEY_UP_ARROW:
  286.    curanimation=animCache->getAnimation("up");
  287.    delta.setPoint(0,blocksize);
  288.    break;
  289.   case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
  290.    curanimation=animCache->getAnimation("down");
  291.    delta.setPoint(0,-blocksize);
  292.    break;
  293.   case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
  294.    curanimation=animCache->getAnimation("left");
  295.    delta.setPoint(-blocksize,0);
  296.    break;
  297.   case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
  298.    curanimation=animCache->getAnimation("right");
  299.    delta.setPoint(blocksize,0);
  300.    break;
  301.   default:
  302.    return DefaultKeyboardDispatcher(keyCode);
  303. }
  304. //判断英雄位置是否可以移动
  305. if(curanimation && !ismoving)
  306. {
  307.   MoveHero(hero.heroSprite->getPosition()+delta,curanimation,keyCode);
  308. }
  309. }
  310. void MagicTower::PlayHeroMovement(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode,
  311.          const std::function<void(void)>& afteraction)
  312. {//anim:帧动画  afteraction:状态更新回调
  313. hero.heroSprite->setSpriteFrame(anim->getFrames().at(0)->getSpriteFrame());

  314. //移动动画和帧动画同时进行
  315. auto spawn=Spawn::createWithTwoActions(Animate::create(anim),MoveTo::create(0.2f,newpos));
  316. //帧动画+移动动画 -> 状态更新 -> 可通行 -> 连击检测
  317. hero.heroSprite->runAction(Sequence::create(spawn,CallFuncN::create([this,afteraction,keyCode](Node* node)
  318. {//所有回调函数需要写一起,否则单另作为Sequence依次执行会失效,不知道是不是bug
  319.   afteraction();
  320.   ismoving=false;
  321.   CCLog("ismoving");
  322.   FlushBoard();
  323.   if(!ismoving)
  324.   {
  325.    if((keyCode == EventKeyboard::KeyCode::KEY_UP_ARROW && GetKeyState(VK_UP) < 0) ||
  326.     (keyCode == EventKeyboard::KeyCode::KEY_DOWN_ARROW && GetKeyState(VK_DOWN) < 0) ||
  327.     (keyCode == EventKeyboard::KeyCode::KEY_LEFT_ARROW && GetKeyState(VK_LEFT) < 0) ||
  328.     (keyCode == EventKeyboard::KeyCode::KEY_RIGHT_ARROW && GetKeyState(VK_RIGHT) < 0))
  329.    {
  330.     OnMove(keyCode,NULL);
  331.    }
  332.   }
  333. }),NULL));
  334. }
  335. void MagicTower::MoveHero(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode)
  336. {//若成功,则捡物品或者攻击
  337. ismoving=true;
  338. Vec2 tilepos;
  339. WorldPosToTilePos(newpos,tilepos);
  340. if(map->getLayer("floor")->getTileGIDAt(tilepos) == FLOOR_WALL)
  341. {//禁止通行
  342.   ismoving=false;
  343.   return;
  344. }
  345. //若是地板则进行上层判断
  346. auto layer=map->getLayer("item");
  347. switch(layer->getTileGIDAt(tilepos))
  348. {
  349.   case ITEM_REDDIAMOND:
  350.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  351.    {//刷新+音乐+物品动画
  352.     hero.offense += 100;
  353.     layer->removeChild(layer->getTileAt(tilepos),true);
  354.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  355.    });
  356.    return;
  357.   case ITEM_BLUEDIAMOND:
  358.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  359.    {//刷新+音乐+物品动画
  360.     hero.defense += 50;
  361.     layer->removeChild(layer->getTileAt(tilepos),true);
  362.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  363.    });
  364.    return;
  365.   case ITEM_REDBLOOD:
  366.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  367.    {//刷新+音乐+物品动画
  368.     hero.life += 400;
  369.     layer->removeChild(layer->getTileAt(tilepos),true);
  370.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  371.    });
  372.    return;
  373.   case ITEM_BLUEBLOOD:
  374.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  375.    {//刷新+音乐+物品动画
  376.     hero.life += 200;
  377.     layer->removeChild(layer->getTileAt(tilepos),true);
  378.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  379.    });
  380.    return;
  381.    
  382.   case ITEM_YELLOWKEY:
  383.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  384.    {//刷新+音乐+物品动画
  385.     hero.keyyellow++;
  386.     layer->removeChild(layer->getTileAt(tilepos),true);
  387.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  388.    });
  389.    return;
  390.    
  391.   case ITEM_BLUEKEY:
  392.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  393.    {//刷新+音乐+物品动画
  394.     hero.keyblue++;
  395.     layer->removeChild(layer->getTileAt(tilepos),true);
  396.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  397.    });
  398.    return;
  399.    
  400.   case ITEM_REDKEY:
  401.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  402.    {//刷新+音乐+物品动画
  403.     hero.keyred++;
  404.     layer->removeChild(layer->getTileAt(tilepos),true);
  405.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  406.    });
  407.    return;
  408.    
  409.   default://若为空,执行上层判断
  410.    break;
  411. }
  412. layer=map->getLayer("enemy");
  413. if(layer->getTileGIDAt(tilepos))
  414. {//若有敌人
  415.   PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  416.   {
  417.    auto animation=AnimationCache::getInstance()->getAnimation("attack");
  418.    auto attacksprite=Sprite::createWithSpriteFrame(animation->getFrames().at(0)->getSpriteFrame());
  419.    attacksprite->setAnchorPoint(Vec2(0,0));
  420.    attacksprite->setPosition(-attacksprite->getContentSize().width/4,-attacksprite->getContentSize().height/4);
  421.    //开始攻击动画+音乐
  422.    hero.heroSprite->addChild(attacksprite);
  423.    attackEnemy(layer,tilepos,attacksprite,Animate::create(animation));
  424.   });
  425.   return;
  426. }
  427. //若为空,执行上层判断
  428. layer=map->getLayer("door");
  429. switch(layer->getTileGIDAt(tilepos))
  430. {
  431.   case DOOR_YELLOW:
  432.    {
  433.     hero.keyyellow--;
  434.     auto animation=AnimationCache::getInstance()->getAnimation("DOOR_YELLOW");
  435.     auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  436.      CallFuncN::create([layer,tilepos](Node*){
  437.       layer->removeChild(layer->getTileAt(tilepos),true);
  438.     })),CallFuncN::create([](Node*){
  439.      SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  440.     }));
  441.     layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  442.      CallFuncN::create([this,newpos,anim,keyCode](Node*){
  443.       PlayHeroMovement(newpos,anim,keyCode,[](){});
  444.     })));   
  445.    }
  446.    return;
  447.   case DOOR_BLUE:
  448.    {
  449.     hero.keyblue--;
  450.     auto animation=AnimationCache::getInstance()->getAnimation("DOOR_BLUE");
  451.     auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  452.      CallFuncN::create([layer,tilepos](Node*){
  453.       layer->removeChild(layer->getTileAt(tilepos),true);
  454.     })),CallFuncN::create([](Node*){
  455.      SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  456.     }));
  457.     layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  458.      CallFuncN::create([this,newpos,anim,keyCode](Node*){
  459.       PlayHeroMovement(newpos,anim,keyCode,[](){});
  460.     })));  
  461.    }
  462.    return;
  463.   case DOOR_RED:
  464.    {
  465.     hero.keyred--;
  466.     auto animation=AnimationCache::getInstance()->getAnimation("DOOR_RED");
  467.     auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  468.      CallFuncN::create([layer,tilepos](Node*){
  469.       layer->removeChild(layer->getTileAt(tilepos),true);
  470.     })),CallFuncN::create([](Node*){
  471.      SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  472.     }));
  473.     layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  474.      CallFuncN::create([this,newpos,anim,keyCode](Node*){
  475.       PlayHeroMovement(newpos,anim,keyCode,[](){});
  476.     })));
  477.    }
  478.    return;
  479.   
  480.   case DOOR_GREEN:
  481.    ismoving=false;
  482.    return;
  483.   case DOOR_UPSTAIRS:
  484.    {
  485.     //更新地图
  486.     Director::getInstance()->setDepthTest(false);
  487.     hero.nexttilepos=Vec2(HeroInitPos[(thislevel+1)*4],HeroInitPos[(thislevel+1)*4+1]);
  488.     auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel+1));
  489.     if(trans)
  490.      Director::getInstance()->replaceScene(trans);
  491.     ismoving=false;
  492.    }
  493.    return;
  494.   case DOOR_DOWNSTAIRS:
  495.    {
  496.     //更新地图
  497.     Director::getInstance()->setDepthTest(false);
  498.     hero.nexttilepos=Vec2(HeroInitPos[(thislevel-1)*4+2],HeroInitPos[(thislevel-1)*4+3]);
  499.     auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel-1));
  500.     if(trans)
  501.      Director::getInstance()->replaceScene(trans);
  502.     ismoving=false;
  503.    }
  504.    return;
  505. }
  506. //若无对象存在,则移动英雄
  507. PlayHeroMovement(newpos,anim,keyCode,[](){});
  508. //在执行PlayerHeroMovement的地方,ismoving交给该函数处理
  509. }
  510. void MagicTower::attackEnemy(TMXLayer* layer,Vec2 tilepos,Sprite* attacksprite,Animate* animate)
  511. {
  512. //判断英雄是否移动了,如果移动则去除animate并结束
  513. Vec2 herointile;
  514. WorldPosToTilePos(hero.heroSprite->getPosition(),herointile);
  515. if(herointile != tilepos)
  516. {
  517.   attacksprite->stopAllActions();
  518.   hero.heroSprite->removeChild(attacksprite,true);
  519.   return;
  520. }
  521. attacksprite->runAction(Sequence::create(animate,CallFuncN::create([this,layer,tilepos,animate](Node* attacksprite)
  522. {
  523.   ValueMap* val=static_cast<ValueMap*>(layer->getTileAt(tilepos)->getUserData());
  524.   int enemylife=(*val)["life"].asInt();
  525.   int enemyoffense=(*val)["offense"].asInt();
  526.   int enemydefense=(*val)["defense"].asInt();
  527.   int harmetoh=(hero.defense>enemyoffense)?0:enemyoffense-hero.defense;//enemy对hero造成的伤害,如果hero的防>enemy的攻,则无伤害
  528.   int harmhtoe=(enemydefense>hero.offense)?0:hero.offense-enemydefense;
  529.   hero.life -= harmetoh;
  530.   enemylife -= harmhtoe;
  531.   SimpleAudioEngine::getInstance()->playEffect("fight.mp3");
  532.   (*val)["life"]=enemylife;
  533.   FlushBoard(val);
  534.   if(enemylife < 0 || hero.life < 0)
  535.   {
  536.    if(hero.life < 0)
  537.    {//英雄挂了
  538.    }
  539.    else
  540.    {
  541.     attacksprite->stopAllActions();
  542.     hero.money += (*val)["money"].asInt();
  543.     hero.heroSprite->removeChild(attacksprite,true);
  544.     layer->removeChild(layer->getTileAt(tilepos),true);
  545.     FlushBoard(val);
  546.     //刷新面板
  547.    }
  548.   }
  549.   else
  550.   {
  551.    attackEnemy(layer,tilepos,static_cast<Sprite*>(attacksprite),animate);
  552.   }
  553. }),NULL));
  554. }
  555. void MagicTower::DefaultKeyboardDispatcher(EventKeyboard::KeyCode keycode)
  556. {//处理其他键盘事件

  557. }
  558. void MagicTower::WorldPosToTilePos(const Vec2& pos,Vec2& objpos)
  559. {//pos为世界坐标系,相对于窗口左下角,目标锚点位于左下角
  560. float rex=map->getContentSize().width/2+(pos.x+blocksize/2-map->getPosition().x);
  561. float rey=map->getContentSize().height/2-(pos.y+blocksize/2-map->getPosition().y);
  562. objpos.setPoint(int(rex/blocksize),int(rey/blocksize));
  563. }
  564. void MagicTower::TilePosToWorldPos(const Vec2& pos,Vec2& objpos)
  565. {//pos为Tile坐标系,相对于窗口左上角
  566. float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
  567. float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y;
  568. objpos.setPoint(rex,rey);
  569. }
  570. void MagicTower::MoveUnitInTile(const Vec2& pos,Sprite* obj)
  571. {//pos为Tile坐标系,相对于左上角
  572. float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
  573. float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y-blocksize;
  574. obj->setPosition(rex,rey);
  575. }
  576. void MagicTower::FlushBoard(ValueMap* obj)
  577. {
  578. char str[20];
  579. sprintf(str,"魔塔 第%d层",thislevel);
  580. board.maintitle->setString(IConvConvert_GBKToUTF8(str));
  581. board.heroname->setString(IConvConvert_GBKToUTF8(hero.name));
  582. sprintf(str,"%d",hero.life);
  583. board.life_hero->setString(IConvConvert_GBKToUTF8(str));
  584. sprintf(str,"%d",hero.offense);
  585. board.offense_hero->setString(IConvConvert_GBKToUTF8(str));
  586. sprintf(str,"%d",hero.defense);
  587. board.defense_hero->setString(IConvConvert_GBKToUTF8(str));
  588. sprintf(str,"%d",hero.money);
  589. board.money_hero->setString(IConvConvert_GBKToUTF8(str));
  590. sprintf(str,"%d",hero.keyyellow);
  591. board.yellowkey->setString(IConvConvert_GBKToUTF8(str));
  592. sprintf(str,"%d",hero.keyblue);
  593. board.bluekey->setString(IConvConvert_GBKToUTF8(str));
  594. sprintf(str,"%d",hero.keyred);
  595. board.redkey->setString(IConvConvert_GBKToUTF8(str));
  596. if(obj)
  597. {
  598.   int category=(*obj)["category"].asInt();
  599.   if(category == TYPE_ENEMY)
  600.   {
  601.    board.enemyname->setString(IConvConvert_GBKToUTF8((*obj)["name"].asString()));
  602.    sprintf(str,"%d",(*obj)["life"].asInt());
  603.    board.life_enemy->setString(IConvConvert_GBKToUTF8(str));
  604.    sprintf(str,"%d",(*obj)["offense"].asInt());
  605.    board.offense_enemy->setString(IConvConvert_GBKToUTF8(str));
  606.    sprintf(str,"%d",(*obj)["defense"].asInt());
  607.    board.defense_enemy->setString(IConvConvert_GBKToUTF8(str));
  608.   }
  609.   else if(category == TYPE_ITEM)
  610.   {
  611.   }
  612. }
  613. }
  614. void MagicTower::SelectSprite(Sprite* sprite)
  615. {
  616. auto data=static_cast<ValueMap*>(sprite->getUserData());
  617. if((*data)["selected"].asBool())
  618. {
  619.   sprite->removeChildByTag('sel');
  620.   (*data)["selected"]=false;
  621. }
  622. else
  623. {
  624.   auto texture=map->getLayer("enemy")->getTexture();
  625.   int hei=texture->getContentSize().height;
  626.   auto selsprite=Sprite::createWithTexture(texture,Rect(0,texture->getContentSize().height-blocksize,blocksize,blocksize));//设置为最后一个
  627.   selsprite->setAnchorPoint(Vec2(0,0));
  628.   selsprite->setPosition(0,0);
  629.   sprite->addChild(selsprite,selsprite->getLocalZOrder(),'sel');
  630.   FlushBoard(data);
  631.   (*data)["selected"]=true;
  632. }
  633. }
  634. //MagicTowerLayerManager管理场景切换
  635. MagicTowerLayerManager& MagicTowerLayerManager::getInstance()
  636. {
  637. static MagicTowerLayerManager manager;
  638. return manager;
  639. }
  640. Scene* MagicTowerLayerManager::getScene(int layer)
  641. {
  642. curlayer=layer;
  643. auto curscene=Scene::create();
  644. auto curlayer=new MagicTower(layer);
  645. if (curscene && curlayer)
  646. {
  647.   curscene->addChild(curlayer);
  648.   curlayer->autorelease();
  649. }
  650. return curscene;
  651. }
  652. Hero MagicTower::hero;
  653. Board MagicTower::board;
  654. MagicTowerLayerManager::MagicTowerLayerManager()
  655. {
  656. curlayer=1;
  657. MagicTower::hero.name="勇士";
  658. MagicTower::hero.life=1000;
  659. MagicTower::hero.offense=200;
  660. MagicTower::hero.defense=200;
  661. MagicTower::hero.keyyellow=10;
  662. MagicTower::hero.keyblue=10;
  663. MagicTower::hero.keyred=10;
  664. MagicTower::hero.money=1000;
  665. MagicTower::hero.nexttilepos=Vec2(6,11);//初始化
  666. }


复制代码


MagicTower.h

  1. #include "MagicTower.h"
  2. #include "..\external\win32-specific\icon\include\iconv.h"
  3. #pragma comment(lib,"libiconv.lib")
  4. USING_NS_CC;
  5. using namespace CocosDenshion;
  6. bool IConvConvert(const char *from_charset, const char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen)
  7. {
  8. iconv_t cd = iconv_open(to_charset, from_charset);
  9. if (cd == 0) return false;
  10. const char **pin = &inbuf;
  11. char **pout = &outbuf;
  12. memset(outbuf,0,outlen);
  13. size_t ret = iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
  14. iconv_close(cd);
  15. return ret == (size_t)(-1) ? false : true;
  16. }
  17. std::string IConvConvert_GBKToUTF8(const std::string& str)
  18. {
  19. const char* textIn = str.c_str();
  20. char textOut[256];
  21. bool ret = IConvConvert("gb2312", "utf-8", textIn, strlen(textIn),textOut, 256);
  22. return ret ? std::string(textOut) : std::string();
  23. }
  24. // on "init" you need to initialize your instance
  25. MagicTower::MagicTower(int level)
  26. {
  27. thislevel=level;
  28. auto director=Director::getInstance();
  29. //director->getOpenGLView()->setFrameSize(416,416);
  30.     //////////////////////////////
  31.     // 1. super init first
  32.     Layer::init();
  33.     Size visibleSize = director->getVisibleSize();
  34.     Vec2 origin = director->getVisibleOrigin();
  35.     /////////////////////////////
  36.     // 2. add a menu item with "X" image, which is clicked to quit the program
  37.     //    you may modify it.
  38.     // add a "close" icon to exit the progress. it's an autorelease object
  39.     auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(MagicTower::menuCloseCallback, this));
  40. closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
  41.                                 origin.y + closeItem->getContentSize().height/2));
  42.     // create menu, it's an autorelease object
  43.     auto menuclose = Menu::create(closeItem, NULL);
  44.     menuclose->setPosition(Vec2::ZERO);
  45.     this->addChild(menuclose, 1);
  46.     /////////////////////////////
  47.     // 3. add your codes below...
  48. InitMap();
  49. InitHero();
  50. FlushBoard();
  51. //初始换方向键回调
  52. auto listener=EventListenerKeyboard::create();
  53. listener->onKeyPressed=CC_CALLBACK_2(MagicTower::OnMove,this);
  54. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
  55. }

  56. void MagicTower::InitMap()
  57. {
  58. //加载地图背景
  59. auto director=Director::getInstance();
  60. Size visibleSize = director->getVisibleSize();
  61. char mapname[20];
  62. sprintf(mapname,"%d.tmx",thislevel);
  63. map=TMXTiledMap::create(mapname);
  64. map->setAnchorPoint(Vec2(0.5f,0.5f));
  65. board.board=TMXTiledMap::create("background.tmx");
  66. board.board->setAnchorPoint(Vec2(0.5f,0.5f));
  67. map->setPosition(visibleSize.width/2,visibleSize.height/2+board.board->getContentSize().height/2);
  68. board.board->setPosition(visibleSize.width/2,visibleSize.height/2-map->getContentSize().height/2);
  69. addChild(map);
  70. addChild(board.board);
  71. InitBoard();
  72. //初始化地图元素
  73. Vector<SpriteFrame*> animFrames(4);
  74. auto enemylayer=map->getLayer("enemy");
  75. auto enemyTexture=enemylayer->getTexture();
  76. for(int i=0;i<map->getMapSize().width;i++)
  77. {
  78.   for(int j=0;j<map->getMapSize().height;j++)
  79.   {
  80.    int id=enemylayer->getTileGIDAt(Vec2(i,j));
  81.    if(id)
  82.    {
  83.     int index=(id-ENEMY_BEGIN)/4;
  84.     auto frame0=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*0,blocksize*index,blocksize,blocksize));
  85.     auto frame1=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*1,blocksize*index,blocksize,blocksize));
  86.     auto frame2=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*2,blocksize*index,blocksize,blocksize));
  87.     auto frame3=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*3,blocksize*index,blocksize,blocksize));
  88.     animFrames.pushBack(frame0);
  89.     animFrames.pushBack(frame1);
  90.     animFrames.pushBack(frame2);
  91.     animFrames.pushBack(frame3);
  92.     auto animation=Animation::createWithSpriteFrames(animFrames,0.1f);
  93.     animFrames.clear();
  94.     auto cursprite=enemylayer->getTileAt(Vec2(i,j));
  95.     if(!cursprite)
  96.      return;
  97.     cursprite->runAction(RepeatForever::create(Animate::create(animation)));
  98.     cursprite->setUserData(ObjManager::getInstance().InitEnemyByType(id));
  99.    }
  100.   }
  101. }
  102. //初始化点击事件
  103. auto listener=EventListenerTouchOneByOne::create();
  104. listener->onTouchBegan=[this,enemylayer](Touch* touch,Event* event)
  105. {
  106.   Vec2 tilepos;
  107.   WorldPosToTilePos(Vec2(touch->getLocation().x-blocksize/2,touch->getLocation().y-blocksize/2),tilepos);
  108.   if(tilepos.x >= 0 && tilepos.y >=0 &&
  109.    tilepos.x < enemylayer->getLayerSize().width && tilepos.y < enemylayer->getLayerSize().height)
  110.   {
  111.    Sprite* node=enemylayer->getTileAt(tilepos);
  112.    if(node)
  113.    {
  114.     SelectSprite(node);
  115.    }
  116.   }
  117.   //根据位置获取单元格,设置为选中状态并刷新数据到面板
  118.   return true;
  119. };
  120. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,enemylayer);
  121. auto itemlayer=map->getLayer("item");
  122. for(int i=0;i<map->getMapSize().width;i++)
  123. {
  124.   for(int j=0;j<map->getMapSize().height;j++)
  125.   {
  126.    int id=itemlayer->getTileGIDAt(Vec2(i,j));
  127.    auto cursprite=enemylayer->getTileAt(Vec2(i,j));
  128.    //if(id && cursprite)
  129.    //{
  130.    // cursprite->setUserData(ObjManager::getInstance().InitItemByType(id));
  131.    //}
  132.   }
  133. }
  134. //初始化门动画
  135. auto doorTexture=map->getLayer("door")->getTexture();
  136. int doordata[]={0,1,2,3};
  137. char* doorname[]={"DOOR_YELLOW","DOOR_BLUE","DOOR_RED","DOOR_GREEN"};
  138. for(int i=0;i<getNum(doordata);i++)
  139. {
  140.   doordata[i];
  141.   auto frame0=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*0,blocksize,blocksize));
  142.   auto frame1=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*1,blocksize,blocksize));
  143.   auto frame2=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*2,blocksize,blocksize));
  144.   auto frame3=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*3,blocksize,blocksize));
  145.   animFrames.pushBack(frame0);
  146.   animFrames.pushBack(frame1);
  147.   animFrames.pushBack(frame2);
  148.   animFrames.pushBack(frame3);
  149.   auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
  150.   animFrames.clear();
  151.   AnimationCache::getInstance()->addAnimation(animation,doorname[i]);
  152. }
  153. }
  154. void MagicTower::InitBoard()
  155. {
  156. //初始化面板
  157. char title[20];
  158. sprintf(title,"魔塔 第%d层",thislevel);
  159. board.maintitle=Label::createWithSystemFont(IConvConvert_GBKToUTF8(title),"黑体",30);
  160. board.maintitle->setColor(Color3B::GREEN);
  161. board.maintitle->setAnchorPoint(Vec2(0.5f,0.5f));
  162. board.maintitle->setPosition(board.board->getContentSize().width/2,blocksize*5+16);
  163. board.board->addChild(board.maintitle);
  164. board.heroname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("英雄"),"黑体",24);
  165. board.heroname->setColor(Color3B::RED);
  166. board.heroname->setAnchorPoint(Vec2(0.5f,0.5f));
  167. board.heroname->setPosition(board.board->getContentSize().width/4,blocksize*5-16);
  168. board.board->addChild(board.heroname);
  169. board.enemyname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("敌方"),"黑体",24);
  170. board.enemyname->setColor(Color3B::RED);
  171. board.enemyname->setAnchorPoint(Vec2(0.5f,0.5f));
  172. board.enemyname->setPosition(board.board->getContentSize().width*7/8,blocksize*5-16);
  173. board.board->addChild(board.enemyname);
  174. board.life_hero=Label::createWithBMFont("myfont.fnt","life");
  175. board.life_hero->setAnchorPoint(Vec2(0,0));
  176. board.life_hero->setScale(0.4f);
  177. board.life_hero->setPosition(blocksize*1,blocksize*3+5);
  178. board.board->addChild(board.life_hero);
  179. board.offense_hero=Label::createWithBMFont("myfont.fnt","offense");
  180. board.offense_hero->setAnchorPoint(Vec2(0,0));
  181. board.offense_hero->setScale(0.4f);
  182. board.offense_hero->setPosition(blocksize*1,blocksize*2+5);
  183. board.board->addChild(board.offense_hero);
  184. board.defense_hero=Label::createWithBMFont("myfont.fnt","defense");
  185. board.defense_hero->setAnchorPoint(Vec2(0,0));
  186. board.defense_hero->setScale(0.4f);
  187. board.defense_hero->setPosition(blocksize*1,blocksize*1+5);
  188. board.board->addChild(board.defense_hero);
  189. board.money_hero=Label::createWithBMFont("myfont.fnt","money");
  190. board.money_hero->setAnchorPoint(Vec2(0,0));
  191. board.money_hero->setScale(0.4f);
  192. board.money_hero->setPosition(blocksize*1,blocksize*0+5);
  193. board.board->addChild(board.money_hero);
  194. board.yellowkey=Label::createWithBMFont("myfont.fnt","yellowkey");
  195. board.yellowkey->setAnchorPoint(Vec2(0,0));
  196. board.yellowkey->setScale(0.4f);
  197. board.yellowkey->setPosition(blocksize*4,blocksize*3+5);
  198. board.board->addChild(board.yellowkey);
  199. board.bluekey=Label::createWithBMFont("myfont.fnt","bluekey");
  200. board.bluekey->setAnchorPoint(Vec2(0,0));
  201. board.bluekey->setScale(0.4f);
  202. board.bluekey->setPosition(blocksize*4,blocksize*2+5);
  203. board.board->addChild(board.bluekey);
  204. board.redkey=Label::createWithBMFont("myfont.fnt","redkey");
  205. board.redkey->setAnchorPoint(Vec2(0,0));
  206. board.redkey->setScale(0.4f);
  207. board.redkey->setPosition(blocksize*4,blocksize*1+5);
  208. board.board->addChild(board.redkey);
  209. board.life_enemy=Label::createWithBMFont("myfont.fnt","life");
  210. board.life_enemy->setAnchorPoint(Vec2(0,0));
  211. board.life_enemy->setScale(0.4f);
  212. board.life_enemy->setPosition(blocksize*11,blocksize*3+5);
  213. board.board->addChild(board.life_enemy);
  214. board.offense_enemy=Label::createWithBMFont("myfont.fnt","offense");
  215. board.offense_enemy->setAnchorPoint(Vec2(0,0));
  216. board.offense_enemy->setScale(0.4f);
  217. board.offense_enemy->setPosition(blocksize*11,blocksize*2+5);
  218. board.board->addChild(board.offense_enemy);
  219. board.defense_enemy=Label::createWithBMFont("myfont.fnt","defense");
  220. board.defense_enemy->setAnchorPoint(Vec2(0,0));
  221. board.defense_enemy->setScale(0.4f);
  222. board.defense_enemy->setPosition(blocksize*11,blocksize*1+5);
  223. board.board->addChild(board.defense_enemy);
  224. }
  225. void MagicTower::InitHero()
  226. {
  227. ismoving=false;
  228. //加载英雄图片
  229. auto director=Director::getInstance();
  230. Size visibleSize = director->getVisibleSize();
  231. auto heroTexture=Director::getInstance()->getTextureCache()->addImage("hero.png");
  232. auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*1,blocksize,blocksize));
  233. hero.heroSprite=Sprite::createWithSpriteFrame(frame0);
  234. hero.heroSprite->setAnchorPoint(Vec2(0,0));
  235. MoveUnitInTile(hero.nexttilepos,hero.heroSprite);
  236. addChild(hero.heroSprite);
  237. //存储英雄移动动画
  238. std::string dirname[]={"down","left","right","up"};
  239. Vector<SpriteFrame*> animFrames(4);
  240. for(int i=0;i<4;i++)
  241. {
  242.   auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*i,blocksize,blocksize));
  243.   auto frame1=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*1,blocksize*i,blocksize,blocksize));
  244.   auto frame2=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*2,blocksize*i,blocksize,blocksize));
  245.   auto frame3=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*3,blocksize*i,blocksize,blocksize));
  246.   animFrames.pushBack(frame0);
  247.   animFrames.pushBack(frame1);
  248.   animFrames.pushBack(frame2);
  249.   animFrames.pushBack(frame3);
  250.   auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
  251.   animation->setRestoreOriginalFrame(false);
  252.   AnimationCache::getInstance()->addAnimation(animation,dirname[i]);
  253.   animFrames.clear();
  254. }
  255. //初始化攻击动画
  256. auto attackTexture= Director::getInstance()->getTextureCache()->addImage("attack.png");
  257. Size unitsize=attackTexture->getContentSizeInPixels();
  258. for(int i=0;i<25;i++)
  259. {
  260.   auto frame0=SpriteFrame::createWithTexture(attackTexture,
  261.    Rect(i/5*unitsize.width/5,i%5*unitsize.height/5,unitsize.width/5,unitsize.height/5));
  262.   animFrames.pushBack(frame0);
  263. }
  264. AnimationCache::getInstance()->addAnimation(Animation::createWithSpriteFrames(animFrames,0.05f),"attack");
  265. animFrames.clear();
  266. }
  267. void MagicTower::menuCloseCallback(Ref* pSender)
  268. {
  269. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
  270. MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
  271.     return;
  272. #endif
  273.     Director::getInstance()->end();
  274. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
  275.     exit(0);
  276. #endif
  277. }
  278. void MagicTower::OnMove(EventKeyboard::KeyCode keyCode, Event* event)
  279. {
  280. auto animCache=AnimationCache::getInstance();
  281. Animation* curanimation=NULL;
  282. Vec2 delta;
  283. switch(keyCode)
  284. {
  285.   case EventKeyboard::KeyCode::KEY_UP_ARROW:
  286.    curanimation=animCache->getAnimation("up");
  287.    delta.setPoint(0,blocksize);
  288.    break;
  289.   case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
  290.    curanimation=animCache->getAnimation("down");
  291.    delta.setPoint(0,-blocksize);
  292.    break;
  293.   case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
  294.    curanimation=animCache->getAnimation("left");
  295.    delta.setPoint(-blocksize,0);
  296.    break;
  297.   case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
  298.    curanimation=animCache->getAnimation("right");
  299.    delta.setPoint(blocksize,0);
  300.    break;
  301.   default:
  302.    return DefaultKeyboardDispatcher(keyCode);
  303. }
  304. //判断英雄位置是否可以移动
  305. if(curanimation && !ismoving)
  306. {
  307.   MoveHero(hero.heroSprite->getPosition()+delta,curanimation,keyCode);
  308. }
  309. }
  310. void MagicTower::PlayHeroMovement(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode,
  311.          const std::function<void(void)>& afteraction)
  312. {//anim:帧动画  afteraction:状态更新回调
  313. hero.heroSprite->setSpriteFrame(anim->getFrames().at(0)->getSpriteFrame());

  314. //移动动画和帧动画同时进行
  315. auto spawn=Spawn::createWithTwoActions(Animate::create(anim),MoveTo::create(0.2f,newpos));
  316. //帧动画+移动动画 -> 状态更新 -> 可通行 -> 连击检测
  317. hero.heroSprite->runAction(Sequence::create(spawn,CallFuncN::create([this,afteraction,keyCode](Node* node)
  318. {//所有回调函数需要写一起,否则单另作为Sequence依次执行会失效,不知道是不是bug
  319.   afteraction();
  320.   ismoving=false;
  321.   CCLog("ismoving");
  322.   FlushBoard();
  323.   if(!ismoving)
  324.   {
  325.    if((keyCode == EventKeyboard::KeyCode::KEY_UP_ARROW && GetKeyState(VK_UP) < 0) ||
  326.     (keyCode == EventKeyboard::KeyCode::KEY_DOWN_ARROW && GetKeyState(VK_DOWN) < 0) ||
  327.     (keyCode == EventKeyboard::KeyCode::KEY_LEFT_ARROW && GetKeyState(VK_LEFT) < 0) ||
  328.     (keyCode == EventKeyboard::KeyCode::KEY_RIGHT_ARROW && GetKeyState(VK_RIGHT) < 0))
  329.    {
  330.     OnMove(keyCode,NULL);
  331.    }
  332.   }
  333. }),NULL));
  334. }
  335. void MagicTower::MoveHero(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode)
  336. {//若成功,则捡物品或者攻击
  337. ismoving=true;
  338. Vec2 tilepos;
  339. WorldPosToTilePos(newpos,tilepos);
  340. if(map->getLayer("floor")->getTileGIDAt(tilepos) == FLOOR_WALL)
  341. {//禁止通行
  342.   ismoving=false;
  343.   return;
  344. }
  345. //若是地板则进行上层判断
  346. auto layer=map->getLayer("item");
  347. switch(layer->getTileGIDAt(tilepos))
  348. {
  349.   case ITEM_REDDIAMOND:
  350.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  351.    {//刷新+音乐+物品动画
  352.     hero.offense += 100;
  353.     layer->removeChild(layer->getTileAt(tilepos),true);
  354.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  355.    });
  356.    return;
  357.   case ITEM_BLUEDIAMOND:
  358.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  359.    {//刷新+音乐+物品动画
  360.     hero.defense += 50;
  361.     layer->removeChild(layer->getTileAt(tilepos),true);
  362.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  363.    });
  364.    return;
  365.   case ITEM_REDBLOOD:
  366.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  367.    {//刷新+音乐+物品动画
  368.     hero.life += 400;
  369.     layer->removeChild(layer->getTileAt(tilepos),true);
  370.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  371.    });
  372.    return;
  373.   case ITEM_BLUEBLOOD:
  374.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  375.    {//刷新+音乐+物品动画
  376.     hero.life += 200;
  377.     layer->removeChild(layer->getTileAt(tilepos),true);
  378.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  379.    });
  380.    return;
  381.    
  382.   case ITEM_YELLOWKEY:
  383.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  384.    {//刷新+音乐+物品动画
  385.     hero.keyyellow++;
  386.     layer->removeChild(layer->getTileAt(tilepos),true);
  387.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  388.    });
  389.    return;
  390.    
  391.   case ITEM_BLUEKEY:
  392.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  393.    {//刷新+音乐+物品动画
  394.     hero.keyblue++;
  395.     layer->removeChild(layer->getTileAt(tilepos),true);
  396.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  397.    });
  398.    return;
  399.    
  400.   case ITEM_REDKEY:
  401.    PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  402.    {//刷新+音乐+物品动画
  403.     hero.keyred++;
  404.     layer->removeChild(layer->getTileAt(tilepos),true);
  405.     SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  406.    });
  407.    return;
  408.    
  409.   default://若为空,执行上层判断
  410.    break;
  411. }
  412. layer=map->getLayer("enemy");
  413. if(layer->getTileGIDAt(tilepos))
  414. {//若有敌人
  415.   PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
  416.   {
  417.    auto animation=AnimationCache::getInstance()->getAnimation("attack");
  418.    auto attacksprite=Sprite::createWithSpriteFrame(animation->getFrames().at(0)->getSpriteFrame());
  419.    attacksprite->setAnchorPoint(Vec2(0,0));
  420.    attacksprite->setPosition(-attacksprite->getContentSize().width/4,-attacksprite->getContentSize().height/4);
  421.    //开始攻击动画+音乐
  422.    hero.heroSprite->addChild(attacksprite);
  423.    attackEnemy(layer,tilepos,attacksprite,Animate::create(animation));
  424.   });
  425.   return;
  426. }
  427. //若为空,执行上层判断
  428. layer=map->getLayer("door");
  429. switch(layer->getTileGIDAt(tilepos))
  430. {
  431.   case DOOR_YELLOW:
  432.    {
  433.     hero.keyyellow--;
  434.     auto animation=AnimationCache::getInstance()->getAnimation("DOOR_YELLOW");
  435.     auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  436.      CallFuncN::create([layer,tilepos](Node*){
  437.       layer->removeChild(layer->getTileAt(tilepos),true);
  438.     })),CallFuncN::create([](Node*){
  439.      SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  440.     }));
  441.     layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  442.      CallFuncN::create([this,newpos,anim,keyCode](Node*){
  443.       PlayHeroMovement(newpos,anim,keyCode,[](){});
  444.     })));   
  445.    }
  446.    return;
  447.   case DOOR_BLUE:
  448.    {
  449.     hero.keyblue--;
  450.     auto animation=AnimationCache::getInstance()->getAnimation("DOOR_BLUE");
  451.     auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  452.      CallFuncN::create([layer,tilepos](Node*){
  453.       layer->removeChild(layer->getTileAt(tilepos),true);
  454.     })),CallFuncN::create([](Node*){
  455.      SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  456.     }));
  457.     layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  458.      CallFuncN::create([this,newpos,anim,keyCode](Node*){
  459.       PlayHeroMovement(newpos,anim,keyCode,[](){});
  460.     })));  
  461.    }
  462.    return;
  463.   case DOOR_RED:
  464.    {
  465.     hero.keyred--;
  466.     auto animation=AnimationCache::getInstance()->getAnimation("DOOR_RED");
  467.     auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  468.      CallFuncN::create([layer,tilepos](Node*){
  469.       layer->removeChild(layer->getTileAt(tilepos),true);
  470.     })),CallFuncN::create([](Node*){
  471.      SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  472.     }));
  473.     layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  474.      CallFuncN::create([this,newpos,anim,keyCode](Node*){
  475.       PlayHeroMovement(newpos,anim,keyCode,[](){});
  476.     })));
  477.    }
  478.    return;
  479.   
  480.   case DOOR_GREEN:
  481.    ismoving=false;
  482.    return;
  483.   case DOOR_UPSTAIRS:
  484.    {
  485.     //更新地图
  486.     Director::getInstance()->setDepthTest(false);
  487.     hero.nexttilepos=Vec2(HeroInitPos[(thislevel+1)*4],HeroInitPos[(thislevel+1)*4+1]);
  488.     auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel+1));
  489.     if(trans)
  490.      Director::getInstance()->replaceScene(trans);
  491.     ismoving=false;
  492.    }
  493.    return;
  494.   case DOOR_DOWNSTAIRS:
  495.    {
  496.     //更新地图
  497.     Director::getInstance()->setDepthTest(false);
  498.     hero.nexttilepos=Vec2(HeroInitPos[(thislevel-1)*4+2],HeroInitPos[(thislevel-1)*4+3]);
  499.     auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel-1));
  500.     if(trans)
  501.      Director::getInstance()->replaceScene(trans);
  502.     ismoving=false;
  503.    }
  504.    return;
  505. }
  506. //若无对象存在,则移动英雄
  507. PlayHeroMovement(newpos,anim,keyCode,[](){});
  508. //在执行PlayerHeroMovement的地方,ismoving交给该函数处理
  509. }
  510. void MagicTower::attackEnemy(TMXLayer* layer,Vec2 tilepos,Sprite* attacksprite,Animate* animate)
  511. {
  512. //判断英雄是否移动了,如果移动则去除animate并结束
  513. Vec2 herointile;
  514. WorldPosToTilePos(hero.heroSprite->getPosition(),herointile);
  515. if(herointile != tilepos)
  516. {
  517.   attacksprite->stopAllActions();
  518.   hero.heroSprite->removeChild(attacksprite,true);
  519.   return;
  520. }
  521. attacksprite->runAction(Sequence::create(animate,CallFuncN::create([this,layer,tilepos,animate](Node* attacksprite)
  522. {
  523.   ValueMap* val=static_cast<ValueMap*>(layer->getTileAt(tilepos)->getUserData());
  524.   int enemylife=(*val)["life"].asInt();
  525.   int enemyoffense=(*val)["offense"].asInt();
  526.   int enemydefense=(*val)["defense"].asInt();
  527.   int harmetoh=(hero.defense>enemyoffense)?0:enemyoffense-hero.defense;//enemy对hero造成的伤害,如果hero的防>enemy的攻,则无伤害
  528.   int harmhtoe=(enemydefense>hero.offense)?0:hero.offense-enemydefense;
  529.   hero.life -= harmetoh;
  530.   enemylife -= harmhtoe;
  531.   SimpleAudioEngine::getInstance()->playEffect("fight.mp3");
  532.   (*val)["life"]=enemylife;
  533.   FlushBoard(val);
  534.   if(enemylife < 0 || hero.life < 0)
  535.   {
  536.    if(hero.life < 0)
  537.    {//英雄挂了
  538.    }
  539.    else
  540.    {
  541.     attacksprite->stopAllActions();
  542.     hero.money += (*val)["money"].asInt();
  543.     hero.heroSprite->removeChild(attacksprite,true);
  544.     layer->removeChild(layer->getTileAt(tilepos),true);
  545.     FlushBoard(val);
  546.     //刷新面板
  547.    }
  548.   }
  549.   else
  550.   {
  551.    attackEnemy(layer,tilepos,static_cast<Sprite*>(attacksprite),animate);
  552.   }
  553. }),NULL));
  554. }
  555. void MagicTower::DefaultKeyboardDispatcher(EventKeyboard::KeyCode keycode)
  556. {//处理其他键盘事件

  557. }
  558. void MagicTower::WorldPosToTilePos(const Vec2& pos,Vec2& objpos)
  559. {//pos为世界坐标系,相对于窗口左下角,目标锚点位于左下角
  560. float rex=map->getContentSize().width/2+(pos.x+blocksize/2-map->getPosition().x);
  561. float rey=map->getContentSize().height/2-(pos.y+blocksize/2-map->getPosition().y);
  562. objpos.setPoint(int(rex/blocksize),int(rey/blocksize));
  563. }
  564. void MagicTower::TilePosToWorldPos(const Vec2& pos,Vec2& objpos)
  565. {//pos为Tile坐标系,相对于窗口左上角
  566. float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
  567. float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y;
  568. objpos.setPoint(rex,rey);
  569. }
  570. void MagicTower::MoveUnitInTile(const Vec2& pos,Sprite* obj)
  571. {//pos为Tile坐标系,相对于左上角
  572. float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
  573. float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y-blocksize;
  574. obj->setPosition(rex,rey);
  575. }
  576. void MagicTower::FlushBoard(ValueMap* obj)
  577. {
  578. char str[20];
  579. sprintf(str,"魔塔 第%d层",thislevel);
  580. board.maintitle->setString(IConvConvert_GBKToUTF8(str));
  581. board.heroname->setString(IConvConvert_GBKToUTF8(hero.name));
  582. sprintf(str,"%d",hero.life);
  583. board.life_hero->setString(IConvConvert_GBKToUTF8(str));
  584. sprintf(str,"%d",hero.offense);
  585. board.offense_hero->setString(IConvConvert_GBKToUTF8(str));
  586. sprintf(str,"%d",hero.defense);
  587. board.defense_hero->setString(IConvConvert_GBKToUTF8(str));
  588. sprintf(str,"%d",hero.money);
  589. board.money_hero->setString(IConvConvert_GBKToUTF8(str));
  590. sprintf(str,"%d",hero.keyyellow);
  591. board.yellowkey->setString(IConvConvert_GBKToUTF8(str));
  592. sprintf(str,"%d",hero.keyblue);
  593. board.bluekey->setString(IConvConvert_GBKToUTF8(str));
  594. sprintf(str,"%d",hero.keyred);
  595. board.redkey->setString(IConvConvert_GBKToUTF8(str));
  596. if(obj)
  597. {
  598.   int category=(*obj)["category"].asInt();
  599.   if(category == TYPE_ENEMY)
  600.   {
  601.    board.enemyname->setString(IConvConvert_GBKToUTF8((*obj)["name"].asString()));
  602.    sprintf(str,"%d",(*obj)["life"].asInt());
  603.    board.life_enemy->setString(IConvConvert_GBKToUTF8(str));
  604.    sprintf(str,"%d",(*obj)["offense"].asInt());
  605.    board.offense_enemy->setString(IConvConvert_GBKToUTF8(str));
  606.    sprintf(str,"%d",(*obj)["defense"].asInt());
  607.    board.defense_enemy->setString(IConvConvert_GBKToUTF8(str));
  608.   }
  609.   else if(category == TYPE_ITEM)
  610.   {
  611.   }
  612. }
  613. }
  614. void MagicTower::SelectSprite(Sprite* sprite)
  615. {
  616. auto data=static_cast<ValueMap*>(sprite->getUserData());
  617. if((*data)["selected"].asBool())
  618. {
  619.   sprite->removeChildByTag('sel');
  620.   (*data)["selected"]=false;
  621. }
  622. else
  623. {
  624.   auto texture=map->getLayer("enemy")->getTexture();
  625.   int hei=texture->getContentSize().height;
  626.   auto selsprite=Sprite::createWithTexture(texture,Rect(0,texture->getContentSize().height-blocksize,blocksize,blocksize));//设置为最后一个
  627.   selsprite->setAnchorPoint(Vec2(0,0));
  628.   selsprite->setPosition(0,0);
  629.   sprite->addChild(selsprite,selsprite->getLocalZOrder(),'sel');
  630.   FlushBoard(data);
  631.   (*data)["selected"]=true;
  632. }
  633. }
  634. //MagicTowerLayerManager管理场景切换
  635. MagicTowerLayerManager& MagicTowerLayerManager::getInstance()
  636. {
  637. static MagicTowerLayerManager manager;
  638. return manager;
  639. }
  640. Scene* MagicTowerLayerManager::getScene(int layer)
  641. {
  642. curlayer=layer;
  643. auto curscene=Scene::create();
  644. auto curlayer=new MagicTower(layer);
  645. if (curscene && curlayer)
  646. {
  647.   curscene->addChild(curlayer);
  648.   curlayer->autorelease();
  649. }
  650. return curscene;
  651. }
  652. Hero MagicTower::hero;
  653. Board MagicTower::board;
  654. MagicTowerLayerManager::MagicTowerLayerManager()
  655. {
  656. curlayer=1;
  657. MagicTower::hero.name="勇士";
  658. MagicTower::hero.life=1000;
  659. MagicTower::hero.offense=200;
  660. MagicTower::hero.defense=200;
  661. MagicTower::hero.keyyellow=10;
  662. MagicTower::hero.keyblue=10;
  663. MagicTower::hero.keyred=10;
  664. MagicTower::hero.money=1000;
  665. MagicTower::hero.nexttilepos=Vec2(6,11);//初始化
  666. }

复制代码


common.cpp


  1. #include "common.h"
  2. #include "cocos2d.h"
  3. #include <iostream>
  4. USING_NS_CC;
  5. struct ENEMY globalEnemyData[]=
  6. {
  7. {TYPE_ENEMY,ENEMY_KULOUREN,"骷髅人","骷髅人",110,25,5,110},
  8. {TYPE_ENEMY,ENEMY_KULOUSHIBING,"骷髅士兵","骷髅士兵",150,40,20,150},
  9. {TYPE_ENEMY,ENEMY_XIAOBIANFU,"小蝙蝠","小蝙蝠",100,20,5,100},
  10. {TYPE_ENEMY,ENEMY_LVTOUGUAI,"绿头怪","绿头怪",50,20,1,50},
  11. {TYPE_ENEMY,ENEMY_HONGTOUGUAI,"红头怪","红头怪",70,15,2,70},
  12. {TYPE_ENEMY,ENEMY_CHUJIFASHI,"初级法师","初级法师",125,50,25,125},
  13. };
  14. struct ITEM globalItemData[]=
  15. {
  16. {TYPE_ITEM,ITEM_REDDIAMOND,"红宝石","增加攻击力"},
  17. {TYPE_ITEM,ITEM_BLUEDIAMOND,"蓝宝石","增加防御力"},
  18. {TYPE_ITEM,ITEM_REDBLOOD,"红血瓶","增加大量生命"},
  19. {TYPE_ITEM,ITEM_BLUEBLOOD,"蓝血瓶","增加少量生命"},
  20. {TYPE_ITEM,ITEM_YELLOWKEY,"黄钥匙","开启黄色门"},
  21. {TYPE_ITEM,ITEM_BLUEKEY,"蓝钥匙","开启蓝色门"},
  22. {TYPE_ITEM,ITEM_REDKEY,"红钥匙","开启红色门"},
  23. };
  24. ObjManager& ObjManager::getInstance()
  25. {
  26. static ObjManager manager;
  27. return manager;
  28. }
  29. ValueMap* ObjManager::InitEnemyByType(int type)
  30. {
  31. ValueMap* curmap=new ValueMap(enemytemp[type]);
  32. enemies.push_back(curmap);
  33. return curmap;
  34. }
  35. ValueMap* ObjManager::InitItemByType(int type)
  36. {
  37. return &itemtemp[type];
  38. }
  39. ObjManager::ObjManager()
  40. {
  41. ValueMap curmap;
  42. for(ENEMY eny:globalEnemyData)
  43. {
  44.   curmap["category"]=eny.category;
  45.   curmap["type"]=eny.type;
  46.   curmap["name"]=eny.name;
  47.   curmap["desc"]=eny.desc;
  48.   curmap["life"]=eny.life;
  49.   curmap["offense"]=eny.offense;
  50.   curmap["defense"]=eny.defense;
  51.   curmap["money"]=eny.money;
  52.   curmap["selected"]=false;
  53.   enemytemp[eny.type]=curmap;
  54.   curmap.clear();
  55. }
  56. for(ITEM item:globalItemData)
  57. {
  58.   curmap["category"]=item.category;
  59.   curmap["type"]=item.type;
  60.   curmap["name"]=item.name;
  61.   curmap["desc"]=item.desc;
  62.   curmap["selected"]=false;
  63.   itemtemp[item.type]=curmap;
  64.   curmap.clear();
  65. }
  66. }
  67. ObjManager::~ObjManager()
  68. {
  69. for(ValueMap* pt:enemies)
  70. {
  71.   delete pt;
  72. }
  73. for(ValueMap* pt:items)
  74. {
  75.   delete pt;
  76. }
  77. }

  78. int HeroInitPos[]=
  79. {//in*2 out*2分别代表从楼下到此层的初始位置和从楼上到此层的初始位置
  80. //     第一层   第二层   第三层   第四层
  81. -1,-1,  -1,-1,    6,10,  2,1,    2,1,  1,10,    2,11,  10,11,    11,10,  1,10
  82. };


复制代码


common.h


  1. #pragma once
  2. #include "cocos2d.h"
  3. #include <iostream>
  4. USING_NS_CC;
  5. #ifndef __HELLOWORLD_MANAGER_H__
  6. #define __HELLOWORLD_MANAGER_H__
  7. #define blocksize 32
  8. enum direction
  9. {
  10. kDown=0,
  11. kLeft=1,
  12. kRight=2,
  13. kUp=3,
  14. };
  15. enum category
  16. {
  17. TYPE_FLOOR,
  18. TYPE_ITEM,
  19. TYPE_ENEMY,
  20. TYPE_DOOR,
  21. };
  22. //对应于tileid
  23. enum floor//floor层对象
  24. {
  25. FLOOR_BEGIN=0,
  26. FLOOR_WALL=FLOOR_BEGIN+7,//墙体
  27. FLOOR_FLOOR=FLOOR_BEGIN+12,//地板
  28. };
  29. enum item//item层对象
  30. {
  31. ITEM_BEGIN=72,
  32. ITEM_REDDIAMOND=ITEM_BEGIN+1,//红宝石
  33. ITEM_BLUEDIAMOND=ITEM_BEGIN+2,//蓝宝石
  34. ITEM_REDBLOOD=ITEM_BEGIN+5,//红血瓶
  35. ITEM_BLUEBLOOD=ITEM_BEGIN+6,//蓝血瓶
  36. ITEM_YELLOWKEY=ITEM_BEGIN+17,//黄钥匙
  37. ITEM_BLUEKEY=ITEM_BEGIN+18,//蓝钥匙
  38. ITEM_REDKEY=ITEM_BEGIN+19,//红钥匙
  39. };
  40. enum enemy
  41. {
  42. ENEMY_BEGIN=136,
  43. ENEMY_KULOUREN=ENEMY_BEGIN+1,//骷髅人
  44. ENEMY_KULOUSHIBING=ENEMY_BEGIN+5,//骷髅士兵
  45. ENEMY_XIAOBIANFU=ENEMY_BEGIN+17,//小蝙蝠
  46. ENEMY_LVTOUGUAI=ENEMY_BEGIN+33,//绿头怪
  47. ENEMY_HONGTOUGUAI=ENEMY_BEGIN+37,//红头怪
  48. ENEMY_CHUJIFASHI=ENEMY_BEGIN+49,//初级法师
  49. };
  50. enum door
  51. {
  52. DOOR_BEGIN=392,
  53. DOOR_YELLOW=DOOR_BEGIN+1,//黄门
  54. DOOR_BLUE=DOOR_BEGIN+2,//蓝门
  55. DOOR_RED=DOOR_BEGIN+3,//红门
  56. DOOR_GREEN=DOOR_BEGIN+4,//绿门
  57. DOOR_UPSTAIRS=DOOR_BEGIN+17,//上楼梯
  58. DOOR_DOWNSTAIRS=DOOR_BEGIN+18,//下楼梯
  59. };
  60. struct ENEMY
  61. {
  62. int category;
  63. int type;
  64. std::string name;//名称
  65. std::string desc;//描述
  66. int life;
  67. int offense;//攻击
  68. int defense;//防御
  69. int money;//金钱
  70. };
  71. struct ITEM
  72. {
  73. int category;
  74. int type;
  75. std::string name;//名称
  76. std::string desc;//描述
  77. };
  78. typedef std::unordered_map<int,ValueMap> ObjMap;
  79. #define getNum(x) (sizeof(x)/(sizeof(x[0])))
  80. class ObjManager
  81. {//用来设置怪物动画
  82. public:
  83. static ObjManager& getInstance();
  84. ValueMap* InitEnemyByType(int type);
  85. ValueMap* InitItemByType(int type);
  86. private:
  87. ObjMap enemytemp;
  88. ObjMap itemtemp;
  89. std::vector<ValueMap*> enemies;
  90. std::vector<ValueMap*> items;
  91. private:
  92. ObjManager();//单例模式
  93. virtual ~ObjManager();
  94. };
  95. struct Hero
  96. {
  97. Sprite* heroSprite;
  98. std::string name;
  99. int life;
  100. int offense;
  101. int defense;
  102. int keyyellow;
  103. int keyblue;
  104. int keyred;
  105. int money;
  106. Vec2 nexttilepos;
  107. };
  108. struct Board
  109. {
  110. TMXTiledMap* board;
  111. Label* maintitle;
  112. //hero
  113. Label* heroname;
  114. Label* life_hero;
  115. Label* offense_hero;
  116. Label* defense_hero;
  117. Label* money_hero;
  118. Label* yellowkey;
  119. Label* bluekey;
  120. Label* redkey;
  121. Label* weapon;
  122. Label* shield;
  123. //enemy
  124. Label* enemyname;
  125. Label* life_enemy;
  126. Label* offense_enemy;
  127. Label* defense_enemy;
  128. };
  129. int HeroInitPos[];

  130. #endif
复制代码




回复

使用道具 举报

 楼主| 发表于 2014-6-19 22:22:38 | 显示全部楼层


游戏文件在群共享里
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-6-19 22:22:41 | 显示全部楼层
mota.png

游戏文件在群共享里
回复 赞! 靠!

使用道具 举报

发表于 2014-6-20 00:03:36 | 显示全部楼层
元始天尊 发表于 2014-6-19 14:22 游戏文件在群共享里
加群链接:编程交流及书籍分享
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-6-22 16:45:51 | 显示全部楼层
改进代码以便在android环境下运行:
android版本在交流群共享里


  1. #include "MagicTower.h"
  2. #include "..\external\win32-specific\icon\include\iconv.h"

  3. USING_NS_CC;
  4. using namespace CocosDenshion;

  5. extern int HeroInitPos[];

  6. #if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
  7. #pragma comment(lib,"libiconv.lib")
  8. bool IConvConvert(const char *from_charset, const char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen)
  9. {
  10.         iconv_t cd = iconv_open(to_charset, from_charset);
  11.         if (cd == 0) return false;
  12.         const char **pin = &inbuf;
  13.         char **pout = &outbuf;
  14.         memset(outbuf,0,outlen);
  15.         size_t ret = iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
  16.         iconv_close(cd);
  17.         return ret == (size_t)(-1) ? false : true;
  18. }

  19. std::string IConvConvert_GBKToUTF8(const std::string& str)
  20. {
  21.         const char* textIn = str.c_str();
  22.         char textOut[256];
  23.         bool ret = IConvConvert("gb2312", "utf-8", textIn, strlen(textIn),textOut, 256);
  24.         return ret ? std::string(textOut) : std::string();
  25. }
  26. #else
  27. std::string IConvConvert_GBKToUTF8(const std::string& str)
  28. {
  29.         return str;
  30. }
  31. #endif

  32. // on "init" you need to initialize your instance
  33. MagicTower::MagicTower(int level)
  34. {
  35.         CCLog("Enter MagicTower");
  36.         thislevel=level;
  37.         auto director=Director::getInstance();
  38.         //director->getOpenGLView()->setFrameSize(416,416);
  39.     //////////////////////////////
  40.     // 1. super init first
  41.     Layer::init();

  42.     Size visibleSize = director->getVisibleSize();
  43.     Vec2 origin = director->getVisibleOrigin();
  44.     /////////////////////////////
  45.     // 2. add a menu item with "X" image, which is clicked to quit the program
  46.     //    you may modify it.

  47.     // add a "close" icon to exit the progress. it's an autorelease object
  48.     auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(MagicTower::menuCloseCallback, this));
  49.         closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
  50.                                 origin.y + closeItem->getContentSize().height/2));

  51.     // create menu, it's an autorelease object
  52.     auto menuclose = Menu::create(closeItem, NULL);
  53.     menuclose->setPosition(Vec2::ZERO);
  54.     this->addChild(menuclose, 1);

  55.     /////////////////////////////
  56.     // 3. add your codes below...
  57.         InitMap();
  58.         InitHero();
  59.         FlushBoard();

  60. #if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
  61.         //初始换方向键回调
  62.         auto listener=EventListenerKeyboard::create();
  63.         listener->onKeyPressed=CC_CALLBACK_2(MagicTower::OnMove,this);
  64.         _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
  65. #else
  66.         //初始化触摸滑动
  67.         auto listener=EventListenerTouchAllAtOnce::create();
  68.         listener->onTouchesMoved=[this](const std::vector<Touch*>& touches,Event* event)
  69.         {
  70.                 auto touch=touches[0];
  71.                 map->setPosition(map->getPosition()+touch->getDelta());
  72.         };
  73.         _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
  74. #endif
  75.         CCLog("Leave MagicTower");
  76. }


  77. void MagicTower::InitMap()
  78. {
  79.         CCLog("Enter InitMap");
  80.         //加载地图背景
  81.         auto director=Director::getInstance();
  82.         Size visibleSize = director->getVisibleSize();
  83.         char mapname[64];
  84.         sprintf(mapname,"%d.tmx",thislevel);
  85.         map=TMXTiledMap::create(mapname);
  86.         map->setAnchorPoint(Vec2(0.5f,0.5f));
  87. //#if(CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  88.         map->setScale(1.5);
  89. //#endif
  90.         board.board=TMXTiledMap::create("background.tmx");
  91.         board.board->setAnchorPoint(Vec2(0.5f,0.5f));
  92.         map->setPosition(visibleSize.width/2,visibleSize.height/2+board.board->getContentSize().height/2);
  93.         board.board->setPosition(visibleSize.width/2,board.board->getContentSize().height/2);
  94.         addChild(map);
  95.         addChild(board.board);
  96.         auto listenerm=EventListenerTouchAllAtOnce::create();
  97.         listenerm->onTouchesMoved=[this](const std::vector<Touch*>& touches, Event  *event)
  98.         {
  99.                 auto touch=touches[0];
  100.                 auto diff=touch->getDelta();
  101.                 map->setPosition(map->getPosition()+diff);
  102.         };
  103. //        _eventDispatcher->addEventListenerWithSceneGraphPriority(listenerm,map);

  104.         auto arrowright=Sprite::create("arrow.png");
  105.         auto arrowdown=Sprite::create("arrow.png");
  106.         auto arrowleft=Sprite::create("arrow.png");
  107.         auto arrowup=Sprite::create("arrow.png");
  108.         arrowright->setAnchorPoint(Vec2(0,0.5));
  109.         arrowright->setScale(3);
  110.         arrowdown->setAnchorPoint(Vec2(0,0.5));
  111.         arrowdown->setRotation(90);
  112.         arrowdown->setScale(3);
  113.         arrowleft->setAnchorPoint(Vec2(0,0.5));
  114.         arrowleft->setRotation(180);
  115.         arrowleft->setScale(3);
  116.         arrowup->setAnchorPoint(Vec2(0,0.5));
  117.         arrowup->setRotation(270);
  118.         arrowup->setScale(3);
  119.         arrowright->setPosition(visibleSize.width/2,visibleSize.height/2);
  120.         arrowdown->setPosition(visibleSize.width/2,visibleSize.height/2);
  121.         arrowleft->setPosition(visibleSize.width/2,visibleSize.height/2);
  122.         arrowup->setPosition(visibleSize.width/2,visibleSize.height/2);
  123.         addChild(arrowright,240,24);
  124.         arrowright->setTag(24);
  125.         addChild(arrowdown,260,26);
  126.         arrowdown->setTag(26);
  127.         addChild(arrowleft,230,23);
  128.         arrowleft->setTag(23);
  129.         addChild(arrowup,250,25);
  130.         arrowup->setTag(25);

  131.         //初始化点击事件
  132.         auto listenerll=EventListenerTouchOneByOne::create();
  133.         listenerll->setSwallowTouches(true);
  134.         listenerll->onTouchEnded=[=](Touch* touch,Event* event)
  135.         {
  136.                 auto animCache=AnimationCache::getInstance();
  137.                 Animation* curanimation=NULL;
  138.                 Vec2 delta;
  139.                 auto target = static_cast<Sprite*>(event->getCurrentTarget());

  140.                 switch(target->getTag())
  141.                 {
  142.                         case 25:
  143.                                 curanimation=animCache->getAnimation("up");
  144.                                 delta.setPoint(0,blocksize);
  145.                                 break;

  146.                         case 26:
  147.                                 curanimation=animCache->getAnimation("down");
  148.                                 delta.setPoint(0,-blocksize);
  149.                                 break;

  150.                         case 23:
  151.                                 curanimation=animCache->getAnimation("left");
  152.                                 delta.setPoint(-blocksize,0);
  153.                                 break;

  154.                         case 24:
  155.                                 curanimation=animCache->getAnimation("right");
  156.                                 delta.setPoint(blocksize,0);
  157.                                 break;
  158.                 }
  159.                 if(curanimation && !ismoving)
  160.                 {
  161.                         MoveHero(hero.heroSprite->getPosition()+delta,curanimation,target->getTag());
  162.                 }
  163.         };

  164.         listenerll->onTouchBegan=[](Touch* touch,Event* event)
  165.         {
  166.                 CCLog("Touch Began!");
  167.                 auto target = static_cast<Sprite*>(event->getCurrentTarget());
  168.                 Vec2 locationInNode=target->convertToNodeSpace(touch->getLocation());
  169.                 Size s=target->getContentSize();
  170.                 Rect rect=Rect(0,0,s.width,s.height);
  171.                 if(!rect.containsPoint(locationInNode))
  172.                         return false;
  173.                 return true;
  174.         };

  175.         _eventDispatcher->addEventListenerWithSceneGraphPriority(listenerll,arrowright);
  176.         _eventDispatcher->addEventListenerWithSceneGraphPriority(listenerll->clone(),arrowdown);
  177.         _eventDispatcher->addEventListenerWithSceneGraphPriority(listenerll->clone(),arrowleft);
  178.         _eventDispatcher->addEventListenerWithSceneGraphPriority(listenerll->clone(),arrowup);


  179.         InitBoard();

  180.         //初始化地图元素
  181.         Vector<SpriteFrame*> animFrames(4);
  182.         auto enemylayer=map->getLayer("enemy");
  183.         auto enemyTexture=enemylayer->getTexture();

  184.         for(int i=0;i<map->getMapSize().width;i++)
  185.         {
  186.                 for(int j=0;j<map->getMapSize().height;j++)
  187.                 {
  188.                         int id=enemylayer->getTileGIDAt(Vec2(i,j));
  189.                         if(id)
  190.                         {
  191.                                 int index=(id-ENEMY_BEGIN)/4;
  192.                                 auto frame0=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*0,blocksize*index,blocksize,blocksize));
  193.                                 auto frame1=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*1,blocksize*index,blocksize,blocksize));
  194.                                 auto frame2=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*2,blocksize*index,blocksize,blocksize));
  195.                                 auto frame3=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*3,blocksize*index,blocksize,blocksize));
  196.                                 animFrames.pushBack(frame0);
  197.                                 animFrames.pushBack(frame1);
  198.                                 animFrames.pushBack(frame2);
  199.                                 animFrames.pushBack(frame3);
  200.                                 auto animation=Animation::createWithSpriteFrames(animFrames,0.1f);
  201.                                 animFrames.clear();
  202.                                 CCLog("x=%d,y=%d",i,j);
  203.                                 auto cursprite=enemylayer->getTileAt(Vec2(i,j));
  204.                                 if(!cursprite)
  205.                                         return;
  206.                                 cursprite->runAction(RepeatForever::create(Animate::create(animation)));
  207.                                 cursprite->setUserData(ObjManager::getInstance().InitEnemyByType(id));
  208.                         }
  209.                 }
  210.         }

  211.        
  212.         //初始化点击事件
  213.         auto listener=EventListenerTouchOneByOne::create();
  214.         listener->onTouchBegan=[this,enemylayer](Touch* touch,Event* event)
  215.         {
  216.                 CCLog("Touch Began!");
  217.                 Vec2 locationInNode=enemylayer->convertToNodeSpace(touch->getLocation());
  218.                 Size s=enemylayer->getContentSize();
  219.                 Rect rect=Rect(0,0,s.width,s.height);
  220.                 if(!rect.containsPoint(locationInNode))
  221.                         return false;

  222.                 Vec2 tilepos;
  223.                 MapPosToTilePos(Vec2(locationInNode.x,locationInNode.y),tilepos);
  224.                 if(tilepos.x >= 0 && tilepos.y >=0 &&
  225.                         tilepos.x < enemylayer->getLayerSize().width && tilepos.y < enemylayer->getLayerSize().height)
  226.                 {
  227.                         Sprite* node=enemylayer->getTileAt(tilepos);
  228.                         if(node)
  229.                         {
  230.                                 SelectSprite(node);
  231.                         }
  232.                 }
  233.                 //根据位置获取单元格,设置为选中状态并刷新数据到面板
  234.                 return true;
  235.         };
  236.         _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,enemylayer);
  237.        

  238.         auto itemlayer=map->getLayer("item");
  239.         for(int i=0;i<map->getMapSize().width;i++)
  240.         {
  241.                 for(int j=0;j<map->getMapSize().height;j++)
  242.                 {
  243.                         int id=itemlayer->getTileGIDAt(Vec2(i,j));
  244.                         CCLog("x=%d,y=%d",i,j);
  245.                         auto cursprite=enemylayer->getTileAt(Vec2(i,j));
  246.                         //if(id && cursprite)
  247.                         //{
  248.                         //        cursprite->setUserData(ObjManager::getInstance().InitItemByType(id));
  249.                         //}
  250.                 }
  251.         }

  252.         //初始化门动画
  253.         auto doorTexture=map->getLayer("door")->getTexture();
  254.         int doordata[]={0,1,2,3};
  255.         std::string doorname[]={"DOOR_YELLOW","DOOR_BLUE","DOOR_RED","DOOR_GREEN"};
  256.         for(int i=0;i<getNum(doordata);i++)
  257.         {
  258.                 doordata[i];
  259.                 auto frame0=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*0,blocksize,blocksize));
  260.                 auto frame1=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*1,blocksize,blocksize));
  261.                 auto frame2=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*2,blocksize,blocksize));
  262.                 auto frame3=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*3,blocksize,blocksize));
  263.                 animFrames.pushBack(frame0);
  264.                 animFrames.pushBack(frame1);
  265.                 animFrames.pushBack(frame2);
  266.                 animFrames.pushBack(frame3);
  267.                 auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
  268.                 animFrames.clear();
  269.                 AnimationCache::getInstance()->addAnimation(animation,doorname[i]);
  270.         }

  271.         CCLog("Leave InitMap");
  272. }

  273. void MagicTower::InitBoard()
  274. {
  275.         CCLog("Enter InitBoard");
  276.         //初始化面板
  277.         char title[64];
  278. #if(CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  279.         sprintf(title,"魔塔 第%d层",thislevel);
  280. #else
  281.         sprintf(title,"MagicTower %dth",thislevel);
  282. #endif
  283.         board.maintitle=Label::createWithSystemFont(IConvConvert_GBKToUTF8(title),"黑体",30);
  284.         board.maintitle->setColor(Color3B::GREEN);
  285.         board.maintitle->setAnchorPoint(Vec2(0.5f,0.5f));
  286.         board.maintitle->setPosition(board.board->getContentSize().width/2,blocksize*5+16);
  287.         board.board->addChild(board.maintitle);

  288.         board.heroname=Label::createWithSystemFont(IConvConvert_GBKToUTF8(hero.name),"黑体",24);
  289.         board.heroname->setColor(Color3B::RED);
  290.         board.heroname->setAnchorPoint(Vec2(0.5f,0.5f));
  291.         board.heroname->setPosition(board.board->getContentSize().width/4,blocksize*5-16);
  292.         board.board->addChild(board.heroname);

  293.         board.enemyname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("敌方"),"黑体",24);
  294.         board.enemyname->setColor(Color3B::RED);
  295.         board.enemyname->setAnchorPoint(Vec2(0.5f,0.5f));
  296.         board.enemyname->setPosition(board.board->getContentSize().width*7/8,blocksize*5-16);
  297.         board.board->addChild(board.enemyname);

  298.         board.life_hero=Label::createWithBMFont("myfont.fnt","life");
  299.         board.life_hero->setAnchorPoint(Vec2(0,0));
  300.         board.life_hero->setScale(0.4f);
  301.         board.life_hero->setPosition(blocksize*1,blocksize*3+5);
  302.         board.board->addChild(board.life_hero);

  303.         board.offense_hero=Label::createWithBMFont("myfont.fnt","offense");
  304.         board.offense_hero->setAnchorPoint(Vec2(0,0));
  305.         board.offense_hero->setScale(0.4f);
  306.         board.offense_hero->setPosition(blocksize*1,blocksize*2+5);
  307.         board.board->addChild(board.offense_hero);

  308.         board.defense_hero=Label::createWithBMFont("myfont.fnt","defense");
  309.         board.defense_hero->setAnchorPoint(Vec2(0,0));
  310.         board.defense_hero->setScale(0.4f);
  311.         board.defense_hero->setPosition(blocksize*1,blocksize*1+5);
  312.         board.board->addChild(board.defense_hero);

  313.         board.money_hero=Label::createWithBMFont("myfont.fnt","money");
  314.         board.money_hero->setAnchorPoint(Vec2(0,0));
  315.         board.money_hero->setScale(0.4f);
  316.         board.money_hero->setPosition(blocksize*1,blocksize*0+5);
  317.         board.board->addChild(board.money_hero);

  318.         board.yellowkey=Label::createWithBMFont("myfont.fnt","yellowkey");
  319.         board.yellowkey->setAnchorPoint(Vec2(0,0));
  320.         board.yellowkey->setScale(0.4f);
  321.         board.yellowkey->setPosition(blocksize*4,blocksize*3+5);
  322.         board.board->addChild(board.yellowkey);

  323.         board.bluekey=Label::createWithBMFont("myfont.fnt","bluekey");
  324.         board.bluekey->setAnchorPoint(Vec2(0,0));
  325.         board.bluekey->setScale(0.4f);
  326.         board.bluekey->setPosition(blocksize*4,blocksize*2+5);
  327.         board.board->addChild(board.bluekey);

  328.         board.redkey=Label::createWithBMFont("myfont.fnt","redkey");
  329.         board.redkey->setAnchorPoint(Vec2(0,0));
  330.         board.redkey->setScale(0.4f);
  331.         board.redkey->setPosition(blocksize*4,blocksize*1+5);
  332.         board.board->addChild(board.redkey);

  333.         board.life_enemy=Label::createWithBMFont("myfont.fnt","life");
  334.         board.life_enemy->setAnchorPoint(Vec2(0,0));
  335.         board.life_enemy->setScale(0.4f);
  336.         board.life_enemy->setPosition(blocksize*11,blocksize*3+5);
  337.         board.board->addChild(board.life_enemy);

  338.         board.offense_enemy=Label::createWithBMFont("myfont.fnt","offense");
  339.         board.offense_enemy->setAnchorPoint(Vec2(0,0));
  340.         board.offense_enemy->setScale(0.4f);
  341.         board.offense_enemy->setPosition(blocksize*11,blocksize*2+5);
  342.         board.board->addChild(board.offense_enemy);

  343.         board.defense_enemy=Label::createWithBMFont("myfont.fnt","defense");
  344.         board.defense_enemy->setAnchorPoint(Vec2(0,0));
  345.         board.defense_enemy->setScale(0.4f);
  346.         board.defense_enemy->setPosition(blocksize*11,blocksize*1+5);
  347.         board.board->addChild(board.defense_enemy);

  348.         CCLog("Leave InitBoard");
  349. }

  350. void MagicTower::InitHero()
  351. {
  352.         CCLog("Enter InitHero");
  353.         ismoving=false;
  354.         //加载英雄图片
  355.         auto director=Director::getInstance();
  356.         Size visibleSize = director->getVisibleSize();
  357.         auto heroTexture=Director::getInstance()->getTextureCache()->addImage("hero.png");
  358.         auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*1,blocksize,blocksize));
  359.         hero.heroSprite=Sprite::createWithSpriteFrame(frame0);
  360.         hero.heroSprite->setAnchorPoint(Vec2(0,0));
  361.         MoveUnitInTile(hero.nexttilepos,hero.heroSprite);

  362.         map->addChild(hero.heroSprite);

  363.         //存储英雄移动动画
  364.         std::string dirname[]={"down","left","right","up"};
  365.         Vector<SpriteFrame*> animFrames(4);
  366.         for(int i=0;i<4;i++)
  367.         {
  368.                 auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*i,blocksize,blocksize));
  369.                 auto frame1=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*1,blocksize*i,blocksize,blocksize));
  370.                 auto frame2=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*2,blocksize*i,blocksize,blocksize));
  371.                 auto frame3=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*3,blocksize*i,blocksize,blocksize));
  372.                 animFrames.pushBack(frame0);
  373.                 animFrames.pushBack(frame1);
  374.                 animFrames.pushBack(frame2);
  375.                 animFrames.pushBack(frame3);
  376.                 auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
  377.                 animation->setRestoreOriginalFrame(false);
  378.                 AnimationCache::getInstance()->addAnimation(animation,dirname[i]);
  379.                 animFrames.clear();
  380.         }

  381.         //初始化攻击动画
  382.         auto attackTexture= Director::getInstance()->getTextureCache()->addImage("attack.png");
  383.         Size unitsize=attackTexture->getContentSizeInPixels();
  384.         for(int i=0;i<25;i++)
  385.         {
  386.                 auto frame0=SpriteFrame::createWithTexture(attackTexture,
  387.                         Rect(i/5*unitsize.width/5,i%5*unitsize.height/5,unitsize.width/5,unitsize.height/5));
  388.                 animFrames.pushBack(frame0);
  389.         }
  390.         AnimationCache::getInstance()->addAnimation(Animation::createWithSpriteFrames(animFrames,0.05f),"attack");
  391.         animFrames.clear();

  392.         CCLog("Leave InitHero");
  393. }

  394. void MagicTower::menuCloseCallback(Ref* pSender)
  395. {
  396. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
  397.         MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
  398.     return;
  399. #endif

  400.     Director::getInstance()->end();

  401. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
  402.     exit(0);
  403. #endif
  404. }

  405. #if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
  406. void MagicTower::OnMove(EventKeyboard::KeyCode keyCode, Event* event)
  407. {
  408.         CCLog("Enter OnMove");
  409.         auto animCache=AnimationCache::getInstance();
  410.         Animation* curanimation=NULL;
  411.         Vec2 delta;
  412.         int direction;

  413.         switch(keyCode)
  414.         {
  415.                 case EventKeyboard::KeyCode::KEY_UP_ARROW:
  416.                         curanimation=animCache->getAnimation("up");
  417.                         delta.setPoint(0,blocksize);
  418.                         direction=25;
  419.                         break;

  420.                 case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
  421.                         curanimation=animCache->getAnimation("down");
  422.                         delta.setPoint(0,-blocksize);
  423.                         direction=26;
  424.                         break;

  425.                 case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
  426.                         curanimation=animCache->getAnimation("left");
  427.                         delta.setPoint(-blocksize,0);
  428.                         direction=23;
  429.                         break;

  430.                 case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
  431.                         curanimation=animCache->getAnimation("right");
  432.                         delta.setPoint(blocksize,0);
  433.                         direction=24;
  434.                         break;

  435.                 default:
  436.                         DefaultKeyboardDispatcher(keyCode);
  437.                         return;
  438.         }

  439.         //判断英雄位置是否可以移动
  440.         if(curanimation && !ismoving)
  441.         {
  442.                 MoveHero(hero.heroSprite->getPosition()+delta,curanimation,direction);
  443.         }
  444.         CCLog("Leave OnMove");
  445. }
  446. #endif

  447. void MagicTower::PlayHeroMovement(const Vec2& newpos,Animation* anim,int direction,const std::function<void(void)>& afteraction)
  448. {//anim:帧动画  afteraction:状态更新回调
  449.         CCLog("Enter PlayeHeroMovement");
  450.         hero.heroSprite->setSpriteFrame(anim->getFrames().at(0)->getSpriteFrame());
  451.        
  452.         //移动动画和帧动画同时进行
  453.         auto spawn=Spawn::createWithTwoActions(Animate::create(anim),MoveTo::create(0.2f,newpos));

  454.         //帧动画+移动动画->状态更新->可通行->连击
  455.         hero.heroSprite->runAction(Sequence::create(spawn,CallFuncN::create([this,afteraction,direction](Node* node)
  456.         {//如果有回调函数需要写一起,否则单另作为Sequence依次执行会失效,不知道是不是bug
  457.                 afteraction();
  458.                 ismoving=false;
  459.                 CCLog("ismoving");
  460.                 FlushBoard();
  461.         }),NULL));
  462.         CCLog("Leave PlayeHeroMovement");
  463. }

  464. void MagicTower::MoveHero(const Vec2& newpos,Animation* anim,int direction)
  465. {//若成功,则捡物品或攻击
  466.         CCLog("Enter MoveHero");

  467.         ismoving=true;

  468.         Vec2 tilepos;
  469.         MapPosToTilePos(newpos+Vec2(blocksize/2,blocksize/2),tilepos);

  470.         if(map->getLayer("floor")->getTileGIDAt(tilepos) == FLOOR_WALL)
  471.         {//禁止通行
  472.                 ismoving=false;
  473.                 return;
  474.         }

  475.         //若是地板则进行上层判断
  476.         auto layer=map->getLayer("item");
  477.         switch(layer->getTileGIDAt(tilepos))
  478.         {
  479.                 case ITEM_REDDIAMOND:
  480.                         PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  481.                         {//刷新+音乐+物品动画
  482.                                 hero.offense += 100;
  483.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  484.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  485.                                 SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  486.                         });
  487.                         return;

  488.                 case ITEM_BLUEDIAMOND:
  489.                         PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  490.                         {//刷新+音乐+物品动画
  491.                                 hero.defense += 50;
  492.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  493.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  494.                                 SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  495.                         });
  496.                         return;

  497.                 case ITEM_REDBLOOD:
  498.                         PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  499.                         {//刷新+音乐+物品动画
  500.                                 hero.life += 400;
  501.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  502.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  503.                                 SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  504.                         });
  505.                         return;

  506.                 case ITEM_BLUEBLOOD:
  507.                         PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  508.                         {//刷新+音乐+物品动画
  509.                                 hero.life += 200;
  510.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  511.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  512.                                 SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  513.                         });
  514.                         return;
  515.                        
  516.                 case ITEM_YELLOWKEY:
  517.                         PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  518.                         {//刷新+音乐+物品动画
  519.                                 hero.keyyellow++;
  520.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  521.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  522.                                 SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  523.                         });
  524.                         return;
  525.                        
  526.                 case ITEM_BLUEKEY:
  527.                         PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  528.                         {//刷新+音乐+物品动画
  529.                                 hero.keyblue++;
  530.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  531.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  532.                                 SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  533.                         });
  534.                         return;
  535.                        
  536.                 case ITEM_REDKEY:
  537.                         PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  538.                         {//刷新+音乐+物品动画
  539.                                 hero.keyred++;
  540.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  541.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  542.                                 SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
  543.                         });
  544.                         return;
  545.                        
  546.                 default://若为空,执行上层判断
  547.                         break;
  548.         }

  549.         layer=map->getLayer("enemy");
  550.         if(layer->getTileGIDAt(tilepos))
  551.         {//若有敌人
  552.                 PlayHeroMovement(newpos,anim,direction,[this,layer,tilepos]()
  553.                 {
  554.                         auto animation=AnimationCache::getInstance()->getAnimation("attack");
  555.                         auto attacksprite=Sprite::createWithSpriteFrame(animation->getFrames().at(0)->getSpriteFrame());
  556.                         attacksprite->setAnchorPoint(Vec2(0,0));
  557.                         attacksprite->setPosition(-attacksprite->getContentSize().width/4,-attacksprite->getContentSize().height/4);
  558.                         //初始化攻击动画+音乐
  559.                         hero.heroSprite->addChild(attacksprite);
  560.                         attackEnemy(layer,tilepos,attacksprite,Animate::create(animation));       
  561.                 });
  562.                 return;
  563.         }
  564.         //若为空,执行上层判断

  565.         layer=map->getLayer("door");
  566.         switch(layer->getTileGIDAt(tilepos))
  567.         {
  568.                 case DOOR_YELLOW:
  569.                         {
  570.                                 hero.keyyellow--;
  571.                                 auto animation=AnimationCache::getInstance()->getAnimation("DOOR_YELLOW");
  572.                                 auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  573.                                         CallFuncN::create([layer,tilepos](Node*){
  574.                                         CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  575.                                         layer->removeChild(layer->getTileAt(tilepos),true);
  576.                                 })),CallFuncN::create([](Node*){
  577.                                         SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  578.                                 }));
  579.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  580.                                 layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  581.                                         CallFuncN::create([this,newpos,anim,direction](Node*){
  582.                                                 PlayHeroMovement(newpos,anim,direction,[](){});
  583.                                 })));                       
  584.                         }
  585.                         return;

  586.                 case DOOR_BLUE:
  587.                         {
  588.                                 hero.keyblue--;
  589.                                 auto animation=AnimationCache::getInstance()->getAnimation("DOOR_BLUE");
  590.                                 auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  591.                                         CallFuncN::create([layer,tilepos](Node*){
  592.                                         CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  593.                                         layer->removeChild(layer->getTileAt(tilepos),true);
  594.                                 })),CallFuncN::create([](Node*){
  595.                                         SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  596.                                 }));
  597.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  598.                                 layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  599.                                         CallFuncN::create([this,newpos,anim,direction](Node*){
  600.                                                 PlayHeroMovement(newpos,anim,direction,[](){});
  601.                                 })));               
  602.                         }
  603.                         return;

  604.                 case DOOR_RED:
  605.                         {
  606.                                 hero.keyred--;
  607.                                 auto animation=AnimationCache::getInstance()->getAnimation("DOOR_RED");
  608.                                 auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
  609.                                         CallFuncN::create([layer,tilepos](Node*){
  610.                                         CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  611.                                         layer->removeChild(layer->getTileAt(tilepos),true);
  612.                                 })),CallFuncN::create([](Node*){
  613.                                         SimpleAudioEngine::getInstance()->playEffect("open.mp3");
  614.                                 }));
  615.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  616.                                 layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
  617.                                         CallFuncN::create([this,newpos,anim,direction](Node*){
  618.                                                 PlayHeroMovement(newpos,anim,direction,[](){});
  619.                                 })));       
  620.                         }
  621.                         return;
  622.                
  623.                 case DOOR_GREEN:
  624.                         ismoving=false;
  625.                         return;

  626.                 case DOOR_UPSTAIRS:
  627.                         {
  628.                                 //更新地图
  629.                                 Director::getInstance()->setDepthTest(false);
  630.                                 hero.nexttilepos=Vec2(HeroInitPos[(thislevel+1)*4],HeroInitPos[(thislevel+1)*4+1]);
  631.                                 auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel+1));
  632.                                 if(trans)
  633.                                         Director::getInstance()->replaceScene(trans);
  634.                                 ismoving=false;
  635.                         }
  636.                         return;

  637.                 case DOOR_DOWNSTAIRS:
  638.                         {
  639.                                 //更新地图
  640.                                 Director::getInstance()->setDepthTest(false);
  641.                                 hero.nexttilepos=Vec2(HeroInitPos[(thislevel-1)*4+2],HeroInitPos[(thislevel-1)*4+3]);
  642.                                 auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel-1));
  643.                                 if(trans)
  644.                                         Director::getInstance()->replaceScene(trans);
  645.                                 ismoving=false;
  646.                         }
  647.                         return;
  648.         }

  649.         //若无对象存在,则移动英雄
  650.         PlayHeroMovement(newpos,anim,direction,[](){});
  651.         //在执行PlayerHeroMovement的地方,ismoving交给该函数处理
  652.         CCLog("Leave MoveHero");
  653. }

  654. void MagicTower::attackEnemy(TMXLayer* layer,Vec2 tilepos,Sprite* attacksprite,Animate* animate)
  655. {
  656.         CCLog("Enter attackEnemy");

  657.         //判断英雄是否移动了,如果移动则去除animate并结束
  658.         Vec2 herointile;
  659.         MapPosToTilePos(hero.heroSprite->getPosition()+Vec2(blocksize/2,blocksize/2),herointile);
  660.         CCLog("hero:(%f %f)",herointile.x,herointile.y);
  661.         if(herointile != tilepos)
  662.         {
  663.                 attacksprite->stopAllActions();
  664.                 hero.heroSprite->removeChild(attacksprite,true);
  665.                 return;
  666.         }

  667.         attacksprite->runAction(Sequence::create(animate,CallFuncN::create([this,layer,tilepos,animate](Node* attacksprite)
  668.         {
  669.                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  670.                 ValueMap* val=static_cast<ValueMap*>(layer->getTileAt(tilepos)->getUserData());
  671.                 int enemylife=(*val)["life"].asInt();
  672.                 int enemyoffense=(*val)["offense"].asInt();
  673.                 int enemydefense=(*val)["defense"].asInt();
  674.                 int harmetoh=(hero.defense>enemyoffense)?0:enemyoffense-hero.defense;
  675.                 //enemy对hero造成的伤害,如果hero的防>enemy的攻,则无伤害
  676.                 int harmhtoe=(enemydefense>hero.offense)?0:hero.offense-enemydefense;
  677.                 hero.life -= harmetoh;
  678.                 enemylife -= harmhtoe;
  679.                 SimpleAudioEngine::getInstance()->playEffect("fight.mp3");       
  680.                 (*val)["life"]=enemylife;
  681.                 FlushBoard(val);

  682.                 if(enemylife < 0 || hero.life < 0)
  683.                 {
  684.                         if(hero.life < 0)
  685.                         {//英雄挂了
  686.                         }
  687.                         else
  688.                         {
  689.                                 attacksprite->stopAllActions();
  690.                                 hero.money += (*val)["money"].asInt();
  691.                                 hero.heroSprite->removeChild(attacksprite,true);
  692.                                 CCLog("x=%d,y=%d",tilepos.x,tilepos.y);
  693.                                 layer->removeChild(layer->getTileAt(tilepos),true);
  694.                                 FlushBoard(val);
  695.                                 //刷新面板
  696.                         }
  697.                 }
  698.                 else
  699.                 {
  700.                         attackEnemy(layer,tilepos,static_cast<Sprite*>(attacksprite),animate);
  701.                 }
  702.         }),NULL));

  703.         CCLog("Leave attackEnemy");
  704. }

  705. void MagicTower::DefaultKeyboardDispatcher(EventKeyboard::KeyCode keycode)
  706. {//处理其他键盘事件
  707.        
  708. }

  709. void MagicTower::TilePosToMapPos(const Vec2& pos,Vec2& objpos)
  710. {//pos为Tile坐标系,相对于窗口左上角
  711.         float rex=pos.x*blocksize;
  712.         float rey=map->getContentSize().height-pos.y*blocksize;
  713.         objpos.setPoint(rex,rey);
  714. }

  715. void MagicTower::MapPosToTilePos(const Vec2& pos,Vec2& objpos)
  716. {//pos为map坐标系,相对于左下角
  717.         float rex=pos.x/(blocksize);
  718.         float rey=(map->getContentSize().height-pos.y)/(blocksize);
  719.         objpos.setPoint(int(rex),int(rey));
  720. }

  721. void MagicTower::MoveUnitInTile(const Vec2& pos,Sprite* obj)
  722. {//pos为Tile坐标系,相对于左上角
  723.         float rex=pos.x*blocksize;
  724.         float rey=map->getContentSize().height-pos.y*blocksize-blocksize;
  725.         obj->setPosition(rex,rey);
  726. }

  727. void MagicTower::FlushBoard(ValueMap* obj)
  728. {
  729.         CCLog("Enter FlushBoard");
  730.         char title[64];
  731. #if(CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
  732.         sprintf(title,"魔塔 第%d层",thislevel);
  733. #else
  734.         sprintf(title,"MagicTower %dth",thislevel);
  735. #endif
  736.         board.maintitle->setString(IConvConvert_GBKToUTF8(title));
  737.         board.heroname->setString(IConvConvert_GBKToUTF8(hero.name));
  738.         sprintf(title,"%d",hero.life);
  739.         board.life_hero->setString(IConvConvert_GBKToUTF8(title));
  740.         sprintf(title,"%d",hero.offense);
  741.         board.offense_hero->setString(IConvConvert_GBKToUTF8(title));
  742.         sprintf(title,"%d",hero.defense);
  743.         board.defense_hero->setString(IConvConvert_GBKToUTF8(title));
  744.         sprintf(title,"%d",hero.money);
  745.         board.money_hero->setString(IConvConvert_GBKToUTF8(title));
  746.         sprintf(title,"%d",hero.keyyellow);
  747.         board.yellowkey->setString(IConvConvert_GBKToUTF8(title));
  748.         sprintf(title,"%d",hero.keyblue);
  749.         board.bluekey->setString(IConvConvert_GBKToUTF8(title));
  750.         sprintf(title,"%d",hero.keyred);
  751.         board.redkey->setString(IConvConvert_GBKToUTF8(title));

  752.         if(obj)
  753.         {
  754.                 int category=(*obj)["category"].asInt();
  755.                 if(category == TYPE_ENEMY)
  756.                 {
  757.                         board.enemyname->setString(IConvConvert_GBKToUTF8((*obj)["name"].asString()));
  758.                         sprintf(title,"%d",(*obj)["life"].asInt());
  759.                         board.life_enemy->setString(IConvConvert_GBKToUTF8(title));
  760.                         sprintf(title,"%d",(*obj)["offense"].asInt());
  761.                         board.offense_enemy->setString(IConvConvert_GBKToUTF8(title));
  762.                         sprintf(title,"%d",(*obj)["defense"].asInt());
  763.                         board.defense_enemy->setString(IConvConvert_GBKToUTF8(title));
  764.                 }
  765.                 else if(category == TYPE_ITEM)
  766.                 {
  767.                 }
  768.         }
  769.         CCLog("Leave FlushBoard");

  770. }

  771. void MagicTower::SelectSprite(Sprite* sprite)
  772. {
  773.         CCLog("Enter SelectSprite");
  774.         auto data=static_cast<ValueMap*>(sprite->getUserData());
  775.         if((*data)["selected"].asBool())
  776.         {
  777.                 sprite->removeChildByTag(1000);
  778.                 (*data)["selected"]=false;
  779.         }
  780.         else
  781.         {
  782.                 auto texture=map->getLayer("enemy")->getTexture();
  783.                 int hei=texture->getContentSize().height;
  784.                 auto selsprite=Sprite::createWithTexture(texture,Rect(0,texture->getContentSize().height-blocksize,blocksize,blocksize));
  785.                 //设置为最后一个
  786.                 selsprite->setAnchorPoint(Vec2(0,0));
  787.                 selsprite->setPosition(0,0);
  788.                 sprite->addChild(selsprite,selsprite->getLocalZOrder(),1000);
  789.                 FlushBoard(data);
  790.                 (*data)["selected"]=true;
  791.         }
  792.         CCLog("Leave SelectSprite");
  793. }

  794. //MagicTowerLayerManager管理场景切换
  795. MagicTowerLayerManager& MagicTowerLayerManager::getInstance()
  796. {
  797.         static MagicTowerLayerManager manager;
  798.         return manager;
  799. }

  800. Scene* MagicTowerLayerManager::getScene(int layer)
  801. {
  802.         curlayer=layer;
  803.         auto curscene=Scene::create();
  804.         auto curlayer=new MagicTower(layer);
  805.         if (curscene && curlayer)
  806.         {
  807.                 curscene->addChild(curlayer);
  808.                 curlayer->autorelease();
  809.         }
  810.         return curscene;
  811. }

  812. Hero MagicTower::hero;
  813. Board MagicTower::board;

  814. MagicTowerLayerManager::MagicTowerLayerManager()
  815. {
  816.         curlayer=1;
  817.         MagicTower::hero.name="勇士";
  818.         MagicTower::hero.life=1000;
  819.         MagicTower::hero.offense=200;
  820.         MagicTower::hero.defense=200;
  821.         MagicTower::hero.keyyellow=10;
  822.         MagicTower::hero.keyblue=10;
  823.         MagicTower::hero.keyred=10;
  824.         MagicTower::hero.money=1000;
  825.         MagicTower::hero.nexttilepos=Vec2(6,10);//初始位置
  826.         SimpleAudioEngine::getInstance()->playBackgroundMusic("background.mp3",true);
  827. }

复制代码


回复 赞! 靠!

使用道具 举报

发表于 2014-6-22 18:26:40 | 显示全部楼层
又一使用cocos2b的家伙。
这画质你敢拿出来给人看?
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-6-22 18:34:24 | 显示全部楼层
几年前的魔塔就是这画质,照样很多人玩,至少比dos画质好画质这玩意,还是要有清晰图片的
回复 赞! 靠!

使用道具 举报

发表于 2014-6-22 18:55:25 | 显示全部楼层
元始天尊 发表于 2014-6-22 10:34
几年前的魔塔就是这画质,照样很多人玩,至少比dos画质好画质这玩意,还是要有清晰图片的
...

画质可不比DOS好。你知道画质的意思么?作为一个艺术品,我能说沙罗曼蛇的画质比雷电2好么?
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-6-22 21:15:12 | 显示全部楼层
0xAA55 发表于 2014-6-22 18:55
画质可不比DOS好。你知道画质的意思么?作为一个艺术品,我能说沙罗曼蛇的画质比雷电2好么? ...

我不需要知道这2游戏画质怎样,因为我不那么关心画质,我更关心程序逻辑,画质的话,2d程序主要还是靠图片,魔塔坐到这个程度基本上逻辑已经出来了,剩下的美工什么的对我来说都不是重点,因为我不做这方面东西,画质这种东西是可以慢慢调的,至于说你要不要用3d方式显卡渲染,和怎么内部实现都是个人喜好。我可以不用粒子效果,我可以不用物理引擎。你既然会3d编程都能编出一个命令行2048呢,我没学过图像编程,我用游戏引擎编出一个几年前的魔塔有啥不行的,我没学过,因此我有理由做到这个程度。当然要有时间我也会去改善画质
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-6-22 21:21:10 | 显示全部楼层
0xAA55 发表于 2014-6-22 18:55
画质可不比DOS好。你知道画质的意思么?作为一个艺术品,我能说沙罗曼蛇的画质比雷电2好么? ...

另外,别说什么cocos2dx没人用之类的话,先搞懂cocos2d cocos2dx区别,不懂就乱说,现在这东西本来就很火。你觉得不好可以不用,谁又没逼着你用cocos2d,谁也没逼着我用热门的游戏引擎。我倒是觉得,如果没有曾经做出过几个小游戏,然后就去实现渲染引擎这种东西,那是筑高台于浮沙,这东西额都是循序渐进的,最开始写东西无论游戏还是什么,可能会写的画质不好,不过慢慢的会用了,就会好的,不是说一下子自己实现个引擎,然后就直接实现一个世人无法直视的游戏,显然不现实,就像你研究dos系统以为可以用到windows内核里去一样,试问可能么,你编出来有用的东西了吗
回复 赞! 靠!

使用道具 举报

发表于 2014-6-23 12:30:12 | 显示全部楼层
元始天尊 发表于 2014-6-22 13:21
另外,别说什么cocos2dx没人用之类的话,先搞懂cocos2d cocos2dx区别,不懂就乱说,现在这东西本来就很火 ...

小学初中的时候我做出个各种各样的小游戏,高中的时候,都删了。所以到了大学我意识到游戏引擎的重要性。此外你搞混了我研究DOS的的初衷,我是为了搞到Windows内核里去?
装逼够了给我滚出去。
回复 赞! 靠!

使用道具 举报

发表于 2014-6-23 12:31:36 | 显示全部楼层
元始天尊 发表于 2014-6-22 13:15
我不需要知道这2游戏画质怎样,因为我不那么关心画质,我更关心程序逻辑,画质的话,2d程序主要还是靠图 ...

你关心这个你关心那个,你知道你的玩家关心什么?
改天我让喷神James给你的游戏做一个视频。
另外你难道还不能理解一个论坛的坛主为什么要编写控制台游戏?是因为水平限制?
回复 赞! 靠!

使用道具 举报

发表于 2014-6-23 12:36:44 | 显示全部楼层
你发这个帖子就是为了秀一下代码?你没看我的帖子基本都是教程么
谁会看你的代码。
回复 赞! 靠!

使用道具 举报

 楼主| 发表于 2014-6-23 15:07:00 | 显示全部楼层
0xAA55 发表于 2014-6-23 12:36
你发这个帖子就是为了秀一下代码?你没看我的帖子基本都是教程么
谁会看你的代码。 ...

要说编码中间遇到什么问题,那就多了去了,总结起来没个一天搞不定,你那些相对来说量比较小,所以可以吧整个探索过程呈现出来,我只好只展示结果了
回复 赞! 靠!

使用道具 举报

发表于 2014-6-23 15:23:29 | 显示全部楼层
元始天尊 发表于 2014-6-23 07:07
要说编码中间遇到什么问题,那就多了去了,总结起来没个一天搞不定,你那些相对来说量比较小,所以可以吧 ...

还是希望你能把过程说一下,要点说一下。这样比较好
回复 赞! 靠!

使用道具 举报

本版积分规则

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-11-22 11:39 , Processed in 0.050656 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表