Compare commits

...

7 Commits

Author SHA1 Message Date
6adb889293 📄 Add license 2024-08-09 22:00:43 +08:00
8fbffdf3f7 🚀 Launch prototype 2024-08-09 17:14:51 +08:00
fa02896e8d World border 2024-08-09 17:06:35 +08:00
34a1b6133f Off screen marker 2024-08-09 16:57:47 +08:00
482bfb04a0 🍱 Add font 2024-08-09 15:58:38 +08:00
dd27528fed Speed up round when no body alive 2024-08-09 15:52:00 +08:00
33c6762ed3 End game 2024-08-09 15:45:40 +08:00
21 changed files with 640 additions and 197 deletions

6
AceTheme.tres Normal file
View File

@@ -0,0 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=3 uid="uid://b4dcn26i0p6ym"]
[ext_resource type="FontFile" uid="uid://dtvh6e1i057a6" path="res://Fonts/Comfortaa-Regular.ttf" id="1_6bbem"]
[resource]
default_font = ExtResource("1_6bbem")

BIN
Fonts/Comfortaa-Regular.ttf Normal file

Binary file not shown.

View File

@@ -0,0 +1,33 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://dtvh6e1i057a6"
path="res://.godot/imported/Comfortaa-Regular.ttf-b5da63c599bb6327af0a826061919753.fontdata"
[deps]
source_file="res://Fonts/Comfortaa-Regular.ttf"
dest_files=["res://.godot/imported/Comfortaa-Regular.ttf-b5da63c599bb6327af0a826061919753.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=1
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

View File

@@ -0,0 +1,15 @@
[gd_scene load_steps=3 format=3 uid="uid://bcnhxdbgcdsjb"]
[ext_resource type="Script" path="res://Scripts/Effects/OffScreenMarker.cs" id="1_8oti1"]
[ext_resource type="Texture2D" uid="uid://bn86o1gfcj502" path="res://Sprites/Alert.png" id="2_qatpw"]
[node name="OffScreenMarker" type="Node2D"]
script = ExtResource("1_8oti1")
[node name="Sprite2D" type="Sprite2D" parent="."]
[node name="Arrow" type="Sprite2D" parent="Sprite2D"]
position = Vector2(-20, 1.29804e-13)
rotation = 3.14159
scale = Vector2(0.04, 0.04)
texture = ExtResource("2_qatpw")

View File

@@ -1,11 +1,13 @@
[gd_scene load_steps=11 format=3 uid="uid://b3gx0bl43lku3"] [gd_scene load_steps=13 format=3 uid="uid://b3gx0bl43lku3"]
[ext_resource type="Script" path="res://Scripts/Player.cs" id="1_0btyt"] [ext_resource type="Script" path="res://Scripts/Player.cs" id="1_0btyt"]
[ext_resource type="Texture2D" uid="uid://c4als6t3k4myc" path="res://Sprites/Player.png" id="1_cqpqa"] [ext_resource type="Texture2D" uid="uid://c4als6t3k4myc" path="res://Sprites/Player.png" id="1_cqpqa"]
[ext_resource type="PackedScene" uid="uid://ds40mib6ur8yf" path="res://Scenes/Bullet.tscn" id="2_nmop0"] [ext_resource type="PackedScene" uid="uid://ds40mib6ur8yf" path="res://Scenes/Bullet.tscn" id="2_nmop0"]
[ext_resource type="PackedScene" uid="uid://nu34biv4xo5k" path="res://Scenes/Brick.tscn" id="3_6sbto"] [ext_resource type="PackedScene" uid="uid://nu34biv4xo5k" path="res://Scenes/Brick.tscn" id="3_6sbto"]
[ext_resource type="Script" path="res://Scripts/Logic/PlayerInput.cs" id="3_tvoua"] [ext_resource type="Script" path="res://Scripts/Logic/PlayerInput.cs" id="3_tvoua"]
[ext_resource type="Theme" uid="uid://b4dcn26i0p6ym" path="res://AceTheme.tres" id="4_64t2j"]
[ext_resource type="Script" path="res://Scripts/Effects/CameraShake.cs" id="4_fwngj"] [ext_resource type="Script" path="res://Scripts/Effects/CameraShake.cs" id="4_fwngj"]
[ext_resource type="PackedScene" uid="uid://bcnhxdbgcdsjb" path="res://Scenes/OffScreenMarker.tscn" id="7_juwvx"]
[sub_resource type="CircleShape2D" id="CircleShape2D_68yf8"] [sub_resource type="CircleShape2D" id="CircleShape2D_68yf8"]
radius = 25.6 radius = 25.6
@@ -62,6 +64,7 @@ offset_left = -90.0
offset_top = -86.0 offset_top = -86.0
offset_right = 90.0 offset_right = 90.0
offset_bottom = -26.0 offset_bottom = -26.0
theme = ExtResource("4_64t2j")
theme_override_constants/separation = 4 theme_override_constants/separation = 4
alignment = 1 alignment = 1
@@ -101,6 +104,8 @@ rotation_smoothing_enabled = true
script = ExtResource("4_fwngj") script = ExtResource("4_fwngj")
Noise = SubResource("FastNoiseLite_cfnx7") Noise = SubResource("FastNoiseLite_cfnx7")
[node name="OffScreenMarker" parent="." instance=ExtResource("7_juwvx")]
[node name="ReloadTimer" type="Timer" parent="."] [node name="ReloadTimer" type="Timer" parent="."]
wait_time = 6.0 wait_time = 6.0
one_shot = true one_shot = true

View File

@@ -1,15 +1,23 @@
[gd_scene load_steps=11 format=3 uid="uid://bjhmjrldq4lkt"] [gd_scene load_steps=15 format=3 uid="uid://bjhmjrldq4lkt"]
[ext_resource type="PackedScene" uid="uid://b3gx0bl43lku3" path="res://Scenes/Player.tscn" id="1_vby0g"] [ext_resource type="PackedScene" uid="uid://b3gx0bl43lku3" path="res://Scenes/Player.tscn" id="1_vby0g"]
[ext_resource type="PackedScene" uid="uid://dk8x2aeq1eevf" path="res://Scenes/UI/BootScreen.tscn" id="2_7aede"] [ext_resource type="PackedScene" uid="uid://dk8x2aeq1eevf" path="res://Scenes/UI/BootScreen.tscn" id="2_7aede"]
[ext_resource type="PackedScene" uid="uid://bvll23f5ibd4v" path="res://Scenes/UI/LaunchScreen.tscn" id="2_7o53i"] [ext_resource type="PackedScene" uid="uid://bvll23f5ibd4v" path="res://Scenes/UI/LaunchScreen.tscn" id="2_7o53i"]
[ext_resource type="Script" path="res://Scripts/Launcher.cs" id="2_u5cms"] [ext_resource type="Script" path="res://Scripts/Launcher.cs" id="2_u5cms"]
[ext_resource type="Theme" uid="uid://b4dcn26i0p6ym" path="res://AceTheme.tres" id="2_w3ynu"]
[ext_resource type="Script" path="res://Scripts/Logic/Scoreboard.cs" id="3_as2wg"] [ext_resource type="Script" path="res://Scripts/Logic/Scoreboard.cs" id="3_as2wg"]
[ext_resource type="Script" path="res://Scripts/Logic/World.cs" id="3_xwguj"] [ext_resource type="Script" path="res://Scripts/Logic/World.cs" id="3_xwguj"]
[ext_resource type="PackedScene" uid="uid://cnf80yioktsvj" path="res://Scenes/UI/GameOverScreen.tscn" id="5_441wx"]
[ext_resource type="PackedScene" uid="uid://bb704b0kpwwkr" path="res://Scenes/UI/PlayerDiedScreen.tscn" id="5_pimes"] [ext_resource type="PackedScene" uid="uid://bb704b0kpwwkr" path="res://Scenes/UI/PlayerDiedScreen.tscn" id="5_pimes"]
[ext_resource type="PackedScene" uid="uid://c7w5sgq0bshk0" path="res://Scenes/UI/HUD.tscn" id="5_qvun1"] [ext_resource type="PackedScene" uid="uid://c7w5sgq0bshk0" path="res://Scenes/UI/HUD.tscn" id="5_qvun1"]
[ext_resource type="PackedScene" uid="uid://dfoy57v3q4of5" path="res://Scenes/UI/Leaderboard.tscn" id="7_j24m7"] [ext_resource type="PackedScene" uid="uid://dfoy57v3q4of5" path="res://Scenes/UI/Leaderboard.tscn" id="7_j24m7"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_48orl"]
size = Vector2(5000, 8)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_o3bru"]
size = Vector2(8, 5000)
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_gyspy"] [sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_gyspy"]
properties/0/path = NodePath(".:RoundProgress") properties/0/path = NodePath(".:RoundProgress")
properties/0/spawn = true properties/0/spawn = true
@@ -17,14 +25,37 @@ properties/0/replication_mode = 1
properties/1/path = NodePath(".:RoundTimeLeft") properties/1/path = NodePath(".:RoundTimeLeft")
properties/1/spawn = true properties/1/spawn = true
properties/1/replication_mode = 1 properties/1/replication_mode = 1
properties/2/path = NodePath(".:RoundCount")
properties/2/spawn = true
properties/2/replication_mode = 1
[node name="Node" type="Node"] [node name="Node" type="Node"]
[node name="WorldBorder" type="StaticBody2D" parent="."]
[node name="Top" type="CollisionShape2D" parent="WorldBorder"]
position = Vector2(2.08165e-12, -2500)
shape = SubResource("RectangleShape2D_48orl")
[node name="Bottom" type="CollisionShape2D" parent="WorldBorder"]
position = Vector2(2.08165e-12, 2500)
shape = SubResource("RectangleShape2D_48orl")
[node name="Left" type="CollisionShape2D" parent="WorldBorder"]
position = Vector2(2500, 2.08165e-12)
shape = SubResource("RectangleShape2D_o3bru")
[node name="Right" type="CollisionShape2D" parent="WorldBorder"]
position = Vector2(-2500, 2.08165e-12)
shape = SubResource("RectangleShape2D_o3bru")
[node name="LaunchScreen" parent="." node_paths=PackedStringArray("Launcher") instance=ExtResource("2_7o53i")] [node name="LaunchScreen" parent="." node_paths=PackedStringArray("Launcher") instance=ExtResource("2_7o53i")]
theme = ExtResource("2_w3ynu")
Launcher = NodePath("../LauncherNode") Launcher = NodePath("../LauncherNode")
[node name="BootScreen" parent="." node_paths=PackedStringArray("World") instance=ExtResource("2_7aede")] [node name="BootScreen" parent="." node_paths=PackedStringArray("World") instance=ExtResource("2_7aede")]
visible = false visible = false
theme = ExtResource("2_w3ynu")
World = NodePath("../World") World = NodePath("../World")
[node name="LauncherNode" type="Node" parent="." node_paths=PackedStringArray("World", "BootMenu", "Overlay")] [node name="LauncherNode" type="Node" parent="." node_paths=PackedStringArray("World", "BootMenu", "Overlay")]
@@ -38,22 +69,32 @@ script = ExtResource("3_as2wg")
[node name="OverlayLayer" type="CanvasLayer" parent="."] [node name="OverlayLayer" type="CanvasLayer" parent="."]
[node name="Leaderboard" parent="OverlayLayer" node_paths=PackedStringArray("Scoreboard") instance=ExtResource("7_j24m7")] [node name="PlayerDiedScreen" parent="OverlayLayer" instance=ExtResource("5_pimes")]
visible = false visible = false
theme = ExtResource("2_w3ynu")
[node name="GameOverScreen" parent="OverlayLayer" node_paths=PackedStringArray("Scoreboard") instance=ExtResource("5_441wx")]
process_mode = 3
visible = false
theme = ExtResource("2_w3ynu")
Scoreboard = NodePath("../../ScoreboardNode")
[node name="Leaderboard" parent="OverlayLayer" node_paths=PackedStringArray("Scoreboard") instance=ExtResource("7_j24m7")]
process_mode = 3
visible = false
theme = ExtResource("2_w3ynu")
Scoreboard = NodePath("../../ScoreboardNode") Scoreboard = NodePath("../../ScoreboardNode")
[node name="Hud" parent="OverlayLayer" node_paths=PackedStringArray("World") instance=ExtResource("5_qvun1")] [node name="Hud" parent="OverlayLayer" node_paths=PackedStringArray("World") instance=ExtResource("5_qvun1")]
visible = false visible = false
theme = ExtResource("2_w3ynu")
World = NodePath("../../World") World = NodePath("../../World")
[node name="PlayerDiedScreen" parent="OverlayLayer" instance=ExtResource("5_pimes")]
visible = false
[node name="World" type="Node2D" parent="." node_paths=PackedStringArray("Scoreboard")] [node name="World" type="Node2D" parent="." node_paths=PackedStringArray("Scoreboard")]
script = ExtResource("3_xwguj") script = ExtResource("3_xwguj")
Scoreboard = NodePath("../ScoreboardNode") Scoreboard = NodePath("../ScoreboardNode")
PlayerScene = ExtResource("1_vby0g") PlayerScene = ExtResource("1_vby0g")
RoundDuration = 10.0 RoundDuration = 180.0
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] [node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
root_path = NodePath("../World") root_path = NodePath("../World")

View File

@@ -0,0 +1,50 @@
[gd_scene load_steps=2 format=3 uid="uid://cnf80yioktsvj"]
[ext_resource type="Script" path="res://Scripts/UI/GameOverScreen.cs" id="1_j12ja"]
[node name="GameOverScreen" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_j12ja")
[node name="CenterContainer" type="CenterContainer" parent="."]
offset_right = 1152.0
offset_bottom = 648.0
[node name="Panel" type="Panel" parent="CenterContainer"]
custom_minimum_size = Vector2(340, 180)
layout_mode = 2
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/Panel"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -129.5
offset_top = -46.5
offset_right = 129.5
offset_bottom = 46.5
grow_horizontal = 2
grow_vertical = 2
[node name="Title" type="Label" parent="CenterContainer/Panel/VBoxContainer"]
layout_mode = 2
theme_override_font_sizes/font_size = 28
text = "Game over"
horizontal_alignment = 1
[node name="Caption" type="Label" parent="CenterContainer/Panel/VBoxContainer"]
layout_mode = 2
text = "You're in the 1st place"
horizontal_alignment = 1
[node name="Caption2" type="Label" parent="CenterContainer/Panel/VBoxContainer"]
layout_mode = 2
text = "Hold Tab key to view leaderboard"
horizontal_alignment = 1

View File

@@ -27,7 +27,7 @@ layout_mode = 2
[node name="MainTitle" type="Label" parent="CenterContainer/VBoxContainer"] [node name="MainTitle" type="Label" parent="CenterContainer/VBoxContainer"]
layout_mode = 2 layout_mode = 2
text = "AceField text = "AceField
Prototype · Closed test" Prototype v0.0.0"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="Spacer" type="BoxContainer" parent="CenterContainer/VBoxContainer"] [node name="Spacer" type="BoxContainer" parent="CenterContainer/VBoxContainer"]

View File

@@ -1,6 +1,7 @@
[gd_scene load_steps=2 format=3 uid="uid://b8s2m7gujfmp6"] [gd_scene load_steps=3 format=3 uid="uid://b8s2m7gujfmp6"]
[ext_resource type="Script" path="res://Scripts/UI/LeaderboardRecord.cs" id="1_jc2uj"] [ext_resource type="Script" path="res://Scripts/UI/LeaderboardRecord.cs" id="1_jc2uj"]
[ext_resource type="Theme" uid="uid://b4dcn26i0p6ym" path="res://AceTheme.tres" id="1_mb1ty"]
[node name="LeaderboardRecord" type="Control"] [node name="LeaderboardRecord" type="Control"]
layout_mode = 3 layout_mode = 3
@@ -14,6 +15,7 @@ offset_right = 0.12793
offset_bottom = 0.0959988 offset_bottom = 0.0959988
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
theme = ExtResource("1_mb1ty")
script = ExtResource("1_jc2uj") script = ExtResource("1_jc2uj")
[node name="Panel" type="Panel" parent="."] [node name="Panel" type="Panel" parent="."]

View File

@@ -13,16 +13,31 @@ layout_mode = 0
offset_right = 1152.0 offset_right = 1152.0
offset_bottom = 648.0 offset_bottom = 648.0
[node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer"] [node name="Panel" type="Panel" parent="CenterContainer"]
custom_minimum_size = Vector2(340, 120)
layout_mode = 2 layout_mode = 2
[node name="Title" type="Label" parent="CenterContainer/VBoxContainer"] [node name="VBoxContainer" type="VBoxContainer" parent="CenterContainer/Panel"]
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -92.0
offset_top = -33.0
offset_right = 92.0
offset_bottom = 33.0
grow_horizontal = 2
grow_vertical = 2
[node name="Title" type="Label" parent="CenterContainer/Panel/VBoxContainer"]
layout_mode = 2 layout_mode = 2
theme_override_font_sizes/font_size = 28 theme_override_font_sizes/font_size = 28
text = "You died" text = "You died"
horizontal_alignment = 1 horizontal_alignment = 1
[node name="Caption" type="Label" parent="CenterContainer/VBoxContainer"] [node name="Caption" type="Label" parent="CenterContainer/Panel/VBoxContainer"]
layout_mode = 2 layout_mode = 2
text = "Respawn in Next Round" text = "Respawn in Next Round"
horizontal_alignment = 1 horizontal_alignment = 1

View File

@@ -0,0 +1,35 @@
using Godot;
namespace AceField.Scripts.Effects;
public partial class OffScreenMarker : Node2D
{
public override void _Process(double delta)
{
var canvas = GetCanvasTransform();
var topLeft = -canvas.Origin / canvas.Scale;
var size = GetViewportRect().Size / canvas.Scale;
SetMarkerPosition(new Rect2(topLeft, size));
SetMarkerRotation();
}
private void SetMarkerPosition(Rect2 bounds)
{
var sprite = GetNode<Sprite2D>("Sprite2D");
sprite.GlobalPosition = new Vector2(
Mathf.Clamp(GlobalPosition.X, bounds.Position.X, bounds.End.X),
Mathf.Clamp(GlobalPosition.Y, bounds.Position.Y, bounds.End.Y)
);
if (bounds.HasPoint(GlobalPosition)) Hide();
else Show();
}
private void SetMarkerRotation()
{
var sprite = GetNode<Sprite2D>("Sprite2D");
var angle = (GlobalPosition - sprite.GlobalPosition).Angle();
sprite.GlobalRotation = angle;
sprite.GetNode<Sprite2D>("Arrow").GlobalRotation = 0;
}
}

View File

@@ -4,147 +4,172 @@ namespace AceField.Scripts.Logic;
public partial class World : Node2D public partial class World : Node2D
{ {
[Export] public Scoreboard Scoreboard; [Export] public Scoreboard Scoreboard;
[Export] public PackedScene PlayerScene; [Export] public PackedScene PlayerScene;
[Export] public int RoundCount = 1; [Export] public int RoundCount = 1;
[Export] public int RoundTotalCount = 20; [Export] public int RoundTotalCount = 20;
[Export] public double RoundDuration = 60; [Export] public double RoundDuration = 60;
[Export] public double RoundProgress; [Export] public double RoundProgress;
[Export] public double RoundTimeLeft; [Export] public double RoundTimeLeft;
private Timer _roundTimer; private Timer _roundTimer;
public void StartGame(string currentPlayerName = null) public void StartGame(string currentPlayerName = null)
{ {
if (!Multiplayer.IsServer()) if (!Multiplayer.IsServer())
return; return;
_roundTimer = new Timer(); _roundTimer = new Timer();
_roundTimer.WaitTime = RoundDuration; _roundTimer.WaitTime = RoundDuration;
_roundTimer.Autostart = true; _roundTimer.Autostart = true;
_roundTimer.Timeout += NewRound; _roundTimer.Timeout += NewRound;
_roundTimer.OneShot = true; _roundTimer.OneShot = true;
AddChild(_roundTimer); GetParent().AddChild(_roundTimer);
_roundTimer.Start(); _roundTimer.Start(RoundDuration);
// Add players into the game // Add players into the game
PutPlayers(currentPlayerName); PutPlayers(currentPlayerName);
} }
public override void _Ready() public override void _Ready()
{ {
if (!Multiplayer.IsServer()) if (!Multiplayer.IsServer())
return; return;
// Handling player connect / disconnect after this client connected // Handling player connect / disconnect after this client connected
Multiplayer.PeerDisconnected += RemovePlayer_Adaptor; Multiplayer.PeerDisconnected += RemovePlayer_Adaptor;
Multiplayer.PeerConnected += AddPlayer_Adaptor; Multiplayer.PeerConnected += AddPlayer_Adaptor;
// Handling player connected before this client // Handling player connected before this client
foreach (var id in Multiplayer.GetPeers()) foreach (var id in Multiplayer.GetPeers())
Scoreboard.AddPlayer(id); Scoreboard.AddPlayer(id);
// Add this client as a player if client isn't a dedicated server // Add this client as a player if client isn't a dedicated server
if (!OS.HasFeature("dedicated_server")) if (!OS.HasFeature("dedicated_server"))
Scoreboard.AddPlayer(1); Scoreboard.AddPlayer(1);
} }
public override void _ExitTree() public override void _ExitTree()
{ {
if (!Multiplayer.IsServer()) if (!Multiplayer.IsServer())
return; return;
Multiplayer.PeerDisconnected -= RemovePlayer_Adaptor; Multiplayer.PeerDisconnected -= RemovePlayer_Adaptor;
Multiplayer.PeerConnected -= AddPlayer_Adaptor; Multiplayer.PeerConnected -= AddPlayer_Adaptor;
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
if (Multiplayer.IsServer()) if (Multiplayer.IsServer())
{ {
RoundProgress = _roundTimer.TimeLeft / _roundTimer.WaitTime; RoundProgress = _roundTimer.TimeLeft / _roundTimer.WaitTime;
RoundTimeLeft = _roundTimer.TimeLeft; RoundTimeLeft = _roundTimer.TimeLeft;
} }
} }
private static string BuildPlayerName(int id) private static string BuildPlayerName(int id)
=> $"Player@{id}"; => $"Player@{id}";
private void AddPlayer_Adaptor(long id) private void AddPlayer_Adaptor(long id)
=> Scoreboard.AddPlayer((int)id); => Scoreboard.AddPlayer((int)id);
private void RemovePlayer_Adaptor(long id) private void RemovePlayer_Adaptor(long id)
=> Scoreboard.RemovePlayer((int)id); => Scoreboard.RemovePlayer((int)id);
private void SpawnPlayer(int id, string name = null) private void SpawnPlayer(int id, string name = null)
{ {
var player = PlayerScene.Instantiate<Player>(); var player = PlayerScene.Instantiate<Player>();
player.PlayerId = id; player.PlayerId = id;
var position = Vector2.FromAngle(GD.Randf() * 2 * Mathf.Pi); player.Position = new Vector2(GD.RandRange(-100, 100), GD.RandRange(-100, 100));
player.Position = new Vector2(position.X * 5f * GD.Randf(), position.Y * 5f * GD.Randf()); player.Name = BuildPlayerName(id);
player.Name = BuildPlayerName(id); player.PlayerDied += (killerId) =>
player.PlayerDied += (killerId) => {
{ if (killerId == 0) return;
if (killerId == 0) return; Scoreboard.AddScore(killerId);
Scoreboard.AddScore(killerId); if (CountPlayer() <= 2)
}; _roundTimer.Start(3);
};
AddChild(player, true); AddChild(player, true);
player.PlayerName = name; player.PlayerName = name;
} }
private void PutPlayers(string currentPlayerName = null) private void PutPlayers(string currentPlayerName = null)
{ {
// Spawn clients // Spawn clients
foreach (var id in Multiplayer.GetPeers()) foreach (var id in Multiplayer.GetPeers())
SpawnPlayer(id, Scoreboard.Players[id]?.Name); SpawnPlayer(id, Scoreboard.Players[id]?.Name);
// Spawn host // Spawn host
if (!OS.HasFeature("dedicated_server")) if (!OS.HasFeature("dedicated_server"))
SpawnPlayer(1, currentPlayerName ?? Scoreboard.Players[1]?.Name); SpawnPlayer(1, currentPlayerName ?? Scoreboard.Players[1]?.Name);
} }
private void NewRound() private void NewRound()
{ {
if (RoundCount >= RoundTotalCount) if (RoundCount >= RoundTotalCount)
{ {
// TODO End this game Rpc(nameof(EndGame));
return; return;
} }
RoundCount++;
foreach (var child in GetChildren())
{
if (child is not Timer)
child.QueueFree();
}
PutPlayers(); RoundCount++;
_roundTimer.Start(); Rpc(nameof(CleanWorld));
}
public Player GetCurrentPlayer() PutPlayers();
{ _roundTimer.Start(RoundDuration);
foreach (var child in GetChildren()) }
{
if (child is Player { IsCurrentPlayer: true } player)
{
return player;
}
}
return null; public Player GetCurrentPlayer()
} {
foreach (var child in GetChildren())
{
if (child is Player { IsCurrentPlayer: true } player)
return player;
}
public T GetTileByPosition<T>(Vector2 position) where T : Node2D return null;
{ }
foreach (var item in GetChildren())
{
if (item is T tile && tile.Position == position)
return tile;
}
return null; public int CountPlayer()
} {
} var count = 0;
foreach (var child in GetChildren())
{
if (child is Player)
count++;
}
return count;
}
public T GetTileByPosition<T>(Vector2 position) where T : Node2D
{
foreach (var item in GetChildren())
{
if (item is T tile && tile.Position == position)
return tile;
}
return null;
}
[Rpc(MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void CleanWorld()
{
foreach (var child in GetChildren())
{
child.QueueFree();
}
}
[Rpc(MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
private void EndGame()
{
GetParent().GetNode<Control>("OverlayLayer/Hud").Hide();
GetParent().GetNode<Control>("OverlayLayer/GameOverScreen").Show();
GetTree().Paused = true;
}
}

View File

@@ -24,7 +24,7 @@ public partial class BootScreen : Control
var count = Multiplayer.GetPeers().Length; var count = Multiplayer.GetPeers().Length;
PlayerCountLabel.Text = $"{(count + 1):00}/{16}"; PlayerCountLabel.Text = $"{(count + 1):00}/{16}";
StartGameButton.Disabled = !Multiplayer.IsServer(); StartGameButton.Disabled = !Multiplayer.IsServer() || Multiplayer.GetPeers().Length == 0;
} }
[Rpc(MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)] [Rpc(MultiplayerApi.RpcMode.AnyPeer, CallLocal = true)]
@@ -32,7 +32,6 @@ public partial class BootScreen : Control
{ {
EmitSignal(SignalName.StartGame); EmitSignal(SignalName.StartGame);
var name = string.IsNullOrEmpty(PlayerNameInput.Text) ? null : PlayerNameInput.Text; var name = string.IsNullOrEmpty(PlayerNameInput.Text) ? null : PlayerNameInput.Text;
// TODO Fix this I don't know why the first round player's name won't fully apply
World.Scoreboard.SetName(Multiplayer.GetUniqueId(), name ?? $"Player#{Multiplayer.GetUniqueId()}"); World.Scoreboard.SetName(Multiplayer.GetUniqueId(), name ?? $"Player#{Multiplayer.GetUniqueId()}");
World.StartGame(currentPlayerName: name); World.StartGame(currentPlayerName: name);
Hide(); Hide();

View File

@@ -0,0 +1,29 @@
using System.Linq;
using AceField.Scripts.Logic;
using Godot;
namespace AceField.Scripts.UI;
public partial class GameOverScreen : Control
{
[Export] public Scoreboard Scoreboard;
public override void _Process(double delta)
{
if (!Visible) return;
var data = Scoreboard.GetData(Multiplayer.GetUniqueId());
if (data == null) return;
var place = 1;
var list = Scoreboard.Players.ToList();
list.Sort((a, b) => b.Value.Score.CompareTo(a.Value.Score));
foreach (var item in list)
{
if (Multiplayer.GetUniqueId() == item.Key) break;
place++;
}
GetNode<Label>("CenterContainer/Panel/VBoxContainer/Caption").Text = $"You're in the {place} place";
}
}

View File

@@ -22,7 +22,7 @@ public partial class HUD : Control
roundBar.Value = World.RoundProgress * 100; roundBar.Value = World.RoundProgress * 100;
var roundLabel = GetNode<Label>("BottomBox/HBox/RoundLabel"); var roundLabel = GetNode<Label>("BottomBox/HBox/RoundLabel");
roundLabel.Text = $"Round {World.RoundCount}"; roundLabel.Text = $"Round {World.RoundCount:00}/{World.RoundTotalCount:00}";
var player = World.GetCurrentPlayer(); var player = World.GetCurrentPlayer();
if (player == null) return; if (player == null) return;

View File

@@ -1,3 +1,4 @@
using System.Linq;
using AceField.Scripts.Logic; using AceField.Scripts.Logic;
using Godot; using Godot;
@@ -12,7 +13,8 @@ public partial class Leaderboard : Control
Visible = Input.IsActionPressed("ui_leaderboard"); Visible = Input.IsActionPressed("ui_leaderboard");
if (!Visible) return; if (!Visible) return;
if (Scoreboard.Players.Count == 1) return;
if (GetNode<Control>("List").GetChildCount() != Scoreboard.Players.Count) if (GetNode<Control>("List").GetChildCount() != Scoreboard.Players.Count)
{ {
CleanNodes(); CleanNodes();
@@ -21,16 +23,17 @@ public partial class Leaderboard : Control
} }
var place = 1; var place = 1;
foreach (var node in GetNode<Control>("List").GetChildren()) var data = Scoreboard.Players.ToList();
data.Sort((a, b) => b.Value.Score.CompareTo(a.Value.Score));
foreach (var item in data)
{ {
if (node is not LeaderboardRecord record) continue; var record = GetNode<Control>("List").GetNode<LeaderboardRecord>($"Record_{place}");
var data = Scoreboard.GetData(record.PlayerId); record!.PlayerId = item.Key;
if (data == null) continue;
record.Place = place; record.Place = place;
record.Score = data.Score; record.Score = item.Value.Score;
record.PlayerName = data.Name; record.PlayerName = item.Value.Name;
place++; place++;
} }
@@ -56,6 +59,7 @@ public partial class Leaderboard : Control
instance.Score = record.Value.Score; instance.Score = record.Value.Score;
instance.PlayerId = record.Key; instance.PlayerId = record.Key;
instance.CustomMinimumSize = new Vector2(0, 80); instance.CustomMinimumSize = new Vector2(0, 80);
instance.Name = $"Record_{place}";
GetNode("List").AddChild(instance); GetNode("List").AddChild(instance);
place++; place++;
} }

BIN
Sprites/Alert.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

34
Sprites/Alert.png.import Normal file
View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bn86o1gfcj502"
path="res://.godot/imported/Alert.png-add14bdc40d4ac79d18d2f38934b24e1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Sprites/Alert.png"
dest_files=["res://.godot/imported/Alert.png-add14bdc40d4ac79d18d2f38934b24e1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@@ -1,14 +1,14 @@
[preset.0] [preset.0]
name="iOS" name="Windows Desktop"
platform="iOS" platform="Windows Desktop"
runnable=true runnable=true
dedicated_server=false dedicated_server=false
custom_features="" custom_features=""
export_filter="all_resources" export_filter="all_resources"
include_filter="" include_filter=""
exclude_filter="" exclude_filter=""
export_path="" export_path="../../../Desktop/AceField.exe"
encryption_include_filters="" encryption_include_filters=""
encryption_exclude_filters="" encryption_exclude_filters=""
encrypt_pck=false encrypt_pck=false
@@ -18,59 +18,199 @@ encrypt_directory=false
custom_template/debug="" custom_template/debug=""
custom_template/release="" custom_template/release=""
architectures/arm64=true debug/export_console_wrapper=1
application/app_store_team_id="" binary_format/embed_pck=true
application/code_sign_identity_debug="" texture_format/bptc=true
application/export_method_debug=1 texture_format/s3tc=true
application/code_sign_identity_release="" texture_format/etc=false
application/export_method_release=0 texture_format/etc2=false
application/targeted_device_family=2 binary_format/architecture="x86_64"
application/bundle_identifier="" codesign/enable=false
application/signature="" codesign/timestamp=true
application/short_version="" codesign/timestamp_server_url=""
application/version="" codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4 application/icon_interpolation=4
application/launch_screens_interpolation=4 application/file_version=""
application/export_project_only=false application/product_version=""
capabilities/access_wifi=false application/company_name=""
capabilities/push_notifications=false application/product_name=""
user_data/accessible_from_files_app=false application/file_description=""
user_data/accessible_from_itunes_sharing=false application/copyright=""
privacy/camera_usage_description="" application/trademarks=""
privacy/camera_usage_description_localized={} application/export_angle=0
privacy/microphone_usage_description="" ssh_remote_deploy/enabled=false
privacy/microphone_usage_description_localized={} ssh_remote_deploy/host="user@host_ip"
privacy/photolibrary_usage_description="" ssh_remote_deploy/port="22"
privacy/photolibrary_usage_description_localized={} ssh_remote_deploy/extra_args_ssh=""
icons/iphone_120x120="" ssh_remote_deploy/extra_args_scp=""
icons/iphone_180x180="" ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
icons/ipad_76x76="" $action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
icons/ipad_152x152="" $trigger = New-ScheduledTaskTrigger -Once -At 00:00
icons/ipad_167x167="" $settings = New-ScheduledTaskSettingsSet
icons/app_store_1024x1024="" $task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
icons/spotlight_40x40="" Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
icons/spotlight_80x80="" Start-ScheduledTask -TaskName godot_remote_debug
icons/settings_58x58="" while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
icons/settings_87x87="" Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
icons/notification_40x40="" ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
icons/notification_60x60="" Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
storyboard/use_launch_screen_storyboard=true Remove-Item -Recurse -Force '{temp_dir}'"
storyboard/image_scale_mode=0 dotnet/include_scripts_content=false
storyboard/custom_image@2x="" dotnet/include_debug_symbols=true
storyboard/custom_image@3x="" dotnet/embed_build_outputs=false
storyboard/use_custom_bg_color=false
storyboard/custom_bg_color=Color(0, 0, 0, 1) [preset.1]
landscape_launch_screens/iphone_2436x1125=""
landscape_launch_screens/iphone_2208x1242="" name="macOS"
landscape_launch_screens/ipad_1024x768="" platform="macOS"
landscape_launch_screens/ipad_2048x1536="" runnable=true
portrait_launch_screens/iphone_640x960="" dedicated_server=false
portrait_launch_screens/iphone_640x1136="" custom_features=""
portrait_launch_screens/iphone_750x1334="" export_filter="all_resources"
portrait_launch_screens/iphone_1125x2436="" include_filter=""
portrait_launch_screens/ipad_768x1024="" exclude_filter=""
portrait_launch_screens/ipad_1536x2048="" export_path="../../../Desktop/AceField.dmg"
portrait_launch_screens/iphone_1242x2208="" encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.1.options]
export/distribution_type=1
binary_format/architecture="universal"
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
application/icon=""
application/icon_interpolation=4
application/bundle_identifier="dev.solsynth.experimental.acefield"
application/signature=""
application/app_category="Games"
application/short_version=""
application/version=""
application/copyright=""
application/copyright_localized={}
application/min_macos_version="10.12"
application/export_angle=0
display/high_res=true
xcode/platform_build="14C18"
xcode/sdk_version="13.1"
xcode/sdk_build="22C55"
xcode/sdk_name="macosx13.1"
xcode/xcode_version="1420"
xcode/xcode_build="14C18"
codesign/codesign=3
codesign/installer_identity=""
codesign/apple_team_id="W7HPZ53V6B"
codesign/identity="726UDWS582"
codesign/entitlements/custom_file=""
codesign/entitlements/allow_jit_code_execution=false
codesign/entitlements/allow_unsigned_executable_memory=false
codesign/entitlements/allow_dyld_environment_variables=false
codesign/entitlements/disable_library_validation=false
codesign/entitlements/audio_input=false
codesign/entitlements/camera=false
codesign/entitlements/location=false
codesign/entitlements/address_book=false
codesign/entitlements/calendars=false
codesign/entitlements/photos_library=false
codesign/entitlements/apple_events=false
codesign/entitlements/debugging=false
codesign/entitlements/app_sandbox/enabled=false
codesign/entitlements/app_sandbox/network_server=false
codesign/entitlements/app_sandbox/network_client=false
codesign/entitlements/app_sandbox/device_usb=false
codesign/entitlements/app_sandbox/device_bluetooth=false
codesign/entitlements/app_sandbox/files_downloads=0
codesign/entitlements/app_sandbox/files_pictures=0
codesign/entitlements/app_sandbox/files_music=0
codesign/entitlements/app_sandbox/files_movies=0
codesign/entitlements/app_sandbox/files_user_selected=0
codesign/entitlements/app_sandbox/helper_executables=[]
codesign/custom_options=PackedStringArray()
notarization/notarization=0
privacy/microphone_usage_description=""
privacy/microphone_usage_description_localized={}
privacy/camera_usage_description=""
privacy/camera_usage_description_localized={}
privacy/location_usage_description=""
privacy/location_usage_description_localized={}
privacy/address_book_usage_description=""
privacy/address_book_usage_description_localized={}
privacy/calendar_usage_description=""
privacy/calendar_usage_description_localized={}
privacy/photos_library_usage_description=""
privacy/photos_library_usage_description_localized={}
privacy/desktop_folder_usage_description=""
privacy/desktop_folder_usage_description_localized={}
privacy/documents_folder_usage_description=""
privacy/documents_folder_usage_description_localized={}
privacy/downloads_folder_usage_description=""
privacy/downloads_folder_usage_description_localized={}
privacy/network_volumes_usage_description=""
privacy/network_volumes_usage_description_localized={}
privacy/removable_volumes_usage_description=""
privacy/removable_volumes_usage_description_localized={}
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
open \"{temp_dir}/{exe_name}.app\" --args {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name}.app/Contents/MacOS/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""
dotnet/include_scripts_content=false
dotnet/include_debug_symbols=true
dotnet/embed_build_outputs=false
[preset.2]
name="Linux/X11"
platform="Linux/X11"
runnable=true
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../../../Desktop/AceField.x86_64"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
[preset.2.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=true
texture_format/bptc=true
texture_format/s3tc=true
texture_format/etc=false
texture_format/etc2=false
binary_format/architecture="x86_64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
export DISPLAY=:0
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
\"{temp_dir}/{exe_name}\" {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""
dotnet/include_scripts_content=false dotnet/include_scripts_content=false
dotnet/include_debug_symbols=true dotnet/include_debug_symbols=true
dotnet/embed_build_outputs=false dotnet/embed_build_outputs=false

7
license Normal file
View File

@@ -0,0 +1,7 @@
Copyright 2024 Solsynth LLC
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -73,5 +73,8 @@ ui_leaderboard={
[rendering] [rendering]
renderer/rendering_method="mobile"
textures/vram_compression/import_etc2_astc=true textures/vram_compression/import_etc2_astc=true
anti_aliasing/quality/msaa_2d=3
anti_aliasing/quality/msaa_3d=3
anti_aliasing/quality/screen_space_aa=1
anti_aliasing/quality/use_taa=true