407 lines
11 KiB
C#
407 lines
11 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using Godot;
|
|
using Godot.Bridge;
|
|
using Godot.NativeInterop;
|
|
|
|
[ScriptPath("res://Scripts/Puzzles/MemoryGame.cs")]
|
|
public class MemoryGame : Node2D
|
|
{
|
|
[Signal]
|
|
public delegate void EndGameSignalEventHandler();
|
|
|
|
public new class MethodName : Node2D.MethodName
|
|
{
|
|
public new static readonly StringName _Ready = "_Ready";
|
|
}
|
|
|
|
public new class PropertyName : Node2D.PropertyName
|
|
{
|
|
public static readonly StringName winDiag = "winDiag";
|
|
|
|
public static readonly StringName loseDiag = "loseDiag";
|
|
|
|
public static readonly StringName music = "music";
|
|
|
|
public static readonly StringName defaultLives = "defaultLives";
|
|
|
|
public static readonly StringName last = "last";
|
|
|
|
public static readonly StringName running = "running";
|
|
|
|
public static readonly StringName lives = "lives";
|
|
}
|
|
|
|
public new class SignalName : Node2D.SignalName
|
|
{
|
|
public static readonly StringName EndGameSignal = "EndGameSignal";
|
|
}
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
public string winDiag;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
public string loseDiag;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
private AudioStream music;
|
|
|
|
[Export(PropertyHint.None, "")]
|
|
public int defaultLives = 5;
|
|
|
|
private List<MemGameCards> cards = new List<MemGameCards>();
|
|
|
|
public List<int> flipped = new List<int>();
|
|
|
|
public MemGameCards last;
|
|
|
|
public bool running;
|
|
|
|
public int lives;
|
|
|
|
public const int max = 18;
|
|
|
|
private static readonly int[] order = new int[18]
|
|
{
|
|
1, 1, 2, 2, 3, 3, 4, 4, 5, 5,
|
|
6, 6, 7, 7, 8, 8, 9, 9
|
|
};
|
|
|
|
public static bool result;
|
|
|
|
private EndGameSignalEventHandler backing_EndGameSignal;
|
|
|
|
public event EndGameSignalEventHandler EndGameSignal
|
|
{
|
|
add
|
|
{
|
|
backing_EndGameSignal = (EndGameSignalEventHandler)Delegate.Combine(backing_EndGameSignal, value);
|
|
}
|
|
remove
|
|
{
|
|
backing_EndGameSignal = (EndGameSignalEventHandler)Delegate.Remove(backing_EndGameSignal, value);
|
|
}
|
|
}
|
|
|
|
public override void _Ready()
|
|
{
|
|
foreach (Node child in GetChildren())
|
|
{
|
|
cards.Add(child.GetChild<MemGameCards>(0));
|
|
}
|
|
base.Modulate = Main.colorClear;
|
|
}
|
|
|
|
public IEnumerator StartGame()
|
|
{
|
|
int[] array = order;
|
|
if (Main.RandomRange(0, 31) == 0)
|
|
{
|
|
int num = Main.RandomRange(0, 8);
|
|
array[num * 2] = 10;
|
|
array[num * 2 + 1] = 10;
|
|
}
|
|
array = order.OrderBy((int x) => Guid.NewGuid()).ToArray();
|
|
for (int num2 = 0; num2 < cards.Count; num2++)
|
|
{
|
|
cards[num2].id = array[num2];
|
|
cards[num2].sprite.Frame = 0;
|
|
cards[num2].flipped = false;
|
|
}
|
|
Audio.PlaySound("snd_shadowpendant_ch1.wav");
|
|
Audio.ChangeMusic(music);
|
|
float a = 0f;
|
|
for (float b = 30f; a <= b + 1f; a += Main.deltaTime)
|
|
{
|
|
base.Modulate = Main.colorClear.Lerp(Main.colorWhite, Mathf.Min(a / b, 1f));
|
|
yield return null;
|
|
}
|
|
Coroutine s = Coroutine.Start(CameraController.PanToObj(this, 2f));
|
|
while (!s.done)
|
|
{
|
|
yield return null;
|
|
}
|
|
Audio.PlaySound("snd_wing_ch1.wav", 1.2f);
|
|
for (int num3 = 0; num3 < cards.Count; num3++)
|
|
{
|
|
Coroutine.Start(cards[num3].FlipAnim(cards[num3].id, noSound: true));
|
|
}
|
|
for (float b = 0f; b < 300f; b += Main.deltaTime)
|
|
{
|
|
if (Input.IsActionJustPressed(Main.keys[4]))
|
|
{
|
|
break;
|
|
}
|
|
if (Input.IsActionJustPressed(Main.keys[5]))
|
|
{
|
|
break;
|
|
}
|
|
yield return null;
|
|
}
|
|
Audio.PlaySound("snd_wing_ch1.wav", 1.2f);
|
|
for (int num4 = 0; num4 < cards.Count; num4++)
|
|
{
|
|
Coroutine.Start(cards[num4].FlipAnim(0, noSound: true));
|
|
}
|
|
for (float b = 0f; b < 30f; b += Main.deltaTime)
|
|
{
|
|
yield return null;
|
|
}
|
|
s = Coroutine.Start(CameraController.PanToObj(Player.instance, 2f));
|
|
while (!s.done)
|
|
{
|
|
yield return null;
|
|
}
|
|
flipped.Clear();
|
|
lives = defaultLives;
|
|
running = true;
|
|
}
|
|
|
|
public IEnumerator EndGame(bool won)
|
|
{
|
|
running = false;
|
|
result = won;
|
|
if (won)
|
|
{
|
|
Audio.PlaySound("snd_won.wav");
|
|
TextSystem.GetText(winDiag);
|
|
}
|
|
else
|
|
{
|
|
TextSystem.GetText(loseDiag);
|
|
}
|
|
while (TextSystem.instance.Visible)
|
|
{
|
|
yield return null;
|
|
}
|
|
Room.current.DoMusic();
|
|
float a = 0f;
|
|
for (float b = 30f; a <= b + 1f; a += Main.deltaTime)
|
|
{
|
|
base.Modulate = Main.colorWhite.Lerp(Main.colorClear, Mathf.Min(a / b, 1f));
|
|
yield return null;
|
|
}
|
|
EmitSignal(SignalName.EndGameSignal);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal static List<MethodInfo> GetGodotMethodList()
|
|
{
|
|
return new List<MethodInfo>(1)
|
|
{
|
|
new MethodInfo(MethodName._Ready, new PropertyInfo(Variant.Type.Nil, "", PropertyHint.None, "", PropertyUsageFlags.Default, exported: false), MethodFlags.Normal, null, null)
|
|
};
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override bool InvokeGodotClassMethod(in godot_string_name method, NativeVariantPtrArgs args, out godot_variant ret)
|
|
{
|
|
if (method == MethodName._Ready && args.Count == 0)
|
|
{
|
|
_Ready();
|
|
ret = default(godot_variant);
|
|
return true;
|
|
}
|
|
return base.InvokeGodotClassMethod(in method, args, out ret);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override bool HasGodotClassMethod(in godot_string_name method)
|
|
{
|
|
if (method == MethodName._Ready)
|
|
{
|
|
return true;
|
|
}
|
|
return base.HasGodotClassMethod(in method);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override bool SetGodotClassPropertyValue(in godot_string_name name, in godot_variant value)
|
|
{
|
|
if (name == PropertyName.winDiag)
|
|
{
|
|
winDiag = VariantUtils.ConvertTo<string>(in value);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.loseDiag)
|
|
{
|
|
loseDiag = VariantUtils.ConvertTo<string>(in value);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.music)
|
|
{
|
|
music = VariantUtils.ConvertTo<AudioStream>(in value);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.defaultLives)
|
|
{
|
|
defaultLives = VariantUtils.ConvertTo<int>(in value);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.last)
|
|
{
|
|
last = VariantUtils.ConvertTo<MemGameCards>(in value);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.running)
|
|
{
|
|
running = VariantUtils.ConvertTo<bool>(in value);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.lives)
|
|
{
|
|
lives = VariantUtils.ConvertTo<int>(in value);
|
|
return true;
|
|
}
|
|
return base.SetGodotClassPropertyValue(in name, in value);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override bool GetGodotClassPropertyValue(in godot_string_name name, out godot_variant value)
|
|
{
|
|
if (name == PropertyName.winDiag)
|
|
{
|
|
value = VariantUtils.CreateFrom(in winDiag);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.loseDiag)
|
|
{
|
|
value = VariantUtils.CreateFrom(in loseDiag);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.music)
|
|
{
|
|
value = VariantUtils.CreateFrom(in music);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.defaultLives)
|
|
{
|
|
value = VariantUtils.CreateFrom(in defaultLives);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.last)
|
|
{
|
|
value = VariantUtils.CreateFrom(in last);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.running)
|
|
{
|
|
value = VariantUtils.CreateFrom(in running);
|
|
return true;
|
|
}
|
|
if (name == PropertyName.lives)
|
|
{
|
|
value = VariantUtils.CreateFrom(in lives);
|
|
return true;
|
|
}
|
|
return base.GetGodotClassPropertyValue(in name, out value);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal static List<PropertyInfo> GetGodotPropertyList()
|
|
{
|
|
return new List<PropertyInfo>
|
|
{
|
|
new PropertyInfo(Variant.Type.String, PropertyName.winDiag, PropertyHint.None, "", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
|
|
new PropertyInfo(Variant.Type.String, PropertyName.loseDiag, PropertyHint.None, "", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
|
|
new PropertyInfo(Variant.Type.Object, PropertyName.music, PropertyHint.ResourceType, "AudioStream", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
|
|
new PropertyInfo(Variant.Type.Int, PropertyName.defaultLives, PropertyHint.None, "", PropertyUsageFlags.Default | PropertyUsageFlags.ScriptVariable, exported: true),
|
|
new PropertyInfo(Variant.Type.Object, PropertyName.last, PropertyHint.None, "", PropertyUsageFlags.ScriptVariable, exported: false),
|
|
new PropertyInfo(Variant.Type.Bool, PropertyName.running, PropertyHint.None, "", PropertyUsageFlags.ScriptVariable, exported: false),
|
|
new PropertyInfo(Variant.Type.Int, PropertyName.lives, PropertyHint.None, "", PropertyUsageFlags.ScriptVariable, exported: false)
|
|
};
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override void SaveGodotObjectData(GodotSerializationInfo info)
|
|
{
|
|
base.SaveGodotObjectData(info);
|
|
info.AddProperty(PropertyName.winDiag, Variant.From(in winDiag));
|
|
info.AddProperty(PropertyName.loseDiag, Variant.From(in loseDiag));
|
|
info.AddProperty(PropertyName.music, Variant.From(in music));
|
|
info.AddProperty(PropertyName.defaultLives, Variant.From(in defaultLives));
|
|
info.AddProperty(PropertyName.last, Variant.From(in last));
|
|
info.AddProperty(PropertyName.running, Variant.From(in running));
|
|
info.AddProperty(PropertyName.lives, Variant.From(in lives));
|
|
info.AddSignalEventDelegate(SignalName.EndGameSignal, backing_EndGameSignal);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override void RestoreGodotObjectData(GodotSerializationInfo info)
|
|
{
|
|
base.RestoreGodotObjectData(info);
|
|
if (info.TryGetProperty(PropertyName.winDiag, out var value))
|
|
{
|
|
winDiag = value.As<string>();
|
|
}
|
|
if (info.TryGetProperty(PropertyName.loseDiag, out var value2))
|
|
{
|
|
loseDiag = value2.As<string>();
|
|
}
|
|
if (info.TryGetProperty(PropertyName.music, out var value3))
|
|
{
|
|
music = value3.As<AudioStream>();
|
|
}
|
|
if (info.TryGetProperty(PropertyName.defaultLives, out var value4))
|
|
{
|
|
defaultLives = value4.As<int>();
|
|
}
|
|
if (info.TryGetProperty(PropertyName.last, out var value5))
|
|
{
|
|
last = value5.As<MemGameCards>();
|
|
}
|
|
if (info.TryGetProperty(PropertyName.running, out var value6))
|
|
{
|
|
running = value6.As<bool>();
|
|
}
|
|
if (info.TryGetProperty(PropertyName.lives, out var value7))
|
|
{
|
|
lives = value7.As<int>();
|
|
}
|
|
if (info.TryGetSignalEventDelegate<EndGameSignalEventHandler>(SignalName.EndGameSignal, out var value8))
|
|
{
|
|
backing_EndGameSignal = value8;
|
|
}
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
internal static List<MethodInfo> GetGodotSignalList()
|
|
{
|
|
return new List<MethodInfo>(1)
|
|
{
|
|
new MethodInfo(SignalName.EndGameSignal, new PropertyInfo(Variant.Type.Nil, "", PropertyHint.None, "", PropertyUsageFlags.Default, exported: false), MethodFlags.Normal, null, null)
|
|
};
|
|
}
|
|
|
|
protected void EmitSignalEndGameSignal()
|
|
{
|
|
EmitSignal(SignalName.EndGameSignal);
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override void RaiseGodotClassSignalCallbacks(in godot_string_name signal, NativeVariantPtrArgs args)
|
|
{
|
|
if (signal == SignalName.EndGameSignal && args.Count == 0)
|
|
{
|
|
backing_EndGameSignal?.Invoke();
|
|
}
|
|
else
|
|
{
|
|
base.RaiseGodotClassSignalCallbacks(in signal, args);
|
|
}
|
|
}
|
|
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
protected override bool HasGodotClassSignal(in godot_string_name signal)
|
|
{
|
|
if (signal == SignalName.EndGameSignal)
|
|
{
|
|
return true;
|
|
}
|
|
return base.HasGodotClassSignal(in signal);
|
|
}
|
|
}
|