返回《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)相关推荐

  1. SRPG游戏开发(三)第二章 创建项目

    返回目录 第二章 创建项目 本章开始我们来创建我们的项目,导入用到的素材. 一 创建项目 打开Unity3D,点击New按钮.这时我们看到创建项目的设置界面. 图 2 - 1创建项目 Project ...

  2. 《SRPG游戏开发》导航(2019.03.04更新)

    <SRPG游戏开发>导航 第一章到第五章并没有使用Markdown,且经过CSDN几次改版和取消目录,这几章排版有些怪怪的. 2019.03.04 第十一章(十 - 十二) ,间章 第十一 ...

  3. SRPG游戏开发(六十)第十一章 地图动作与地图事件 - 九 触发事件与切换回合(Trigger Events and Change Turn)

    返回<SRPG游戏开发>导航 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一 ...

  4. SRPG游戏开发(六十一)第十一章 地图动作与地图事件 - 十 NPC操作(NPC Control)

    返回<SRPG游戏开发>导航 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一 ...

  5. SRPG游戏开发(五十六)第十一章 地图动作与地图事件 - 五 移动、攻击与待机(Move, Attack and Holding)

    返回总目录 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一章来完成地图上的操作,地图的操 ...

  6. SRPG游戏开发(五十三)第十一章 地图动作与地图事件 - 二 地图剧情(Map Plot)

    返回总目录 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一章来完成地图上的操作,地图的操 ...

  7. SRPG游戏开发(六十四)间章 第十一点五章 总结(Summary)

    返回<SRPG游戏开发>导航 间章 第十一点五章 总结(Summary) 这一章,是对第十章与第十一章的一个补充性质的文章. 文章目录 间章 第十一点五章 总结(Summary) 一 说明 ...

  8. SRPG游戏开发(五十二)第十一章 地图动作与地图事件 - 一 初始化地图动作(Initialize Map Action)

    返回总目录 第十一章 地图动作与地图事件(Map Action and Map Event) 我们已经有了剧本,而且可以运行剧本,但我们还缺少对地图的操作控制. 我们这一章来完成地图上的操作,地图的操 ...

  9. Unity4.x 2D游戏开发基础教程第1章Unity及其组成的介绍

    Unity4.x 2D游戏开发基础教程第1章Unity及其组成的介绍 本书主要讲解的是,如何使用Unity开发2D游戏.但在开始讲解之前,最好先熟悉一下Unity这个工具.本章会首先介绍Unity的下 ...

最新文章

  1. 使用Python,OpenCV在视频中进行实时条形码检测
  2. 那些年Android黑科技③:干大事不择手段
  3. bottle中文文档
  4. 只需一行代码实现增删查改,微软已经让我们很简单。谈AccessDataSource的使用。...
  5. 和计算机互动英语,计算机专业英语互动教学方法探讨
  6. 通过 pxe(网络安装)完成centos 系统的网络安装
  7. jQuery Ajax – Servlets集成:构建完整的应用程序
  8. php 安装pdo odbc,PHP PDO ODBC连接
  9. ubuntu 12.04安装与配置
  10. 基于sklearn的分类器实战
  11. 大华sd集成android so库,android平台上集成大华sdk
  12. oracle序列自增
  13. python 验证码识别
  14. 使用Spire组件抛出异常The type initializer for 'spr857' threw an exception
  15. 2020北京国际金融安全论坛(二)
  16. Testin云测如何成为传统企业转型升级的“X”因子?
  17. 多个PDF合并成一个PDF
  18. 图解迪士尼发展史:华特·迪士尼建立的动画王国
  19. C#程序打印AX2012的SSRS
  20. 同样是码农,收入差距怎么这么大呢?

热门文章

  1. App启动通用流程图方案
  2. wps上下标怎么对齐_在EXCEL中,怎样将上、下标对齐?
  3. CubieBoard1【大屏计划】- 霸气平板 - 个人整合帖子【丰富】
  4. 我在拼多多这三年(转载)
  5. mysql主从和mycat读写分离的安装及验证
  6. c# spire.xls 设置文字为微软雅黑_学习 原来Excel文字排版也这样漂亮!
  7. 太全了,一线互联网大厂都在用的Android UI框架完全解析,拿去吧你
  8. 蓝牙UART和PCM接口传输的信号 硬件接口
  9. mooc国防科技大学第一单元测试
  10. Google Earth上的GeoEye数据