SRPG游戏开发(六十三)第十一章 地图动作与地图事件 - 十二 完善地图信息与测试(Perfect MapEventInfo and Testing)
返回《SRPG游戏开发》导航
第十一章 地图动作与地图事件(Map Action and Map Event)
我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制。
我们这一章来完成地图上的操作,地图的操作将全部由MapAction
控制。
文章目录
- 第十一章 地图动作与地图事件(Map Action and Map Event)
- 十二 完善地图信息与测试(Perfect MapEventInfo and Testing)
- 1 完善地图信息(Perfect MapEventInfo)
- 1.1 地图开始事件(Map Start Event)
- 1.2 地图结束事件(Map End Event)
- 1.3 胜利结果(Win Result)
- 1.4 地图信息(Map Event Info)
- 2 测试(Testing)
- 2.1 地图信息与地图剧本(Map Event Info and Map Script)
- 2.2 测试剧情剧本(Test Script)
- 2.3 测试结果(Testing Result)
- 2.4 测试完整代码(Testing Code)
十二 完善地图信息与测试(Perfect MapEventInfo and Testing)
我们来测试我们的成果。
1 完善地图信息(Perfect MapEventInfo)
首先,我们先来完善一下地图信息。
我们之前将所有的地图事件都放在了一起,在这里,我们将地图开始和地图结束的事件分开。
1.1 地图开始事件(Map Start Event)
这个事件是在读取地图时触发的。且它没有条件,是直接触发,且只触发一次。
我们在CanTrigger
中,让它直接返回true
,这样就直接屏蔽了条件。
我们单独建立一个类:
using System;namespace DR.Book.SRPG_Dev.ScriptManagement
{[Serializable]public class MapEventNoCondition : MapEvent{public override bool CanTrigger(MapAction action){if (!onlyonce){onlyonce = true;}return true;}}
}
1.2 地图结束事件(Map End Event)
这个事件是在地图结束时触发的。无论它触发什么事件,在结尾都应该触发WinResult
或者是LoseResult
,同样它们只能触发一次。
所以这个事件,我们添加它们:
using System;
using System.Collections;
using System.Xml.Serialization;namespace DR.Book.SRPG_Dev.ScriptManagement
{[Serializable]public class MapEventWinLose : MapEvent{[XmlElement("WinResult", typeof(WinResult))][XmlElement("LoseResult", typeof(LoseResult))]public Result resultTrigger;public override bool CanTrigger(MapAction action){if (!onlyonce){onlyonce = true;}return base.CanTrigger(action);}public override IEnumerator Trigger(MapAction action, Action<MapEvent> onTriggered = null, Action<string> onError = null){// 触发过了if (isTriggered){yield break;}// 是否满足所有触发条件if (!CanTrigger(action)){yield break;}// 触发事件if (triggers != null && triggers.Count != 0){int i = 0;while (i < triggers.Count){Result trigger = triggers[i++];if (trigger == null){continue;}if (!trigger.Trigger(action)){if (onError != null){onError(string.Format("MapEvent {0} -> Event Trigger error.", id));}isTriggered = true;yield break;}do{yield return null;} while (action.status != ActionStatus.WaitInput);}}if ((resultTrigger == null)|| (resultTrigger.type != MapEventResultType.WinResult && resultTrigger.type != MapEventResultType.LoseResult)|| (!resultTrigger.Trigger(action))){if (onError != null){onError(string.Format("MapEventWinLose {0} -> Event Trigger error.", id));}isTriggered = true;action.MapEndCommand(-1);yield break;}// 如果只能触发一次,则设置触发过事件了if (onlyonce){isTriggered = true;}if (onTriggered != null){onTriggered(this);}}}
}
1.3 胜利结果(Win Result)
我们结束地图的事件是可以有多个分支,
例如胜利条件有多种:
到达某地
杀死某个角色
失败条件类似,也可以有多种。
我们在这里规定失败时的参数就是-1,而胜利可以有多种状态。在剧本中,判断就可以有多种选择。
例如
battle Stage0Scene map0;if Stage0Scene == 1 goto #Stage0WinPos;if Stage0Scene == 2 goto #Stage0WinRole;// othergoto #Stage0Lose;
所以我们的胜利结果需要一个参数:
[Serializable]public class WinResult : Result{[XmlAttribute]public int result;public sealed override MapEventResultType type{get { return MapEventResultType.WinResult; }}public override bool Trigger(MapAction action){action.MapEndCommand(result);return true;}}
提示:加入参数后,可以不使用LoseResult
(它显得多余了),只使用WinResult
。
1.4 地图信息(Map Event Info)
类似于胜利结果,状态有多种,所以我们也可能有多个胜利结果。
using System;
using System.Xml.Serialization;namespace DR.Book.SRPG_Dev.ScriptManagement
{[Serializable]public class MapEventInfo{// 省略其它参数[XmlElement]public MapEventNoCondition startEvent;[XmlArray, XmlArrayItem]public MapEvent[] events;[XmlArray, XmlArrayItem]public MapEventWinLose[] resultEvents;}
}
不要忘记,在MapAction
中也要做相应的修改:
/// <summary>/// 读取事件/// </summary>/// <param name="info"></param>/// <returns></returns>private bool LoadMapEvent(MapEventInfo info){// 地图加载事件if (info.startEvent != null){if (info.startEvent.entryConditionType != MapEventConditionType.NoneCondition){info.startEvent.entryConditionType = MapEventConditionType.NoneCondition;}m_MapEvents.Add(info.startEvent);}// 地图中的事件if (info.events != null){for (int i = 0; i < info.events.Length; i++){MapEvent me = info.events[i];if (me == null){continue;}if (!m_MapEvents.Add(me)){error = string.Format("MapAction -> Load map event failure. Entry type `{0}` is not supported."+ " Or, id of map event is already exist.",me.entryConditionType);return false;}}}// 地图结束事件if (info.resultEvents != null){for (int i = 0; i < info.resultEvents.Length; i++){MapEvent me = info.resultEvents[i];if (me == null){continue;}if (!m_MapEvents.Add(me)){error = string.Format("MapAction -> Load map event failure. Entry type `{0}` is not supported."+ " Or, id of map event is already exist.",me.entryConditionType);return false;}}}// 执行地图加载事件TriggerEvents(MapEventConditionType.NoneCondition, () =>{OnChangeTurn(AttitudeTowards.Player);});return true;}
2 测试(Testing)
在测试阶段,我们可以多些一些地图的测试脚本进行测试。
2.1 地图信息与地图剧本(Map Event Info and Map Script)
最基本的脚本map0.xml
:
<?xml version="1.0" encoding="utf-8"?>
<MapEventInfo nextScene="" scenarioName="stage0"><mouseCursor prefab="MouseCursor" x="5" y="5" /><cursor>Cursor</cursor><startEvent id="0" onlyonce="true"><triggers><CreateObjectResult><ClassUnique x="5" y="5" attitudeTowards="Player" id="0" /><ClassUnique x="18" y="5" attitudeTowards="Enemy" id="1" /><ClassFollowing x="19" y="5" attitudeTowards="Enemy" id="0" level="1" items="0" /></CreateObjectResult><ScenarioResult flag="#Start" /></triggers></startEvent><resultEvents><MapEventWinLose id="10" onlyonce="true"><PositionCondition x="2" y="4" /><triggers><ScenarioResult flag="#Win" /></triggers><WinResult result="1" /></MapEventWinLose><MapEventWinLose id="20" onlyonce="true"><PositionCondition x="2" y="6" /><LoseResult /></MapEventWinLose></resultEvents>
</MapEventInfo>
地图开始事件:
创建3个角色(1个玩家,2个敌人)(2个独有角色,1个杂兵);
从剧本
stage0
的剧情标识符#Start
开始运行剧本;
地图事件:无;
地图结束事件:
到达坐标(2,4)从剧本
stage0
的剧情标识符#Win
开始运行剧本,之后战斗胜利;到达坐标(2,6)战斗失败。
这里只是举了个例子,你可以自己编写条件,并尝试更多的条件与结果。
地图剧本为stage0.txt
:
// stage0.txt
// 首关#Start; // 剧本开始text top"战斗好激烈啊,我们行不行?";text bottom"没问题的,放心吧。";clear text;back;#Win;text top"我们赢了";clear text;back;
2.2 测试剧情剧本(Test Script)
同样的,我们的测试剧本test.txt
也需要修改:
// 测试剧本
// test.txt#Testing; // 测试剧本#TestMenuIfGotoCmd;clear text;menu option"测试var、calc和debug命令""测试text命令""测试battle命令与MapAction";if option == 0 goto #TestVarCalcDebugCmd;if option == 1 goto #TestTextCmd;if option == 2 goto #TestMapAction;goto #Testing;// 省略中间剧本代码#TestMapAction;text global"3:测试MapAction:""场景:Stage0Scene;""剧本:map0。";battle Stage0Scene map0;if Stage0Scene == 1 goto #Stage0Win;goto #Stage0Lose;#Stage0Win;text global"战斗胜利";goto #TestMapActionEnd;#Stage0Lose;text global"战斗失败";goto #TestMapActionEnd;#TestMapActionEnd;text global"测试MapAction结束";goto #Testing;
2.3 测试结果(Testing Result)
我们直接在Unity中运行游戏,查看测试结果,如 图 11.12 所示。
- 图 11.12 Testing
2.4 测试完整代码(Testing Code)
修改测试代码(EditorTestGamePlot.cs
):
#region ---------- File Info ----------
/// **********************************************************************
/// Copyright (C) 2019 DarkRabbit(ZhangHan)
///
/// File Name: EditorTestGamePlot.cs
/// Author: DarkRabbit
/// Create Time: Sat, 12 Jan 2019 23:56:52 GMT
/// Modifier:
/// Module Description:
/// Version: V1.0.0
/// **********************************************************************
#endregion ---------- File Info ----------using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
#if UNITY_EDITOR
using UnityEditor;
#endifnamespace DR.Book.SRPG_Dev.ScriptManagement.Testing
{using DR.Book.SRPG_Dev.Framework;using DR.Book.SRPG_Dev.Models;public class EditorTestGamePlot : MonoBehaviour{public const string testSceneName = "TestGamePlotScene";public bool m_DebugInfo = true;public string m_TestScript = "test";public bool m_IsTxt = true;#region Unity Callback
#if UNITY_EDITORprivate void Awake(){ConfigLoader.rootDirectory = Application.streamingAssetsPath + "/Config";ConfigLoader.LoadConfig(typeof(TextInfoConfig));}private void Start(){GameDirector.instance.debugInfo = m_DebugInfo;GameDirector.instance.firstScenario = m_TestScript;GameDirector.instance.firstScenarioIsTxt = m_IsTxt;SceneManager.sceneLoaded += SceneManager_sceneLoaded;SceneManager.LoadSceneAsync("InterludeScene", LoadSceneMode.Single);}private void SceneManager_sceneLoaded(Scene scene, LoadSceneMode mode){Debug.LogFormat("Load Scene: {0}.", scene.name);SceneManager.sceneLoaded -= SceneManager_sceneLoaded;if (!GameDirector.instance.LoadFirstScenario()){Debug.LogError("Load first scenario error.");EditorApplication.isPlaying = false;return;}GameDirector.instance.RunGameAction();}
#endif#endregion}
}
至此,本章内容全部完成。
SRPG游戏开发(六十三)第十一章 地图动作与地图事件 - 十二 完善地图信息与测试(Perfect MapEventInfo and Testing)相关推荐
- SRPG游戏开发(三)第二章 创建项目
返回目录 第二章 创建项目 本章开始我们来创建我们的项目,导入用到的素材. 一 创建项目 打开Unity3D,点击New按钮.这时我们看到创建项目的设置界面. 图 2 - 1创建项目 Project ...
- 《SRPG游戏开发》导航(2019.03.04更新)
<SRPG游戏开发>导航 第一章到第五章并没有使用Markdown,且经过CSDN几次改版和取消目录,这几章排版有些怪怪的. 2019.03.04 第十一章(十 - 十二) ,间章 第十一 ...
- SRPG游戏开发(六十)第十一章 地图动作与地图事件 - 九 触发事件与切换回合(Trigger Events and Change Turn)
返回<SRPG游戏开发>导航 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一 ...
- SRPG游戏开发(六十一)第十一章 地图动作与地图事件 - 十 NPC操作(NPC Control)
返回<SRPG游戏开发>导航 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一 ...
- SRPG游戏开发(五十六)第十一章 地图动作与地图事件 - 五 移动、攻击与待机(Move, Attack and Holding)
返回总目录 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一章来完成地图上的操作,地图的操 ...
- SRPG游戏开发(五十三)第十一章 地图动作与地图事件 - 二 地图剧情(Map Plot)
返回总目录 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一章来完成地图上的操作,地图的操 ...
- SRPG游戏开发(六十四)间章 第十一点五章 总结(Summary)
返回<SRPG游戏开发>导航 间章 第十一点五章 总结(Summary) 这一章,是对第十章与第十一章的一个补充性质的文章. 文章目录 间章 第十一点五章 总结(Summary) 一 说明 ...
- SRPG游戏开发(五十二)第十一章 地图动作与地图事件 - 一 初始化地图动作(Initialize Map Action)
返回总目录 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一章来完成地图上的操作,地图的操 ...
- Unity4.x 2D游戏开发基础教程第1章Unity及其组成的介绍
Unity4.x 2D游戏开发基础教程第1章Unity及其组成的介绍 本书主要讲解的是,如何使用Unity开发2D游戏.但在开始讲解之前,最好先熟悉一下Unity这个工具.本章会首先介绍Unity的下 ...
最新文章
- 使用Python,OpenCV在视频中进行实时条形码检测
- 那些年Android黑科技③:干大事不择手段
- bottle中文文档
- 只需一行代码实现增删查改,微软已经让我们很简单。谈AccessDataSource的使用。...
- 和计算机互动英语,计算机专业英语互动教学方法探讨
- 通过 pxe(网络安装)完成centos 系统的网络安装
- jQuery Ajax – Servlets集成:构建完整的应用程序
- php 安装pdo odbc,PHP PDO ODBC连接
- ubuntu 12.04安装与配置
- 基于sklearn的分类器实战
- 大华sd集成android so库,android平台上集成大华sdk
- oracle序列自增
- python 验证码识别
- 使用Spire组件抛出异常The type initializer for 'spr857' threw an exception
- 2020北京国际金融安全论坛(二)
- Testin云测如何成为传统企业转型升级的“X”因子?
- 多个PDF合并成一个PDF
- 图解迪士尼发展史:华特·迪士尼建立的动画王国
- C#程序打印AX2012的SSRS
- 同样是码农,收入差距怎么这么大呢?