Audio system and rich text
This commit is contained in:
parent
a6f817efbc
commit
68cafff083
161 changed files with 1605 additions and 255 deletions
|
|
@ -29,6 +29,7 @@ public partial class Sun : Area2D
|
|||
_fade.Stop();
|
||||
scoring = true;
|
||||
|
||||
GetNode<ChannelPlayer>("SunPlayer").Play();
|
||||
var tween = CreateTween();
|
||||
tween.TweenInterval(0.1);
|
||||
tween.TweenProperty(this, "global_position", GetCanvasTransform().AffineInverse() * (Counter.GlobalPosition + Counter.PivotOffset), 0.5).SetTrans(Tween.TransitionType.Cubic).SetEase(Tween.EaseType.Out);
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ public class Utility
|
|||
//
|
||||
#region Enums
|
||||
|
||||
public enum EffectSlots {FREEZE, STUN, POISON, GARLIC};
|
||||
|
||||
public enum DamageTypes {PHYSICAL, ICE};
|
||||
public enum EffectSlots { FREEZE, STUN, POISON, GARLIC };
|
||||
|
||||
public enum DamageTypes { PHYSICAL, ICE };
|
||||
|
||||
#endregion
|
||||
|
||||
|
|
@ -25,9 +25,12 @@ public class Utility
|
|||
public const int TileWidth = 50;
|
||||
public const int TileHeight = 60;
|
||||
public const int LayersCount = 3;
|
||||
public static Vector2I LeftFieldBoundary = new(305,76);
|
||||
public static Vector2I RightFieldBoundary = new(755,376);
|
||||
public static Vector2I LeftFieldBoundary = new(305, 76);
|
||||
public static Vector2I RightFieldBoundary = new(755, 376);
|
||||
public static readonly Vector2 Tile = new(TileWidth, TileHeight);
|
||||
|
||||
public static double SFX = 1.0f;
|
||||
public static double Music = 1.0f;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
85
scripts/audio/AudioSequencer.cs
Normal file
85
scripts/audio/AudioSequencer.cs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
public partial class AudioSequencer : Node
|
||||
{
|
||||
private static AudioSequencer instance;
|
||||
private Dictionary<string, AudioStreamPlayer> channels = [];
|
||||
private Dictionary<string, bool> channelProcess = [];
|
||||
private Dictionary<string, ChannelSettings> channelSettings = [];
|
||||
|
||||
[Export]
|
||||
private ChannelSettings standardSettings;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
instance = this;
|
||||
}
|
||||
|
||||
public static bool IsChannelPlaying(string id)
|
||||
{
|
||||
if (instance.channels.ContainsKey(id) == false)
|
||||
{
|
||||
instance.InitiateChannel(id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (instance.channelSettings[id].restartTreshold == 0)
|
||||
return false;
|
||||
if (instance.channelSettings[id].restartTreshold < 0)
|
||||
return instance.channelProcess[id];
|
||||
|
||||
return instance.channelProcess[id] && instance.channels[id].GetPlaybackPosition() < instance.channelSettings[id].restartTreshold / Engine.TimeScale;
|
||||
}
|
||||
|
||||
public static void Play(string id, AudioStream what)
|
||||
{
|
||||
if (IsChannelPlaying(id)) return;
|
||||
instance.PlayAtChannel(id, what);
|
||||
}
|
||||
|
||||
public static void ChangeSettings(string id, ChannelSettings settings)
|
||||
{
|
||||
if (instance.channels.ContainsKey(id) == false)
|
||||
{
|
||||
instance.InitiateChannel(id, settings);
|
||||
return;
|
||||
}
|
||||
instance.channelSettings[id] = settings;
|
||||
}
|
||||
|
||||
private AudioStreamPlayer InitiateChannel(string id, ChannelSettings settings = null)
|
||||
{
|
||||
AudioStreamPlayer player = new();
|
||||
|
||||
AddChild(player);
|
||||
channels.Add(id, player);
|
||||
channelProcess.Add(id, false);
|
||||
player.Name = id;
|
||||
|
||||
player.Finished += () => { MarkChannel(id, false); };
|
||||
|
||||
if (settings != null)
|
||||
{
|
||||
channelSettings.Add(id, settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
channelSettings.Add(id, standardSettings);
|
||||
}
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
private void PlayAtChannel(string id, AudioStream what)
|
||||
{
|
||||
channels[id].Stream = what;
|
||||
channels[id].Play();
|
||||
MarkChannel(id, true);
|
||||
}
|
||||
|
||||
private void MarkChannel(string id, bool how)
|
||||
{
|
||||
channelProcess[id] = how;
|
||||
}
|
||||
}
|
||||
1
scripts/audio/AudioSequencer.cs.uid
Normal file
1
scripts/audio/AudioSequencer.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cauc1ieq84fwg
|
||||
43
scripts/audio/AudioSlider.cs
Normal file
43
scripts/audio/AudioSlider.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using Godot;
|
||||
using Newlon;
|
||||
|
||||
public partial class AudioSlider : HSlider
|
||||
{
|
||||
enum TYPE
|
||||
{
|
||||
SFX,
|
||||
MUSIC
|
||||
}
|
||||
|
||||
[Export] private TYPE affects;
|
||||
public override void _Ready()
|
||||
{
|
||||
DragEnded += OnDragEnded;
|
||||
if (affects == TYPE.SFX)
|
||||
{
|
||||
SetValueNoSignal(Utility.SFX);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetValueNoSignal(Utility.Music);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragEnded(bool hasChanged)
|
||||
{
|
||||
if (hasChanged)
|
||||
{
|
||||
if (affects == TYPE.SFX)
|
||||
{
|
||||
Utility.SFX = Value;
|
||||
AudioServer.SetBusVolumeDb(0, Mathf.LinearToDb((float)Value));
|
||||
}
|
||||
else
|
||||
{
|
||||
Utility.Music = Value;
|
||||
AudioServer.SetBusVolumeDb(1, Mathf.LinearToDb((float)Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
1
scripts/audio/AudioSlider.cs.uid
Normal file
1
scripts/audio/AudioSlider.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://ciccaxqo70s13
|
||||
16
scripts/audio/ChannelPlayer.cs
Normal file
16
scripts/audio/ChannelPlayer.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using Godot;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class ChannelPlayer : Node
|
||||
{
|
||||
[Export] private ChannelSettings settings;
|
||||
[Export] private AudioStream audioStream;
|
||||
[Export] private string channel;
|
||||
|
||||
public void Play()
|
||||
{
|
||||
AudioSequencer.Play(channel, audioStream);
|
||||
if (settings != null)
|
||||
AudioSequencer.ChangeSettings(channel, settings);
|
||||
}
|
||||
}
|
||||
1
scripts/audio/ChannelPlayer.cs.uid
Normal file
1
scripts/audio/ChannelPlayer.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c36bj8u7jghc7
|
||||
35
scripts/audio/ChannelPlaylist.cs
Normal file
35
scripts/audio/ChannelPlaylist.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class ChannelPlaylist : Node
|
||||
{
|
||||
[Export] private Array<AudioStream> playlist;
|
||||
[Export] private Array<string> channels;
|
||||
[Export] private ChannelSettings channelSettings;
|
||||
private int internal_index = 0;
|
||||
|
||||
public void Play()
|
||||
{
|
||||
AudioSequencer.Play(channels[internal_index], playlist[internal_index]);
|
||||
}
|
||||
|
||||
public void SetIndex(int index)
|
||||
{
|
||||
internal_index = index;
|
||||
if (internal_index >= playlist.Count)
|
||||
{
|
||||
internal_index = 0;
|
||||
}
|
||||
else if (internal_index < 0)
|
||||
{
|
||||
internal_index = playlist.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
public void Next()
|
||||
{
|
||||
SetIndex(internal_index + 1);
|
||||
}
|
||||
|
||||
}
|
||||
1
scripts/audio/ChannelPlaylist.cs.uid
Normal file
1
scripts/audio/ChannelPlaylist.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cnn0ymuhypdff
|
||||
7
scripts/audio/ChannelSettings.cs
Normal file
7
scripts/audio/ChannelSettings.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
using Godot;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class ChannelSettings : Resource
|
||||
{
|
||||
[Export] public float restartTreshold;
|
||||
}
|
||||
1
scripts/audio/ChannelSettings.cs.uid
Normal file
1
scripts/audio/ChannelSettings.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c1x4n4nqyq72f
|
||||
|
|
@ -8,7 +8,7 @@ public partial class Previewport : SubViewport
|
|||
private RuntimePlantData current_display;
|
||||
|
||||
[Export] private Label title;
|
||||
[Export] private Label description;
|
||||
[Export] private RichTextLabel description;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ public class ChoosableHandler : SeedpacketHandler, ISeedpacketPress
|
|||
|
||||
public void Pressed()
|
||||
{
|
||||
if(LevelGUIElements.Instance.SeedpacketsHotbar.GetChildCount() > 9) return;
|
||||
if (LevelGUIElements.Instance.SeedpacketsHotbar.GetChildCount() > 9) return;
|
||||
_owner.disablePacket = true;
|
||||
|
||||
var hotbarSeedpacket = Seedpacket.Prefab.Instantiate<Seedpacket>();
|
||||
|
|
@ -18,6 +18,8 @@ public class ChoosableHandler : SeedpacketHandler, ISeedpacketPress
|
|||
var pregameHandler = new HotbarPregameHandler(hotbarSeedpacket);
|
||||
hotbarSeedpacket.SetHandler(pregameHandler);
|
||||
pregameHandler.Clicked += OnHotbarClicked;
|
||||
|
||||
AudioSequencer.Play("tap", Seedpacket.TapStream);
|
||||
}
|
||||
|
||||
public void OnHotbarClicked()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ public class HotbarHandler : SeedpacketHandler, ISeedpacketPress, ISeedpacketPro
|
|||
|
||||
public void Pressed()
|
||||
{
|
||||
PlantField.Instance.SetPlant(_owner,_owner.GetPlantResource());
|
||||
PlantField.Instance.SetPlant(_owner, _owner.GetPlantResource());
|
||||
AudioSequencer.Play("lift_seed", Seedpacket.LiftStream);
|
||||
}
|
||||
|
||||
public void Process()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class HotbarPregameHandler : SeedpacketHandler, ISeedpacketPress
|
|||
{
|
||||
if (Clicked != null) Clicked();
|
||||
_owner.QueueFree();
|
||||
AudioSequencer.Play("tap", Seedpacket.UntapStream);
|
||||
}
|
||||
|
||||
public void OnLevelStateChanged(RuntimeLevelData.LevelStates state)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ namespace Newlon.Components.GUI.Seedpackets;
|
|||
|
||||
public partial class Seedpacket : TextureButton
|
||||
{
|
||||
public static AudioStream TapStream;
|
||||
public static AudioStream UntapStream;
|
||||
public static AudioStream LiftStream;
|
||||
private const string PATH_TO_PACKED_SCENE = "res://scenes/gui/seedpacket.tscn";
|
||||
private PlantResource _resource;
|
||||
private Label _cost;
|
||||
|
|
@ -18,8 +21,14 @@ public partial class Seedpacket : TextureButton
|
|||
// Node overrides
|
||||
public override void _Ready()
|
||||
{
|
||||
if (TapStream == null)
|
||||
{
|
||||
TapStream = ResourceLoader.Load<AudioStream>("res://assets/audio/gui/tap.mp3");
|
||||
UntapStream = ResourceLoader.Load<AudioStream>("res://assets/audio/gui/tap2.mp3");
|
||||
LiftStream = ResourceLoader.Load<AudioStream>("res://assets/audio/gui/seedlift.mp3");
|
||||
}
|
||||
if (_resource != null)
|
||||
UpdateContents();
|
||||
UpdateContents();
|
||||
if (Prefab == null)
|
||||
{
|
||||
Prefab = ResourceLoader.Load<PackedScene>(PATH_TO_PACKED_SCENE);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ public partial class PlantField : Node2D
|
|||
private PlantResource _resource;
|
||||
private Seedpacket _slot;
|
||||
private bool _previousCanPlace;
|
||||
private ChannelPlayer player;
|
||||
[Export] private PackedScene particles;
|
||||
public static PlantField Instance {get; private set;}
|
||||
|
||||
|
|
@ -17,6 +18,7 @@ public partial class PlantField : Node2D
|
|||
{
|
||||
Instance = this;
|
||||
_plantSetter = GetChild<Node2D>(0);
|
||||
player = GetNode<ChannelPlayer>("PlantPlayer");
|
||||
}
|
||||
|
||||
public void SetPlant(Seedpacket slot, PlantResource plant)
|
||||
|
|
@ -99,6 +101,8 @@ public partial class PlantField : Node2D
|
|||
|
||||
PoolContainer.Instance.SpawnParticles(particles, plant.GlobalPosition + Vector2.Down * Utility.TileHeight/2.0f);
|
||||
|
||||
player.Play();
|
||||
|
||||
// Unfocusing and recharging slot
|
||||
_slot.Recharge();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,10 @@ using Newlon.Components.Zombies;
|
|||
public partial class FallParticle : RigidBody2D
|
||||
{
|
||||
[Export] private RuntimeZombieData data;
|
||||
[Export] private Timer deathTimer;
|
||||
[Export] private Vector2 falloffImpulseMin = Vector2.Zero;
|
||||
[Export] private Vector2 falloffImpulseMax = Vector2.Zero;
|
||||
[Export] private Vector2 falloffOffsetMin = Vector2.Zero;
|
||||
[Export] private Vector2 falloffOffsetMax = Vector2.Zero;
|
||||
[Export] private float minAngle;
|
||||
[Export] private float maxAngle;
|
||||
[Export] private float minTorque;
|
||||
[Export] private float maxTorque;
|
||||
[Export] private float Impulse;
|
||||
public void FallOff()
|
||||
{
|
||||
|
|
@ -21,14 +20,14 @@ public partial class FallParticle : RigidBody2D
|
|||
Callable.From(() =>
|
||||
{
|
||||
Reparent(PoolContainer.Instance.Zombies);
|
||||
ApplyImpulse(RandomVector(falloffImpulseMin, falloffImpulseMax).Normalized() * Impulse, RandomVector(falloffOffsetMin, falloffOffsetMax));
|
||||
float rng_angle = Mathf.DegToRad((float)GD.RandRange(minAngle, maxAngle));
|
||||
float rng_torque = Mathf.DegToRad((float)GD.RandRange(minTorque, maxTorque));
|
||||
ApplyImpulse(new Vector2(Mathf.Sin(rng_angle) * Impulse, Mathf.Cos(rng_angle) * Impulse));
|
||||
ApplyTorqueImpulse(rng_torque);
|
||||
}).CallDeferred();
|
||||
|
||||
deathTimer.Start();
|
||||
}
|
||||
|
||||
private Vector2 RandomVector(Vector2 min, Vector2 max)
|
||||
{
|
||||
return new Vector2((float)GD.RandRange(min.X,max.X),(float)GD.RandRange(min.Y,max.Y));
|
||||
var tween = CreateTween();
|
||||
tween.TweenInterval(4.0);
|
||||
tween.TweenProperty(this, "modulate", new Color(Modulate.R, Modulate.G, Modulate.B, 0f), 1.0);
|
||||
tween.TweenCallback(Callable.From(QueueFree));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public partial class ExplosionComponent : Area2D
|
|||
|
||||
PoolContainer.Instance.SpawnParticles(particles, GetParent<RuntimePlantData>().GlobalPosition);
|
||||
|
||||
GetNode<ChannelPlayer>("ExplosionPlayer").Play();
|
||||
GetParent<RuntimePlantData>().Kill();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,15 @@ public partial class RuntimePlantData : Node2D, IEntity
|
|||
public int Line { get; set; }
|
||||
public PlantResource Resource;
|
||||
|
||||
private AudioStream eatenSound;
|
||||
|
||||
[Signal]
|
||||
public delegate void OnHPChangedEventHandler(int amount, Node origin);
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_hp = _maxHP;
|
||||
eatenSound = ResourceLoader.Load<AudioStream>("res://assets/audio/sfx/gulp.mp3");
|
||||
}
|
||||
|
||||
public virtual void Heal(int amount, Node origin)
|
||||
|
|
@ -46,6 +49,7 @@ public partial class RuntimePlantData : Node2D, IEntity
|
|||
if (_hp <= 0)
|
||||
{
|
||||
Kill();
|
||||
AudioSequencer.Play("plant_eaten", eatenSound);
|
||||
}
|
||||
}
|
||||
public virtual void Kill()
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ public partial class RuntimeZombieData : Node2D, IEntity, ILocalTimescale, IEffe
|
|||
{
|
||||
[Signal]
|
||||
public delegate void OnHPChangedEventHandler(int deltaHP, Node origin);
|
||||
[Signal]
|
||||
public delegate void OnDamagedEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void OnLocalTimescaleChangedEventHandler(int currentTimescale);
|
||||
|
|
@ -18,6 +20,11 @@ public partial class RuntimeZombieData : Node2D, IEntity, ILocalTimescale, IEffe
|
|||
private int _maxHP;
|
||||
[Export]
|
||||
private Armor _armor;
|
||||
|
||||
[Export]
|
||||
private AudioStream garlicSound;
|
||||
[Export]
|
||||
private AudioStream freezeSound;
|
||||
|
||||
|
||||
private float _localTimescale = 1.0f;
|
||||
|
|
@ -61,7 +68,6 @@ public partial class RuntimeZombieData : Node2D, IEntity, ILocalTimescale, IEffe
|
|||
else
|
||||
_hp += amount;
|
||||
EmitSignal(SignalName.OnHPChanged,amount,origin);
|
||||
|
||||
|
||||
if (MaxHp > 0)
|
||||
{
|
||||
|
|
@ -78,6 +84,7 @@ public partial class RuntimeZombieData : Node2D, IEntity, ILocalTimescale, IEffe
|
|||
else
|
||||
_hp -= amount;
|
||||
EmitSignal(SignalName.OnHPChanged,-amount, origin);
|
||||
EmitSignal(SignalName.OnDamaged);
|
||||
|
||||
if (_hp <= 0)
|
||||
{
|
||||
|
|
@ -94,11 +101,27 @@ public partial class RuntimeZombieData : Node2D, IEntity, ILocalTimescale, IEffe
|
|||
public void GiveEffect(Effect what)
|
||||
{
|
||||
int slot = (int)what.Slot;
|
||||
if(_activeEffectSlots[slot] != null)
|
||||
if (_activeEffectSlots[slot] == null)
|
||||
{
|
||||
_effectSlotTimers[slot].Stop();
|
||||
_activeEffectSlots[slot].Exit(this);
|
||||
switch (what.Slot)
|
||||
{
|
||||
case Utility.EffectSlots.FREEZE:
|
||||
AudioSequencer.Play("zombie_freeze", freezeSound);
|
||||
var settings = new ChannelSettings();
|
||||
settings.restartTreshold = -1;
|
||||
AudioSequencer.ChangeSettings("zombie_freeze",settings);
|
||||
break;
|
||||
case Utility.EffectSlots.GARLIC:
|
||||
AudioSequencer.Play("zombie_garlic", garlicSound);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_activeEffectSlots[slot] != null)
|
||||
{
|
||||
_effectSlotTimers[slot].Stop();
|
||||
_activeEffectSlots[slot].Exit(this);
|
||||
}
|
||||
_effectSlotTimers[slot].WaitTime = what.Duration;
|
||||
_effectSlotTimers[slot].Start();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ public partial class SlownessEffect : Effect
|
|||
|
||||
public override void Enter(Node target)
|
||||
{
|
||||
if(target is IEffectHandler handler)
|
||||
if (target is IEffectHandler handler)
|
||||
{
|
||||
if(target is ILocalTimescale timescalable)
|
||||
if (target is ILocalTimescale timescalable)
|
||||
timescalable.LocalTimescale *= Multiplier;
|
||||
if(target is CanvasItem canvasItem)
|
||||
if (target is CanvasItem canvasItem)
|
||||
canvasItem.Modulate = ColorOverride;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue