日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

今天开始做战斗,回合制战斗代码实现第四篇 刀塔传奇战斗模式(即时卡牌战斗模式)

發(fā)布時間:2024/1/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 今天开始做战斗,回合制战斗代码实现第四篇 刀塔传奇战斗模式(即时卡牌战斗模式) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? 說是即時卡牌戰(zhàn)斗,其實在我看來這種玩法也是回合制戰(zhàn)斗的一種,差不多算是九宮格戰(zhàn)斗的一種變種,在一個回合120秒內(nèi),分成了3次小規(guī)模的遇怪自動戰(zhàn)斗,而這種自動戰(zhàn)斗不在是回合而是即時的,但整個戰(zhàn)斗過程,都不是做即時通信的,所以對網(wǎng)絡要求也不是很高,一般2d網(wǎng)絡就可以很流暢的玩這種弱聯(lián)網(wǎng)的手游,所以近期這種模式成為了手機網(wǎng)游的比較流行的一種戰(zhàn)斗模式,當然卡牌類游戲還有幾種比如就秒開源的暗黑世界類,采用這種戰(zhàn)斗方式的手游現(xiàn)在有去吧比卡丘這樣的作品,再就是益智類戰(zhàn)斗卡牌代表作品爐石傳說,這兩種卡牌的實現(xiàn)方式我們后面來研究(本來許諾的仙劍demo3d回合戰(zhàn)斗我們先等等),循例我們先看看這種戰(zhàn)斗模式是什么樣子的。這種游戲的模式呢,我最早玩的游戲并非出現(xiàn)在手游上,而是頁游的萌戰(zhàn)記不同的是,萌戰(zhàn)記的玩法還介于即使卡牌和九宮格之間,技能的釋放還是跟九宮格戰(zhàn)斗一樣,自動完成,不過整個戰(zhàn)斗大概可分為站位,出手,狀態(tài),BUFF及戰(zhàn)斗數(shù)值五種構(gòu)成的方式已經(jīng)有了新戰(zhàn)斗系統(tǒng)的雛形了,而且可能萌戰(zhàn)記的玩法更注重職業(yè)的選擇比如tank就是tank,治療,dps也劃分非常清晰,所以跟刀塔傳奇玩法差別還是很明顯,不過萌戰(zhàn)記在vip收費的環(huán)節(jié)策劃疏漏嚴重,運營也相對失敗,所以玩過的玩家可能不多,好了,我們回到刀塔傳奇的戰(zhàn)斗模式上,

1.站位:英雄出場的位置應該在數(shù)值表中進行了固定的配置,英雄移動差不多遵循,選定技能---選定技能目標----判斷技能攻擊距離-----尋路,

2.出手:

  1) 第一次出手順序:除了有白虎這種一出場就buff的,一般都是固定。那么做法有兩種,一種是英雄表中配置出手權重值,還有一種就是出場陣容中計算出手順序。

  2) 英雄技能出手順序:這個是根據(jù)英雄數(shù)據(jù)表中配置的,如普通攻擊→第二個技能→第三個技能→第四個技能→普通攻擊→第二個技能,被動技能則是戰(zhàn)斗一開始就釋放,效果持續(xù)到戰(zhàn)斗結(jié)束。

  3) 英雄攻擊間隔:實際上刀塔傳奇中是沒有攻擊速度這一概念的,那么果斷推測每個英雄的攻擊間隔應該都是固定。即英雄出手順序,普攻,小技能之間的間隔也是固定的。有個特例就是手動釋放的大招,在這里英雄普攻之后,也能立即釋放大招,沒有間隔。那么釋放完大招后,攻擊間隔怎樣算,我的理解是大招刷新了攻擊間隔,英雄開始重復之前的攻擊間隔。(不過新手游《那年那兔那些事》加入了攻擊速度這個概念,所以并不是絕對的)

3. 狀態(tài)及buff

  dota和刀塔傳奇的魅力就在這里,幾十種狀態(tài),幾十種buff。

  我們把戰(zhàn)斗場景中的會造成模型動作改變的稱為狀態(tài),而只造成屬性上改變的稱為buff,這個概念在這里再提一下。一個英雄的狀態(tài)是唯一性的,buff卻有很多種。例如,一個英雄同時中了眩暈和毒技能,那么這個時候他擁有一個眩暈的顯示狀態(tài),以及眩暈帶來的不可攻擊不可釋放技能不可行動的buff和毒技能帶來的減速和持續(xù)掉血的buff。

  其中刀塔傳奇還做了一個特殊的狀態(tài),就是受擊,當敵方英雄對此英雄造成的傷害超過到最大血量的一定百分比的時候,此英雄處于受擊狀態(tài),并刷新攻擊間隔。

整個戰(zhàn)斗流程可以歸為,出場->站位->出手->狀態(tài)及buff改變->結(jié)束戰(zhàn)斗,

以上這些只是刀塔傳奇一些皮毛的分析,因為如果做大規(guī)模的分析可能要分析很多問題,拿站位來說,那年那兔那些事里面的火力支援大招經(jīng)常會出現(xiàn)攻擊位置判定跟敵人位置不同步的情況,經(jīng)常出現(xiàn)大招放完,沒有對敵人造成傷害,這種情況可能刀塔傳奇和其他類似的游戲也有,我們這里就不討論了,因為這個到底是什么情況,可能只有游戲的當值策劃才能說的明白,在制作游戲過程中,可能需要策劃進行長時間討論和調(diào)試才能確定。

好了,我們現(xiàn)在開始搞干貨,如果就是上面這幾行網(wǎng)上也能看到的文字,可能觀眾要罵人了,當然這也不符合我博客的習慣,既然是講做戰(zhàn)斗,當然要做了,所以下面我們看看如何實現(xiàn)這種戰(zhàn)斗模式,(事先說明,代碼不是我寫的,代碼來自于網(wǎng)絡,作者不詳,我這里只貼出代碼和相應的講解,無法提供代碼工程,需要工程請度娘自尋,或者私信留言給我,不是我小氣,因為不是我的代碼可能涉及一些商業(yè)利益等問題,所以沒辦法開源共享),原作者的開發(fā)環(huán)境是winxp+vs2012+cocos2dx3.0,因為xp系統(tǒng)的編譯和win7以后的編譯有差別,直接編譯會報錯,所以我對代碼做了重構(gòu)(開始想過直接修改平臺工具集的選項,不過報error LNK2038: 檢測到“_MSC_VER”的不匹配項: 值“1700”不匹配,重新生成解決方案也沒有成功,所以只好重新搭建工程,編譯器改變?yōu)関110),并且升級引擎(我電腦里沒有裝cocos2dx3.0版本)改為了win764位+vs2012+cocos2dx3.5,因為引擎升級到了cocos2dx3.5,所以適當?shù)男薷牧诵┐a,好了廢話就到這我們開始。

代碼的目錄結(jié)構(gòu)非常清晰,注意開發(fā)語言是c++11(有興趣的小伙伴可以改成lua或者js等等),

代碼可以說寫的非常完整,戰(zhàn)斗需要實現(xiàn)的東西都實現(xiàn)了,下面我們就來看看這個東東到底是怎么寫的,.H文件就不貼出來,我們直接帖Cpp,如果真對這段代碼感興趣,可以百度或者私信給我,我們開始,首先建好工程,之后我們開始代碼之旅

先是AppDelegate這個類不用多說吧,cocos2dx生成之后需要這個來做啟動,如果不懂請去看cocos2dx基礎,我們直接看代碼

#include "AppDelegate.h" //#include "HelloWorldScene.h" #include "GameScene.h" #include "LoadScene.h" #include "OverScene.h" USING_NS_CC;AppDelegate::AppDelegate() {}AppDelegate::~AppDelegate() { }bool AppDelegate::applicationDidFinishLaunching() {// initialize directorauto director = Director::getInstance();auto glview = director->getOpenGLView();if(!glview) {glview = GLViewImpl::create("GameDT");// glview = GLView::create("My Game");glview->setFrameSize(600, 360);director->setOpenGLView(glview);}// turn on display FPSdirector->setDisplayStats(true);// set FPS. the default value is 1.0/60 if you don't call thisdirector->setAnimationInterval(1.0 / 60);glview->setDesignResolutionSize(800, 480, kResolutionExactFit);// create a scene. it's an autorelease object// auto scene = HelloWorld::createScene();//auto scene = GameScene::createScene();auto scene = LoadScene::createScene();//auto scene = OverScene::createScene();// rundirector->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(); } 這個類代碼沒什么可說的,創(chuàng)建工程自動就可以生成,我們修改的除了包含頭文件之外,其實最重要的只有改auto scene = LoadScene::createScene();這句,因為cocos2dx工作的方式是, AppDelegate這個類啟動一個Scene類,然后建立很多Layer類,然后把畫出的Layer添加到Scene上,所以我們現(xiàn)在開始看scene類,在我們這叫做LoadScene

#include "LoadScene.h" #include "GameScene.h" LoadScene::LoadScene() {numOfRes = 12;numOfLoadedRes = 0; }Scene* LoadScene::createScene() {auto scene = Scene::create();auto layer = LoadScene::create();scene->addChild(layer);return scene; }bool LoadScene::init() {if (!Layer::init()){return false;}auto size = Director::getInstance()->getWinSize();labelLoad = Label::createWithTTF("loading...", "fonts/Marker Felt.ttf", 25);labelPercent = Label::createWithTTF("0", "fonts/Marker Felt.ttf", 25);labelLoad->setPosition(size.width/2, size.height/2 -140);labelPercent->setPosition(size.width/2, size.height/2 -100);this->addChild(labelLoad);this->addChild(labelPercent);this->loadRes();return true; }//異步加載 void LoadScene::loadRes() {//加載精靈動畫SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/magic.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/magic2.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/magic3.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/magic4.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/monster1.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/monster2.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/monster3.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/monster4.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/monster5.plist");SpriteFrameCache::getInstance()->addSpriteFramesWithFile("plist/monster6.plist");TextureCache::getInstance()->addImageAsync("plist/magic.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/magic2.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/magic3.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/magic4.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/monster1.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/monster2.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/monster3.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/monster4.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/monster5.png",CC_CALLBACK_1(LoadScene::loadCallback, this));TextureCache::getInstance()->addImageAsync("plist/monster6.png",CC_CALLBACK_1(LoadScene::loadCallback, this));//加載地圖TextureCache::getInstance()->addImageAsync("map/bbg_spring2.png",CC_CALLBACK_1(LoadScene::loadCallback, this));//戰(zhàn)斗場景組件TextureCache::getInstance()->addImageAsync("card/panel.png",CC_CALLBACK_1(LoadScene::loadCallback, this)); } void LoadScene::loadCallback(Texture2D* texture) {numOfLoadedRes++;char tmp[10];sprintf(tmp, "%d", (int)(((float)numOfLoadedRes/numOfRes) * 100));labelPercent->setString(tmp);if (numOfLoadedRes == numOfRes){//this->removeChild(labelLoad, true);//this->removeChild(labelPercent, true);this->scheduleOnce(schedule_selector(LoadScene::toStartScene), 1.0f);}}void LoadScene::toStartScene(float dt) {auto gameScene = GameScene::createScene();Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, gameScene)); }這個類看上去代碼量不大,是干什么用的呢?其實是畫進度條,要實現(xiàn)的東西也很簡單,畫一個loading文字,然后,畫一個動態(tài)0到100的遞增,那下面的代碼是干什么的呢?
我們看toStartScene方法是跳轉(zhuǎn)到我們真正的游戲Scene界面類GameScene,而loadRes就是異步加載資源,當然別忘了回調(diào)函數(shù)loadCallback,函數(shù)里numOfLoadedRes == numOfRes就是加載完成時,調(diào)用跳轉(zhuǎn)方法 toStartScene,好了我們看下一個類GameScene

#include "GameScene.h" //#include "json/document.h" //#include "GameInstance.h"GameScene::GameScene() { } GameScene::~GameScene() { }Scene* GameScene::createScene() {auto scene = Scene::create();auto layer = GameScene::create();scene->addChild(layer);return scene; }bool GameScene::init() {if (!Layer::init()){return false;}this->initMap();spriteSystem = SpriteSystem::create();this->addChild(spriteSystem, 1);/*magicSystem = MagicSystem::create();this->addChild(magicSystem, 2);*/return true; }void GameScene::initMap() {auto size = Director::getInstance()->getVisibleSize();auto texMap1 = TextureCache::getInstance()->getTextureForKey("map/bbg_spring2.png");auto map1 = Sprite::createWithTexture(texMap1);map1->setPosition(size.width/2, size.height/2);this->addChild(map1); }真是一個類比一個類簡單,這個類看上去代碼更少,我們看看都干了什么東東,

this->initMap();

spriteSystem = SpriteSystem::create();

this->addChild(spriteSystem, 1);看過之后發(fā)現(xiàn)init這3行最重要,具體工作是,initMap加載繪制地圖,其實就是畫一張背景圖,然后對spriteSystem類進行初始化,然后把這個Layer類繪制到Scene上面,下面我們開始研究這個這段代碼中最重要的類,

#include "SpriteSystem.h" #include "GameInstance.h" #include "Magic.h" #include "OverScene.h" #include "Resource.h"SpriteSystem::SpriteSystem() {m_bIsAttack = false;m_fElapseTime = 0; }SpriteSystem::~SpriteSystem() {}bool SpriteSystem::init() {if (!Layer::init()){return false;}m_bIsAttack = false;m_fElapseTime = 0;m_fOverTime = 0;bool spSel[6] = {true, true, true, true, true, true};for (unsigned int i = 0; i < 6; i++){GameInstance::getInstance()->spSel[i] = spSel[i];m_fOldScheTime[i] = 0;m_fScheduleTime[i] = 0;}GameInstance::getInstance()->heroNum = 3;GameInstance::getInstance()->enemyNum = 3;this->readJson(spConf);this->readMagicJson(magConf);this->initSprite();this->setMagicPanel();return true; }_stSpriteConfig SpriteSystem::readConfig(SpriteId id) {_stSpriteConfig tmp;tmp = spConf[id-1];return tmp; }void SpriteSystem::readJson(_stSpriteConfig (&spConf)[6]) {//_stSpriteConfig spConf[6];rapidjson::Document doc;std::string str = FileUtils::getInstance()->getStringFromFile(s_spConfJson);doc.Parse<rapidjson::kParseDefaultFlags>(str.c_str());for(unsigned int i = 0; i < 6; i++){rapidjson::Value &val =doc[(rapidjson::SizeType)(i)];if (val.HasMember("id")&&val.HasMember("name")&&val.HasMember("type")&&val.HasMember("life")&&val.HasMember("attack")&&val.HasMember("attackSpeed")&&val.HasMember("power")&& val.HasMember("magicGroup")){spConf[i].id = (SpriteId)val["id"].GetInt();spConf[i].name = val["name"].GetString();spConf[i].type = (SpriteType)val["type"].GetInt();spConf[i].life = val["life"].GetInt();spConf[i].attack = val["attack"].GetInt(); spConf[i].attackSpeed = val["attackSpeed"].GetDouble(); spConf[i].power = val["power"].GetInt();}rapidjson::Value& num = val["stateNum"][(rapidjson::SizeType)0];spConf[i].stateNum.idleNum = num["idleNum"].GetInt();spConf[i].stateNum.runNum = num["runNum"].GetInt();spConf[i].stateNum.attackNum = num["attackNum"].GetInt();spConf[i].stateNum.hurtNum = num["hurtNum"].GetInt();spConf[i].stateNum.deadNum = num["deadNum"].GetInt();rapidjson::Value& group = val["magicGroup"][(rapidjson::SizeType)0];spConf[i].magicGroup.magic1 = (MagicId)group["magic1"].GetInt();spConf[i].magicGroup.magic2 = (MagicId)group["magic2"].GetInt();}//return spConf;}_stMagicConfig SpriteSystem::readMagConfig(MagicId id) {_stMagicConfig tmp;tmp = magConf[id-1];return tmp; }void SpriteSystem::readMagicJson(_stMagicConfig (&magConf)[11]) {rapidjson::Document doc;std::string str = FileUtils::getInstance()->getStringFromFile(s_spMagJson);doc.Parse<rapidjson::kParseDefaultFlags>(str.c_str());for (unsigned int i = 0; i < 11; i++){rapidjson::Value &val =doc[(rapidjson::SizeType)(i)];if (val.HasMember("id")&&val.HasMember("name")&&val.HasMember("count")){magConf[i].id = (MagicId)val["id"].GetInt();magConf[i].name = val["name"].GetString();magConf[i].count = val["count"].GetInt();}} }void SpriteSystem::update(float dt) {float fOldTime = m_fElapseTime;m_fElapseTime = m_fElapseTime + (dt*1000);if(fOldTime < 5000.0f && m_fElapseTime >= 5000.0f && GameInstance::getInstance()->isGameOver == false){m_bIsAttack = true;}if (GameInstance::getInstance()->isGameOver == false && m_bIsAttack == true){this->spAttackSchedule(dt);}for (unsigned int i = 0; i < 6; i++){if (m_bsSp[i]->getCurLife() < 0 && m_bsSp[i]->getSpriteState() != SPRITESTATE_DEAD){m_bsSp[i]->startAction(SPRITESTATE_DEAD);if (i < 3){m_itItem[i]->setEnabled(false);m_ptLife[i]->setPercentage(0);m_ptPower[i]->setPercentage(0);//CCLOG("Set false%d", m_ptPower[i]->getPercentage());}if (m_bsSp[i]->getSpConf().id == SPRITEID_1 ||m_bsSp[i]->getSpConf().id == SPRITEID_2 || m_bsSp[i]->getSpConf().id == SPRITEID_3){GameInstance::getInstance()->heroNum--;}else{GameInstance::getInstance()->enemyNum--;}}}if (GameInstance::getInstance()->isGameOver == false){if (GameInstance::getInstance()->heroNum == 0){GameInstance::getInstance()->isWin = false;GameInstance::getInstance()->isGameOver = true;m_fOverTime = m_fElapseTime;}if (GameInstance::getInstance()->enemyNum == 0){GameInstance::getInstance()->isWin = true;GameInstance::getInstance()->isGameOver = true;m_fOverTime = m_fElapseTime;} }if (GameInstance::getInstance()->isGameOver == true){if (m_fElapseTime >= m_fOverTime + 2000.0f){unscheduleUpdate();Director::getInstance()->replaceScene(TransitionCrossFade::create(1.5f, OverScene::createScene()));}}for (unsigned int i = 0; i < 6; i++){if (m_bsSp[i]->getSpriteState() != SPRITESTATE_DEAD){if (i < 3){this->ergodicSprite(m_bsSp[i], m_bsSp[3], m_bsSp[4], m_bsSp[5]);}else{this->ergodicSprite(m_bsSp[i], m_bsSp[0], m_bsSp[1], m_bsSp[2]);}}else if(i < 3){m_itItem[i]->setEnabled(false);}}for (unsigned int i = 0; i < 3; i++){if (m_bsSp[i]->getSpriteState() != SPRITESTATE_DEAD){this->showBottomLife(m_bsSp[i]); this->showPower(m_bsSp[i]);}}}void SpriteSystem::initSprite() {struct _stSpConf{float spScale[6];Point spPosStart[6];Point spPosEnd[6];bool spFlip[6];_stSpConf(){spScale[0] = 0.8f; spScale[1] = 1.0f; spScale[2] = 1.0f; spScale[3] = 1.0f; spScale[4] = 1.0f; spScale[5] = 1.0f;spFlip[0] = true; spFlip[1] = true; spFlip[2] = true;spFlip[3] = false; spFlip[4] = false; spFlip[5] = false;spPosStart[0] = PointS_1; spPosStart[1] = PointS_2; spPosStart[2] = PointS_3;spPosStart[3] = PointS_4; spPosStart[4] = PointS_5; spPosStart[5] = PointS_6;spPosEnd[0] = PointE_1; spPosEnd[1] = PointE_2; spPosEnd[2] = PointE_3;spPosEnd[3] = PointE_4; spPosEnd[4] = PointE_5; spPosEnd[5] = PointE_6;}}_stSpConf;for (unsigned int i = 0; i < 6; i++){if (GameInstance::getInstance()->spSel[i]){m_bsSp[i] = BaseSprite::create(spConf[i]);m_bsSp[i]->setScale(_stSpConf.spScale[i]);m_bsSp[i]->setPosition(_stSpConf.spPosStart[i]);m_bsSp[i]->setFlippedX(_stSpConf.spFlip[i]);m_bsSp[i]->startAction(SPRITESTATE_IDLE);m_bsSp[i]->move(MoveType_To, _stSpConf.spPosEnd[i], 4.5f);//m_fScheduleTime[i] = m_bsSp[i]->getSpConf().attackSpeed;i < 3 ? m_bsSp[i]->setTargetSp(m_bsSp[3]) : m_bsSp[i]->setTargetSp(m_bsSp[0]);this->addChild(m_bsSp[i], 1);}}scheduleUpdate();}void SpriteSystem::spAttackSchedule(float dt) {for (unsigned int i = 0; i <6; i++){//釋放魔法狀態(tài),將定時器時間設為0if (m_bsSp[i]->getIsMagic() == true){m_fScheduleTime[i] = 0;}//普通攻擊狀態(tài)if (m_bsSp[i]->getSpriteState() != SPRITESTATE_DEAD && m_bsSp[i]->getIsMagic() == false){m_fOldScheTime[i] = m_fScheduleTime[i];m_fScheduleTime[i] += dt;if (m_fOldScheTime[i] < m_bsSp[i]->getSpConf().attackSpeed && m_fScheduleTime[i] >= m_bsSp[i]->getSpConf().attackSpeed){m_bsSp[i]->startAction(SPRITESTATE_ATTACK);//遠距離攻擊if (m_bsSp[i]->getSpConf().type != SPRITETYPE_FRONT){this->magicMove(m_bsSp[i]->getSpConf().magicGroup.magic1, m_bsSp[i], m_bsSp[i]->getTargetSp());}//直接攻擊else{m_bsSp[i]->getTargetSp()->setCurLife(m_bsSp[i]->getTargetSp()->getCurLife() - m_bsSp[i]->getSpConf().attack);this->showLife(m_bsSp[i]->getTargetSp());if (m_bsSp[i]->getCurPower() <= m_bsSp[i]->getSpConf().power){m_bsSp[i]->setCurPower(m_bsSp[i]->getCurPower() + m_bsSp[i]->getSpConf().attack*2);}}m_fOldScheTime[i] = 0;m_fScheduleTime[i] = 0;}}} }void SpriteSystem::magicMove(MagicId id, BaseSprite* attackSprite, BaseSprite* hurtSprite) {auto attackPos = attackSprite->getPosition();auto hurtPos = hurtSprite->getPosition();auto size = Director::getInstance()->getVisibleSize().width;std::string name = GameInstance::getInstance()->getMagicName(id);name += "_001.png";Sprite* magic = CCSprite::createWithSpriteFrameName(name.c_str());magic->setScale(0.6f);if (id == MAGIC_9){magic->setRotation(-90);}magic->setPosition(attackPos);this->addChild(magic, 2);float s = ccpDistance(attackPos, hurtPos);float v = 300.0f;auto move = MoveTo::create(s/v, hurtPos);auto callfunc = CallFunc::create(std::bind(&SpriteSystem::magicMoveCallback, this, magic,attackSprite));magic->runAction(Sequence::create(move, callfunc, NULL));}void SpriteSystem::magicMoveCallback(Node* node, BaseSprite* sp) {node->setVisible(false);this->removeChild(node);if (sp){sp->getTargetSp()->setCurLife(sp->getTargetSp()->getCurLife() - sp->getSpConf().attack);this->showLife(sp->getTargetSp());if (sp->getCurPower() <= sp->getSpConf().power){sp->setCurPower(sp->getCurPower() + sp->getSpConf().attack*2);}}}void SpriteSystem::showLife(BaseSprite* sp) {auto startPos = Point(sp->getPositionX(), sp->getPositionY() + sp->getContentSize().height/2 + 5);auto endPos = Point(sp->getPositionX(),sp->getPositionY() + sp->getContentSize().height/2 + 20);//資源尺寸不一導致if (sp->getSpConf().id == 1){startPos = Point(sp->getPositionX() - 30, sp->getPositionY() + sp->getContentSize().height/2 + 5 - 90);endPos = Point(sp->getPositionX() - 30,sp->getPositionY() +sp->getContentSize().height/2 + 20 - 90);}if (sp->getSpConf().id == 6){startPos = Point(sp->getPositionX(), sp->getPositionY() + sp->getContentSize().height/2 - 30);endPos = Point(sp->getPositionX(),sp->getPositionY() +sp->getContentSize().height/2 -15);}float per = float(sp->getCurLife() )/ (float)sp->getSpConf().life;Node* node = Node::create();Sprite* lifebg = Sprite::create(s_ptBg); ProgressTimer* life = ProgressTimer::create(Sprite::create(sp->getSpConf().id<3 ? s_ptLife : s_ptLife2));life->setType(ProgressTimer::Type::BAR);life->setMidpoint(Point::ANCHOR_MIDDLE_LEFT);life->setBarChangeRate(Point::ANCHOR_MIDDLE_RIGHT);life->setPercentage(per*100);node->setPosition(startPos);node->addChild(lifebg, 0);node->addChild(life, 1);this->addChild(node, 2);auto moveUp = MoveTo::create(0.5f, endPos);auto fadeout = FadeOut::create(0.5f);auto spawn = Spawn::create(moveUp, fadeout, NULL);auto callfunc = CallFunc::create(std::bind(&SpriteSystem::showLifeCallback, this, node));node->runAction(Sequence::create(spawn, callfunc, NULL));}void SpriteSystem::showLifeCallback(Node* node) {node->setVisible(false);this->removeChild(node); }void SpriteSystem::ergodicSprite(BaseSprite* attack,BaseSprite* tmp1, BaseSprite* tmp2, BaseSprite* tmp3) {BaseSprite* tmps[3] = {tmp1, tmp2, tmp3};for (unsigned int i = 0; i < 3; i++){if (attack && tmps[i] && tmps[i]->getSpriteState() != SPRITESTATE_DEAD){attack->setTargetSp(tmps[i]);break;}} }void SpriteSystem::setMagicPanel() {Sprite* panel = Sprite::create(s_magPan);panel->setPosition(400, 90);struct _stMagPan{float scale[3];Point spPos[3];bool enable[3];Point ptPos[6];_stMagPan(){scale[0] = 0.8f; scale[1] = 0.8f; scale[2] = 0.8f;spPos[0] = Point(534, 90); spPos[1] = Point(318, 90); spPos[2] = Point(106, 90);enable[0] = false; enable[1] = false; enable[2] = false;ptPos[0] = Point(106, 30); ptPos[1] = Point(318, 30); ptPos[2] = Point(534, 30); ptPos[3] = Point(106, 10); ptPos[4] = Point(318, 10); ptPos[5] = Point(534, 10);}}_stMagPan;Sprite* spNor[3];Sprite* spDis[3];Sprite* life[3];Sprite* power[3];Sprite* ptBg[6];for (unsigned int i = 0; i < 3; i++){//英雄頭像設為按鈕spNor[i] = Sprite::create(s_panSpNor[i]);spDis[i] = Sprite::create(s_panSpDis[i]);m_itItem[i] = MenuItemSprite::create(spNor[i], spNor[i], spDis[i], std::bind(&SpriteSystem::itemCallback, this, std::placeholders::_1,i));m_itItem[i]->setScale(_stMagPan.scale[i]);m_itItem[i]->setPosition(_stMagPan.spPos[i]);m_itItem[i]->setEnabled(_stMagPan.enable[i]);//生命值,魔法值m_ptLife[i] = ProgressTimer::create(Sprite::create(s_ptLife));m_ptLife[i]->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);m_ptLife[i]->setType(ProgressTimer::Type::BAR);m_ptLife[i]->setMidpoint(Point::ANCHOR_MIDDLE_LEFT);m_ptLife[i]->setBarChangeRate(Point::ANCHOR_MIDDLE_RIGHT);m_ptLife[i]->setPercentage(100);m_ptPower[i] = ProgressTimer::create(Sprite::create(s_ptPower));m_ptPower[i]->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);m_ptPower[i]->setType(ProgressTimer::Type::BAR);m_ptPower[i]->setMidpoint(Point::ANCHOR_MIDDLE_LEFT);m_ptPower[i]->setBarChangeRate(Point::ANCHOR_MIDDLE_RIGHT);m_ptPower[i]->setPercentage(0);}auto menu = Menu::create(m_itItem[0], m_itItem[1], m_itItem[2], NULL);menu->setPosition(Point::ZERO);panel->addChild(menu,1);for (unsigned int i = 0; i < 6; i++){ptBg[i] = Sprite::create(s_ptBg);ptBg[i]->setPosition(_stMagPan.ptPos[i]);panel->addChild(ptBg[i]);}ptBg[0]->addChild(m_ptLife[0],2);ptBg[1]->addChild(m_ptLife[1],2);ptBg[2]->addChild(m_ptLife[2],2);ptBg[3]->addChild(m_ptPower[0],2);ptBg[4]->addChild(m_ptPower[1],2);ptBg[5]->addChild(m_ptPower[2],2);this->addChild(panel, 1);}void SpriteSystem::itemCallback(Ref* pSender,int Num) {m_itItem[Num]->setEnabled(false);CCLOG("Num%d", Num);m_bsSp[Num]->setCurPower(0);m_bsSp[Num]->startAction(SPRITESTATE_MAGIC);this->startMagic(m_bsSp[Num], m_bsSp[Num]->getSpConf().magicGroup.magic2, 3);}void SpriteSystem::showBottomLife(BaseSprite* sprite) {float per = (((float)sprite->getCurLife()/sprite->getSpConf().life)*100);SpriteId id = sprite->getSpConf().id;switch (id){case SPRITEID_1:m_ptLife[2]->setPercentage(per);break;case SPRITEID_2:m_ptLife[1]->setPercentage(per);break;case SPRITEID_3:m_ptLife[0]->setPercentage(per);break;case SPRITEID_4:break;case SPRITEID_5:break;case SPRITEID_6:break;default:break;} } void SpriteSystem::showPower(BaseSprite* sprite) {float per = (((float)sprite->getCurPower()/sprite->getSpConf().power)*100);SpriteId id = sprite->getSpConf().id;switch (id){case SPRITEID_1:m_ptPower[2]->setPercentage(per);if (per >= 100){m_itItem[0]->setEnabled(true);}break;case SPRITEID_2:m_ptPower[1]->setPercentage(per);if (per >= 100){m_itItem[1]->setEnabled(true);}break;case SPRITEID_3:m_ptPower[0]->setPercentage(per);if (per >= 100){m_itItem[2]->setEnabled(true);}break;case SPRITEID_4:break;case SPRITEID_5:break;case SPRITEID_6:break;default:break;} }void SpriteSystem::startMagic(BaseSprite* tmp,MagicId id, int times) {Magic* magic = Magic::create(magConf[tmp->getSpConf().magicGroup.magic2-1]);magic->setPosition(600, 300);this->addChild(magic, 1);magic->startMagic(12, times);this->magicHurt(tmp, m_bsSp[3], m_bsSp[4], m_bsSp[5]);}void SpriteSystem::magicHurt(BaseSprite* attack,BaseSprite* tmp1, BaseSprite* tmp2, BaseSprite* tmp3) {BaseSprite* tmps[3] = {tmp1, tmp2, tmp3};for (unsigned int i = 0; i < 3; i++){if (tmps[i] && tmps[i]->getSpriteState() != SPRITESTATE_DEAD){tmps[i]->setCurLife(tmps[i]->getCurLife() - attack->getSpConf().attack);CCLOG("showlifes");this->showLife(tmps[i]);}} }一下代碼量就變多了,差不多700行,我們慢慢來看,init開始看里面開始都是些初始化數(shù)據(jù)

比如GameInstance::getInstance()->heroNum = 3;
GameInstance::getInstance()->enemyNum = 3;關于GameInstance這個靜態(tài)類我們后面再來看

this->readJson(spConf);
this->readMagicJson(magConf);
this->initSprite();
this->setMagicPanel();看看這4個方法調(diào)用,先看看readJson方法,這個方法用來讀取sp精靈的數(shù)據(jù)(這個數(shù)據(jù)在網(wǎng)游中應該由服務器傳過來),這里是本地的我們看看

如圖,我們看到這個數(shù)據(jù)由外部json文件得到,網(wǎng)絡游戲流程大致也差不多,我們后面以暗黑世界對象看看網(wǎng)絡通信怎么來解析這個地方,這里就先不講,具體的解析過程readJson里面很詳細

接著readMagicJson方法跟上面的讀取方式幾乎相同,,我們看下json文件里面寫了什么東西,先是spriteConfig.json

[{"id": 1,"name": "yemanshouren","type": 1,"life": 100,"attack": 15,"attackSpeed": 2.5,"power": 100,"magicGroup": [{"magic1": 0,"magic2": 8}],"stateNum": [{"idleNum": 1,"runNum": 6,"attackNum": 12,"hurtNum": 1,"deadNum": 6}]},{"id": 2,"name": "quanjiniao","type": 2,"life": 100,"attack": 18,"attackSpeed": 5.2,"power": 100,"magicGroup": [{"magic1": 9,"magic2": 3}],"stateNum": [{"idleNum": 1,"runNum": 6,"attackNum": 10,"hurtNum": 1,"deadNum": 3}]},{"id": 3,"name": "duyanguai","type": 3,"life": 100,"attack": 10,"attackSpeed": 6.3,"power": 100,"magicGroup": [{"magic1": 9,"magic2": 10}],"stateNum": [{"idleNum": 1,"runNum": 8,"attackNum": 12,"hurtNum": 1,"deadNum": 10}]},{"id": 4,"name": "manzutu","type": 1,"life": 100,"attack": 13,"attackSpeed": 3.1,"power": 100,"magicGroup": [{"magic1": 9,"magic2": 3}],"stateNum": [{"idleNum": 1,"runNum": 6,"attackNum": 6,"hurtNum": 1,"deadNum": 6}]},{"id": 5,"name": "xiaoemo","type": 2,"life": 100,"attack": 15,"attackSpeed": 6.3,"power": 100,"magicGroup": [{"magic1": 5,"magic2": 1}],"stateNum": [{"idleNum": 1,"runNum": 6,"attackNum": 10,"hurtNum": 1,"deadNum": 12}]},{"id": 6,"name": "jielingqishi","type": 3,"life": 100,"attack": 18,"attackSpeed": 7.5,"power": 100,"magicGroup": [{"magic1": 5,"magic2": 4}],"stateNum": [{"idleNum": 1,"runNum": 2,"attackNum": 6,"hurtNum": 1,"deadNum": 9}]} ]之后是magicConfig.json [{"id": 1,"name": "fireblast","count": 10},{"id": 2,"name": "burn","count": 6},{"id": 3,"name": "icepiton","count": 8},{"id": 4,"name": "shocked","count": 4},{"id": 5,"name": "firedevil","count": 6},{"id": 6,"name": "lightstrike","count": 6},{"id": 7,"name": "bossfire","count": 4},{"id": 8,"name": "firedevilblast","count": 6},{"id": 9,"name": "fireball","count": 4},{"id": 10,"name": "bossstore","count": 5},{"id": 11,"name": "magicring","count": 1} ]

下面的加載sprite精靈方法,initSprite我們加個斷點直觀的看一下,一看嚇一跳,原來這個create方法里面包含了這么多東西,的確,不過這個東西就是我們上面json里面的id1的數(shù)據(jù),之后的方法我們截個圖來看

把方法折疊起來一下變得直觀了,我們一個方法一個方法的看,spAttackSchedule方法是一個攻擊的計時器,通過這個計時,來控制自動攻擊的頻率,里面有個特別的地方就是,當魔法攻擊的時候,計時會歸0,然后等待魔法之后重新開始計時,magicMove和magicMoveCallback兩個方法用來控制攻擊子彈的移動及消亡,因為刀塔傳奇這一類的游戲,不像格斗類游戲攻擊的碰撞盒子安在身上,而是靠子彈(魔法)來攻擊,所以這個方法控制能不能打倒怪物就很重要了,showLife這個就不用說了,傷血之后,頭上會有個血條,那年那兔那些事這樣的游戲會有個選項,是否顯示,showLifeCallback就是隱藏方法,setMagicPanel是設置魔法的面板方法,畫出面板肯定要有按鍵響應itemCallback就是用來響應我們的輸入的。showBottomLife和showPower是用來畫出和控制魔法控制條的(只有集滿氣才可以釋放),釋放出startMagic技能,當然要判斷傷害了magicHurt,這樣這個類就看完了,雖然看上去代碼很多,卻并不復雜,當然僅有這個類游戲還不能正常運轉(zhuǎn),這個類里面用到了幾個靜態(tài)類,我們來看看都有哪些,作用又是干什么的。

#include "GameInstance.h" #include "Resource.h" static GameInstance *s_SharedGameInstance = nullptr;GameInstance::GameInstance() {for (unsigned int i = 0; i <6; i++){spSel[i] = false;}isGameOver = false;isWin = false; }GameInstance::~GameInstance() {}GameInstance* GameInstance::getInstance() {if (!s_SharedGameInstance){s_SharedGameInstance = new GameInstance();//s_SharedGameInstance->init();}return s_SharedGameInstance; }Animate* GameInstance::setAnimate(const char* frameName, int frameCount, int fps, bool restore,int times) {using namespace cocos2d;Vector<SpriteFrame*> frames;for (int i = 1; i <= frameCount; i++){const char* imgName = String::createWithFormat(frameName, i)->getCString();SpriteFrame* frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(imgName);frames.pushBack(frame);}auto animation = Animation::createWithSpriteFrames(frames, 1.0f/fps, times);animation->setRestoreOriginalFrame(restore);auto animate = Animate::create(animation);return animate; }//MagicConfig GameInstance::readDataBase(MagicId id) //{ // MagicConfig magicConf; // sqlite3* pdb; // std::string path = "database/magic.db3"; // int result; // char** re; // int row; // int col; // // result = sqlite3_open(path.c_str(), &pdb); // // sqlite3_get_table(pdb, "select * from magicConfig", &re, &row,&col, NULL); // // magicConf.id = (MagicId)atoi(re[2*col+0]); // magicConf.name = re[id*col+1]; // magicConf.count = atoi(re[id*col+2]); // // sqlite3_close(pdb); // // return magicConf; //}std::string GameInstance::getMagicName(MagicId id) {_stMagicConfig mgConf;rapidjson::Document doc;std::string str = FileUtils::getInstance()->getStringFromFile(s_spMagJson);doc.Parse<rapidjson::kParseDefaultFlags>(str.c_str());rapidjson::Value &val =doc[(rapidjson::SizeType)(id-1)];std::string name = val["name"].GetString();return name;}int GameInstance::getMagicNum(MagicId id) {_stMagicConfig mgConf;rapidjson::Document doc;std::string str = FileUtils::getInstance()->getStringFromFile(s_spMagJson);doc.Parse<rapidjson::kParseDefaultFlags>(str.c_str());rapidjson::Value &val =doc[(rapidjson::SizeType)(id-1)];int count = val["count"].GetInt();return count; }std::string GameInstance::getSpriteName(SpriteId id) {std::string name;_stSpriteConfig spConf;rapidjson::Document doc;std::string str = FileUtils::getInstance()->getStringFromFile(s_spConfJson);doc.Parse<rapidjson::kParseDefaultFlags>(str.c_str());rapidjson::Value &val =doc[(rapidjson::SizeType)(id-1)];if (val.HasMember("name")){name = val["name"].GetString();}return name; }std::string GameInstance::getStateName(SpriteId id,SpriteState state) {std::string str = GameInstance::getInstance()->getSpriteName(id);switch (state){case SPRITESTATE_IDLE:str += "_run_%03d.png";break;case SPRITESTATE_RUN:str += "_run_%03d.png";break;case SPRITESTATE_ATTACK:str += "_attack_%03d.png";break;case SPRITESTATE_HURT:str += "_run_%03d.png";break;case SPRITESTATE_DEAD:str += "_dead_%03d.png";break;default:break;}return str; }這個類很直觀,是一個精靈動畫控制類,可以看到這樣的語句,當xx的時候使用哪張圖片,cocos2dx提供的精靈動畫畫法各有千秋,用哪種自己習慣, #include "Magic.h" #include "sqlite3.h" #include "GameInstance.h" Magic::Magic():magicAction(nullptr) {}Magic::~Magic() {//CC_SAFE_RELEASE_NULL(magicAction); }Magic* Magic::create(_stMagicConfig magConfig) {Magic* sprite = new Magic();sprite->magicConf = magConfig;std::string spriteName = GameInstance::getInstance()->getMagicName(sprite->magicConf.id);spriteName += "_001.png";auto spriteFrame = SpriteFrameCache::getInstance()->spriteFrameByName(spriteName);if (spriteFrame && sprite->initWithSpriteFrame(spriteFrame)){sprite->autorelease();return sprite;}else{delete sprite;sprite = NULL;return NULL;}return NULL; }void Magic::setMagic() {std::string str;str = this->magicConf.name;str += "_%03d.png";this->magicAction = GameInstance::getInstance()->setAnimate(str.c_str(), this->magicConf.count, this->magicFps, false, this->magicTimes); } void Magic::startMagic(int fps, int times) {this->magicFps = fps;this->magicTimes = times;this->setMagic();Animate* tmp = (Animate*)this->magicAction;auto callfunc = CallFunc::create(CC_CALLBACK_0(Magic::startMagicCallback, this));auto sequence = Sequence::create(tmp, callfunc, NULL);this->runAction(sequence); }void Magic::startMagicCallback() {this->setVisible(false); }void Magic::move(Point endPoint, int duration, float speed) {float s= ccpDistance(this->getPosition(), endPoint);auto move = MoveTo::create(s/speed,endPoint);this->runAction(move); }
上面畫出了人物,下面理所應當?shù)膽摪涯Хó嫵鰜砹?#xff0c;魔法精靈控制類就這樣出現(xiàn)了,
#include "OverScene.h"#include "GameInstance.h" #include "GameScene.h"OverScene::OverScene() { }Scene* OverScene::createScene() {auto scene = Scene::create();auto layer = OverScene::create();scene->addChild(layer);GameInstance::getInstance()->isGameOver = false;return scene; }bool OverScene::init() {if (!Layer::init()){return false;}auto ui = cocostudio::GUIReader::getInstance()->widgetFromJsonFile("gameover/NewUI4_1.ExportJson");this->addChild(ui);Button* back = (Button*)Helper::seekWidgetByName(ui,"back");Button* fight = (Button*)Helper::seekWidgetByName(ui,"fight");if (GameInstance::getInstance()->isWin){Sprite* title =Sprite::create("map/stagedetail_raid_title.png");title->setPosition(400, 240);this->addChild(title);}else{Sprite* title = Sprite::create("map/failed_title.png");title->setPosition(400, 240);this->addChild(title);}back->addTouchEventListener(this, toucheventselector(OverScene::tbackCallback));fight->addTouchEventListener(this, toucheventselector(OverScene::tfightCallback));/*Sprite* bg = Sprite::create("map/gameover.png");bg->setPosition(400, 240);this->addChild(bg);if (GameInstance::getInstance()->isWin){Sprite* title =Sprite::create("map/stagedetail_raid_title.png");title->setPosition(400, 240);this->addChild(title);}else{Sprite* title = Sprite::create("map/failed_title.png");title->setPosition(400, 240);this->addChild(title);}auto back = MenuItemSprite::create(Sprite::create("button/replaybtn.png"), Sprite::create("button/replaybtn-disabled.png"),CC_CALLBACK_1(OverScene::backCallback,this));back->setPosition(back->getContentSize().width/2, back->getContentSize().height/2);auto fight = MenuItemSprite::create(Sprite::create("button/prepare_go_battle.png"), Sprite::create("button/prepare_go_battle_press.png"),CC_CALLBACK_1(OverScene::fightCallback,this));fight->setPosition(800-back->getContentSize().width/2, back->getContentSize().height/2);auto menu =Menu::create(back, fight, NULL);menu->setPosition(Point::ZERO);this->addChild(menu);*/return true; }void OverScene::backCallback(Ref* sender) {Director::getInstance()->end();} void OverScene::fightCallback(Ref* sender) {Director::getInstance()->replaceScene(GameScene::createScene());}void OverScene::tbackCallback(Ref* sender, TouchEventType type) {switch (type){case TOUCH_EVENT_ENDED:Director::getInstance()->end();break;} } void OverScene::tfightCallback(Ref* sender, TouchEventType type) {switch (type){case TOUCH_EVENT_ENDED:Director::getInstance()->replaceScene(GameScene::createScene());break;} }當戰(zhàn)斗全都結(jié)束了,自然要看戰(zhàn)斗結(jié)束了。好了,到這代碼差不多快完事了,其中有兩個.H文件

#ifndef _CONFIG_ #define _CONFIG_USING_NS_CC; //精靈初始位置 const Point PointS_1 = Point(355, 317) - Point(380, 0); const Point PointS_2 = Point(190, 290)- Point(380, 0); const Point PointS_3 = Point(80, 300)- Point(380, 0); const Point PointS_4 = Point(445, 300)+ Point(380, 0); const Point PointS_5 = Point(550, 313)+ Point(380, 0); const Point PointS_6 = Point(720, 355)+ Point(380, 0);const Point PointE_1 = Point(355, 317); const Point PointE_2 = Point(190, 290); const Point PointE_3 = Point(80, 300); const Point PointE_4 = Point(445, 300); const Point PointE_5 = Point(550, 313); const Point PointE_6 = Point(720, 355);//精靈的唯一標示 enum SpriteId {SPRITEID_1 = 1,SPRITEID_2,SPRITEID_3,SPRITEID_4,SPRITEID_5,SPRITEID_6};//每個技能的唯一標示 enum MagicId {MAGIC_1 = 1,MAGIC_2,MAGIC_3,MAGIC_4,MAGIC_5,MAGIC_6,MAGIC_7,MAGIC_8,MAGIC_9,MAGIC_10,MAGIC_11, }; //精靈狀態(tài) enum SpriteState {SPRITESTATE_IDLE,SPRITESTATE_RUN,SPRITESTATE_ATTACK,SPRITESTATE_MAGIC,SPRITESTATE_HURT,SPRITESTATE_DEAD }; //精靈類型 前排、中排、后排 enum SpriteType {SPRITETYPE_FRONT = 1, //前排SPRITETYPE_MIDDLE, //中排SPRITETYPE_BACK //后排 };enum MoveType {MoveType_To,MoveType_By };//精靈每個狀態(tài)的動畫數(shù)量 struct StateNum {int idleNum; //空閑int runNum; //跑動int attackNum; //攻擊int hurtNum; //受傷int deadNum; //死亡 };//精靈屬性struct MagicGroup {MagicId magic1;MagicId magic2; };struct _stSpriteConfig {SpriteId id; //精靈ID,唯一識別std::string name; //名字SpriteType type; //類型,前排、中排、后排int life; //生命值int attack; //攻擊力double attackSpeed; //攻擊速度int power; //魔法值MagicGroup magicGroup; //魔法類別,遠距離、直接攻擊StateNum stateNum; //各動畫幀數(shù) };//技能屬性 struct _stMagicConfig {MagicId id;std::string name;int count;};struct AttackId {bool s1;bool s2;bool s3; }; #endif #ifndef _RESOURCE_H_ #define _RESOURCE_H_static const char s_magPan[] = "panel/panel.png";static const char s_panSpNor[3][64] = {"panel/sprite1.png","panel/sprite2.png","panel/sprite3.png"}; static const char s_panSpDis[3][64] = {"panel/sprite1no.png","panel/sprite2no.png","panel/sprite3no.png"}; static const char s_spConfJson[] = "json/spriteConfig.json";static const char s_ptBg[] = "button/lifebg2.png"; static const char s_ptLife[] = "button/herolife.png"; static const char s_ptLife2[] = "button/life.png"; static const char s_ptPower[] = "button/power.png";static const char s_spMagJson[] = "json/magicConfig.json";#endif到這里全部代碼差不多貼完了,不知道為什么原作者代碼里有沒有用到的東東,我懷疑是這段代碼可能是從某個項目中拆出來的,因為我認為跟戰(zhàn)斗沒啥關系,所以就不貼出來,因為沒辦法直接開放源碼,看過這篇的小伙伴需要代碼的話,可以自行搜索,或者私信給我,好了,這篇就到這,我們后面再見。







總結(jié)

以上是生活随笔為你收集整理的今天开始做战斗,回合制战斗代码实现第四篇 刀塔传奇战斗模式(即时卡牌战斗模式)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。