返回总目录

第九章 战斗系统(Combat System)

在SRPG中,大多数情况是指角色与角色之间的战斗。而这种战斗一般有两种模式:

  • 地图中直接战斗;

  • 有专门的战斗场景。

这两种模式的战斗在数据上没有任何区别,只有战斗动画的区别。

就像之前描述的,SRPG也是RPG,所以战斗方式和回合制RPG的战斗几乎是相同的。主要区别是RPG每个回合需要手动操作(也有自动战斗的),直到战斗结束;而SRPG是自动战斗,且多数情况只有一个回合(额外回合也是由于技能、物品或剧情需要)。且RPG多数是多人战斗,而SRPG多数是每边就一个。

我们这一章就来写一个战斗系统。


文章目录

  • 第九章 战斗系统(Combat System)
    • 一 战斗属性(Combat Properties)
      • 1 角色战斗属性(Role Fight Properties)
        • 1.1 物品属性叠加(Sum of Item Properties)
        • 1.2 战斗属性(Fight Properties)
      • 2 战斗单位(Combat Unit)

一 战斗属性(Combat Properties)

战斗中需要的属性是需要从我们的角色身上获取的。

我们在这里还是拿《FE4》来举例,在《FE4》中的基础战斗属性包含:

  • 物理攻击力(attack) = 武器攻击力 + 角色力量(STR) + 道具力量

  • 魔法攻击力(mage attack) = 武器攻击力 + 角色魔力(MAG) + 道具魔力

  • 物理防御力(defence) = 角色防御(DEF) + 道具防御

  • 魔法防御力(mage defence) = 角色魔防(MDF) + 道具魔防

  • 攻速(speed) = 角色速度(SPD) + 道具速度 - 武器重量(weight)

  • 命中(hit rate) = (角色技巧(SKL) + 道具技巧) * 2 + 武器命中(hit rate)

  • 回避(avoidance) = (角色速度 + 道具速度) * 2 + 角色幸运 + 道具幸运

  • 爆击(crit):暂不考虑

  • 攻击范围(attack range):来自武器

  • 生命值(hp)与最大生命值(max hp)

了解这些后,我们来实现它们。


1 角色战斗属性(Role Fight Properties)

经过之前的分析,我们的角色需要一些战斗属性;而属性是需要计算的。而在属性中,我们需要装备的属性(装备的武器和饰品)。

1.1 物品属性叠加(Sum of Item Properties)

我们在Role类中添加计算属性叠加方法:

        /// <summary>/// 物品属性叠加/// </summary>/// <param name="type"></param>/// <returns></returns>public int GetItemFightPropertySum(FightPropertyType type){if (type == FightPropertyType.MaxLength){return 0;}int value = 0;// 如果装备武器不为null,则叠加武器属性if (equipedWeapon != null){value += equipedWeapon.uniqueInfo.fightProperties[type];}// 叠加所有饰品属性foreach (Item item in items){if (item != null && item.itemType == ItemType.Ornament){value += (item as Ornament).uniqueInfo.fightProperties[type];}}return value;}

添加Luk叠加方法:

        /// <summary>/// 物品幸运叠加/// </summary>/// <returns></returns>public int GetItemLukSum(){int value = 0;// 如果装备武器不为null,则叠加武器幸运if (equipedWeapon != null){value += equipedWeapon.uniqueInfo.luk;}// 叠加所有饰品幸运foreach (Item item in items){if (item != null && item.itemType == ItemType.Ornament){value += (item as Ornament).uniqueInfo.luk;}}return value;}

1.2 战斗属性(Fight Properties)

有了叠加属性的方法后,我们来添加战斗中需要的属性:

        /// <summary>/// 物理攻击力/// </summary>public int attack{get{if (equipedWeapon == null){return 0;}int atk = equipedWeapon.uniqueInfo.attack;atk += fightProperties[FightPropertyType.STR];atk += GetItemFightPropertySum(FightPropertyType.STR);return atk;}}/// <summary>/// 魔法攻击力/// </summary>public int mageAttack{get{if (equipedWeapon == null){return 0;}int mag = equipedWeapon.uniqueInfo.attack;mag += fightProperties[FightPropertyType.MAG];mag += GetItemFightPropertySum(FightPropertyType.MAG);return mag;}}/// <summary>/// 物理防御力/// </summary>public int defence{get{int def = fightProperties[FightPropertyType.DEF];def += GetItemFightPropertySum(FightPropertyType.DEF);return def;}}/// <summary>/// 魔法防御力/// </summary>public int mageDefence{get{int mdf = fightProperties[FightPropertyType.MDF];mdf += GetItemFightPropertySum(FightPropertyType.MDF);return mdf;}}/// <summary>/// 攻速/// </summary>public int speed{get{if (equipedWeapon == null){return 0;}int spd = fightProperties[FightPropertyType.SPD];spd += GetItemFightPropertySum(FightPropertyType.SPD);spd -= equipedWeapon.uniqueInfo.weight;return spd;}}/// <summary>/// 命中率/// </summary>public int hit{get{if (equipedWeapon == null){return 0;}int skl = fightProperties[FightPropertyType.SKL];skl += GetItemFightPropertySum(FightPropertyType.SKL);int hit = equipedWeapon.uniqueInfo.hit + skl * 2;return hit;}}/// <summary>/// 回避率/// </summary>public int avoidance{get{int spd = fightProperties[FightPropertyType.SPD];spd += GetItemFightPropertySum(FightPropertyType.SPD);int avd = spd * 2 + luk + GetItemLukSum();return avd;}}

2 战斗单位(Combat Unit)

在写战斗单位之前,我们应该先明确我们使用哪种方式进行属性变化,常用的也有两种方式:

  • 边战斗(播放战斗动画)边计算属性变化;

  • 一次性将战斗数据都计算完,然后播放战斗动画。

如果你在玩游戏时经常性的使用SL大法,你就会发现游戏使用的哪种方式。比如,在主机模拟器中的游戏,攻击战斗动画播放时你存储了信息(假设攻击力是一个范围,正常情况每次攻击力都在此范围的一个随机值),那么无论你如何提取进度最后的数据都是相同的,这就是因为数据早在播放前就计算好了。

我们这里采用一次性计算完成。而战斗单位只是保存进入战斗时双方的固定属性。由于战斗属性在战斗中需要经常性的调用,所以我们把属性存储起来,不用每次调用都重新计算一次;而且我们需要知道站位(也就是首次进攻方与防守方的位置,这在RPG中有许多位置,在SRPG中只有两个)

建立战斗属性类(CombatUnit):

using System;namespace DR.Book.SRPG_Dev.CombatManagement
{using DR.Book.SRPG_Dev.Models;using DR.Book.SRPG_Dev.Maps;public class CombatUnit : IDisposable{public MapClass mapClass { get; private set; }public Role role { get { return mapClass.role; } }/// <summary>/// 战斗中的位置/// </summary>public int position { get; private set; }/// <summary>/// 生命值/// </summary>public int hp { get; private set; }/// <summary>/// 最大生命值/// </summary>public int maxHp { get; private set; }/// <summary>/// 魔法值/// </summary>public int mp { get; private set; }/// <summary>/// 最大魔法值/// </summary>public int maxMp { get; private set; }/// <summary>/// 攻击/// </summary>public int atk { get; private set; }/// <summary>/// 魔法攻击/// </summary>public int mageAtk { get; private set; }/// <summary>/// 防御/// </summary>public int def { get; private set; }/// <summary>/// 魔法防御/// </summary>public int mageDef { get; private set; }/// <summary>/// 攻速/// </summary>public int speed { get; private set; }/// <summary>/// 命中率/// </summary>public int hit { get; private set; }/// <summary>/// 爆击率/// </summary>public int crit { get; private set; }/// <summary>/// 回避率/// </summary>public int avoidance { get; private set; }/// <summary>/// 武器类型/// </summary>public WeaponType weaponType { get; private set; }/// <summary>/// 武器耐久度/// </summary>public int durability { get; private set; }public CombatUnit(int position){this.position = position;}public bool Load(MapClass mapClass){if (mapClass == null){return false;}if (mapClass.role == null){return false;}this.mapClass = mapClass;this.hp = role.hp;this.mp = role.mp;this.maxHp = role.maxHp;this.maxMp = role.maxMp;this.atk = role.attack;this.mageAtk = role.mageAttack;this.def = role.defence;this.mageDef = role.mageDefence;this.speed = role.speed;this.hit = role.hit;//this.crit = role.crit;this.avoidance = role.avoidance;if (role.equipedWeapon == null){this.weaponType = WeaponType.Unknow;this.durability = 0;}else{this.weaponType = role.equipedWeapon.uniqueInfo.weaponType;this.durability = role.equipedWeapon.durability;}return true;}public void Dispose(){this.mapClass = null;this.position = -1;}public void ClearMapClass(){this.mapClass = null;}}
}

SRPG游戏开发(三十九)第九章 战斗系统 - 一 战斗属性(Combat Properties)相关推荐

  1. 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十九讲:apache+php+mysql开发环境搭建(wamp)

    陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十九讲:apache+php+mysql开发环境搭建(wamp) window环境下进行网站建设时,必须要进行wamp环境的搭建.本文介绍了如果配置apac ...

  2. SRPG游戏开发(四十)第九章 战斗系统 - 二 计算战斗数据(Calculate Combat Data)

    返回总目录 第九章 战斗系统(Combat System) 在SRPG中,大多数情况是指角色与角色之间的战斗.而这种战斗一般有两种模式: 地图中直接战斗: 有专门的战斗场景. 这两种模式的战斗在数据上 ...

  3. 【Visual C++】游戏开发笔记十九 DirectX与OpenGL的博弈

    From: http://blog.csdn.net/zhmxy555/article/details/7522960 本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://bl ...

  4. SRPG游戏开发(二)第一章 FE4部分技术简述

    返回目录 第一章 FE4部分技术简述 本章节主要记录在开发FE4时,分析Rom的内容.我们从进入游戏后所见的顺序进行简述,详细的内容到开发时再谈论. 一    不再阐述的常用系统 这个部分的系统在所有 ...

  5. 【Visual C 】游戏开发笔记十九 DirectX与OpenGL的博弈

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...

  6. 【IOS-COCOS2D游戏开发之十九】游戏数据存储的四种常用方式NSKEYEDARCHIVER/NSUSERDEFAULTS/WRITE写入/SQLITE3...

    本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2d/513.html ...

  7. SRPG游戏开发(十)第五章 颜色映射与职业动画 - 二 颜色组(Color Chart)

    返回目录 第五章 颜色映射与职业动画 二       颜色组(Color Chart) 颜色组是保存许多颜色的一个容器,可以在Swapper中直接创建List<Color>或Color[] ...

  8. SRPG游戏开发(十六)第六章 基本框架 - 一 本章简介(Introduction)

    返回总目录 第六章 基本框架(Framework) 这一章主要编写各个游戏都有的基本框架. 关于源码.打包好的dll文件还没有上传,如何使用它们的Example工程也没有上传. 先来介绍一下源码的各个 ...

  9. Minecraft 1.12.2模组开发(三十九) 反应器(TileEntity方块实体)

    说到方块实体(TileEntity),可以理解为一种功能性方块,比如熔炉,箱子,附魔台等. 我们今天来做一个类似于熔炉的反应器 熔炉逻辑: 放入燃料-> 放入物品 -> 获取产出物品 1. ...

最新文章

  1. Java 异步与同步的区别
  2. tensorflow intel platform 优化
  3. 设计模式----组合模式UML和实现代码
  4. 如何获取有性能问题的SQL
  5. 基于IndRNN的手机传感器动作识别
  6. jMeter CSV Data set config 的 sharing mode 和 Thread group loop 配合使用
  7. vba 当前文件名_值得学习和珍藏的VBA常用编程代码语句
  8. win7系统应用程序安装不了的解决教程
  9. nsqlookupd:高性能消息中间件 NSQ 解析
  10. 【IDEA】idea 运行测试类报错 Failed to resolve org.junit.platform:junit-platform-launcher:1.5.2
  11. Words For Today [2011-07-31]
  12. 二层、三层、四层交换的比较
  13. 如何编译Android的kernel,如何下载并编译Android 4.0内核源码Goldfish(图文)
  14. 163等各种邮箱端口号设置
  15. 嵌入式设备引入机器学习:有eIQ就够了!
  16. 【关于四足机器人那些事】足端轨迹规划-复合摆线轨迹
  17. java打包跳过test_maven打包如何跳过测试操作的?
  18. Jquery获取选中复选框的值(checkBox)
  19. Windows 11系统映像恢复到新硬盘的3种方式
  20. 【重磅推荐】【monero-node-rpcWallet】完美解决节点和RPCWallet同步,并且100%可以正常打开Wallet的方案【附加常见错误汇总】

热门文章

  1. JS中判断对象是对象还是数组
  2. conda虚拟环境路径包含系统python路径问题
  3. vivado导入tcl例程
  4. Maven的基本原理和Maven2的新特性
  5. go gin下配置https
  6. 小厂的数据分析师都需要会什么?想转行的来看看
  7. ubuntu 改屏幕分辨率命令_如何使用 命令行 更改屏幕分辨率?
  8. Python项目打包发布方法
  9. 5G催化智能经济快速崛起
  10. 电脑重启bootmgr_怎么处理开机出错提示bootmgr image is corrupt