diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn index 294456c..1c50d95 100644 --- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn +++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0004.tscn @@ -15,6 +15,7 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 [sub_resource type="ShaderMaterial" id="ShaderMaterial_p0wfd"] resource_local_to_scene = true @@ -26,6 +27,7 @@ shader_parameter/outline_color = Color(0, 0, 0, 1) shader_parameter/outline_rainbow = false shader_parameter/outline_use_blend = true +shader_parameter/grey = 0.0 [sub_resource type="RectangleShape2D" id="RectangleShape2D_c0onq"] size = Vector2(4, 4) @@ -40,7 +42,7 @@ _data = [Vector2(0, 0.730415), 0.0, 0.0, 0, 0, Vector2(0.245238, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.0235023), 0.0, 0.0, 0, 0] point_count = 3 -[sub_resource type="CurveTexture" id="CurveTexture_uftx4"] +[sub_resource type="CurveTexture" id="CurveTexture_ie2e7"] curve = SubResource("Curve_dt320") [sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_kelfq"] @@ -54,7 +56,7 @@ gravity = Vector3(0, 0, 0) scale_min = 0.15 scale_max = 0.6 -scale_curve = SubResource("CurveTexture_uftx4") +scale_curve = SubResource("CurveTexture_ie2e7") color = Color(0.619608, 0.619608, 0.619608, 1) anim_offset_max = 1.0 diff --git a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn index ef1081d..499d04b 100644 --- a/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn +++ b/DungeonShooting_Godot/prefab/bullet/normal/Bullet0005.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=7 format=3 uid="uid://cjgnw37tqiqh7"] +[gd_scene load_steps=12 format=3 uid="uid://cjgnw37tqiqh7"] [ext_resource type="Script" path="res://src/game/activity/bullet/normal/BrushBullet.cs" id="1_13wdl"] [ext_resource type="Shader" path="res://resource/material/Blend.gdshader" id="2_v0al6"] [ext_resource type="SpriteFrames" uid="uid://jj8oh76pi53j" path="res://resource/spriteFrames/bullet/Bullet0005.tres" id="3_mmvqn"] +[ext_resource type="Texture2D" uid="uid://h7hkgbwj1li" path="res://resource/sprite/effects/common/Smoke.png" id="4_esjg6"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_v77gw"] resource_local_to_scene = true @@ -31,6 +32,34 @@ [sub_resource type="RectangleShape2D" id="RectangleShape2D_c0onq"] size = Vector2(6, 3.5625) +[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_aiome"] +particles_animation = true +particles_anim_h_frames = 3 +particles_anim_v_frames = 1 +particles_anim_loop = false + +[sub_resource type="Curve" id="Curve_5pn38"] +_data = [Vector2(0, 0.730415), 0.0, 0.0, 0, 0, Vector2(0.245238, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.0235023), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_uftx4"] +curve = SubResource("Curve_5pn38") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_ewus5"] +lifetime_randomness = 0.7 +particle_flag_disable_z = true +angle_max = 360.0 +spread = 180.0 +initial_velocity_min = 5.0 +initial_velocity_max = 15.0 +angular_velocity_max = 45.0 +gravity = Vector3(0, 0, 0) +scale_min = 0.15 +scale_max = 0.6 +scale_curve = SubResource("CurveTexture_uftx4") +color = Color(0.95, 0.70965, 0.6365, 0.392157) +anim_offset_max = 1.0 + [node name="Bullet0005" type="CharacterBody2D" node_paths=PackedStringArray("CollisionArea", "CollisionShape2D", "ShadowSprite", "AnimatedSprite", "Collision")] collision_layer = 2 script = ExtResource("1_13wdl") @@ -60,5 +89,12 @@ position = Vector2(1, 0) shape = SubResource("RectangleShape2D_c0onq") +[node name="GPUParticles2D" type="GPUParticles2D" parent="AnimatedSprite"] +material = SubResource("CanvasItemMaterial_aiome") +amount = 10 +process_material = SubResource("ParticleProcessMaterial_ewus5") +texture = ExtResource("4_esjg6") +lifetime = 0.5 + [node name="Collision" type="CollisionShape2D" parent="."] shape = SubResource("RectangleShape2D_c0onq") diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 41d4a89..f31b88b 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -248,6 +248,12 @@ /// public bool IsCustomShadowSprite { get; private set; } + /// + /// 记录绘制液体的笔刷上一次绘制的位置
+ /// 每次调用 DrawLiquid() 后都会记录这一次绘制的位置, 记录这个位置用作执行补间操作, 但是一旦停止绘制了, 需要手动清理记录的位置, 也就是将 BrushPrevPosition 置为 null + ///
+ public Vector2I? BrushPrevPosition { get; set; } + // -------------------------------------------------------------------------------- private static readonly StringName _shader_grey = "grey"; @@ -1794,4 +1800,52 @@ return _repelForce.Velocity; } + + /// + /// 根据笔刷 id 在该物体位置绘制液体, 该 id 为 LiquidMaterial 表的 id + /// + public void DrawLiquid(string brushId) + { + if (AffiliationArea != null) + { + DrawLiquid(LiquidBrushManager.GetBrush(brushId)); + } + } + + /// + /// 根据笔刷数据在该物体位置绘制液体 + /// + public void DrawLiquid(BrushImageData brush) + { + if (AffiliationArea != null) + { + var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position); + AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(brush, BrushPrevPosition, pos, 0); + BrushPrevPosition = pos; + } + } + + /// + /// 根据笔刷 id 在该物体位置绘制液体, 该 id 为 LiquidMaterial 表的 id + /// + public void DrawLiquid(string brushId, Vector2I offset) + { + if (AffiliationArea != null) + { + DrawLiquid(LiquidBrushManager.GetBrush(brushId), offset); + } + } + + /// + /// 根据笔刷数据在该物体位置绘制液体 + /// + public void DrawLiquid(BrushImageData brush, Vector2I offset) + { + if (AffiliationArea != null) + { + var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position) + offset; + AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(brush, BrushPrevPosition, pos, 0); + BrushPrevPosition = pos; + } + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/liquid/LiquidCanvas.cs b/DungeonShooting_Godot/src/framework/map/liquid/LiquidCanvas.cs index 374e64f..75550b7 100644 --- a/DungeonShooting_Godot/src/framework/map/liquid/LiquidCanvas.cs +++ b/DungeonShooting_Godot/src/framework/map/liquid/LiquidCanvas.cs @@ -17,6 +17,11 @@ /// 画布缩放 /// public static int CanvasScale { get; } = 4; + + /// + /// 画布每秒更新频率 + /// + public static int UpdateFps { get; set; } = 30; public bool IsDestroyed { get; private set; } @@ -36,6 +41,7 @@ private bool _changeFlag = false; //所属房间 private RoomInfo _roomInfo; + private double _processTimer; public LiquidCanvas(RoomInfo roomInfo, int width, int height) { @@ -66,6 +72,15 @@ { //这里待优化, 应该每次绘制都将像素点放入 _tempList 中, 然后帧结束再统一提交 + _processTimer += delta; + if (_processTimer < 1d / UpdateFps) + { + return; + } + + var newDelta = _processTimer; + _processTimer %= 1d / UpdateFps; + //更新消除逻辑 if (_updateImagePixels.Count > 0) { @@ -132,7 +147,7 @@ _changeFlag = false; } - _runTime += (float)delta; + _runTime += (float)newDelta; } /// diff --git a/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs b/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs index 15809f5..9413e01 100644 --- a/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs +++ b/DungeonShooting_Godot/src/game/activity/bullet/normal/BrushBullet.cs @@ -20,7 +20,6 @@ public float EffectiveAltitude { get; set; } = -1; private BrushImageData _brushData; - private Vector2I? _prevPosition; public override void OnInit() { @@ -32,17 +31,19 @@ { base.Process(delta); //测试笔刷 - if ((EffectiveAltitude < 0 || Altitude <= EffectiveAltitude)&& AffiliationArea != null) + if ((EffectiveAltitude < 0 || Altitude <= EffectiveAltitude)) { - var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position); - AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(_brushData, _prevPosition, pos, 0); - _prevPosition = pos; + DrawLiquid(_brushData); + } + else + { + BrushPrevPosition = null; } } public override void OnLeavePool() { base.OnLeavePool(); - _prevPosition = null; + BrushPrevPosition = null; } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs index 32ae476..a365d5d 100644 --- a/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs +++ b/DungeonShooting_Godot/src/game/activity/role/enemy/NoWeaponEnemy.cs @@ -8,7 +8,6 @@ [Tool] public partial class NoWeaponEnemy : Enemy { - private Vector2I? _prevPosition = null; private BrushImageData _brushData; public override void OnInit() @@ -25,12 +24,7 @@ base.Process(delta); //测试笔刷 - if (AffiliationArea != null) - { - var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position); - AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(_brushData, _prevPosition, pos, 0); - _prevPosition = pos; - } + DrawLiquid(_brushData); } public override void Attack() @@ -62,7 +56,7 @@ debris.PutDown(effPos, RoomLayerEnum.NormalLayer); debris.MoveController.AddForce(Velocity + realVelocity); debris.SetFace(Face); - debris.PrevPosition = _prevPosition; + debris.BrushPrevPosition = BrushPrevPosition; //派发敌人死亡信号 EventManager.EmitEvent(EventEnum.OnEnemyDie, this); diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs index b643085..53909ad 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs @@ -29,7 +29,6 @@ //翻滚冷却计时器 private float _rollCoolingTimer = 0; - private Vector2I? _prevPosition = null; private BrushImageData _brushData2; /// @@ -235,17 +234,12 @@ } //测试刷地 - // if (AffiliationArea != null) - // { - // var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position); - // AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(_brushData2, _prevPosition, pos, 0); - // _prevPosition = pos; - // } + //DrawLiquid(_brushData2); } protected override void OnAffiliationChange(AffiliationArea prevArea) { - _prevPosition = null; + //BrushPrevPosition = null; base.OnAffiliationChange(prevArea); } diff --git a/DungeonShooting_Godot/src/game/effects/enemy/EnemyDead0002.cs b/DungeonShooting_Godot/src/game/effects/enemy/EnemyDead0002.cs index 3786200..c498165 100644 --- a/DungeonShooting_Godot/src/game/effects/enemy/EnemyDead0002.cs +++ b/DungeonShooting_Godot/src/game/effects/enemy/EnemyDead0002.cs @@ -4,10 +4,6 @@ [Tool] public partial class EnemyDead0002 : AutoFreezeObject { - /// - /// 上一帧笔刷坐标 - /// - public Vector2I? PrevPosition = null; private BrushImageData _brushData; public override void OnInit() @@ -21,11 +17,13 @@ base.Process(delta); //测试笔刷 - if (FreezeCount == 0 && AffiliationArea != null) + if (FreezeCount == 0) { - var pos = AffiliationArea.RoomInfo.LiquidCanvas.ToLiquidCanvasPosition(Position); - AffiliationArea.RoomInfo.LiquidCanvas.DrawBrush(_brushData, PrevPosition, pos, 0); - PrevPosition = pos; + DrawLiquid(_brushData); + } + else + { + BrushPrevPosition = null; } } } \ No newline at end of file