- UID
- 2
- 精华
- 积分
- 7736
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
花了一个礼拜,学了cocos2dx 1000行c++代码的魔塔,麻雀虽小五脏俱全,甚至比原版魔塔有创新的地方。
比如支持直接点选怪物查看其属性,楼层切换动画,,打怪时允许撤离,,等,代码如下,注释已经写得很清楚,自行研究。
里面lambda表达式是我的得意之处,对于动画的过程回调我也着重研究了一番。做什么东西都不是那么容易的,嘴说说就可以做出来的,
这个魔塔也是,因为做的时候,你才会发现哪里要怎么写才好实现。现在仍有bug,不过已经无伤大雅了。现在做了4个关卡,有兴趣的,可以自己在做
AppDelegate.cpp
- #include "AppDelegate.h"
- #include "MagicTower.h"
- USING_NS_CC;
- AppDelegate::AppDelegate() {
- }
- AppDelegate::~AppDelegate()
- {
- }
- bool AppDelegate::applicationDidFinishLaunching() {
- // initialize director
- auto director = Director::getInstance();
- auto glview = director->getOpenGLView();
- if(!glview) {
- glview = GLView::create("My Game");
- director->setOpenGLView(glview);
- }
- // turn on display FPS
- director->setDisplayStats(true);
- // set FPS. the default value is 1.0/60 if you don't call this
- director->setAnimationInterval(1.0 / 60);
- // create a scene. it's an autorelease object
- auto scene = MagicTowerLayerManager::getInstance().getScene();
- // run
- director->runWithScene(scene);
- return true;
- }
- // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
- void AppDelegate::applicationDidEnterBackground() {
- Director::getInstance()->stopAnimation();
- // if you use SimpleAudioEngine, it must be pause
- // SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
- }
- // this function will be called when the app is active again
- void AppDelegate::applicationWillEnterForeground() {
- Director::getInstance()->startAnimation();
- // if you use SimpleAudioEngine, it must resume here
- // SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
- }
复制代码
AppDelegate.h
- #ifndef _APP_DELEGATE_H_
- #define _APP_DELEGATE_H_
- #include "cocos2d.h"
- /**
- @brief The cocos2d Application.
- The reason for implement as private inheritance is to hide some interface call by Director.
- */
- class AppDelegate : private cocos2d::Application
- {
- public:
- AppDelegate();
- virtual ~AppDelegate();
- /**
- @brief Implement Director and Scene init code here.
- @return true Initialize success, app continue.
- @return false Initialize failed, app terminate.
- */
- virtual bool applicationDidFinishLaunching();
- /**
- @brief The function be called when the application enter background
- @param the pointer of the application
- */
- virtual void applicationDidEnterBackground();
- /**
- @brief The function be called when the application enter foreground
- @param the pointer of the application
- */
- virtual void applicationWillEnterForeground();
- };
- #endif // _APP_DELEGATE_H_
复制代码
MagicTower.cpp
- #include "MagicTower.h"
- #include "..\external\win32-specific\icon\include\iconv.h"
- #pragma comment(lib,"libiconv.lib")
- USING_NS_CC;
- using namespace CocosDenshion;
- bool IConvConvert(const char *from_charset, const char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen)
- {
- iconv_t cd = iconv_open(to_charset, from_charset);
- if (cd == 0) return false;
- const char **pin = &inbuf;
- char **pout = &outbuf;
- memset(outbuf,0,outlen);
- size_t ret = iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
- iconv_close(cd);
- return ret == (size_t)(-1) ? false : true;
- }
- std::string IConvConvert_GBKToUTF8(const std::string& str)
- {
- const char* textIn = str.c_str();
- char textOut[256];
- bool ret = IConvConvert("gb2312", "utf-8", textIn, strlen(textIn),textOut, 256);
- return ret ? std::string(textOut) : std::string();
- }
- // on "init" you need to initialize your instance
- MagicTower::MagicTower(int level)
- {
- thislevel=level;
- auto director=Director::getInstance();
- //director->getOpenGLView()->setFrameSize(416,416);
- //////////////////////////////
- // 1. super init first
- Layer::init();
- Size visibleSize = director->getVisibleSize();
- Vec2 origin = director->getVisibleOrigin();
- /////////////////////////////
- // 2. add a menu item with "X" image, which is clicked to quit the program
- // you may modify it.
- // add a "close" icon to exit the progress. it's an autorelease object
- auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(MagicTower::menuCloseCallback, this));
- closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
- origin.y + closeItem->getContentSize().height/2));
- // create menu, it's an autorelease object
- auto menuclose = Menu::create(closeItem, NULL);
- menuclose->setPosition(Vec2::ZERO);
- this->addChild(menuclose, 1);
- /////////////////////////////
- // 3. add your codes below...
- InitMap();
- InitHero();
- FlushBoard();
- //初始换方向键回调
- auto listener=EventListenerKeyboard::create();
- listener->onKeyPressed=CC_CALLBACK_2(MagicTower::OnMove,this);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
- }
- void MagicTower::InitMap()
- {
- //加载地图背景
- auto director=Director::getInstance();
- Size visibleSize = director->getVisibleSize();
- char mapname[20];
- sprintf(mapname,"%d.tmx",thislevel);
- map=TMXTiledMap::create(mapname);
- map->setAnchorPoint(Vec2(0.5f,0.5f));
- board.board=TMXTiledMap::create("background.tmx");
- board.board->setAnchorPoint(Vec2(0.5f,0.5f));
- map->setPosition(visibleSize.width/2,visibleSize.height/2+board.board->getContentSize().height/2);
- board.board->setPosition(visibleSize.width/2,visibleSize.height/2-map->getContentSize().height/2);
- addChild(map);
- addChild(board.board);
- InitBoard();
- //初始化地图元素
- Vector<SpriteFrame*> animFrames(4);
- auto enemylayer=map->getLayer("enemy");
- auto enemyTexture=enemylayer->getTexture();
- for(int i=0;i<map->getMapSize().width;i++)
- {
- for(int j=0;j<map->getMapSize().height;j++)
- {
- int id=enemylayer->getTileGIDAt(Vec2(i,j));
- if(id)
- {
- int index=(id-ENEMY_BEGIN)/4;
- auto frame0=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*0,blocksize*index,blocksize,blocksize));
- auto frame1=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*1,blocksize*index,blocksize,blocksize));
- auto frame2=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*2,blocksize*index,blocksize,blocksize));
- auto frame3=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*3,blocksize*index,blocksize,blocksize));
- animFrames.pushBack(frame0);
- animFrames.pushBack(frame1);
- animFrames.pushBack(frame2);
- animFrames.pushBack(frame3);
- auto animation=Animation::createWithSpriteFrames(animFrames,0.1f);
- animFrames.clear();
- auto cursprite=enemylayer->getTileAt(Vec2(i,j));
- if(!cursprite)
- return;
- cursprite->runAction(RepeatForever::create(Animate::create(animation)));
- cursprite->setUserData(ObjManager::getInstance().InitEnemyByType(id));
- }
- }
- }
- //初始化点击事件
- auto listener=EventListenerTouchOneByOne::create();
- listener->onTouchBegan=[this,enemylayer](Touch* touch,Event* event)
- {
- Vec2 tilepos;
- WorldPosToTilePos(Vec2(touch->getLocation().x-blocksize/2,touch->getLocation().y-blocksize/2),tilepos);
- if(tilepos.x >= 0 && tilepos.y >=0 &&
- tilepos.x < enemylayer->getLayerSize().width && tilepos.y < enemylayer->getLayerSize().height)
- {
- Sprite* node=enemylayer->getTileAt(tilepos);
- if(node)
- {
- SelectSprite(node);
- }
- }
- //根据位置获取单元格,设置为选中状态并刷新数据到面板
- return true;
- };
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,enemylayer);
- auto itemlayer=map->getLayer("item");
- for(int i=0;i<map->getMapSize().width;i++)
- {
- for(int j=0;j<map->getMapSize().height;j++)
- {
- int id=itemlayer->getTileGIDAt(Vec2(i,j));
- auto cursprite=enemylayer->getTileAt(Vec2(i,j));
- //if(id && cursprite)
- //{
- // cursprite->setUserData(ObjManager::getInstance().InitItemByType(id));
- //}
- }
- }
- //初始化门动画
- auto doorTexture=map->getLayer("door")->getTexture();
- int doordata[]={0,1,2,3};
- char* doorname[]={"DOOR_YELLOW","DOOR_BLUE","DOOR_RED","DOOR_GREEN"};
- for(int i=0;i<getNum(doordata);i++)
- {
- doordata[i];
- auto frame0=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*0,blocksize,blocksize));
- auto frame1=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*1,blocksize,blocksize));
- auto frame2=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*2,blocksize,blocksize));
- auto frame3=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*3,blocksize,blocksize));
- animFrames.pushBack(frame0);
- animFrames.pushBack(frame1);
- animFrames.pushBack(frame2);
- animFrames.pushBack(frame3);
- auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
- animFrames.clear();
- AnimationCache::getInstance()->addAnimation(animation,doorname[i]);
- }
- }
- void MagicTower::InitBoard()
- {
- //初始化面板
- char title[20];
- sprintf(title,"魔塔 第%d层",thislevel);
- board.maintitle=Label::createWithSystemFont(IConvConvert_GBKToUTF8(title),"黑体",30);
- board.maintitle->setColor(Color3B::GREEN);
- board.maintitle->setAnchorPoint(Vec2(0.5f,0.5f));
- board.maintitle->setPosition(board.board->getContentSize().width/2,blocksize*5+16);
- board.board->addChild(board.maintitle);
- board.heroname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("英雄"),"黑体",24);
- board.heroname->setColor(Color3B::RED);
- board.heroname->setAnchorPoint(Vec2(0.5f,0.5f));
- board.heroname->setPosition(board.board->getContentSize().width/4,blocksize*5-16);
- board.board->addChild(board.heroname);
- board.enemyname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("敌方"),"黑体",24);
- board.enemyname->setColor(Color3B::RED);
- board.enemyname->setAnchorPoint(Vec2(0.5f,0.5f));
- board.enemyname->setPosition(board.board->getContentSize().width*7/8,blocksize*5-16);
- board.board->addChild(board.enemyname);
- board.life_hero=Label::createWithBMFont("myfont.fnt","life");
- board.life_hero->setAnchorPoint(Vec2(0,0));
- board.life_hero->setScale(0.4f);
- board.life_hero->setPosition(blocksize*1,blocksize*3+5);
- board.board->addChild(board.life_hero);
- board.offense_hero=Label::createWithBMFont("myfont.fnt","offense");
- board.offense_hero->setAnchorPoint(Vec2(0,0));
- board.offense_hero->setScale(0.4f);
- board.offense_hero->setPosition(blocksize*1,blocksize*2+5);
- board.board->addChild(board.offense_hero);
- board.defense_hero=Label::createWithBMFont("myfont.fnt","defense");
- board.defense_hero->setAnchorPoint(Vec2(0,0));
- board.defense_hero->setScale(0.4f);
- board.defense_hero->setPosition(blocksize*1,blocksize*1+5);
- board.board->addChild(board.defense_hero);
- board.money_hero=Label::createWithBMFont("myfont.fnt","money");
- board.money_hero->setAnchorPoint(Vec2(0,0));
- board.money_hero->setScale(0.4f);
- board.money_hero->setPosition(blocksize*1,blocksize*0+5);
- board.board->addChild(board.money_hero);
- board.yellowkey=Label::createWithBMFont("myfont.fnt","yellowkey");
- board.yellowkey->setAnchorPoint(Vec2(0,0));
- board.yellowkey->setScale(0.4f);
- board.yellowkey->setPosition(blocksize*4,blocksize*3+5);
- board.board->addChild(board.yellowkey);
- board.bluekey=Label::createWithBMFont("myfont.fnt","bluekey");
- board.bluekey->setAnchorPoint(Vec2(0,0));
- board.bluekey->setScale(0.4f);
- board.bluekey->setPosition(blocksize*4,blocksize*2+5);
- board.board->addChild(board.bluekey);
- board.redkey=Label::createWithBMFont("myfont.fnt","redkey");
- board.redkey->setAnchorPoint(Vec2(0,0));
- board.redkey->setScale(0.4f);
- board.redkey->setPosition(blocksize*4,blocksize*1+5);
- board.board->addChild(board.redkey);
- board.life_enemy=Label::createWithBMFont("myfont.fnt","life");
- board.life_enemy->setAnchorPoint(Vec2(0,0));
- board.life_enemy->setScale(0.4f);
- board.life_enemy->setPosition(blocksize*11,blocksize*3+5);
- board.board->addChild(board.life_enemy);
- board.offense_enemy=Label::createWithBMFont("myfont.fnt","offense");
- board.offense_enemy->setAnchorPoint(Vec2(0,0));
- board.offense_enemy->setScale(0.4f);
- board.offense_enemy->setPosition(blocksize*11,blocksize*2+5);
- board.board->addChild(board.offense_enemy);
- board.defense_enemy=Label::createWithBMFont("myfont.fnt","defense");
- board.defense_enemy->setAnchorPoint(Vec2(0,0));
- board.defense_enemy->setScale(0.4f);
- board.defense_enemy->setPosition(blocksize*11,blocksize*1+5);
- board.board->addChild(board.defense_enemy);
- }
- void MagicTower::InitHero()
- {
- ismoving=false;
- //加载英雄图片
- auto director=Director::getInstance();
- Size visibleSize = director->getVisibleSize();
- auto heroTexture=Director::getInstance()->getTextureCache()->addImage("hero.png");
- auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*1,blocksize,blocksize));
- hero.heroSprite=Sprite::createWithSpriteFrame(frame0);
- hero.heroSprite->setAnchorPoint(Vec2(0,0));
- MoveUnitInTile(hero.nexttilepos,hero.heroSprite);
- addChild(hero.heroSprite);
- //存储英雄移动动画
- std::string dirname[]={"down","left","right","up"};
- Vector<SpriteFrame*> animFrames(4);
- for(int i=0;i<4;i++)
- {
- auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*i,blocksize,blocksize));
- auto frame1=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*1,blocksize*i,blocksize,blocksize));
- auto frame2=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*2,blocksize*i,blocksize,blocksize));
- auto frame3=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*3,blocksize*i,blocksize,blocksize));
- animFrames.pushBack(frame0);
- animFrames.pushBack(frame1);
- animFrames.pushBack(frame2);
- animFrames.pushBack(frame3);
- auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
- animation->setRestoreOriginalFrame(false);
- AnimationCache::getInstance()->addAnimation(animation,dirname[i]);
- animFrames.clear();
- }
- //初始化攻击动画
- auto attackTexture= Director::getInstance()->getTextureCache()->addImage("attack.png");
- Size unitsize=attackTexture->getContentSizeInPixels();
- for(int i=0;i<25;i++)
- {
- auto frame0=SpriteFrame::createWithTexture(attackTexture,
- Rect(i/5*unitsize.width/5,i%5*unitsize.height/5,unitsize.width/5,unitsize.height/5));
- animFrames.pushBack(frame0);
- }
- AnimationCache::getInstance()->addAnimation(Animation::createWithSpriteFrames(animFrames,0.05f),"attack");
- animFrames.clear();
- }
- void MagicTower::menuCloseCallback(Ref* pSender)
- {
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
- MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
- return;
- #endif
- Director::getInstance()->end();
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- exit(0);
- #endif
- }
- void MagicTower::OnMove(EventKeyboard::KeyCode keyCode, Event* event)
- {
- auto animCache=AnimationCache::getInstance();
- Animation* curanimation=NULL;
- Vec2 delta;
- switch(keyCode)
- {
- case EventKeyboard::KeyCode::KEY_UP_ARROW:
- curanimation=animCache->getAnimation("up");
- delta.setPoint(0,blocksize);
- break;
- case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
- curanimation=animCache->getAnimation("down");
- delta.setPoint(0,-blocksize);
- break;
- case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
- curanimation=animCache->getAnimation("left");
- delta.setPoint(-blocksize,0);
- break;
- case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
- curanimation=animCache->getAnimation("right");
- delta.setPoint(blocksize,0);
- break;
- default:
- return DefaultKeyboardDispatcher(keyCode);
- }
- //判断英雄位置是否可以移动
- if(curanimation && !ismoving)
- {
- MoveHero(hero.heroSprite->getPosition()+delta,curanimation,keyCode);
- }
- }
- void MagicTower::PlayHeroMovement(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode,
- const std::function<void(void)>& afteraction)
- {//anim:帧动画 afteraction:状态更新回调
- hero.heroSprite->setSpriteFrame(anim->getFrames().at(0)->getSpriteFrame());
-
- //移动动画和帧动画同时进行
- auto spawn=Spawn::createWithTwoActions(Animate::create(anim),MoveTo::create(0.2f,newpos));
- //帧动画+移动动画 -> 状态更新 -> 可通行 -> 连击检测
- hero.heroSprite->runAction(Sequence::create(spawn,CallFuncN::create([this,afteraction,keyCode](Node* node)
- {//所有回调函数需要写一起,否则单另作为Sequence依次执行会失效,不知道是不是bug
- afteraction();
- ismoving=false;
- CCLog("ismoving");
- FlushBoard();
- if(!ismoving)
- {
- if((keyCode == EventKeyboard::KeyCode::KEY_UP_ARROW && GetKeyState(VK_UP) < 0) ||
- (keyCode == EventKeyboard::KeyCode::KEY_DOWN_ARROW && GetKeyState(VK_DOWN) < 0) ||
- (keyCode == EventKeyboard::KeyCode::KEY_LEFT_ARROW && GetKeyState(VK_LEFT) < 0) ||
- (keyCode == EventKeyboard::KeyCode::KEY_RIGHT_ARROW && GetKeyState(VK_RIGHT) < 0))
- {
- OnMove(keyCode,NULL);
- }
- }
- }),NULL));
- }
- void MagicTower::MoveHero(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode)
- {//若成功,则捡物品或者攻击
- ismoving=true;
- Vec2 tilepos;
- WorldPosToTilePos(newpos,tilepos);
- if(map->getLayer("floor")->getTileGIDAt(tilepos) == FLOOR_WALL)
- {//禁止通行
- ismoving=false;
- return;
- }
- //若是地板则进行上层判断
- auto layer=map->getLayer("item");
- switch(layer->getTileGIDAt(tilepos))
- {
- case ITEM_REDDIAMOND:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.offense += 100;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
- case ITEM_BLUEDIAMOND:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.defense += 50;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
- case ITEM_REDBLOOD:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.life += 400;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
- case ITEM_BLUEBLOOD:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.life += 200;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- case ITEM_YELLOWKEY:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.keyyellow++;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- case ITEM_BLUEKEY:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.keyblue++;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- case ITEM_REDKEY:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.keyred++;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- default://若为空,执行上层判断
- break;
- }
- layer=map->getLayer("enemy");
- if(layer->getTileGIDAt(tilepos))
- {//若有敌人
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {
- auto animation=AnimationCache::getInstance()->getAnimation("attack");
- auto attacksprite=Sprite::createWithSpriteFrame(animation->getFrames().at(0)->getSpriteFrame());
- attacksprite->setAnchorPoint(Vec2(0,0));
- attacksprite->setPosition(-attacksprite->getContentSize().width/4,-attacksprite->getContentSize().height/4);
- //开始攻击动画+音乐
- hero.heroSprite->addChild(attacksprite);
- attackEnemy(layer,tilepos,attacksprite,Animate::create(animation));
- });
- return;
- }
- //若为空,执行上层判断
- layer=map->getLayer("door");
- switch(layer->getTileGIDAt(tilepos))
- {
- case DOOR_YELLOW:
- {
- hero.keyyellow--;
- auto animation=AnimationCache::getInstance()->getAnimation("DOOR_YELLOW");
- auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
- CallFuncN::create([layer,tilepos](Node*){
- layer->removeChild(layer->getTileAt(tilepos),true);
- })),CallFuncN::create([](Node*){
- SimpleAudioEngine::getInstance()->playEffect("open.mp3");
- }));
- layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
- CallFuncN::create([this,newpos,anim,keyCode](Node*){
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- })));
- }
- return;
- case DOOR_BLUE:
- {
- hero.keyblue--;
- auto animation=AnimationCache::getInstance()->getAnimation("DOOR_BLUE");
- auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
- CallFuncN::create([layer,tilepos](Node*){
- layer->removeChild(layer->getTileAt(tilepos),true);
- })),CallFuncN::create([](Node*){
- SimpleAudioEngine::getInstance()->playEffect("open.mp3");
- }));
- layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
- CallFuncN::create([this,newpos,anim,keyCode](Node*){
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- })));
- }
- return;
- case DOOR_RED:
- {
- hero.keyred--;
- auto animation=AnimationCache::getInstance()->getAnimation("DOOR_RED");
- auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
- CallFuncN::create([layer,tilepos](Node*){
- layer->removeChild(layer->getTileAt(tilepos),true);
- })),CallFuncN::create([](Node*){
- SimpleAudioEngine::getInstance()->playEffect("open.mp3");
- }));
- layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
- CallFuncN::create([this,newpos,anim,keyCode](Node*){
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- })));
- }
- return;
-
- case DOOR_GREEN:
- ismoving=false;
- return;
- case DOOR_UPSTAIRS:
- {
- //更新地图
- Director::getInstance()->setDepthTest(false);
- hero.nexttilepos=Vec2(HeroInitPos[(thislevel+1)*4],HeroInitPos[(thislevel+1)*4+1]);
- auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel+1));
- if(trans)
- Director::getInstance()->replaceScene(trans);
- ismoving=false;
- }
- return;
- case DOOR_DOWNSTAIRS:
- {
- //更新地图
- Director::getInstance()->setDepthTest(false);
- hero.nexttilepos=Vec2(HeroInitPos[(thislevel-1)*4+2],HeroInitPos[(thislevel-1)*4+3]);
- auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel-1));
- if(trans)
- Director::getInstance()->replaceScene(trans);
- ismoving=false;
- }
- return;
- }
- //若无对象存在,则移动英雄
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- //在执行PlayerHeroMovement的地方,ismoving交给该函数处理
- }
- void MagicTower::attackEnemy(TMXLayer* layer,Vec2 tilepos,Sprite* attacksprite,Animate* animate)
- {
- //判断英雄是否移动了,如果移动则去除animate并结束
- Vec2 herointile;
- WorldPosToTilePos(hero.heroSprite->getPosition(),herointile);
- if(herointile != tilepos)
- {
- attacksprite->stopAllActions();
- hero.heroSprite->removeChild(attacksprite,true);
- return;
- }
- attacksprite->runAction(Sequence::create(animate,CallFuncN::create([this,layer,tilepos,animate](Node* attacksprite)
- {
- ValueMap* val=static_cast<ValueMap*>(layer->getTileAt(tilepos)->getUserData());
- int enemylife=(*val)["life"].asInt();
- int enemyoffense=(*val)["offense"].asInt();
- int enemydefense=(*val)["defense"].asInt();
- int harmetoh=(hero.defense>enemyoffense)?0:enemyoffense-hero.defense;//enemy对hero造成的伤害,如果hero的防>enemy的攻,则无伤害
- int harmhtoe=(enemydefense>hero.offense)?0:hero.offense-enemydefense;
- hero.life -= harmetoh;
- enemylife -= harmhtoe;
- SimpleAudioEngine::getInstance()->playEffect("fight.mp3");
- (*val)["life"]=enemylife;
- FlushBoard(val);
- if(enemylife < 0 || hero.life < 0)
- {
- if(hero.life < 0)
- {//英雄挂了
- }
- else
- {
- attacksprite->stopAllActions();
- hero.money += (*val)["money"].asInt();
- hero.heroSprite->removeChild(attacksprite,true);
- layer->removeChild(layer->getTileAt(tilepos),true);
- FlushBoard(val);
- //刷新面板
- }
- }
- else
- {
- attackEnemy(layer,tilepos,static_cast<Sprite*>(attacksprite),animate);
- }
- }),NULL));
- }
- void MagicTower::DefaultKeyboardDispatcher(EventKeyboard::KeyCode keycode)
- {//处理其他键盘事件
-
- }
- void MagicTower::WorldPosToTilePos(const Vec2& pos,Vec2& objpos)
- {//pos为世界坐标系,相对于窗口左下角,目标锚点位于左下角
- float rex=map->getContentSize().width/2+(pos.x+blocksize/2-map->getPosition().x);
- float rey=map->getContentSize().height/2-(pos.y+blocksize/2-map->getPosition().y);
- objpos.setPoint(int(rex/blocksize),int(rey/blocksize));
- }
- void MagicTower::TilePosToWorldPos(const Vec2& pos,Vec2& objpos)
- {//pos为Tile坐标系,相对于窗口左上角
- float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
- float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y;
- objpos.setPoint(rex,rey);
- }
- void MagicTower::MoveUnitInTile(const Vec2& pos,Sprite* obj)
- {//pos为Tile坐标系,相对于左上角
- float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
- float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y-blocksize;
- obj->setPosition(rex,rey);
- }
- void MagicTower::FlushBoard(ValueMap* obj)
- {
- char str[20];
- sprintf(str,"魔塔 第%d层",thislevel);
- board.maintitle->setString(IConvConvert_GBKToUTF8(str));
- board.heroname->setString(IConvConvert_GBKToUTF8(hero.name));
- sprintf(str,"%d",hero.life);
- board.life_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.offense);
- board.offense_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.defense);
- board.defense_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.money);
- board.money_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.keyyellow);
- board.yellowkey->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.keyblue);
- board.bluekey->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.keyred);
- board.redkey->setString(IConvConvert_GBKToUTF8(str));
- if(obj)
- {
- int category=(*obj)["category"].asInt();
- if(category == TYPE_ENEMY)
- {
- board.enemyname->setString(IConvConvert_GBKToUTF8((*obj)["name"].asString()));
- sprintf(str,"%d",(*obj)["life"].asInt());
- board.life_enemy->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",(*obj)["offense"].asInt());
- board.offense_enemy->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",(*obj)["defense"].asInt());
- board.defense_enemy->setString(IConvConvert_GBKToUTF8(str));
- }
- else if(category == TYPE_ITEM)
- {
- }
- }
- }
- void MagicTower::SelectSprite(Sprite* sprite)
- {
- auto data=static_cast<ValueMap*>(sprite->getUserData());
- if((*data)["selected"].asBool())
- {
- sprite->removeChildByTag('sel');
- (*data)["selected"]=false;
- }
- else
- {
- auto texture=map->getLayer("enemy")->getTexture();
- int hei=texture->getContentSize().height;
- auto selsprite=Sprite::createWithTexture(texture,Rect(0,texture->getContentSize().height-blocksize,blocksize,blocksize));//设置为最后一个
- selsprite->setAnchorPoint(Vec2(0,0));
- selsprite->setPosition(0,0);
- sprite->addChild(selsprite,selsprite->getLocalZOrder(),'sel');
- FlushBoard(data);
- (*data)["selected"]=true;
- }
- }
- //MagicTowerLayerManager管理场景切换
- MagicTowerLayerManager& MagicTowerLayerManager::getInstance()
- {
- static MagicTowerLayerManager manager;
- return manager;
- }
- Scene* MagicTowerLayerManager::getScene(int layer)
- {
- curlayer=layer;
- auto curscene=Scene::create();
- auto curlayer=new MagicTower(layer);
- if (curscene && curlayer)
- {
- curscene->addChild(curlayer);
- curlayer->autorelease();
- }
- return curscene;
- }
- Hero MagicTower::hero;
- Board MagicTower::board;
- MagicTowerLayerManager::MagicTowerLayerManager()
- {
- curlayer=1;
- MagicTower::hero.name="勇士";
- MagicTower::hero.life=1000;
- MagicTower::hero.offense=200;
- MagicTower::hero.defense=200;
- MagicTower::hero.keyyellow=10;
- MagicTower::hero.keyblue=10;
- MagicTower::hero.keyred=10;
- MagicTower::hero.money=1000;
- MagicTower::hero.nexttilepos=Vec2(6,11);//初始化
- }
复制代码
MagicTower.h
- #include "MagicTower.h"
- #include "..\external\win32-specific\icon\include\iconv.h"
- #pragma comment(lib,"libiconv.lib")
- USING_NS_CC;
- using namespace CocosDenshion;
- bool IConvConvert(const char *from_charset, const char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen)
- {
- iconv_t cd = iconv_open(to_charset, from_charset);
- if (cd == 0) return false;
- const char **pin = &inbuf;
- char **pout = &outbuf;
- memset(outbuf,0,outlen);
- size_t ret = iconv(cd,pin,(size_t *)&inlen,pout,(size_t *)&outlen);
- iconv_close(cd);
- return ret == (size_t)(-1) ? false : true;
- }
- std::string IConvConvert_GBKToUTF8(const std::string& str)
- {
- const char* textIn = str.c_str();
- char textOut[256];
- bool ret = IConvConvert("gb2312", "utf-8", textIn, strlen(textIn),textOut, 256);
- return ret ? std::string(textOut) : std::string();
- }
- // on "init" you need to initialize your instance
- MagicTower::MagicTower(int level)
- {
- thislevel=level;
- auto director=Director::getInstance();
- //director->getOpenGLView()->setFrameSize(416,416);
- //////////////////////////////
- // 1. super init first
- Layer::init();
- Size visibleSize = director->getVisibleSize();
- Vec2 origin = director->getVisibleOrigin();
- /////////////////////////////
- // 2. add a menu item with "X" image, which is clicked to quit the program
- // you may modify it.
- // add a "close" icon to exit the progress. it's an autorelease object
- auto closeItem = MenuItemImage::create("CloseNormal.png","CloseSelected.png",CC_CALLBACK_1(MagicTower::menuCloseCallback, this));
- closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
- origin.y + closeItem->getContentSize().height/2));
- // create menu, it's an autorelease object
- auto menuclose = Menu::create(closeItem, NULL);
- menuclose->setPosition(Vec2::ZERO);
- this->addChild(menuclose, 1);
- /////////////////////////////
- // 3. add your codes below...
- InitMap();
- InitHero();
- FlushBoard();
- //初始换方向键回调
- auto listener=EventListenerKeyboard::create();
- listener->onKeyPressed=CC_CALLBACK_2(MagicTower::OnMove,this);
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
- }
- void MagicTower::InitMap()
- {
- //加载地图背景
- auto director=Director::getInstance();
- Size visibleSize = director->getVisibleSize();
- char mapname[20];
- sprintf(mapname,"%d.tmx",thislevel);
- map=TMXTiledMap::create(mapname);
- map->setAnchorPoint(Vec2(0.5f,0.5f));
- board.board=TMXTiledMap::create("background.tmx");
- board.board->setAnchorPoint(Vec2(0.5f,0.5f));
- map->setPosition(visibleSize.width/2,visibleSize.height/2+board.board->getContentSize().height/2);
- board.board->setPosition(visibleSize.width/2,visibleSize.height/2-map->getContentSize().height/2);
- addChild(map);
- addChild(board.board);
- InitBoard();
- //初始化地图元素
- Vector<SpriteFrame*> animFrames(4);
- auto enemylayer=map->getLayer("enemy");
- auto enemyTexture=enemylayer->getTexture();
- for(int i=0;i<map->getMapSize().width;i++)
- {
- for(int j=0;j<map->getMapSize().height;j++)
- {
- int id=enemylayer->getTileGIDAt(Vec2(i,j));
- if(id)
- {
- int index=(id-ENEMY_BEGIN)/4;
- auto frame0=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*0,blocksize*index,blocksize,blocksize));
- auto frame1=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*1,blocksize*index,blocksize,blocksize));
- auto frame2=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*2,blocksize*index,blocksize,blocksize));
- auto frame3=SpriteFrame::createWithTexture(enemyTexture,Rect(blocksize*3,blocksize*index,blocksize,blocksize));
- animFrames.pushBack(frame0);
- animFrames.pushBack(frame1);
- animFrames.pushBack(frame2);
- animFrames.pushBack(frame3);
- auto animation=Animation::createWithSpriteFrames(animFrames,0.1f);
- animFrames.clear();
- auto cursprite=enemylayer->getTileAt(Vec2(i,j));
- if(!cursprite)
- return;
- cursprite->runAction(RepeatForever::create(Animate::create(animation)));
- cursprite->setUserData(ObjManager::getInstance().InitEnemyByType(id));
- }
- }
- }
- //初始化点击事件
- auto listener=EventListenerTouchOneByOne::create();
- listener->onTouchBegan=[this,enemylayer](Touch* touch,Event* event)
- {
- Vec2 tilepos;
- WorldPosToTilePos(Vec2(touch->getLocation().x-blocksize/2,touch->getLocation().y-blocksize/2),tilepos);
- if(tilepos.x >= 0 && tilepos.y >=0 &&
- tilepos.x < enemylayer->getLayerSize().width && tilepos.y < enemylayer->getLayerSize().height)
- {
- Sprite* node=enemylayer->getTileAt(tilepos);
- if(node)
- {
- SelectSprite(node);
- }
- }
- //根据位置获取单元格,设置为选中状态并刷新数据到面板
- return true;
- };
- _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,enemylayer);
- auto itemlayer=map->getLayer("item");
- for(int i=0;i<map->getMapSize().width;i++)
- {
- for(int j=0;j<map->getMapSize().height;j++)
- {
- int id=itemlayer->getTileGIDAt(Vec2(i,j));
- auto cursprite=enemylayer->getTileAt(Vec2(i,j));
- //if(id && cursprite)
- //{
- // cursprite->setUserData(ObjManager::getInstance().InitItemByType(id));
- //}
- }
- }
- //初始化门动画
- auto doorTexture=map->getLayer("door")->getTexture();
- int doordata[]={0,1,2,3};
- char* doorname[]={"DOOR_YELLOW","DOOR_BLUE","DOOR_RED","DOOR_GREEN"};
- for(int i=0;i<getNum(doordata);i++)
- {
- doordata[i];
- auto frame0=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*0,blocksize,blocksize));
- auto frame1=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*1,blocksize,blocksize));
- auto frame2=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*2,blocksize,blocksize));
- auto frame3=SpriteFrame::createWithTexture(doorTexture,Rect(blocksize*doordata[i],blocksize*3,blocksize,blocksize));
- animFrames.pushBack(frame0);
- animFrames.pushBack(frame1);
- animFrames.pushBack(frame2);
- animFrames.pushBack(frame3);
- auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
- animFrames.clear();
- AnimationCache::getInstance()->addAnimation(animation,doorname[i]);
- }
- }
- void MagicTower::InitBoard()
- {
- //初始化面板
- char title[20];
- sprintf(title,"魔塔 第%d层",thislevel);
- board.maintitle=Label::createWithSystemFont(IConvConvert_GBKToUTF8(title),"黑体",30);
- board.maintitle->setColor(Color3B::GREEN);
- board.maintitle->setAnchorPoint(Vec2(0.5f,0.5f));
- board.maintitle->setPosition(board.board->getContentSize().width/2,blocksize*5+16);
- board.board->addChild(board.maintitle);
- board.heroname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("英雄"),"黑体",24);
- board.heroname->setColor(Color3B::RED);
- board.heroname->setAnchorPoint(Vec2(0.5f,0.5f));
- board.heroname->setPosition(board.board->getContentSize().width/4,blocksize*5-16);
- board.board->addChild(board.heroname);
- board.enemyname=Label::createWithSystemFont(IConvConvert_GBKToUTF8("敌方"),"黑体",24);
- board.enemyname->setColor(Color3B::RED);
- board.enemyname->setAnchorPoint(Vec2(0.5f,0.5f));
- board.enemyname->setPosition(board.board->getContentSize().width*7/8,blocksize*5-16);
- board.board->addChild(board.enemyname);
- board.life_hero=Label::createWithBMFont("myfont.fnt","life");
- board.life_hero->setAnchorPoint(Vec2(0,0));
- board.life_hero->setScale(0.4f);
- board.life_hero->setPosition(blocksize*1,blocksize*3+5);
- board.board->addChild(board.life_hero);
- board.offense_hero=Label::createWithBMFont("myfont.fnt","offense");
- board.offense_hero->setAnchorPoint(Vec2(0,0));
- board.offense_hero->setScale(0.4f);
- board.offense_hero->setPosition(blocksize*1,blocksize*2+5);
- board.board->addChild(board.offense_hero);
- board.defense_hero=Label::createWithBMFont("myfont.fnt","defense");
- board.defense_hero->setAnchorPoint(Vec2(0,0));
- board.defense_hero->setScale(0.4f);
- board.defense_hero->setPosition(blocksize*1,blocksize*1+5);
- board.board->addChild(board.defense_hero);
- board.money_hero=Label::createWithBMFont("myfont.fnt","money");
- board.money_hero->setAnchorPoint(Vec2(0,0));
- board.money_hero->setScale(0.4f);
- board.money_hero->setPosition(blocksize*1,blocksize*0+5);
- board.board->addChild(board.money_hero);
- board.yellowkey=Label::createWithBMFont("myfont.fnt","yellowkey");
- board.yellowkey->setAnchorPoint(Vec2(0,0));
- board.yellowkey->setScale(0.4f);
- board.yellowkey->setPosition(blocksize*4,blocksize*3+5);
- board.board->addChild(board.yellowkey);
- board.bluekey=Label::createWithBMFont("myfont.fnt","bluekey");
- board.bluekey->setAnchorPoint(Vec2(0,0));
- board.bluekey->setScale(0.4f);
- board.bluekey->setPosition(blocksize*4,blocksize*2+5);
- board.board->addChild(board.bluekey);
- board.redkey=Label::createWithBMFont("myfont.fnt","redkey");
- board.redkey->setAnchorPoint(Vec2(0,0));
- board.redkey->setScale(0.4f);
- board.redkey->setPosition(blocksize*4,blocksize*1+5);
- board.board->addChild(board.redkey);
- board.life_enemy=Label::createWithBMFont("myfont.fnt","life");
- board.life_enemy->setAnchorPoint(Vec2(0,0));
- board.life_enemy->setScale(0.4f);
- board.life_enemy->setPosition(blocksize*11,blocksize*3+5);
- board.board->addChild(board.life_enemy);
- board.offense_enemy=Label::createWithBMFont("myfont.fnt","offense");
- board.offense_enemy->setAnchorPoint(Vec2(0,0));
- board.offense_enemy->setScale(0.4f);
- board.offense_enemy->setPosition(blocksize*11,blocksize*2+5);
- board.board->addChild(board.offense_enemy);
- board.defense_enemy=Label::createWithBMFont("myfont.fnt","defense");
- board.defense_enemy->setAnchorPoint(Vec2(0,0));
- board.defense_enemy->setScale(0.4f);
- board.defense_enemy->setPosition(blocksize*11,blocksize*1+5);
- board.board->addChild(board.defense_enemy);
- }
- void MagicTower::InitHero()
- {
- ismoving=false;
- //加载英雄图片
- auto director=Director::getInstance();
- Size visibleSize = director->getVisibleSize();
- auto heroTexture=Director::getInstance()->getTextureCache()->addImage("hero.png");
- auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*1,blocksize,blocksize));
- hero.heroSprite=Sprite::createWithSpriteFrame(frame0);
- hero.heroSprite->setAnchorPoint(Vec2(0,0));
- MoveUnitInTile(hero.nexttilepos,hero.heroSprite);
- addChild(hero.heroSprite);
- //存储英雄移动动画
- std::string dirname[]={"down","left","right","up"};
- Vector<SpriteFrame*> animFrames(4);
- for(int i=0;i<4;i++)
- {
- auto frame0=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*0,blocksize*i,blocksize,blocksize));
- auto frame1=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*1,blocksize*i,blocksize,blocksize));
- auto frame2=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*2,blocksize*i,blocksize,blocksize));
- auto frame3=SpriteFrame::createWithTexture(heroTexture,Rect(blocksize*3,blocksize*i,blocksize,blocksize));
- animFrames.pushBack(frame0);
- animFrames.pushBack(frame1);
- animFrames.pushBack(frame2);
- animFrames.pushBack(frame3);
- auto animation=Animation::createWithSpriteFrames(animFrames,0.05f);
- animation->setRestoreOriginalFrame(false);
- AnimationCache::getInstance()->addAnimation(animation,dirname[i]);
- animFrames.clear();
- }
- //初始化攻击动画
- auto attackTexture= Director::getInstance()->getTextureCache()->addImage("attack.png");
- Size unitsize=attackTexture->getContentSizeInPixels();
- for(int i=0;i<25;i++)
- {
- auto frame0=SpriteFrame::createWithTexture(attackTexture,
- Rect(i/5*unitsize.width/5,i%5*unitsize.height/5,unitsize.width/5,unitsize.height/5));
- animFrames.pushBack(frame0);
- }
- AnimationCache::getInstance()->addAnimation(Animation::createWithSpriteFrames(animFrames,0.05f),"attack");
- animFrames.clear();
- }
- void MagicTower::menuCloseCallback(Ref* pSender)
- {
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
- MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
- return;
- #endif
- Director::getInstance()->end();
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
- exit(0);
- #endif
- }
- void MagicTower::OnMove(EventKeyboard::KeyCode keyCode, Event* event)
- {
- auto animCache=AnimationCache::getInstance();
- Animation* curanimation=NULL;
- Vec2 delta;
- switch(keyCode)
- {
- case EventKeyboard::KeyCode::KEY_UP_ARROW:
- curanimation=animCache->getAnimation("up");
- delta.setPoint(0,blocksize);
- break;
- case EventKeyboard::KeyCode::KEY_DOWN_ARROW:
- curanimation=animCache->getAnimation("down");
- delta.setPoint(0,-blocksize);
- break;
- case EventKeyboard::KeyCode::KEY_LEFT_ARROW:
- curanimation=animCache->getAnimation("left");
- delta.setPoint(-blocksize,0);
- break;
- case EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
- curanimation=animCache->getAnimation("right");
- delta.setPoint(blocksize,0);
- break;
- default:
- return DefaultKeyboardDispatcher(keyCode);
- }
- //判断英雄位置是否可以移动
- if(curanimation && !ismoving)
- {
- MoveHero(hero.heroSprite->getPosition()+delta,curanimation,keyCode);
- }
- }
- void MagicTower::PlayHeroMovement(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode,
- const std::function<void(void)>& afteraction)
- {//anim:帧动画 afteraction:状态更新回调
- hero.heroSprite->setSpriteFrame(anim->getFrames().at(0)->getSpriteFrame());
-
- //移动动画和帧动画同时进行
- auto spawn=Spawn::createWithTwoActions(Animate::create(anim),MoveTo::create(0.2f,newpos));
- //帧动画+移动动画 -> 状态更新 -> 可通行 -> 连击检测
- hero.heroSprite->runAction(Sequence::create(spawn,CallFuncN::create([this,afteraction,keyCode](Node* node)
- {//所有回调函数需要写一起,否则单另作为Sequence依次执行会失效,不知道是不是bug
- afteraction();
- ismoving=false;
- CCLog("ismoving");
- FlushBoard();
- if(!ismoving)
- {
- if((keyCode == EventKeyboard::KeyCode::KEY_UP_ARROW && GetKeyState(VK_UP) < 0) ||
- (keyCode == EventKeyboard::KeyCode::KEY_DOWN_ARROW && GetKeyState(VK_DOWN) < 0) ||
- (keyCode == EventKeyboard::KeyCode::KEY_LEFT_ARROW && GetKeyState(VK_LEFT) < 0) ||
- (keyCode == EventKeyboard::KeyCode::KEY_RIGHT_ARROW && GetKeyState(VK_RIGHT) < 0))
- {
- OnMove(keyCode,NULL);
- }
- }
- }),NULL));
- }
- void MagicTower::MoveHero(const Vec2& newpos,Animation* anim,EventKeyboard::KeyCode keyCode)
- {//若成功,则捡物品或者攻击
- ismoving=true;
- Vec2 tilepos;
- WorldPosToTilePos(newpos,tilepos);
- if(map->getLayer("floor")->getTileGIDAt(tilepos) == FLOOR_WALL)
- {//禁止通行
- ismoving=false;
- return;
- }
- //若是地板则进行上层判断
- auto layer=map->getLayer("item");
- switch(layer->getTileGIDAt(tilepos))
- {
- case ITEM_REDDIAMOND:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.offense += 100;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
- case ITEM_BLUEDIAMOND:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.defense += 50;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
- case ITEM_REDBLOOD:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.life += 400;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
- case ITEM_BLUEBLOOD:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.life += 200;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- case ITEM_YELLOWKEY:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.keyyellow++;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- case ITEM_BLUEKEY:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.keyblue++;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- case ITEM_REDKEY:
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {//刷新+音乐+物品动画
- hero.keyred++;
- layer->removeChild(layer->getTileAt(tilepos),true);
- SimpleAudioEngine::getInstance()->playEffect("eat.mp3");
- });
- return;
-
- default://若为空,执行上层判断
- break;
- }
- layer=map->getLayer("enemy");
- if(layer->getTileGIDAt(tilepos))
- {//若有敌人
- PlayHeroMovement(newpos,anim,keyCode,[this,layer,tilepos]()
- {
- auto animation=AnimationCache::getInstance()->getAnimation("attack");
- auto attacksprite=Sprite::createWithSpriteFrame(animation->getFrames().at(0)->getSpriteFrame());
- attacksprite->setAnchorPoint(Vec2(0,0));
- attacksprite->setPosition(-attacksprite->getContentSize().width/4,-attacksprite->getContentSize().height/4);
- //开始攻击动画+音乐
- hero.heroSprite->addChild(attacksprite);
- attackEnemy(layer,tilepos,attacksprite,Animate::create(animation));
- });
- return;
- }
- //若为空,执行上层判断
- layer=map->getLayer("door");
- switch(layer->getTileGIDAt(tilepos))
- {
- case DOOR_YELLOW:
- {
- hero.keyyellow--;
- auto animation=AnimationCache::getInstance()->getAnimation("DOOR_YELLOW");
- auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
- CallFuncN::create([layer,tilepos](Node*){
- layer->removeChild(layer->getTileAt(tilepos),true);
- })),CallFuncN::create([](Node*){
- SimpleAudioEngine::getInstance()->playEffect("open.mp3");
- }));
- layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
- CallFuncN::create([this,newpos,anim,keyCode](Node*){
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- })));
- }
- return;
- case DOOR_BLUE:
- {
- hero.keyblue--;
- auto animation=AnimationCache::getInstance()->getAnimation("DOOR_BLUE");
- auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
- CallFuncN::create([layer,tilepos](Node*){
- layer->removeChild(layer->getTileAt(tilepos),true);
- })),CallFuncN::create([](Node*){
- SimpleAudioEngine::getInstance()->playEffect("open.mp3");
- }));
- layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
- CallFuncN::create([this,newpos,anim,keyCode](Node*){
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- })));
- }
- return;
- case DOOR_RED:
- {
- hero.keyred--;
- auto animation=AnimationCache::getInstance()->getAnimation("DOOR_RED");
- auto spawn=Spawn::createWithTwoActions(Sequence::createWithTwoActions(Animate::create(animation),
- CallFuncN::create([layer,tilepos](Node*){
- layer->removeChild(layer->getTileAt(tilepos),true);
- })),CallFuncN::create([](Node*){
- SimpleAudioEngine::getInstance()->playEffect("open.mp3");
- }));
- layer->getTileAt(tilepos)->runAction(Sequence::createWithTwoActions(spawn,
- CallFuncN::create([this,newpos,anim,keyCode](Node*){
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- })));
- }
- return;
-
- case DOOR_GREEN:
- ismoving=false;
- return;
- case DOOR_UPSTAIRS:
- {
- //更新地图
- Director::getInstance()->setDepthTest(false);
- hero.nexttilepos=Vec2(HeroInitPos[(thislevel+1)*4],HeroInitPos[(thislevel+1)*4+1]);
- auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel+1));
- if(trans)
- Director::getInstance()->replaceScene(trans);
- ismoving=false;
- }
- return;
- case DOOR_DOWNSTAIRS:
- {
- //更新地图
- Director::getInstance()->setDepthTest(false);
- hero.nexttilepos=Vec2(HeroInitPos[(thislevel-1)*4+2],HeroInitPos[(thislevel-1)*4+3]);
- auto trans=TransitionCrossFade::create(0.5,MagicTowerLayerManager::getInstance().getScene(thislevel-1));
- if(trans)
- Director::getInstance()->replaceScene(trans);
- ismoving=false;
- }
- return;
- }
- //若无对象存在,则移动英雄
- PlayHeroMovement(newpos,anim,keyCode,[](){});
- //在执行PlayerHeroMovement的地方,ismoving交给该函数处理
- }
- void MagicTower::attackEnemy(TMXLayer* layer,Vec2 tilepos,Sprite* attacksprite,Animate* animate)
- {
- //判断英雄是否移动了,如果移动则去除animate并结束
- Vec2 herointile;
- WorldPosToTilePos(hero.heroSprite->getPosition(),herointile);
- if(herointile != tilepos)
- {
- attacksprite->stopAllActions();
- hero.heroSprite->removeChild(attacksprite,true);
- return;
- }
- attacksprite->runAction(Sequence::create(animate,CallFuncN::create([this,layer,tilepos,animate](Node* attacksprite)
- {
- ValueMap* val=static_cast<ValueMap*>(layer->getTileAt(tilepos)->getUserData());
- int enemylife=(*val)["life"].asInt();
- int enemyoffense=(*val)["offense"].asInt();
- int enemydefense=(*val)["defense"].asInt();
- int harmetoh=(hero.defense>enemyoffense)?0:enemyoffense-hero.defense;//enemy对hero造成的伤害,如果hero的防>enemy的攻,则无伤害
- int harmhtoe=(enemydefense>hero.offense)?0:hero.offense-enemydefense;
- hero.life -= harmetoh;
- enemylife -= harmhtoe;
- SimpleAudioEngine::getInstance()->playEffect("fight.mp3");
- (*val)["life"]=enemylife;
- FlushBoard(val);
- if(enemylife < 0 || hero.life < 0)
- {
- if(hero.life < 0)
- {//英雄挂了
- }
- else
- {
- attacksprite->stopAllActions();
- hero.money += (*val)["money"].asInt();
- hero.heroSprite->removeChild(attacksprite,true);
- layer->removeChild(layer->getTileAt(tilepos),true);
- FlushBoard(val);
- //刷新面板
- }
- }
- else
- {
- attackEnemy(layer,tilepos,static_cast<Sprite*>(attacksprite),animate);
- }
- }),NULL));
- }
- void MagicTower::DefaultKeyboardDispatcher(EventKeyboard::KeyCode keycode)
- {//处理其他键盘事件
-
- }
- void MagicTower::WorldPosToTilePos(const Vec2& pos,Vec2& objpos)
- {//pos为世界坐标系,相对于窗口左下角,目标锚点位于左下角
- float rex=map->getContentSize().width/2+(pos.x+blocksize/2-map->getPosition().x);
- float rey=map->getContentSize().height/2-(pos.y+blocksize/2-map->getPosition().y);
- objpos.setPoint(int(rex/blocksize),int(rey/blocksize));
- }
- void MagicTower::TilePosToWorldPos(const Vec2& pos,Vec2& objpos)
- {//pos为Tile坐标系,相对于窗口左上角
- float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
- float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y;
- objpos.setPoint(rex,rey);
- }
- void MagicTower::MoveUnitInTile(const Vec2& pos,Sprite* obj)
- {//pos为Tile坐标系,相对于左上角
- float rex=pos.x*blocksize-map->getContentSize().width/2+map->getPosition().x;
- float rey=map->getContentSize().height/2-pos.y*blocksize+map->getPosition().y-blocksize;
- obj->setPosition(rex,rey);
- }
- void MagicTower::FlushBoard(ValueMap* obj)
- {
- char str[20];
- sprintf(str,"魔塔 第%d层",thislevel);
- board.maintitle->setString(IConvConvert_GBKToUTF8(str));
- board.heroname->setString(IConvConvert_GBKToUTF8(hero.name));
- sprintf(str,"%d",hero.life);
- board.life_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.offense);
- board.offense_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.defense);
- board.defense_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.money);
- board.money_hero->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.keyyellow);
- board.yellowkey->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.keyblue);
- board.bluekey->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",hero.keyred);
- board.redkey->setString(IConvConvert_GBKToUTF8(str));
- if(obj)
- {
- int category=(*obj)["category"].asInt();
- if(category == TYPE_ENEMY)
- {
- board.enemyname->setString(IConvConvert_GBKToUTF8((*obj)["name"].asString()));
- sprintf(str,"%d",(*obj)["life"].asInt());
- board.life_enemy->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",(*obj)["offense"].asInt());
- board.offense_enemy->setString(IConvConvert_GBKToUTF8(str));
- sprintf(str,"%d",(*obj)["defense"].asInt());
- board.defense_enemy->setString(IConvConvert_GBKToUTF8(str));
- }
- else if(category == TYPE_ITEM)
- {
- }
- }
- }
- void MagicTower::SelectSprite(Sprite* sprite)
- {
- auto data=static_cast<ValueMap*>(sprite->getUserData());
- if((*data)["selected"].asBool())
- {
- sprite->removeChildByTag('sel');
- (*data)["selected"]=false;
- }
- else
- {
- auto texture=map->getLayer("enemy")->getTexture();
- int hei=texture->getContentSize().height;
- auto selsprite=Sprite::createWithTexture(texture,Rect(0,texture->getContentSize().height-blocksize,blocksize,blocksize));//设置为最后一个
- selsprite->setAnchorPoint(Vec2(0,0));
- selsprite->setPosition(0,0);
- sprite->addChild(selsprite,selsprite->getLocalZOrder(),'sel');
- FlushBoard(data);
- (*data)["selected"]=true;
- }
- }
- //MagicTowerLayerManager管理场景切换
- MagicTowerLayerManager& MagicTowerLayerManager::getInstance()
- {
- static MagicTowerLayerManager manager;
- return manager;
- }
- Scene* MagicTowerLayerManager::getScene(int layer)
- {
- curlayer=layer;
- auto curscene=Scene::create();
- auto curlayer=new MagicTower(layer);
- if (curscene && curlayer)
- {
- curscene->addChild(curlayer);
- curlayer->autorelease();
- }
- return curscene;
- }
- Hero MagicTower::hero;
- Board MagicTower::board;
- MagicTowerLayerManager::MagicTowerLayerManager()
- {
- curlayer=1;
- MagicTower::hero.name="勇士";
- MagicTower::hero.life=1000;
- MagicTower::hero.offense=200;
- MagicTower::hero.defense=200;
- MagicTower::hero.keyyellow=10;
- MagicTower::hero.keyblue=10;
- MagicTower::hero.keyred=10;
- MagicTower::hero.money=1000;
- MagicTower::hero.nexttilepos=Vec2(6,11);//初始化
- }
复制代码
common.cpp
- #include "common.h"
- #include "cocos2d.h"
- #include <iostream>
- USING_NS_CC;
- struct ENEMY globalEnemyData[]=
- {
- {TYPE_ENEMY,ENEMY_KULOUREN,"骷髅人","骷髅人",110,25,5,110},
- {TYPE_ENEMY,ENEMY_KULOUSHIBING,"骷髅士兵","骷髅士兵",150,40,20,150},
- {TYPE_ENEMY,ENEMY_XIAOBIANFU,"小蝙蝠","小蝙蝠",100,20,5,100},
- {TYPE_ENEMY,ENEMY_LVTOUGUAI,"绿头怪","绿头怪",50,20,1,50},
- {TYPE_ENEMY,ENEMY_HONGTOUGUAI,"红头怪","红头怪",70,15,2,70},
- {TYPE_ENEMY,ENEMY_CHUJIFASHI,"初级法师","初级法师",125,50,25,125},
- };
- struct ITEM globalItemData[]=
- {
- {TYPE_ITEM,ITEM_REDDIAMOND,"红宝石","增加攻击力"},
- {TYPE_ITEM,ITEM_BLUEDIAMOND,"蓝宝石","增加防御力"},
- {TYPE_ITEM,ITEM_REDBLOOD,"红血瓶","增加大量生命"},
- {TYPE_ITEM,ITEM_BLUEBLOOD,"蓝血瓶","增加少量生命"},
- {TYPE_ITEM,ITEM_YELLOWKEY,"黄钥匙","开启黄色门"},
- {TYPE_ITEM,ITEM_BLUEKEY,"蓝钥匙","开启蓝色门"},
- {TYPE_ITEM,ITEM_REDKEY,"红钥匙","开启红色门"},
- };
- ObjManager& ObjManager::getInstance()
- {
- static ObjManager manager;
- return manager;
- }
- ValueMap* ObjManager::InitEnemyByType(int type)
- {
- ValueMap* curmap=new ValueMap(enemytemp[type]);
- enemies.push_back(curmap);
- return curmap;
- }
- ValueMap* ObjManager::InitItemByType(int type)
- {
- return &itemtemp[type];
- }
- ObjManager::ObjManager()
- {
- ValueMap curmap;
- for(ENEMY eny:globalEnemyData)
- {
- curmap["category"]=eny.category;
- curmap["type"]=eny.type;
- curmap["name"]=eny.name;
- curmap["desc"]=eny.desc;
- curmap["life"]=eny.life;
- curmap["offense"]=eny.offense;
- curmap["defense"]=eny.defense;
- curmap["money"]=eny.money;
- curmap["selected"]=false;
- enemytemp[eny.type]=curmap;
- curmap.clear();
- }
- for(ITEM item:globalItemData)
- {
- curmap["category"]=item.category;
- curmap["type"]=item.type;
- curmap["name"]=item.name;
- curmap["desc"]=item.desc;
- curmap["selected"]=false;
- itemtemp[item.type]=curmap;
- curmap.clear();
- }
- }
- ObjManager::~ObjManager()
- {
- for(ValueMap* pt:enemies)
- {
- delete pt;
- }
- for(ValueMap* pt:items)
- {
- delete pt;
- }
- }
- int HeroInitPos[]=
- {//in*2 out*2分别代表从楼下到此层的初始位置和从楼上到此层的初始位置
- // 第一层 第二层 第三层 第四层
- -1,-1, -1,-1, 6,10, 2,1, 2,1, 1,10, 2,11, 10,11, 11,10, 1,10
- };
复制代码
common.h
- #pragma once
- #include "cocos2d.h"
- #include <iostream>
- USING_NS_CC;
- #ifndef __HELLOWORLD_MANAGER_H__
- #define __HELLOWORLD_MANAGER_H__
- #define blocksize 32
- enum direction
- {
- kDown=0,
- kLeft=1,
- kRight=2,
- kUp=3,
- };
- enum category
- {
- TYPE_FLOOR,
- TYPE_ITEM,
- TYPE_ENEMY,
- TYPE_DOOR,
- };
- //对应于tileid
- enum floor//floor层对象
- {
- FLOOR_BEGIN=0,
- FLOOR_WALL=FLOOR_BEGIN+7,//墙体
- FLOOR_FLOOR=FLOOR_BEGIN+12,//地板
- };
- enum item//item层对象
- {
- ITEM_BEGIN=72,
- ITEM_REDDIAMOND=ITEM_BEGIN+1,//红宝石
- ITEM_BLUEDIAMOND=ITEM_BEGIN+2,//蓝宝石
- ITEM_REDBLOOD=ITEM_BEGIN+5,//红血瓶
- ITEM_BLUEBLOOD=ITEM_BEGIN+6,//蓝血瓶
- ITEM_YELLOWKEY=ITEM_BEGIN+17,//黄钥匙
- ITEM_BLUEKEY=ITEM_BEGIN+18,//蓝钥匙
- ITEM_REDKEY=ITEM_BEGIN+19,//红钥匙
- };
- enum enemy
- {
- ENEMY_BEGIN=136,
- ENEMY_KULOUREN=ENEMY_BEGIN+1,//骷髅人
- ENEMY_KULOUSHIBING=ENEMY_BEGIN+5,//骷髅士兵
- ENEMY_XIAOBIANFU=ENEMY_BEGIN+17,//小蝙蝠
- ENEMY_LVTOUGUAI=ENEMY_BEGIN+33,//绿头怪
- ENEMY_HONGTOUGUAI=ENEMY_BEGIN+37,//红头怪
- ENEMY_CHUJIFASHI=ENEMY_BEGIN+49,//初级法师
- };
- enum door
- {
- DOOR_BEGIN=392,
- DOOR_YELLOW=DOOR_BEGIN+1,//黄门
- DOOR_BLUE=DOOR_BEGIN+2,//蓝门
- DOOR_RED=DOOR_BEGIN+3,//红门
- DOOR_GREEN=DOOR_BEGIN+4,//绿门
- DOOR_UPSTAIRS=DOOR_BEGIN+17,//上楼梯
- DOOR_DOWNSTAIRS=DOOR_BEGIN+18,//下楼梯
- };
- struct ENEMY
- {
- int category;
- int type;
- std::string name;//名称
- std::string desc;//描述
- int life;
- int offense;//攻击
- int defense;//防御
- int money;//金钱
- };
- struct ITEM
- {
- int category;
- int type;
- std::string name;//名称
- std::string desc;//描述
- };
- typedef std::unordered_map<int,ValueMap> ObjMap;
- #define getNum(x) (sizeof(x)/(sizeof(x[0])))
- class ObjManager
- {//用来设置怪物动画
- public:
- static ObjManager& getInstance();
- ValueMap* InitEnemyByType(int type);
- ValueMap* InitItemByType(int type);
- private:
- ObjMap enemytemp;
- ObjMap itemtemp;
- std::vector<ValueMap*> enemies;
- std::vector<ValueMap*> items;
- private:
- ObjManager();//单例模式
- virtual ~ObjManager();
- };
- struct Hero
- {
- Sprite* heroSprite;
- std::string name;
- int life;
- int offense;
- int defense;
- int keyyellow;
- int keyblue;
- int keyred;
- int money;
- Vec2 nexttilepos;
- };
- struct Board
- {
- TMXTiledMap* board;
- Label* maintitle;
- //hero
- Label* heroname;
- Label* life_hero;
- Label* offense_hero;
- Label* defense_hero;
- Label* money_hero;
- Label* yellowkey;
- Label* bluekey;
- Label* redkey;
- Label* weapon;
- Label* shield;
- //enemy
- Label* enemyname;
- Label* life_enemy;
- Label* offense_enemy;
- Label* defense_enemy;
- };
- int HeroInitPos[];
- #endif
复制代码
|
|