前些时日一直在看关于软件系统复杂度还有面向数据编程、ECS的知识,有了一些理解,想尝试使用这些思想来编程。本来想自己写个卡牌游戏,但由于游戏没有设计清楚,编码的时候举步维艰。于是,我捡起之前打算使用的CCGToolkit。
在之前打算自己写卡牌游戏的时候,考虑了比如卡牌的数据结构,卡牌技能的逻辑如何组织,发现CCGToolkit的作者还是很有代码功力的。(毕竟是50刀的资源)我想使用面向数据的思维方式去架构,但在面向对象编程的框架下没有想到很好的方法,作者使用大量的data only blueprint和data table,并且灵活应用了function library已经使得系统非常得简洁了。我目前没有想到更好的方法。
虽然这套框架有许多可取之处,比如能很方便地自定义卡牌和技能(它的使用说明上,也只介绍了这两个拓展),但我在拓展“护盾”属性的时候,虽然模仿已有的“Mana”值成功实现了护盾的基本机制和表现,但感觉要理解这个过程比较费力。一个系统的复杂度很大程度上是与理解的困难度相挂钩的,越难理解,说明系统越复杂。于是我打算重构它的部分系统使得其他拓展更加方便。
这次,我们先来看看当生命值(PlayerHealth)变化时更新其表现的逻辑。
实现功能
- 桌面上,人物(敌我双方)头像右上角的血量图标,当血量发生改变时要改变数值显示,并播放简单的动画效果
(具体来说,应该就是) - 屏幕右上方和右下方的血量UI数字要随生命值的变化而变化
仅仅是简单的两个功能,不同的设计方式也会诞生出复杂度完全不同的系统。不知道简书怎么上传可以缩放的图片,就不把分析还有蓝图什么的传上来了。
原项目存在的问题
- 只改变生命值时,会调用跟生命值改变无关的逻辑。
- 玩家1的生命值改变,会调用玩家2的逻辑。
- 很深的函数调用逻辑,我们喜欢flat,扁平的结构,尽量避免函数的层层嵌套。
- 单个函数做了过多的工作,我们调用它的时候,其实只是想要其中一部分的工作。会显著提升复杂度。
- 单个状态改变触发的事件,经历了服务端->客户端->服务端,其实可以服务端->客户端。
- 在UI组件里存了player state的引用或是成员变量的副本,这是完全没必要的耦合,只要在函数参数表里加一项输入即可。
网友评论