今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗

今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗说到九宫格战斗 就不能不提一款游戏 神仙道 在神仙道之前 九宫格战斗的模式就在几款游戏里面有应用 但神仙道是真真正正把这种战斗模式发扬光大的里程碑 当时无论口碑 还是市场占有率都可以说是空前的 这款游戏我玩到 150 级 可以说是投入精力比较大的一款游戏 在游戏里面也交了很多朋友 虽然最近这种游戏模式因为一些原因走下坡路 现阶段刀塔传奇这种模式的游戏很吃香 不过既然说回合制游戏 那么就还是讨论一下

     说到九宫格战斗,就不能不提一款游戏《神仙道》,在神仙道之前,九宫格战斗的模式就在几款游戏里面有应用,但神仙道是真真正正把这种战斗模式发扬光大的里程碑,当时无论口碑,还是市场占有率都可以说是空前的,这款游戏我玩到150级,可以说是投入精力比较大的一款游戏,在游戏里面也交了很多朋友,虽然最近这种游戏模式因为一些原因走下坡路(现阶段刀塔传奇这种模式的游戏很吃香),不过既然说回合制游戏,那么就还是讨论一下。

一、 战斗系统概述
1 此战斗系统适用于PVE(玩家与怪物战斗)和PVP(玩家与玩家战斗)
2 游戏为横版,攻守双方分部屏幕左右两边                  
3 战场上攻防双方各有一个3*3的9宫格方阵
4 回合制战斗,按双方各自的出手顺序

今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗

二、 战斗内容
2.1 战斗单位
2.1.1 战场上的一方最多只能有五个战斗单位,战斗单位包括主角和伙伴(这个在后期改为有一个伙伴作为后备,当前排角色死亡后来填补空缺【不过反响并不好】)
2.1.2 每场战斗可以派遣数个伙伴随主角一起参与,最高参与人数与奇术系统相关
2.2 战斗触发
2.2.1 战斗触发入口 多人副本入口、开启活动副本入口
2.2.2 触碰明雷怪 在单人副本中行走进入明雷怪触发战斗范围后,切换至战斗画面
2.3 战斗规则
2.3.1 回合制 每场战斗20回合,如果回合满则自动结束战斗
2.3.2 攻击顺序
A. 按照双方先攻值判断队伍出手先后顺序
B. 按本方出手顺序依次筛选出第N个出手的战斗单位
C. 死亡的战斗单位不参与筛选,如果本方第N个出手的战斗单位死亡,则本轮次轮空
2.4 战场形势
2.4.1 战场位置 战场上攻防双方各有一个3*3的9宫格方阵,根据阵型不同,玩家可以布置
2.4.2 战斗位置编号 为9宫格每个格子进行编号,阵型系统根据编号,给予上场的单位出手顺序

今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗

2.5 战斗带入属性
 2.5.1 玩家等级 1-100(这里用100是因为100级之前神仙道的概率公式直接使用百分数,110之后更新,概率由百分数改为概率等级,参考魔兽世界600等级==1%)
 2.5.2 职业 剑灵、飞羽、将星、武圣、方士、术士
 2.5.3 HP 每个战斗单位的总血量值
 2.5.4 普通攻击力/法术攻击力 物理职业读取普通攻击力值,法师职业读取法术攻击力值
 2.5.5 普通防御力/法术防御力 物理职业读取普通防御力值,法师职业读取法术防御力值
 2.5.6 绝技攻击力 士气达到100时,释放绝技时读取的绝技攻击力值
 2.5.7 绝技防御力 受到绝技伤害时,读取的绝技防御力值
 2.5.8 命中概率、闪避概率 (出手战斗单位命中概率-防御方闪避)是一个在[0,1]区间的概率值(110之后改为概率等级),决定是否成功命中对方或被对方躲避掉此次伤害
 2.5.9   暴击概率 成功触发暴击事件的概率(110之后改为概率等级
 2.5.10  减少对方暴击 减少对方触发暴击事件的概率(110之后改为概率等级
 2.5.11  必杀 增加触发暴击事件后产生的伤害值(110之后改为概率等级
 2.5.12  格挡概率 成功触发格挡事件的概率(110之后改为概率等级
 2.5.13  减少对方格挡 减少对方触发格挡事件的概率(110之后改为概率等级
 2.5.14  士气值 士气值累积达到100时,触发绝技(110之后改为概率等级
2.6 攻击事件
2.6.1 普通攻击 物理攻击型战斗单位在士气未达到100时的攻击方式
2.6.2 法术攻击 法术攻击型战斗单位在士气未达到100时的攻击方式
2.6.3 绝技攻击 战斗单位的士气值达到100时的攻击方式
2.6.4 血量减少 攻击放成功给予目标战斗单位伤害后,目标战斗单位血量减少
2.6.5 暴击 按暴击概率是否成功触发暴击事件,若成功触发则产生(1+0.5+必杀值)*E的伤害,失败则伤害值仍为E(E为按攻防公式产生的非绝技伤害值)
2.6.6 命中 出手战斗单位成功对目标战斗单位造成单次伤害
2.6.7 闪避 目标战斗单位成功躲避出手战斗单位造成的单次伤害
2.6.8 格挡 按概率成功触发格挡事件后,受到的伤害值减半,状态维持1回合
2.6.9 反击 被近战单体攻击并触发格挡之后,触发反击对对方造成数值为E的伤害
 2.6.10 士气
A. 获得:初始值及获得士气值见下表(身上有特殊BUFF时也会获得士气值)
职业 初始默认值 物理攻击 被物理攻击 法术攻击 被法术攻击 绝技攻击 被绝技攻击 BUFF增加
剑灵 50 25 25 25 25 0 0 参见BUFF表
武圣 50 25 25 25 25 0 0 参见BUFF表
飞羽 50 25 25 25 25 0 0 参见BUFF表
将星 50 25 25 25 25 0 0 参见BUFF表
方士 50 25 25 25 25 0 0 参见BUFF表
术士 50 25 25 25 25 0 0 参见BUFF表
B. 消耗
每次士气值达到或超过100触发绝技后,士气值减少至0
受到减少士气值的技能攻击,士气值减少
2.7 战斗结果
2.7.1 一方的所有战斗单位的血量和为0,战斗结束。战斗单位血量和大于0的一方获胜
2.7.2 每场战斗只有20回合,如果20回合后双方没有分出胜负,则防守方(战斗画面右方)胜利
2.8 战斗奖励
2.8.1 战斗之后根据配置文件处理战斗获得
2.8.2 战斗中死亡的战斗单位也可以获得经验奖励。经验奖励只与战斗结果有关,即战斗胜利,
胜利方的所有参战的战斗单位都可以获得经验奖励,战斗胜利,所有战斗单位没有经验
奖励
2.9 战斗结束后的血量补充
2.9.1 战斗单位升级  血量自动补满
2.9.2 战斗单位未升级
A. 主角身上有血池buff
a. 血池足够 所有参战的战斗单位血量补满(补给血量值为A),血池血量减少A
b. 血池不足 按照战斗单位的出手顺序为战斗单位依次补给血量
实例:
战斗单位 出手顺序 总HP 当前HP 血池血量 需要的补给 实际的补给
A 1 4000 1000
0
3000 3000
B 2 4000 2000 18462 2000 2000
C 3 4000 1000 3000 3000
D 4 4000 1500 2500 2500
c. 特殊情况:
D当前HP为0,在恢复C血时已经消耗掉血池的全部存余血量,默认为D增加1点HP
B. 主角身上无血池buff
战斗单位血量为0,自动为其增加1点血量
战斗单位剩余血量不为0,不增加血量

三、 战斗表现形式
3.1 状态说明
状态 说明
普通近程攻击 出手战斗单位从原地消失→播放向目标战斗单位前进的动作→播放出手战斗单位的攻击动作以及目标战斗单位被攻击的动作→目标战斗单位损失血量→出手战斗单位消失→播放出手战斗单位退回原地的动作→出手战斗单位出现在原位
普通远程攻击 播放出手战斗单位的攻击动作及特效→播放目标战斗单位的被攻击动作及特效→目标战斗单位损失血量
普通法术攻击 播放出手战斗单位的攻击动作及特效→播放目标战斗单位的被攻击动作及特效→目标战斗单位损失血量
绝技攻击 播放出手战斗单位的攻击动作及特效→播放目标战斗单位的被攻击动作及特效→目标战斗单位损失血量
闪避 播放出手战斗单位的攻击动作及特效→播放目标战斗单位的被攻击动作及特效,同时在目标战斗单位出现“闪避”字样
暴击 播放出手战斗单位的攻击动作及特效,同时在出手战斗单位出现“暴击”字样→播放目标战斗单位的被攻击动作及特效→目标战斗单位损失血量
格挡 播放出手战斗单位的攻击动作及特效→播放目标战斗单位的被攻击动作及特效,同时在目标战斗单位出现“格挡”字样→目标战斗单位损失血量
损失血量 目标战斗单位显示减少的血量数值
反击 目标战斗单位在格挡状态下,在目标战斗单位处出现“反击”字样→目标战斗单位从原地消失→播放向原出手战斗单位前进的动作→播放目标战斗单位的攻击动作以及出手战斗单位被攻击的动作→原出手战斗单位损失血量→目标战斗单位消失→播放目标战斗单位退回原地的动作→目标战斗单位出现在原位
四、 流程图  

4.1战斗回合流程 今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗4.2战斗轮次流程 今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗4.3战斗行动准备流程 今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗

4.4战斗进行阶段流程今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗4.5战斗结束阶段流程今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗4.6buffer流程今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗

4.7选择攻击方式流程今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗4.8战斗单位死亡流程今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗4.9战斗替补单位流程

命中、暴击、必杀、格挡计算流程

今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗好了,战斗系统就这些,好家伙,真佩服策划的工作能力(上面这些是某公司山寨神仙道
时候的策划文档摘抄,这里感谢原作者)




好了,我们的文档这样就完成了,也就是说我们的战斗系统要做到上面文档要求的效果,那会是什么样的呢?这里感谢as3页游方面的专家leo老兄提供战斗系统源码,因为这里代码有现成的,我们只是做代码分析,因为这个战斗系统代码不是我写的这里就不公开散布了,所以需要源码的小伙伴可以私信给我吐舌头。我们这里只做分析。

我们先看看配置文件,战斗的battle数据文件(本来应该是服务器即使生成)


  
           
           
           
           
           

           
  
           
           
           
           
            
             
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
             
             
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
             
             
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
              
             
           



接着看下文档类

package leo
{
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.profiler.showRedrawRegions;
	
	import leo.controller.util.LayerUtil;
	import leo.proxy.GameConst;
	import leo.proxy.transmission.LoaderUtil;
	import leo.view.ui.BtnBattle;
	import leo.view.ui.BtnBattleTips;
	import leo.view.ui.UIBattleList;
	
	[SWF(width="1250",height="650",frameRate="24",backgroundColor="0")]
	public class BattlePlayer extends Sprite
	{
		private var curView :*;
		private var battleLayer :Sprite;
		private var popLayer :Sprite;
		private var btnBattle :BtnBattle;
		private var btnBattleTips :BtnBattleTips;
		public function BattlePlayer()
		{
			init();
			
		}
		
		private function init():void
		{
			
			LoaderUtil.I.loadConfig();
			this.battleLayer = new Sprite();
			this.popLayer = new Sprite();
			this.addChild(battleLayer);
			this.addChild(popLayer);
			LayerUtil.I.layerDict[GameConst.BATTLE_LAYER] = this.battleLayer;
			LayerUtil.I.layerDict[GameConst.POP_LAYER] = this.popLayer;
			GameConst.main = this;
		}
		/*
		public function rhand():void
		{
			btnBattle = new BtnBattle();
			this.addChild(btnBattle);
			btnBattleTips = new BtnBattleTips();
			btnBattleTips.x = btnBattle.x + btnBattle.width - 20;
			btnBattleTips.y = btnBattle.y + btnBattle.height - 20;
			btnBattleTips.mouseChildren = btnBattleTips.mouseEnabled = false;
			this.addChild(btnBattleTips);
			btnBattle.addEventListener(MouseEvent.MOUSE_UP,mouseHandler);
		}
		*/
		public function setStage(view :*):void
		{
			if(this.curView && this.battleLayer && this.battleLayer.contains(this.curView))
			{
				this.curView.destroy;
				this.battleLayer.removeChild(this.curView);
			}
			battleLayer.addChild(view);
		}
		
		public function show():void
		{
			//btnBattle.visible = true;
			//btnBattle.mouseChildren = btnBattle.mouseEnabled = true;
			//btnBattleTips.play();
		}
		
		public function hide():void
		{
			//btnBattle.visible = false;
			//btnBattle.mouseChildren = btnBattle.mouseEnabled = false;
			//btnBattleTips.stop();
		}
		public function mouseHandler():void
		//private function mouseHandler(e :MouseEvent):void
		{
			trace("load");
			var view :UIBattleList = new UIBattleList(null);
			setStage(view);
			//hide();
		}
		
	}
}

init方法中有LoaderUtil.I.loadConfig();我们看下LoaderUtil这个静态类

package leo.proxy.transmission
{
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.Dictionary;
	import flash.utils.getDefinitionByName;
	
	import leo.proxy.GameConst;
	import leo.proxy.battles.action.Action_AddObject;
	import leo.proxy.battles.action.Action_Attack;
	import leo.proxy.battles.action.IBattleAction;
	import leo.proxy.battles.vo.BattleVO;
	import leo.proxy.vo.BaseUI;
	import leo.proxy.vo.RoleAssetsVO;

	/
	 * 加载工具 
	 * @author leo
	 * 
	 */	
	public class LoaderUtil
	{
		private static var _I :LoaderUtil = null;
		/
		 * 加载器缓存 
		 */		
		public var loaderDict :Dictionary = new Dictionary();
		/
		 * 所有加载过的UI的VO 
		 */		
		public var fileList :Dictionary = new Dictionary();
		/
		 * 缓存的战斗VO表 
		 */		
		public var battleVOList :Dictionary = new Dictionary();
		/
		 * 缓存战斗地图 
		 */		
		public var battleMapDict :Dictionary = new Dictionary();
		/
		 * 总加载数 
		 */		
		private var sum :int;
		/
		 * 当前已加载数 
		 */		
		private var index :int;
		/
		 * 加载列表成功函数 
		 */		
		private var rhand :Function;
		/
		 * 加载列表失败函数 
		 */		
		private var fhand :Function;
		/
		 *  加载UI成功函数
		 */		
		private var uiRhand :Function;
		/
		 * 加载UI失败函数 
		 */		
		private var uiFhand :Function;
		public function LoaderUtil(prv :PrivateClass)
		{
		}
		/
		 * 加载UI列表 
		 * @param list  完整路径列表
		 * @param rhand
		 * @param fhand
		 * 
		 */		
		public function loadList(list :Array,rhand :Function = null,fhand :Function = null):void
		{
			if(!list || list.length == 0)
			{
				return;
			}
			this.rhand = rhand;
			this.fhand = fhand;
			this.sum = 0;
			this.sum = list.length;
			for(var i :int = 0; i < list.length; i++)
			{
				var url :String = list[i] as String;
				var loader :CustomLoader = new CustomLoader();
				loader.id = url;
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);
				loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,errorHandler);
				var loaderContext :LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);
				loader.load(new URLRequest(url),loaderContext);
				this.loaderDict[loader.id] = loader;
			}
		}
		/
		 * 加载UI列表成功 
		 * @param e
		 * 
		 */		
		private function completeHandler(e :Event):void
		{
			this.index++;
			var loader :CustomLoader = (e.target as LoaderInfo).loader as CustomLoader;
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,completeHandler);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,errorHandler);
			if(this.loaderDict[loader.id])
			{
				loader.unload();
				delete this.loaderDict[loader.id];
				loader = null;
			}
			
			if(this.index == this.sum)
			{
				if(this.rhand != null)
				{
					rhand();
					rhand = null;
					fhand = null;
				}
			}
		}
		/
		 * 加载UI列表失败 
		 * @param e
		 * 
		 */		
		private function errorHandler(e :IOErrorEvent):void
		{
			if(this.fhand != null)
			{
				fhand();
				rhand = null;
				fhand = null;
			}
			var loader :CustomLoader = (e.target as LoaderInfo).loader as CustomLoader;
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,completeHandler);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,errorHandler);
			trace("加载组ui出错");
		}
		
		/
		 * 加载单个UI 
		 * @param vo
		 * @param rhand
		 * @param fhand
		 * 
		 */		
		public function loadUI(vo :BaseUI,rhand :Function,fhand :Function = null):void
		{
			if(!vo)
			{
				return;
			}
			this.uiRhand = rhand;
			this.uiFhand = fhand;
			var url :String = vo.swfPath;
			var loader :CustomLoader = new CustomLoader();
			loader.id = url;
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE,uiComplete);
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,uiError);
			var loaderContext :LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);
			loader.load(new URLRequest(url),loaderContext);
			this.loaderDict[loader.id] = loader;
			this.fileList[vo.swfPath] = vo;
		}
		/
		 * 加载单个UI成功 
		 * @param e
		 * 
		 */		
		private function uiComplete(e :Event):void
		{
			var loader :CustomLoader = (e.target as LoaderInfo).loader as CustomLoader;
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,completeHandler);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,errorHandler);
			if(this.fileList[loader.id])
			{
				var vo :BaseUI = this.fileList[loader.id] as BaseUI;
				vo.isComplete = true;
				vo.isLoading = false;
			}
			
			if(this.loaderDict[loader.id])
			{
				loader.unload();
				delete this.loaderDict[loader.id];
				loader = null;
			}
			
			if(this.uiRhand != null)
			{
				this.uiRhand();
				this.uiRhand = null;
				uiFhand = null;
			}
			
		}
		/
		 * 加载单个UI失败 
		 * @param e
		 * 
		 */		
		private function uiError(e :IOErrorEvent):void
		{
			var loader :CustomLoader = (e.target as LoaderInfo).loader as CustomLoader;
			loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,completeHandler);
			loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,errorHandler);
			if(this.uiFhand != null)
			{
				uiFhand();
				this.uiRhand = null;
				uiFhand = null;
			}
			trace("加载单个ui出错");
		}
		
		/
		 * 加载config.xml 
		 * 
		 */		
		public function loadConfig():void
		{
			var str :String = GameConst.CONFIG_XML;
			var loader :URLLoader = new URLLoader();
			loader.addEventListener(Event.COMPLETE,configComplete);
			loader.addEventListener(IOErrorEvent.IO_ERROR,configError);
			loader.load(new URLRequest(str));
		}
		/
		 * 加载config.xml成功 
		 * @param e
		 * 
		 */		
		private function configComplete(e :Event):void
		{
			var xml :XML = new XML(((e.target) as URLLoader).data);
			
			GameConst.uiDir = xml.uiDir;
			GameConst.itemDir = xml.itemDir;
			GameConst.roleDir = xml.roleDir;
			GameConst.mapDir = xml.mapDir;
			GameConst.battleXML = xml.battleXML;
			
			var str :String = xml.ui;
			var ary :Array = str.split(",");
			
			while(ary.length > 0)
			{
				var url :String = GameConst.uiDir + ary.pop() + ".swf";
				GameConst.uiList.push(url);
			}
			((e.target) as URLLoader).removeEventListener(Event.COMPLETE,configComplete);
			((e.target) as URLLoader).removeEventListener(IOErrorEvent.IO_ERROR,configError);
			loadBattleData();
		}
		/
		 * 加载config.xml失败 
		 * @param e
		 * 
		 */		
		private function  configError(e :IOErrorEvent):void
		{
			((e.target) as URLLoader).removeEventListener(Event.COMPLETE,configComplete);
			((e.target) as URLLoader).removeEventListener(IOErrorEvent.IO_ERROR,configError);
			trace("加载config出错");
		}
		/
		 * 加载战斗XML 
		 * 
		 */		
		private function loadBattleData():void
		{
			var loader :URLLoader = new URLLoader();
			var url :String = GameConst.battleXML;
			loader.addEventListener(Event.COMPLETE,battleXMLComplete);
			loader.addEventListener(IOErrorEvent.IO_ERROR,battleXMLError);
			loader.load(new URLRequest(url));
		}
		/
		 * 加载战斗XML成功 
		 * @param e
		 * 
		 */		
		private function battleXMLComplete(e :Event):void
		{
			var loader :URLLoader = e.target as URLLoader;
			var xml :XML = new XML(loader.data);
			
			for each(var battleXML :XML in xml.battle)
			{
				var battleVO :BattleVO = new BattleVO();
				battleVO.battleInfoVO.parse(battleXML,battleVO);
				
				
				for each(var actionXML :XML in battleXML.item)
				{
					var actionName :String= actionXML.@actionName;
					
					//注意一定要导入要实例化的类才能getDefinitionByName,要不然会报错
					importClass();
					var path :String = GameConst.PACKAGE_ACTION;
					var actionCls:Class = getDefinitionByName(path + actionName) as Class;
					var action:IBattleAction = new actionCls() as IBattleAction;
					action.parse(actionXML,battleVO);
					battleVO.actions.push(action);
				}
				this.battleVOList[battleVO.battleInfoVO.id] = battleVO;
			}

			loader.removeEventListener(Event.COMPLETE,battleXMLComplete);
			loader.removeEventListener(IOErrorEvent.IO_ERROR,battleXMLError);
			loader = null;
			
			//loadList(GameConst.uiList, GameConst.main.rhand);
			loadList(GameConst.uiList,GameConst.main.mouseHandler);
		}
		/
		 * 加载战斗XML失败 
		 * @param e
		 * 
		 */		
		private function battleXMLError(e :IOErrorEvent):void
		{
			var loader :URLLoader = e.target as URLLoader;
			loader.removeEventListener(Event.COMPLETE,battleXMLComplete);
			loader.removeEventListener(IOErrorEvent.IO_ERROR,battleXMLError);
			trace("加载战斗XML出错");
		}
		
		public function checkIsLoad(swfPath :String):Boolean
		{
			var vo :BaseUI = this.fileList[swfPath] as BaseUI;
			if(vo && (vo.isLoading || vo.isComplete))
			{
				return true;
			}
			return false;
		}
		
		private function importClass():void
		{
			var cls1 :Action_AddObject;
			var cls2 :Action_Attack;
		}


		public static function get I():LoaderUtil
		{
			if(_I == null)
			{
				_I = new LoaderUtil(new PrivateClass());
			}
			return _I;
		}

	}
}

class PrivateClass{}

public function loadConfig():void{}方法里面有这样一句var str :String = GameConst.CONFIG_XML;而得到xml的外部链接

package leo.proxy
{
	import flash.filters.GlowFilter;
	
	import leo.BattlePlayer;

	/
	 * 游戏常用的常量 
	 * @author leo
	 * 
	 */	
	public class GameConst
	{
		public static var main :BattlePlayer = null;
public static const CONFIG_XML :String = "leo/assets/data/config.xml";
	//	public static const CONFIG_XML :String = "http://www.longsihao.com/games/BattlePlayer/assets/data/netConfig.xml";
		public static var itemDir :String;
		public static var uiDir :String;
		public static var roleDir :String;
		public static var mapDir :String;
		public static var battleXML :String;
		public static var uiList :Array = [];
		public static var smallLoading :String = "smallLoading";
		public static const POP_LAYER :String = "pop_layer";
		public static const BATTLE_LAYER :String = "battle_layer";
		
		public static const PACKAGE_ACTION :String = "leo.proxy.battles.action.";
		public static const ROLE_ACTION_ARY :Array = ["attack","be_hit","fighting_idle"];
		public static const SPEED :int = 3;
		
		public static const MOUSE_ON :Array = [new GlowFilter(0xffff00,1,2,2,2,2)];
		public static const SKILL_NAME :Array = ["天魔杀星","冰凌剑空","灵木刺阵","十方剑气","天魔斩","八方棍法","雷动八方","琥珀冲杀","毒龙蚀天","地狱之火","葬林狂舞"];
		public function GameConst()
		{
		}
	}
}

private function configComplete(e :Event):void{}方法中的

然后private function loadBattleData():void{}加载这战斗xml,我们可以看到trace(“actionName=” + actionName);得到的xml文件数据

今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗


方法最后loadList(GameConst.uiList,GameConst.main.mouseHandler);加载进入游戏的控制列表

回到文档类中的public function mouseHandler():void{}方法中var view :UIBattleList = new UIBattleList(null);setStage(view);调用battleLayer.addChild(view);

将view加载到舞台上面,UIBattleList中的baseUI = new BaseUI(“BattleList”,”BattleList”);来加载battlelist.swf文件文件截图

今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗override protected function swfLoadComplete():void{}中的this.itemList = new Vector.

();

package leo.proxy.vo
{
	import leo.proxy.GameConst;
	/
	 * 加载UIVO基类 
	 * @author Leo
	 * 
	 */
	public class BaseUI
	{
		public var fileName :String;
		public var linkName :String;
		public var isLoading :Boolean = true;
		public var isComplete :Boolean = false;
		public function BaseUI(fileName :String , linkName :String)
		{
			this.fileName = fileName;
			this.linkName = linkName;
		}
		
		public function get swfPath():String
		{
			return GameConst.uiDir + this.fileName + ".swf";	
		}
		
		
		public function complete():void
		{
			this.isComplete = true;
			this.isLoading = false;
		}
	}
}
package leo.view.ui
{
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.Dictionary;
	
	import leo.controller.util.UIUtil;
	import leo.proxy.GameConst;
	import leo.proxy.battles.vo.BattleVO;
	import leo.proxy.transmission.LoaderUtil;
	import leo.proxy.vo.BaseUI;

	/
	 * 战斗列表UI 
	 * @author Leo
	 * 
	 */	
	public class UIBattleList extends UILoadingBase
	{
		public static var I :UIBattleList;
		public var btnClose :SimpleButton;
		public var itemList :Vector.
            
  
            
            
            
            
            
              ; public var btnLeft :SimpleButton; public var btnRight :SimpleButton; public var txtPage :TextField; public function UIBattleList(baseUI:BaseUI) { if(!baseUI) { baseUI = new BaseUI("BattleList","BattleList"); } super(baseUI); } override protected function swfLoadComplete():void { super.swfLoadComplete(); if(!content) { return; } this.itemList = new Vector. 
             
               (); binding(content,itemList,UIBattleListItem); btnClose = content.btnClose; this.btnLeft = content.btnLeft; this.btnRight = content.btnRight; this.txtPage = content.txtPage; data = []; var list :Dictionary = LoaderUtil.I.battleVOList; for (var key :* in list) { var vo :BattleVO = list[key] as BattleVO; if(vo) { data.push(vo); } } var index :int = 0; for each(var item :UIBattleListItem in itemList) { if(data[index]) { item.data = data[index]; }else { item.data = null; } index++; } addEventListener(MouseEvent.MOUSE_UP,mouseHandler); I = this; } private function mouseHandler(e :MouseEvent):void { trace("btn_close========"); switch(e.target) { case this.btnClose: trace("btn_close"); destroy(); break; case this.btnLeft: trace("left"); break; case this.btnRight: trace("right"); break; } } override public function destroy():void { super.destroy(); removeEventListener(MouseEvent.MOUSE_UP,mouseHandler); unBinding(itemList); if(this.parent) { this.parent.removeChild(this); } I = null; if(GameConst.main) { GameConst.main.show(); } } } } 
              
            

binding(content,itemList,UIBattleListItem);绑定了数据和战斗播放按钮,super.swfLoadComplete();调用了父类的方法中的content = BitmapUtil.I.getMCByName(baseUI.linkName);

package leo.view.ui
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	
	import leo.controller.util.LayerUtil;
	import leo.proxy.GameConst;
	import leo.proxy.battles.vo.BattleVO;
	import leo.proxy.vo.BaseUI;

	/
	 * 战役列表子项 
	 * @author Leo
	 * 
	 */	
	public class UIBattleListItem extends SimpleButton
	{
		public var txtBattleName :TextField;
		public var txtBattleContent :TextField;
		public var txtBattleAward :TextField;
		public var mcContent :MovieClip;
		public var btnShow :SimpleButton;
		private var mc :MovieClip;
		private var _data :BattleVO;
		public function UIBattleListItem(mc :* = null)
		{
			if(mc)
			{
				this.mc = mc;
				this.txtBattleAward = mc.txtBattleAward;
				this.txtBattleContent = mc.txtBattleContent;
				this.txtBattleName = mc.txtBattleName;
				this.mcContent = mc.mcContent;
				this.btnShow = mc.btnShow;
				
				mc.addEventListener(MouseEvent.MOUSE_OVER,mouseHandler);
				mc.addEventListener(MouseEvent.MOUSE_OUT,mouseHandler);
				mc.addEventListener(MouseEvent.MOUSE_UP,mouseHandler);
			}
			super();
		}
		
		private function mouseHandler(e :MouseEvent):void
		{
			switch(e.type)
			{
				case MouseEvent.MOUSE_OVER:
					if(this.mcContent)
					{
						this.mcContent.filters = GameConst.MOUSE_ON;
					}
					break;
				case MouseEvent.MOUSE_OUT:
					if(this.mcContent)
					{
						this.mcContent.filters = null;
					}
					break;
				case MouseEvent.MOUSE_UP:
					switch(e.currentTarget)
					{
						case this.mc:
						case this.btnShow:
							show();
					}
					break;
			}
			
		}
		
		private function show():void
		{
			if(UIBattleList.I)
			{
				UIBattleList.I.destroy();
			}
			trace("开始播放战役");
			
			if(data)
			{
				var view :UIBattleView = new UIBattleView(data);
				LayerUtil.I.layerDict[UIBattleView.NAME] = view;
				GameConst.main.setStage(view);
			}
			
			if(GameConst.main)
			{
				GameConst.main.hide();
			}
		}

		public function get data():BattleVO
		{
			return _data;
		}

		public function set data(vo:BattleVO):void
		{
			_data = vo;
			
			if(vo == null)
			{
				this.mc.visible = false;
				return;
			}
			
			this.txtBattleName.text = vo.battleInfoVO.name;
			this.txtBattleContent.htmlText = "经验: " + "" + vo.battleInfoVO.exp + "" + "     " +
											"金币: " + "" + vo.battleInfoVO.gold + "" + "     " +
											"物品: " + "" + vo.battleInfoVO.itemID + "";
		}
		
		public function destroy():void
		{
			mc.addEventListener(MouseEvent.MOUSE_OVER,mouseHandler);
			mc.addEventListener(MouseEvent.MOUSE_OUT,mouseHandler);
			mc.addEventListener(MouseEvent.MOUSE_UP,mouseHandler);
			mc = null;
			txtBattleName = null;
			txtBattleContent = null;
			txtBattleAward = null;
			mcContent = null;
			btnShow = null;
		}
		

	}
}

mc.addEventListener(MouseEvent.MOUSE_OVER,mouseHandler);
mc.addEventListener(MouseEvent.MOUSE_OUT,mouseHandler);
mc.addEventListener(MouseEvent.MOUSE_UP,mouseHandler);

鼠标按下时show方法

今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗


package leo.view.ui
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import ghostcat.manager.SoundManager;
	
	import leo.controller.util.BitmapUtil;
	import leo.controller.util.LayerUtil;
	import leo.controller.util.PlayerUtil;
	import leo.controller.util.RoleManage;
	import leo.proxy.GameConst;
	import leo.proxy.battles.action.BaseBattleAction;
	import leo.proxy.battles.action.IBattleAction;
	import leo.proxy.battles.vo.BattleVO;
	import leo.proxy.transmission.LoaderUtil;
	import leo.proxy.vo.BaseUI;
	import leo.proxy.vo.RoleAssetsVO;
	import leo.view.role.MapObject;
	
	/
	 * 战斗视图层 
	 * @author Leo
	 * 
	 */	
	public class UIBattleView extends Sprite
	{
		public static const NAME :String = "UIBattleView";
		public var battleMap :UIBattleMap;
		public var battlePlace :UIBattlePlace;
		public var battleRoleLayer :UIBattleRoleLayer;
		public var btnStartBattle :SimpleButton;
		public var btnExitBattle :SimpleButton;
		
		public  var battleVO :BattleVO;
		private var timer :Timer;
		public function UIBattleView(battleVO :BattleVO)
		{
			this.battleVO = battleVO;
			super();
			
			if(!this.battleVO)
			{
				return;
			}
			if(stage)
			{
				init();
			}else
			{
				addEventListener(Event.ADDED_TO_STAGE,init);
			}
			
		}
		
		private function init(e :* = null):void
		{
			
			removeEventListener(Event.ADDED_TO_STAGE,init);
			this.battleMap = new UIBattleMap(this.battleVO.battleInfoVO.battleMapID);
			this.addChild(this.battleMap);
			
			this.battlePlace =  new UIBattlePlace();
			this.addChild(this.battlePlace);
			
			this.battleRoleLayer = new UIBattleRoleLayer(this.battleVO,battlePlace);
			this.addChild(this.battleRoleLayer);
			
			this.btnExitBattle = BitmapUtil.I.getBtnByName("BtnExitBattle");
			if(this.btnExitBattle)
			{
				this.addChild(this.btnExitBattle);
				this.btnExitBattle.x = stage.stageWidth - 150;
				this.btnExitBattle.y = stage.stageHeight - 70;
			}
			this.btnStartBattle = BitmapUtil.I.getBtnByName("BtnStartBattle");
			if(this.btnStartBattle)
			{
				this.addChild(this.btnStartBattle);
				this.btnStartBattle.x = stage.stageWidth - 250;
				this.btnStartBattle.y = stage.stageHeight - 70;
			}
			
			this.timer = new Timer(30);
			this.timer.addEventListener(TimerEvent.TIMER,timerHandler);
			this.timer.start();
			
			addEventListener(MouseEvent.MOUSE_UP,clickHandler);
			
			//播放战斗音乐
			PlayerUtil.I.playBattleMusic();
		}
		
		private function clickHandler(e :MouseEvent):void
		{
			switch(e.target)
			{
				case this.btnExitBattle:
					trace("退出战斗");
					destroy();
					break;
				case this.btnStartBattle:
					trace("开始战斗");
					startBattle();
					this.btnStartBattle.visible = false;
					break;
			}
		}
		/
		 * timer更新显示对象 
		 * @param e
		 * 
		 */		
		private function timerHandler(e :TimerEvent):void
		{
			var list :Vector.
                 
  
                 
                 
                 
                 
                 
                   = RoleManage.I.roleList; if(!list || list.length == 0) { return; } for each(var mapObj :MapObject in list) { mapObj.update(); } PlayerUtil.I.update(); } / * 开始战役 */ private function startBattle():void { PlayerUtil.I.playBattle(this.battleVO.actions); } / * 销毁 * */ public function destroy():void { removeEventListener(MouseEvent.MOUSE_UP,clickHandler); this.timer.stop(); this.timer.removeEventListener(TimerEvent.TIMER,timerHandler); this.timer = null; RoleManage.I.destroyRoleObj(); PlayerUtil.I.resetAction(); delete LayerUtil.I.layerDict[UIBattleView.NAME]; if(this.parent) { this.parent.removeChild(this); } if(GameConst.main) { GameConst.main.show(); } PlayerUtil.I.stopBattleMusic(); } } } 
                 

private function startBattle():void{}方法中PlayerUtil.I.playBattle(this.battleVO.actions);

package leo.controller.util
{
	import flash.geom.Point;
	
	import ghostcat.manager.SoundManager;
	
	import leo.proxy.battles.action.BaseBattleAction;
	import leo.proxy.battles.vo.AddObjectVO;
	import leo.view.role.MapObject;
	import leo.view.ui.UIBattleResult;
	import leo.view.ui.UIBattleView;

	/
	 * 播放器工具 
	 * @author Leo
	 * 
	 */	
	public class PlayerUtil
	{
		private static var _I :PlayerUtil = null;
		/
		 * 开始播放 
		 */		
		private var start :Boolean = false;
		/
		 * 当前正在播放的动作 
		 */		
		private var curAction :BaseBattleAction;
		/
		 * 当前播放的序列 
		 */		
		private var curIndex :int;
		/
		 * 需要播放的列表 
		 */		
		private var actionList :Array;
		public function PlayerUtil(prv :PrivateClass)
		{
		}
		/
		 * 开始播放战斗 
		 * @param actionList
		 * 
		 */		
		public function playBattle(actionList :Array):void
		{
			if(!actionList || actionList.length == 0)
			{
				return;
			}
			this.actionList = actionList;
			this.curIndex = 0;
			this.start = true;
			curAction = actionList[curIndex];
			curAction.exec();
			
		}
		/
		 * 更新播放序列
		 * 
		 */		
		public function update ():void
		{
			if(!start || !this.actionList || this.actionList.length == 0)
			{
				return;
			}

			
			if(curAction.allActionFinish)
			{
				this.curIndex++;
				if(this.curIndex > this.actionList.length - 1)
				{
					//播放完成,战斗结束
					this.start = false;
					resetAction();
					winOrlose();
					return;
				}
				this.curAction = this.actionList[this.curIndex];
				this.curAction.exec();
			}
			
		}
		/
		 * 获取近身攻击后人物返回的点 
		 * @param fireObj
		 * @return 
		 * 
		 */		
		public function getGoBackPoint(fireObj :MapObject):Point
		{
			var battleView :UIBattleView = LayerUtil.I.layerDict[UIBattleView.NAME] as UIBattleView;
			var home :Boolean = fireObj.addObjVO.roleType == AddObjectVO.TYPE_HERO ? true : false;
			var p :Point = battleView.battlePlace.getPlacePosition(fireObj.addObjVO.place,home);
			
			return p;
		}
		/
		 * 停止战斗音乐
		 */		
		public function stopBattleMusic():void
		{
			//停止战斗音乐
			SoundManager.instance.stop("BattleMusic");
		}
		/
		 * 播放战斗音乐
		 */		
		public function playBattleMusic():void
		{
			//停止战斗音乐
			SoundManager.instance.play("BattleMusic",-1);
		}
		/
		 * 播放受伤音乐
		 */		
		public function playHurtMusic():void
		{
			SoundManager.instance.play("HurtMusic");
		}
		/
		 * 播放技能效果音乐
		 */		
		public function playSkillMusic():void
		{
			SoundManager.instance.play("SkillMusic");
		}
		/
		 * 重置战斗命令 
		 * 
		 */		
		public function resetAction():void
		{
			for each(var baseBattleAction :BaseBattleAction in this.actionList)
			{
				if(baseBattleAction.allActionFinish)
				{
					baseBattleAction.allActionFinish = false;
				}
				
				if(baseBattleAction.queue)
				{
					baseBattleAction.queue.halt();
				}
			}
		}
		
		private function winOrlose():void
		{
			var roleList :Vector.
                  
  
                  
                  
                  
                  
                  
                    = RoleManage.I.roleList; var result :Boolean = false; for each(var mapObj :MapObject in roleList) { if(mapObj && mapObj.isAlive) { if(mapObj.addObjVO.roleType == AddObjectVO.TYPE_HERO) { result = true; break; } } } var uiBattleView :UIBattleView = LayerUtil.I.getLayer(UIBattleView.NAME) as UIBattleView; if(uiBattleView) { if(result) //战斗胜利 { uiBattleView.battleRoleLayer.addChild(new UIBattleResult(true)); }else // 战斗失败 { uiBattleView.battleRoleLayer.addChild(new UIBattleResult(false)); } }else { trace("PlayerUtil 战斗UI查找出错"); } } public static function get I():PlayerUtil { if(_I == null) { _I = new PlayerUtil(new PrivateClass()); } return _I; } } } class PrivateClass{} 
                  

private function winOrlose():void{}来获得战斗结果,最后交由

	var uiBattleView :UIBattleView = LayerUtil.I.getLayer(UIBattleView.NAME) as UIBattleView;
			if(uiBattleView)
			{
				if(result)  //战斗胜利
				{
					uiBattleView.battleRoleLayer.addChild(new UIBattleResult(true));
				}else   // 战斗失败
				{
					uiBattleView.battleRoleLayer.addChild(new UIBattleResult(false));
				}
			}else
			{
				trace("PlayerUtil 战斗UI查找出错");
			}

上面只是走了一遍基本流程,整个战斗系统相对庞大(这里就不都贴出来了,不是我的作品,开源别人的东西不道德),需要源码的小伙伴私信给我就好。我们看下战斗效果。 今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗 今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗 今天开始做战斗,回合制战斗代码实现第二篇,九宫格战斗






















版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228812.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午6:08
下一篇 2026年3月16日 下午6:09


相关推荐

  • Samsung_tiny4412(驱动笔记10)—-mdev,bus,device,driver,platform「建议收藏」

    Samsung_tiny4412(驱动笔记10)—-mdev,bus,device,driver,platform「建议收藏」|一.预热文章:|二.mdev原理及配置:|三.busdevicedriver接口:|四.platformbus

    2022年7月1日
    27
  • 云端呼叫中心坐席并发测试结果[通俗易懂]

    云端呼叫中心坐席并发测试结果[通俗易懂]很久没有写关于asterisk压力测试的相关文章了。今晚终于可以抽一点时间来写点东西,跟大家来分享一下。以下是本人最近开发的一套云端虚拟坐席租用系统,历经半年时间的实现和优化。          在近段时间,云端服务器是一个比较很热门话题,并且很大程度上综合硬件的资源的,节约成本的同时,还有的好处就是简化服务器部署的难度和时间。其他关于云端服务的其他好处,在此不必多说了,大家可以参考一

    2022年7月12日
    26
  • 第一个微信小程序的诞生

    第一个微信小程序的诞生开发小程序的第一步 你需要拥有一个小程序帐号 通过这个帐号你就可以管理你的小程序 跟随这个教程 开始你的小程序之旅吧 进入小程序注册页根据指引填写信息和提交相应的资料 注意邮箱是没有被微信号或者公众号绑定 如果绑定了可以解绑就可以使用 下一步 邮箱激活账号信息填写完进入邮箱激活 需要到邮件里面验证登录使用电脑登录邮箱 我这里是网易邮箱 可使用 步骤一样最后一步 信息登记 就可以拥有自己的小程序帐号 手机微信为管理员扫描二维码在这个小程序管理平台 你可以管理你的小程序的权限 查看数据报表 发布小程序等操

    2026年3月19日
    2
  • Java中数字的四舍五入和取整

    Java中数字的四舍五入和取整Java中对数字进行四舍五入或取整处理经常使用Math库中的三个方法:ceilfloorround1ceil向上取整ceil英文释义:天花板。天花板在上面,所以是向上取整,好记了。Math.ceil函数接收一个double类型的参数,用于对数字进行向上取整(遇小数进1),即返回一个大于或等于传入参数的最小整数(但还是以double类型返回)。2floor向下取整floor英文释义:地板。地板在下面,所以是向下取整,好记了。Math.floor函数接收一个double

    2022年7月7日
    23
  • JVM性能调优

    JVM性能调优1、JVM调优目标:使用较小的内存占用来获得较高的吞吐量或者较低的延迟。程序在上线前的测试或运行中有时会出现一些大大小小的JVM问题,比如cpuload过高、请求延迟、tps降低等,甚至出现内存泄漏(每次垃圾收集使用的时间越来越长,垃圾收集频率越来越高,每次垃圾收集清理掉的垃圾数据越来越少)、内存溢出导致系统崩溃,因此需要对JVM进行调优,使得程序在正常运行的前提下,获得更高的用户体验和运行…

    2022年6月11日
    36
  • 技术总结|十分钟了解Git的Worktree

    技术总结|十分钟了解Git的Worktree

    2026年3月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号