dasasdhba 发表于 2022-6-18 16:50:05

飞龟新增预览,调整探照灯预览,完成炮台和跟踪炮台,完成水面

dasasdhba 发表于 2022-6-18 21:39:38

完成四色飞鱼和游鱼生成器

dasasdhba 发表于 2022-6-19 15:21:54

完成时间100单位提醒,增加晃屏功能,完成石盾、布布鬼、花瓣探照灯

dasasdhba 发表于 2022-6-20 18:45:22

本帖最后由 dasasdhba 于 2022-6-23 21:15 编辑

完成刺猬云,法礼云

dasasdhba 发表于 2022-6-23 21:15:04

完成锤子龟,火球龟,甜菜龟

dasasdhba 发表于 2022-6-26 17:16:39

完成音乐系统和无敌星

dasasdhba 发表于 2022-6-26 21:31:46

将大部分物件的行为调整为与坐标系无关

dasasdhba 发表于 2022-6-27 16:05:39

完成岩浆,火球,乌贼,飞鱼

dasasdhba 发表于 2022-6-27 16:19:51

还差滚屏坦克移动桥弹簧CP敌人实心封顶砖通关杆子水管再整理一点素材应该就能发单关测试版了

dasasdhba 发表于 2022-6-29 16:41:17

完成滚屏系统和坦克套餐

dasasdhba 发表于 2022-6-30 23:08:23

果然每次做引擎都逃不掉跟运动实心斗智斗勇的环节((
调整和优化部分 class 的实现方法
调整玩家和敌人物理以适配运动实心
基本完成运动实心的框架

dasasdhba 发表于 2022-7-1 19:51:06

加了一些图标
完成运动实心(不包括素材)

dasasdhba 发表于 2022-7-2 17:11:34

完成弹簧和 CP
修正 godot 向量的 rotate 方法的精度问题
新增玩家挤死判定(未充分测试)

dasasdhba 发表于 2022-7-2 17:17:07

话说有没有人愿意帮我整理tileset和景物素材的(((

newlife2017 发表于 2022-7-2 17:43:27

开源吗(

dasasdhba 发表于 2022-7-3 12:31:55

newlife2017 发表于 2022-7-2 17:43
开源吗(

显然

dasasdhba 发表于 2022-7-3 21:51:42

完成马里奥/敌人实心,封顶实心,通关杆,Game Over

dasasdhba 发表于 2022-7-4 13:22:27

添加一些素材

dasasdhba 发表于 2022-7-6 18:06:58

背景和链条

dasasdhba 发表于 2022-7-8 18:18:54

完成水管,调整图层,发布单关测试版

dasasdhba 发表于 2022-7-25 18:01:00

完整版已出,不过还差一些小东西,等什么时候我要用或者如果有人急用的话我再做,完整版说明先咕着((

zqh——123 发表于 2022-7-28 19:28:30

比较好

克洛伊Prime 发表于 2022-9-7 15:29:48

dasasdhba 发表于 2022-7-25 18:01
完整版已出,不过还差一些小东西,等什么时候我要用或者如果有人急用的话我再做,完整版说明先咕着(( ...

好!!!

dasasdhba 发表于 2023-7-22 00:44:21

这段时间接触了一些 C# 面向对象开发,回看 Berry 目前的情况可以说是比较脱离正规的面向对象设计模式,姑且算是能用但我已经不忍直视了(

现在我正在考虑基于 Godot 4 C# 重构本项目。
当然,重构项目名可能会改,还没想好,但我懒得开新帖了就在这发记录好了。

顺带一提我现在动力不是很足,所以估计进度会很缓慢。

dasasdhba 发表于 2023-7-22 02:34:34

本帖最后由 dasasdhba 于 2023-7-22 02:36 编辑

姑且先写一点最近的思考再开始记录。

首先我现在觉得采用 Godot 的节点设计模式来设计 entity 并打包成 PackedScene 这样的模式是个跟开发相当冲突的模式,只是做 prototype 很快很爽。

具体理由很多很杂,我想到啥写啥了。
当一段 script 严重依赖于节点树的特定结构时,要想复用那就非常麻烦,你不得不遵循你一直以来挖下的坑。Berry 经常被这类问题所困扰,毕竟当两个 entity 有相似之处时,我当然希望能够复用,但又必须得保证特定的节点树结构,实在是很郁闷。
(如果把节点树上每个节点都看成一个 system,Berry 实际上就是耦合极其严重的情况,非常混乱。)

创建 entity 很麻烦。举例来说,我希望创建一个板栗,用这模式我就得 load("res://xxxxxx/goomba.tscn").instantiate(),当然 Berry 不是这么干的,Berry 那会是 export 一个 PackedScene 属性来实现的,但说实话还是很麻烦。后来我想了一个法子是让一个静态的 Loader 在游戏运行一开始建立一个 dict 把特定文件夹里面的文件路径和文件名之间做一个映射,有点像 game maker 那样的感觉。但说实话要是能够直接 new Goomba() 不比这爽多了。

局限于节点树难以设计继承关系。比如我想设计一个 Enemy class 来实现一些敌人的基本功能,本着 Godot 的节点设计模式我马上就发现不对劲:一般的敌人显然是得基于物理节点,但也有一些敌人比如飞乌龟是不需要的,那么问题来了,Enemy 继承谁?有人可能会指出并不需要把 Enemy class 作为一个 entity 的根节点来考虑,作为子节点也是可以的。但这样的话,这 EntityNode 恐怕只能起一个识别身份的作用,比较理想的情况下,通过 entity 是应该能得到几乎所有东西的。何况,这样搞我怎么可能实现刚才提到的 new Goomba()?再说,连这一层继承都搞不定还谈什么多重继承和多态?

不妨仔细考虑一下,要想实现 new Goomba() 到底需要什么?

可以预见的是,我们大概率会失去 Godot 方便的可视化编辑器,但也可以通过设计一些 tool 或者 spawner 来缓解这个问题。所以这个问题姑且不算作问题。

首先, Godot 游戏本身必然是基于节点树的,节点树必不可少,但我们现在希望能够通过一行 new Goomba() 就能将节点树设置好,那我们只能把树结构写在代码中了。(专门用特定 class 来封装特定 PackedScene 就算了,治标不治本属于是。)

然后,Entity class 应该在哪?我现在得出的结论是:Entity 并不需要在节点树中。具体来说,Entity 初始化的时候,把需要进 SceneTree 的节点树建立好,其自身必然建立了对这个节点树中所有节点的引用,那么接下来 Entity 就根本没必要在 SceneTree 待着了。当然,用这个想法来考虑,会发现很多东西其实都没必要进节点树,这么说可能更加准确:Entity 初始化,新建所有需要的 component,把该进节点树的安排进去,该互相稍微得知道对方一点的 components 互相联系一下。当然,component 也可能需要访问 Entity,这个可以通过 metadata 实现。

最后返回来说说 spawner 的问题,spawner 就可以专门负责新建 entity 并修改相关参数,用于编辑器使用。但也可以扩展一些功能,比如做入屏才生成,敌人复活等功能,这样考虑的话,entity 与其 spawner 也有必要建立一个联系。

至于为什么不想用 gdscript 了,我也简单说几点。
首先 gdscript 它这个每一个 *.gd 文件就代表一个 class,但我一旦想给这个 class 起个名字,它就必须得是个能在编辑器里边创建的所谓 GlobalClass。C# 就没有这个问题。

哦对了,你还必须得至少继承一个 Object 还是 RefCounted class 才行,反正就连创建一个全新的类都不行,难绷。虽然怎么说,至少得继承 RefCounted 有一些垃圾回收机制方面的考量,不过 C# 根本不需要考虑这个,笑死。

再说说 C# 相比 gdscript 有什么,就说最基本的:
namespace:管理分类 class 的神器。
partial class:一个 class 能分几个文件来写,比所有东西全塞一个文件可方便多了。
interface:规范开发的神器。(虽然说实话要用 Godot 那堆 API 的时候这东西就没法用了,也没办法。)
public private protected:虽然你说 gdscript 全 public 好像也没什么问题,但这东西有总归比没有要好很多。

要是说更基本的,说实话 class 能方便的命名和分类就已经赢 gdscript 太多了。gdscript 做全局的一些东西动不动就要搞 Singleton,虽然前段时间终于出了个 static var 但总归访问起来还是麻烦。C# 这边直接在某个 namespace 里面搞个 class,然后 class 里面搞 static 成员就完事,别的地方要用 using 一下 namespace 的事情。

这还只是最基本的,我且不说 C# namespace System 这里面都有不少有用的东西,甚至我还能去找 nuget package 用。而且就拿自定义数据结构这事来说,C# 是真比 gdscript 方便多了。

哦对了,coding 和 debug 一定要用 vs,coding 不用可能还好,debug 你要是用 Godot,那报错信息基本没法看的。至于 vs debug 有多好用,我就不说了。(这边推荐 vs2022,毕竟 godot4 目前好像是 .net6,还是比较新的。)

当然你说 C# 有什么缺点,那我觉得主要是看 Godot API 文档不太舒服,毕竟人家文档就只是给 gdscript 写的。

不过我的重构项目并不打算纯 C#,偶尔拿 gdscript 做点 editor tool 也挺省事,反正它们又不会在实际游戏中运行。

囿里有条小咸鱼 发表于 2023-7-22 14:39:21

本帖最后由 电童·Isamo 于 2023-7-22 20:45 编辑

dasasdhba 发表于 2023-7-22 02:34
姑且先写一点最近的思考再开始记录。

首先我现在觉得采用 Godot 的节点设计模式来设计 entity 并打包成 Pa ...
说实话,Godot Mono自带的C#编辑器也是依托答辩,所以vs coding还是有必要的
C#唯一比较不太舒服的就是每次改完代码都得在godot里build一次,而且build一次还要停个五六秒(当然不同电脑性能build速度不同,具体还是看自己电脑的实际情况),如果官方能出热build功能我觉得还是比较舒服的

dasasdhba 发表于 2023-7-25 01:09:42

简单记录一下目前的进度。


底层:
抽象类 Entity2D,Spawner2D 基本功能设计
EntityContainer 类继承 RefCounted 用于包装 Enitiy2D 以达到与 Godot.Variant 兼容
StateMachine 类以及需要继承实现的 State 抽象类用于实现状态机


玩家:
抽象类 Player 基本功能设计
静态数据类 PlayerState 存储玩家相关信息
具象类 PlayerPlatfomer 用于完成 MF 玩家基本操作和运动(工事中):
-PlayerPlatfomerMovement 类基于 CharacterBody2D 为根节点
--Walk 相关的函数已完成,但是目前计划改为由 StateMachine 系统替代,后续尚需修改
--碰撞遮罩切换和玩家跳跃的 event,其中碰撞遮罩切换已由 PlayerCollisonShape 类订阅
-PlayerInput 类处理玩家基本输入
-PlayerInputPlatfomer 类额外处理相对重力方向(UpDirection)的方向键输入
-PlayerCollisonShape 类处理玩家两类状态的碰撞遮罩及其切换


泛型类 PlayerPlatfomerSpawner<T> 用于生成玩家(尚未配置参数)


Utils:
Meta 类用于辅助节点与 Enitiy2D 的绑定。
View 类用于快速计算是否在屏内等信息。


Asset:
Texture2DHolder,SpriteFramesHolder,AudioSreamHolder 用于辅助加载相关 Asset


Godot plugin Code Generator 自动检测文件系统变化并基于 res://assets/ 中的相关资源自动生成以资源文件名(格式化为 C# 命名风格)为类名的基于上述 Holder 的 class 并写入 cs 文件(目前是单线程,可能会卡编辑器,之后考虑尝试改为多线程)


还有一些刚新建类但还没开始搞的:
PlayerPlatfomerMario,基于 PlayerPlatfomer,应当后续开发抽象动画组件类并实现具象 Mario 动画组件类并接入至此


AudioStreamManager 组件类用于辅助播放音效,尚未想到合适的实现方式,有以下几个矛盾:
1. 是否需要同时支持 AudioSreamPlayer 与 AudioStreamPlayer2D?如果需要,使用泛型类是否更合适?
2. AudioStream 资源是否需要预加载?如果预加载,采用何种标识方式?
3. AudioStreamPlayer 节点是否需要预生成?如果预生成,数量不够用的时候怎么办?
4. 当与其相连接的 Entity free 掉之后,一次性音效何时释放容易处理,但循环播放的音效应当如何处理?

dasasdhba 发表于 2023-7-26 00:07:19

用 C# 多线程重构了 Code Generator,稳定性和性能应该会好一些。

dasasdhba 发表于 2023-7-27 01:27:08

做了 AudioStreamManager 类用于播放音效(音乐相对全局一点可能需要另开静态成员来搞),播放的 API 暂时基于 AudioStreamPlayer 和 AudioStreamPlayer2D,即时创建播完即释放,不知性能如何。
做了一半基于 ShapeCast2D 组的重叠测试类(做成组是因为 CollisionObject2D 可以有很多碰撞遮罩,我希望找到一个能与其“同步”的结构),比较纠结不同 ShapeCast2D 报告了相同的碰撞的情况应该怎么处理才比较高效,毕竟去判断 arr 里面有没有当前结果会比较浪费性能。(其实 AddException 值得考虑,但这样好像还是 O(n^2) 的复杂度,虽然没什么操作在里边。)
或者说能不能不基于 ShapeCast2D,也值得考虑,首先 PhysicsBody2D 的 TestMove 不太满足要求,只有布尔信息;MoveAndCollide 加上 test only 参数倒是可以考虑,只是有点浪费,毕竟我只需要重叠信息。基于 Area2D 不是很有可能,不能实时更新是硬伤。
现在也在考虑 collision mask 和 collision layer 这俩玩意根据不同实体分类搞几个静态常量存着,不然不太方便,问题在于怎么个分类法以及图层怎么个分法。

dasasdhba 发表于 2023-7-27 22:31:18

放弃 ShapeCast2D 组,以 PhysicsDirectSpaceState2D.IntersectShape() 为基本 API 封装了 Overlap2D 类用于快速重叠测试,并基于此扩展了能够类似 CollisionObject2D 拥有多个 shape 的抽象类 OverlapManager2D
具体实现了能够直接使用 CollisionShape2D 为 shape 的 OverlapCollisionObject2D,使用自建的 OverlapShape2D 为 shape 的 OverlapObject2D,以及通过指定一特定 CollisionObject2D 并直接使用其 shape 的 OverlapCollisionSync2D(这个估计最常用)
上述提到的都是不基于节点的类,方便起见,为 OverlapObject2D,OverlapShape2D,以及 OverlapCollisionSync2D 做了 GlobalClass 节点封装。(没有做 OverlapCollisionObject2D 的封装,因为没什么必要,而且编辑器还会警告 CollsionShape2D 必须得放在 CollisionObject2D 下面,乐。)虽然我感觉这些封装后的节点类我大概率不会用上太多,毕竟按目前的设计模式节点树并不是必要的,但也许有的东西可以直接以此为根节点,比如说一些只需要去碰撞别人不需要别人来碰撞自己的东西。
页: 1 [2] 3
查看完整版本: 【Godot】Mario Forever Berry Editor 工程记录帖