SRPG游戏开发(三十九)第九章 战斗系统 - 一 战斗属性(Combat Properties)
返回总目录
第九章 战斗系统(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)相关推荐
- 陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十九讲:apache+php+mysql开发环境搭建(wamp)
陈力:传智播客古代 珍宝币 泡泡龙游戏开发第十九讲:apache+php+mysql开发环境搭建(wamp) window环境下进行网站建设时,必须要进行wamp环境的搭建.本文介绍了如果配置apac ...
- SRPG游戏开发(四十)第九章 战斗系统 - 二 计算战斗数据(Calculate Combat Data)
返回总目录 第九章 战斗系统(Combat System) 在SRPG中,大多数情况是指角色与角色之间的战斗.而这种战斗一般有两种模式: 地图中直接战斗: 有专门的战斗场景. 这两种模式的战斗在数据上 ...
- 【Visual C++】游戏开发笔记十九 DirectX与OpenGL的博弈
From: http://blog.csdn.net/zhmxy555/article/details/7522960 本系列文章由zhmxy555(毛星云)编写,转载请注明出处. http://bl ...
- SRPG游戏开发(二)第一章 FE4部分技术简述
返回目录 第一章 FE4部分技术简述 本章节主要记录在开发FE4时,分析Rom的内容.我们从进入游戏后所见的顺序进行简述,详细的内容到开发时再谈论. 一 不再阐述的常用系统 这个部分的系统在所有 ...
- 【Visual C 】游戏开发笔记十九 DirectX与OpenGL的博弈
分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 本系列文 ...
- 【IOS-COCOS2D游戏开发之十九】游戏数据存储的四种常用方式NSKEYEDARCHIVER/NSUSERDEFAULTS/WRITE写入/SQLITE3...
本站文章均为 李华明Himi 原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2d/513.html ...
- SRPG游戏开发(十)第五章 颜色映射与职业动画 - 二 颜色组(Color Chart)
返回目录 第五章 颜色映射与职业动画 二 颜色组(Color Chart) 颜色组是保存许多颜色的一个容器,可以在Swapper中直接创建List<Color>或Color[] ...
- SRPG游戏开发(十六)第六章 基本框架 - 一 本章简介(Introduction)
返回总目录 第六章 基本框架(Framework) 这一章主要编写各个游戏都有的基本框架. 关于源码.打包好的dll文件还没有上传,如何使用它们的Example工程也没有上传. 先来介绍一下源码的各个 ...
- Minecraft 1.12.2模组开发(三十九) 反应器(TileEntity方块实体)
说到方块实体(TileEntity),可以理解为一种功能性方块,比如熔炉,箱子,附魔台等. 我们今天来做一个类似于熔炉的反应器 熔炉逻辑: 放入燃料-> 放入物品 -> 获取产出物品 1. ...
最新文章
- Java 异步与同步的区别
- tensorflow intel platform 优化
- 设计模式----组合模式UML和实现代码
- 如何获取有性能问题的SQL
- 基于IndRNN的手机传感器动作识别
- jMeter CSV Data set config 的 sharing mode 和 Thread group loop 配合使用
- vba 当前文件名_值得学习和珍藏的VBA常用编程代码语句
- win7系统应用程序安装不了的解决教程
- nsqlookupd:高性能消息中间件 NSQ 解析
- 【IDEA】idea 运行测试类报错 Failed to resolve org.junit.platform:junit-platform-launcher:1.5.2
- Words For Today [2011-07-31]
- 二层、三层、四层交换的比较
- 如何编译Android的kernel,如何下载并编译Android 4.0内核源码Goldfish(图文)
- 163等各种邮箱端口号设置
- 嵌入式设备引入机器学习:有eIQ就够了!
- 【关于四足机器人那些事】足端轨迹规划-复合摆线轨迹
- java打包跳过test_maven打包如何跳过测试操作的?
- Jquery获取选中复选框的值(checkBox)
- Windows 11系统映像恢复到新硬盘的3种方式
- 【重磅推荐】【monero-node-rpcWallet】完美解决节点和RPCWallet同步,并且100%可以正常打开Wallet的方案【附加常见错误汇总】