-
Notifications
You must be signed in to change notification settings - Fork 0
/
FallingObject.cs
147 lines (124 loc) · 3.96 KB
/
FallingObject.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using Godot;
using System;
using System.Drawing;
using System.Linq;
public partial class FallingObject : Node2D
{
[Signal]
public delegate void FellEventHandler();
private Field _field;
public const float FallTime = 1.0f;
public Vector2[] GridPosition { get; private set; }
public Godot.Color Color { get; private set; }
public override void _Ready()
{
_field = GetParent<Field>();
for (int i = 0; i < GridPosition.Length; i++)
{
GridPosition[i] = new Vector2(GridPosition[i].X + 4, GridPosition[i].Y + 20);
}
FallCycle();
}
public async void FallCycle()
{
while (true)
{
await ToSignal(GetTree().CreateTimer(FallTime), SceneTreeTimer.SignalName.Timeout);
Fall();
}
}
private void Fall()
{
foreach (Vector2 gridPoint in GridPosition)
{
if (!_field.IsValidDestination((int)gridPoint.X, (int)gridPoint.Y - 1))
{
EmitSignal(SignalName.Fell);
return;
}
}
for (int i = 0; i < GridPosition.Length; i++)
{
GridPosition[i] = GridPosition[i] with {Y = GridPosition[i].Y - 1};
}
QueueRedraw();
}
public override void _UnhandledInput(InputEvent @event)
{
if (@event.IsActionPressed("left"))
{
foreach (Vector2 gridPoint in GridPosition)
{
if (!_field.IsValidDestination((int)gridPoint.X - 1, (int)gridPoint.Y))
{
return;
}
}
for (int i = 0; i < GridPosition.Length; i++)
{
GridPosition[i] = GridPosition[i] with {X = GridPosition[i].X - 1};
}
QueueRedraw();
} else if (@event.IsActionPressed("right"))
{
foreach (Vector2 gridPoint in GridPosition)
{
if (!_field.IsValidDestination((int)gridPoint.X + 1, (int)gridPoint.Y))
{
return;
}
}
for (int i = 0; i < GridPosition.Length; i++)
{
GridPosition[i] = GridPosition[i] with {X = GridPosition[i].X + 1};
}
QueueRedraw();
} else if (@event.IsActionPressed("drop"))
{
Vector2 last_point = new Vector2();
while (last_point != GridPosition[0])
{
last_point = GridPosition[0];
Fall();
}
} else if (@event.IsActionPressed("rotate"))
{
// Arbitrarily chose to rotate around the second block.
Vector2 centralBlock = GridPosition[1];
Vector2[] localCoords = new Vector2[GridPosition.Length];
for (int i = 0; i < GridPosition.Length; i++)
{
localCoords[i] = GridPosition[i] - centralBlock;
}
// Do the rotation and test.
for (int i = 0; i < localCoords.Length; i++)
{
localCoords[i] = localCoords[i].Rotated((float)Math.PI / 2.0f).Round();
Vector2 result = centralBlock + localCoords[i];
if (!_field.IsValidDestination((int)result.X, (int)result.Y))
{
return;
}
}
// Apply the result.
for (int i = 0; i < GridPosition.Length; i++)
{
GridPosition[i] = centralBlock + localCoords[i];
}
QueueRedraw();
}
}
public override void _Draw()
{
foreach (Vector2 point in GridPosition)
{
_field.BlockStyleBox.BgColor = Color;
DrawStyleBox(_field.BlockStyleBox, _field.GridToRect((int)point.X, (int)point.Y));
}
}
public FallingObject(in Vector2[] p_points, Godot.Color p_color)
{
GridPosition = p_points;
Color = p_color;
}
}