Compare commits
11 Commits
98b3202361
...
godot-4.5
| Author | SHA1 | Date | |
|---|---|---|---|
| 00772b6330 | |||
| 3d8694377a | |||
| bc3108ea37 | |||
| 7257242fce | |||
| 03abf91f59 | |||
| e6f8989d16 | |||
| db2a090acc | |||
| dfc9201f62 | |||
| 46553a351a | |||
| a8ff492aed | |||
| aa73e54b3e |
@@ -1,6 +1,4 @@
|
||||
using Godot;
|
||||
using Limbo.Console.Sharp;
|
||||
using Mr.BrickAdventures.scripts;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
@@ -17,66 +15,42 @@ public partial class ConsoleManager : Node
|
||||
_gameManager = GetNode<GameManager>("/root/GameManager");
|
||||
_achievementManager = GetNode<AchievementManager>("/root/AchievementManager");
|
||||
_skillManager = GetNode<SkillManager>("/root/SkillManager");
|
||||
|
||||
RegisterConsoleCommands();
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
UnregisterConsoleCommands();
|
||||
}
|
||||
|
||||
[ConsoleCommand("add_coins", "Adds a specified amount of coins to the player's total.")]
|
||||
private void AddCoinsCommand(int amount)
|
||||
{
|
||||
_gameManager.AddCoins(amount);
|
||||
LimboConsole.Info($"Increased coins by {amount}. Total coins: {_gameManager.GetCoins()}");
|
||||
}
|
||||
|
||||
[ConsoleCommand("set_coins", "Sets the player's total coins to a specified amount.")]
|
||||
private void SetCoinsCommand(int amount)
|
||||
{
|
||||
_gameManager.SetCoins(amount);
|
||||
LimboConsole.Info($"Set coins to {amount}. Total coins: {_gameManager.GetCoins()}");
|
||||
}
|
||||
|
||||
[ConsoleCommand("set_lives", "Sets the player's total lives to a specified amount.")]
|
||||
private void SetLivesCommand(int amount)
|
||||
{
|
||||
_gameManager.SetLives(amount);
|
||||
LimboConsole.Info($"Set lives to {amount}.");
|
||||
}
|
||||
|
||||
[ConsoleCommand("add_lives", "Adds a specified amount of lives to the player's total.")]
|
||||
private void AddLivesCommand(int amount)
|
||||
{
|
||||
_gameManager.AddLives(amount);
|
||||
LimboConsole.Info($"Increased lives by {amount}. Total lives: {_gameManager.GetLives()}");
|
||||
}
|
||||
|
||||
[ConsoleCommand("set_health", "Sets the player's health to a specified amount.")]
|
||||
private void SetHealthCommand(float amount)
|
||||
{
|
||||
var playerHealthComponent = _gameManager.Player.GetNode<HealthComponent>("HealthComponent");
|
||||
if (playerHealthComponent != null)
|
||||
{
|
||||
playerHealthComponent.Health = amount;
|
||||
LimboConsole.Info($"Set player health to {amount}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LimboConsole.Warn("Player HealthComponent not found.");
|
||||
}
|
||||
}
|
||||
|
||||
[ConsoleCommand("reset_session", "Resets the current session state.")]
|
||||
private void ResetSessionCommand()
|
||||
{
|
||||
_gameManager.ResetCurrentSessionState();
|
||||
LimboConsole.Info("Current session state has been reset.");
|
||||
}
|
||||
|
||||
[ConsoleCommand("unlock_skill", "Unlocks and activates a skill by its name.")]
|
||||
private void UnlockSkillCommand(string skillName)
|
||||
{
|
||||
if (!GetSkillManagement()) return;
|
||||
@@ -84,14 +58,12 @@ public partial class ConsoleManager : Node
|
||||
var skill = _skillManager.GetSkillByName(skillName);
|
||||
if (skill == null)
|
||||
{
|
||||
LimboConsole.Warn($"Skill '{skillName}' not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
_gameManager.UnlockSkill(skill);
|
||||
_skillManager.ActivateSkill(skill);
|
||||
_skillUnlockerComponent.EmitSignal(SkillUnlockerComponent.SignalName.SkillUnlocked, skill);
|
||||
LimboConsole.Info($"Skill '{skillName}' has been unlocked and activated.");
|
||||
}
|
||||
|
||||
private bool GetSkillManagement()
|
||||
@@ -99,7 +71,6 @@ public partial class ConsoleManager : Node
|
||||
var player = _gameManager.Player;
|
||||
if (player == null || !IsInstanceValid(player))
|
||||
{
|
||||
LimboConsole.Warn("Player node not found or is invalid.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -107,21 +78,17 @@ public partial class ConsoleManager : Node
|
||||
|
||||
if (_skillManager != null && _skillUnlockerComponent != null) return true;
|
||||
|
||||
LimboConsole.Warn("SkillManager or SkillUnlockerComponent not found on the player.");
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
[ConsoleCommand("unlock_all_skills", "Unlocks and activates all available skills.")]
|
||||
private void UnlockAllSkillsCommand()
|
||||
{
|
||||
if (!GetSkillManagement()) return;
|
||||
|
||||
_skillUnlockerComponent.UnlockAllSkills();
|
||||
LimboConsole.Info("All skills have been unlocked and activated.");
|
||||
}
|
||||
|
||||
[ConsoleCommand("remove_skill", "Deactivates and removes a skill by its name.")]
|
||||
private void RemoveSkillCommand(string skillName)
|
||||
{
|
||||
if (!GetSkillManagement()) return;
|
||||
@@ -129,16 +96,13 @@ public partial class ConsoleManager : Node
|
||||
var skill = _skillManager.GetSkillByName(skillName);
|
||||
if (skill == null)
|
||||
{
|
||||
LimboConsole.Warn($"Skill '{skillName}' not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
_gameManager.RemoveSkill(skill.Name);
|
||||
_skillManager.DeactivateSkill(skill);
|
||||
LimboConsole.Info($"Skill '{skillName}' has been deactivated.");
|
||||
}
|
||||
|
||||
[ConsoleCommand("remove_all_skills", "Deactivates and removes all skills.")]
|
||||
private void RemoveAllSkillsCommand()
|
||||
{
|
||||
if (!GetSkillManagement()) return;
|
||||
@@ -148,23 +112,18 @@ public partial class ConsoleManager : Node
|
||||
_gameManager.RemoveSkill(skill.Name);
|
||||
_skillManager.DeactivateSkill(skill);
|
||||
}
|
||||
LimboConsole.Info("All skills have been deactivated.");
|
||||
}
|
||||
|
||||
[ConsoleCommand("next_level", "Advances the game to the next level.")]
|
||||
private void GoToNextLevelCommand()
|
||||
{
|
||||
_gameManager.OnLevelComplete();
|
||||
}
|
||||
|
||||
[ConsoleCommand("unlock_achievement", "Unlocks an achievement by its ID.")]
|
||||
private void UnlockAchievementCommand(string achievementId)
|
||||
{
|
||||
_achievementManager.UnlockAchievement(achievementId);
|
||||
LimboConsole.Info($"Attempted to unlock achievement '{achievementId}'.");
|
||||
}
|
||||
|
||||
[ConsoleCommand("reset_achievement", "Resets (locks) an achievement by its ID.")]
|
||||
private void ResetAchievementCommand(string achievementId)
|
||||
{
|
||||
_achievementManager.LockAchievement(achievementId);
|
||||
|
||||
9
Autoloads/EventBus.cs
Normal file
9
Autoloads/EventBus.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
|
||||
public partial class EventBus : Node
|
||||
{
|
||||
[Signal] public delegate void LevelStartedEventHandler(int levelIndex, Node currentScene);
|
||||
[Signal] public delegate void LevelCompletedEventHandler(int levelIndex, Node currentScene, double completionTime);
|
||||
}
|
||||
1
Autoloads/EventBus.cs.uid
Normal file
1
Autoloads/EventBus.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bb2yq5wggdw3w
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
using Mr.BrickAdventures.scripts.Resources;
|
||||
using Double = System.Double;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
|
||||
@@ -18,6 +18,8 @@ public partial class GameManager : Node
|
||||
|
||||
private List<Node> _sceneNodes = [];
|
||||
private PlayerController _player;
|
||||
private SpeedRunManager _speedRunManager;
|
||||
private EventBus _eventBus;
|
||||
|
||||
[Export]
|
||||
public Dictionary PlayerState { get; set; } = new()
|
||||
@@ -50,6 +52,12 @@ public partial class GameManager : Node
|
||||
_sceneNodes.Clear();
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_speedRunManager = GetNode<SpeedRunManager>("/root/SpeedRunManager");
|
||||
_eventBus = GetNode<EventBus>("/root/EventBus");
|
||||
}
|
||||
|
||||
private void OnNodeAdded(Node node)
|
||||
{
|
||||
_sceneNodes.Add(node);
|
||||
@@ -133,7 +141,8 @@ public partial class GameManager : Node
|
||||
{ "current_level", 0 },
|
||||
{ "completed_levels", new Array<int>() },
|
||||
{ "unlocked_levels", new Array<int>() {0}},
|
||||
{ "unlocked_skills", new Array<SkillData>() }
|
||||
{ "unlocked_skills", new Array<SkillData>() },
|
||||
{ "statistics", new Godot.Collections.Dictionary<string, Variant>()}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -151,6 +160,7 @@ public partial class GameManager : Node
|
||||
{
|
||||
PlayerState["current_level"] = next;
|
||||
GetTree().ChangeSceneToPacked(LevelScenes[next]);
|
||||
_eventBus.EmitSignal(EventBus.SignalName.LevelStarted, next, GetTree().CurrentScene);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,6 +197,9 @@ public partial class GameManager : Node
|
||||
{
|
||||
ResetPlayerState();
|
||||
ResetCurrentSessionState();
|
||||
|
||||
_speedRunManager?.StartTimer();
|
||||
|
||||
GetTree().ChangeSceneToPacked(LevelScenes[0]);
|
||||
GetNode<SaveSystem>("/root/SaveSystem").SaveGame();
|
||||
}
|
||||
@@ -212,10 +225,14 @@ public partial class GameManager : Node
|
||||
{
|
||||
var levelIndex = (int)PlayerState["current_level"];
|
||||
MarkLevelComplete(levelIndex);
|
||||
|
||||
AddCoins((int)CurrentSessionState["coins_collected"]);
|
||||
foreach (var s in (Array)CurrentSessionState["skills_unlocked"])
|
||||
UnlockSkill((SkillData)s);
|
||||
|
||||
var completionTime = _speedRunManager?.GetCurrentLevelTime() ?? 0.0;
|
||||
_eventBus.EmitSignal(EventBus.SignalName.LevelCompleted, levelIndex, GetTree().CurrentScene, completionTime);
|
||||
|
||||
ResetCurrentSessionState();
|
||||
TryToGoToNextLevel();
|
||||
GetNode<SaveSystem>("/root/SaveSystem").SaveGame();
|
||||
|
||||
112
Autoloads/GhostManager.cs
Normal file
112
Autoloads/GhostManager.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
using Mr.BrickAdventures.scripts;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
|
||||
public partial class GhostManager : Node
|
||||
{
|
||||
[Export] private PackedScene GhostPlayerScene { get; set; }
|
||||
|
||||
public bool IsRecording { get; private set; } = false;
|
||||
public bool IsPlaybackEnabled { get; private set; } = true;
|
||||
|
||||
private List<GhostFrame> _currentRecording = [];
|
||||
private double _startTime = 0.0;
|
||||
private int _currentLevelIndex = -1;
|
||||
|
||||
public void StartRecording(int levelIndex)
|
||||
{
|
||||
if (!IsPlaybackEnabled) return;
|
||||
|
||||
_currentLevelIndex = levelIndex;
|
||||
_currentRecording.Clear();
|
||||
_startTime = Time.GetTicksMsec() / 1000.0;
|
||||
IsRecording = true;
|
||||
GD.Print("Ghost recording started.");
|
||||
}
|
||||
|
||||
public void StopRecording(bool levelCompleted, double finalTime)
|
||||
{
|
||||
if (!IsRecording) return;
|
||||
IsRecording = false;
|
||||
|
||||
if (levelCompleted)
|
||||
{
|
||||
var bestTime = LoadBestTime(_currentLevelIndex);
|
||||
if (finalTime < bestTime)
|
||||
{
|
||||
SaveGhostData(_currentLevelIndex, finalTime);
|
||||
GD.Print($"New best ghost saved for level {_currentLevelIndex}. Time: {finalTime}");
|
||||
}
|
||||
}
|
||||
_currentRecording.Clear();
|
||||
}
|
||||
|
||||
public void RecordFrame(Vector2 position)
|
||||
{
|
||||
if (!IsRecording) return;
|
||||
|
||||
var frame = new GhostFrame
|
||||
{
|
||||
Timestamp = (Time.GetTicksMsec() / 1000.0) - _startTime,
|
||||
Position = position
|
||||
};
|
||||
_currentRecording.Add(frame);
|
||||
}
|
||||
|
||||
public void SpawnGhostPlayer(int levelIndex, Node parent)
|
||||
{
|
||||
if (!IsPlaybackEnabled || GhostPlayerScene == null) return;
|
||||
|
||||
var ghostData = LoadGhostData(levelIndex);
|
||||
if (ghostData.Count > 0)
|
||||
{
|
||||
var ghostPlayer = GhostPlayerScene.Instantiate<GhostPlayer>();
|
||||
parent.AddChild(ghostPlayer);
|
||||
ghostPlayer.StartPlayback(ghostData);
|
||||
GD.Print($"Ghost player spawned for level {levelIndex}.");
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveGhostData(int levelIndex, double time)
|
||||
{
|
||||
var path = $"user://ghost_level_{levelIndex}.dat";
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Write);
|
||||
|
||||
var dataToSave = new Godot.Collections.Dictionary
|
||||
{
|
||||
{ "time", time },
|
||||
{ "frames", _currentRecording.ToArray() }
|
||||
};
|
||||
file.StoreVar(dataToSave);
|
||||
}
|
||||
|
||||
private List<GhostFrame> LoadGhostData(int levelIndex)
|
||||
{
|
||||
var path = $"user://ghost_level_{levelIndex}.dat";
|
||||
if (!FileAccess.FileExists(path)) return [];
|
||||
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||
var savedData = (Dictionary)file.GetVar();
|
||||
var framesArray = (Array)savedData["frames"];
|
||||
|
||||
var frames = new List<GhostFrame>();
|
||||
foreach (var obj in framesArray)
|
||||
{
|
||||
frames.Add((GhostFrame)obj);
|
||||
}
|
||||
return frames;
|
||||
}
|
||||
|
||||
private double LoadBestTime(int levelIndex)
|
||||
{
|
||||
var path = $"user://ghost_level_{levelIndex}.dat";
|
||||
if (!FileAccess.FileExists(path)) return double.MaxValue;
|
||||
|
||||
using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
|
||||
var data = (Dictionary)file.GetVar();
|
||||
return (double)data["time"];
|
||||
}
|
||||
}
|
||||
1
Autoloads/GhostManager.cs.uid
Normal file
1
Autoloads/GhostManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cgmuod4p2hg5h
|
||||
62
Autoloads/SpeedRunManager.cs
Normal file
62
Autoloads/SpeedRunManager.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
|
||||
public partial class SpeedRunManager : Node
|
||||
{
|
||||
public bool IsRunning { get; private set; } = false;
|
||||
public bool IsVisible { get; private set; } = false;
|
||||
|
||||
private double _startTime;
|
||||
private double _levelStartTime;
|
||||
private List<double> _splits = [];
|
||||
|
||||
[Signal] public delegate void TimeUpdatedEventHandler(double totalTime, double levelTime);
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (!IsRunning || !IsVisible) return;
|
||||
|
||||
EmitSignalTimeUpdated(GetCurrentTotalTime(), GetCurrentLevelTime());
|
||||
}
|
||||
|
||||
public void StartTimer()
|
||||
{
|
||||
_startTime = Time.GetTicksMsec() / 1000.0;
|
||||
_levelStartTime = _startTime;
|
||||
_splits.Clear();
|
||||
IsRunning = true;
|
||||
GD.Print("Speedrun timer started.");
|
||||
}
|
||||
|
||||
public void StopTimer()
|
||||
{
|
||||
if (!IsRunning) return;
|
||||
IsRunning = false;
|
||||
var finalTime = GetCurrentTotalTime();
|
||||
GD.Print($"Speedrun finished. Final time: {FormatTime(finalTime)}");
|
||||
|
||||
// Save personal best if applicable
|
||||
}
|
||||
|
||||
public void Split()
|
||||
{
|
||||
if (!IsRunning) return;
|
||||
|
||||
var now = Time.GetTicksMsec() / 1000.0;
|
||||
var splitTime = now - _levelStartTime;
|
||||
_splits.Add(splitTime);
|
||||
_levelStartTime = now;
|
||||
GD.Print($"Split recorded: {FormatTime(splitTime)}");
|
||||
}
|
||||
|
||||
public double GetCurrentTotalTime() => IsRunning ? (Time.GetTicksMsec() / 1000.0) - _startTime : 0;
|
||||
public double GetCurrentLevelTime() => IsRunning ? (Time.GetTicksMsec() / 1000.0) - _levelStartTime : 0;
|
||||
|
||||
public static string FormatTime(double time)
|
||||
{
|
||||
var span = System.TimeSpan.FromSeconds(time);
|
||||
return $"{(int)span.TotalMinutes:00}:{span.Seconds:00}.{span.Milliseconds:000}";
|
||||
}
|
||||
}
|
||||
1
Autoloads/SpeedRunManager.cs.uid
Normal file
1
Autoloads/SpeedRunManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c6ohe36xw1h21
|
||||
78
Autoloads/StatisticsManager.cs
Normal file
78
Autoloads/StatisticsManager.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Mr.BrickAdventures.Autoloads;
|
||||
|
||||
public partial class StatisticsManager : Node
|
||||
{
|
||||
private GameManager _gameManager;
|
||||
private AchievementManager _achievementManager;
|
||||
private Dictionary<string, Variant> _stats = new();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_gameManager = GetNode<GameManager>("/root/GameManager");
|
||||
_achievementManager = GetNode<AchievementManager>("/root/AchievementManager");
|
||||
LoadStatistics();
|
||||
}
|
||||
|
||||
private void LoadStatistics()
|
||||
{
|
||||
if (_gameManager.PlayerState.TryGetValue("statistics", out var statsObj))
|
||||
{
|
||||
_stats = (Dictionary<string, Variant>)statsObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
_stats = new Dictionary<string, Variant>();
|
||||
_gameManager.PlayerState["statistics"] = _stats;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases a numerical statistic by a given amount.
|
||||
/// </summary>
|
||||
public void IncrementStat(string statName, int amount = 1)
|
||||
{
|
||||
if (_stats.TryGetValue(statName, out var currentValue))
|
||||
{
|
||||
_stats[statName] = (int)currentValue + amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
_stats[statName] = amount;
|
||||
}
|
||||
GD.Print($"Stat '{statName}' updated to: {_stats[statName]}");
|
||||
CheckAchievementsForStat(statName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a statistic.
|
||||
/// </summary>
|
||||
public Variant GetStat(string statName, Variant defaultValue = default)
|
||||
{
|
||||
return _stats.TryGetValue(statName, out var value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the updated stat meets the criteria for any achievements.
|
||||
/// </summary>
|
||||
private void CheckAchievementsForStat(string statName)
|
||||
{
|
||||
switch (statName)
|
||||
{
|
||||
case "enemies_defeated":
|
||||
if ((int)GetStat(statName, 0) >= 100)
|
||||
{
|
||||
_achievementManager.UnlockAchievement("slayer_100_enemies");
|
||||
}
|
||||
break;
|
||||
case "jumps_made":
|
||||
if ((int)GetStat(statName, 0) >= 1000)
|
||||
{
|
||||
_achievementManager.UnlockAchievement("super_jumper");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
Autoloads/StatisticsManager.cs.uid
Normal file
1
Autoloads/StatisticsManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c5p3l2mhkw0p4
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Godot.NET.Sdk/4.4.1">
|
||||
<Project Sdk="Godot.NET.Sdk/4.5.0">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
@@ -8,6 +8,5 @@
|
||||
<PackageReference Include="Facepunch.Steamworks" Version="2.3.3" />
|
||||
<PackageReference Include="Facepunch.Steamworks.Dlls" Version="2.3.2" />
|
||||
<PackageReference Include="Facepunch.Steamworks.Library" Version="2.3.3" />
|
||||
<PackageReference Include="LimboConsole.Sharp" Version="0.0.1-beta-008" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,7 +1,9 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AArea2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F116d8c5f8dae51522ba398e1d89e3d4722f4af7b6e7f071196b928be44af7_003FArea2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACamera2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fa2e12a1a67ad701a97608de6be85250e3e353951ecf8058a02c703490c753_003FCamera2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACanvasItem_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fef7b819b226fab796d1dfe66d415dd7510bcac87675020ddb8f03a828e763_003FCanvasItem_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACecovym_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Ftmp_003FJetBrainsPerUserTemp_002D1000_002D1_003FSandboxFiles_003FSadijuw_003FCecovym_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACharacterBody2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fbba0bbd7a98ee58286e9484fbe86e01afff6232283f6efd3556eb7116453_003FCharacterBody2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACollisionShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F2ca9b7334678f5c97c7c2a9fbe4837be71cae11b6a30408dd4791b18f997e4a_003FCollisionShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ACSharpInstanceBridge_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F94701b444afa4c3d9a7a53ebcaa35fd1583c00_003F14_003F4b4ade3f_003FCSharpInstanceBridge_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADelegateUtils_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F94701b444afa4c3d9a7a53ebcaa35fd1583c00_003F08_003F45f75e10_003FDelegateUtils_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
@@ -9,5 +11,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003Fe747192abb38e2df82cbdb37e721567726f559914a7b81f8b26ba537de632f4_003FList_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AMr_002EBrickAdventures_002Escripts_002Ecomponents_002ECollectableComponent_005FScriptSignals_002Egenerated_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F80d9408eb7280c15eb4a12b61cdf8f7f1b0c5a2_003FMr_002EBrickAdventures_002Escripts_002Ecomponents_002ECollectableComponent_005FScriptSignals_002Egenerated_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ANode2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F86db9cd834346aad02d74c1b66dd9c64d6ef3147435dd9c9c9477b48f7_003FNode2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APhysicsBody2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F4fcd28ddaffa68e6fe53288161b788dea7d402b4a41b9d9f0f0f2c52f9af075_003FPhysicsBody2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARectangleShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003Fa1cc98873548652da0c14ecefa4737431426fcbb24a7f0641e3d9c266c3_003FRectangleShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ARigidBody2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E2_003Fresharper_002Dhost_003FSourcesCache_003F7bc3ccc1ac5bbc68933d64c7b7eb5ab4aecde2b73c686dd6495b68bdf08ba5b2_003FRigidBody2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AShape2D_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FSourcesCache_003F3671dbbd9b17cdf2bf9075b468b6bd7e3ab13fc3be7a116484085d3b6cc9fe_003FShape2D_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=25 format=3 uid="uid://bockkmyn8il4c"]
|
||||
[gd_scene load_steps=26 format=3 uid="uid://bockkmyn8il4c"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="1_hh6y0"]
|
||||
[ext_resource type="Texture2D" uid="uid://duxx56wxmjoxd" path="res://sprites/basic_enemy.png" id="2_laaj3"]
|
||||
@@ -14,6 +14,7 @@
|
||||
[ext_resource type="AudioStream" uid="uid://b3tsqhr06pbrs" path="res://sfx/enemy_hurt.wav" id="14_ndloc"]
|
||||
[ext_resource type="AudioStream" uid="uid://dyev46uqusimi" path="res://sfx/shoot.wav" id="15_cg63s"]
|
||||
[ext_resource type="PackedScene" uid="uid://dx80ivlvuuew4" path="res://objects/fxs/fire_fx.tscn" id="16_jqaq6"]
|
||||
[ext_resource type="Script" uid="uid://cgfynrn68lp12" path="res://scripts/components/KnockbackComponent.cs" id="17_ih01d"]
|
||||
[ext_resource type="PackedScene" uid="uid://ck6nml06tm6ue" path="res://objects/fxs/ice_fx.tscn" id="17_o7qsb"]
|
||||
[ext_resource type="PackedScene" uid="uid://b12tppjkkqpt4" path="res://objects/fxs/hit_particles.tscn" id="18_v861c"]
|
||||
|
||||
@@ -172,3 +173,7 @@ visible = false
|
||||
[node name="HitParticles" parent="." instance=ExtResource("18_v861c")]
|
||||
position = Vector2(0, 1)
|
||||
process_material = SubResource("ParticleProcessMaterial_pxaaa")
|
||||
|
||||
[node name="KnockbackComponent" type="Node" parent="."]
|
||||
script = ExtResource("17_ih01d")
|
||||
metadata/_custom_type_script = "uid://cgfynrn68lp12"
|
||||
|
||||
31
objects/entities/bouncing_mushroom.tscn
Normal file
31
objects/entities/bouncing_mushroom.tscn
Normal file
@@ -0,0 +1,31 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://c0j1yun5s7kns"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bu0yv6rktj221" path="res://sprites/bouncing_mushroom.png" id="1_t1exj"]
|
||||
[ext_resource type="Script" uid="uid://bgbnof7aeydmq" path="res://scripts/components/JumpPadComponent.cs" id="2_w2gbr"]
|
||||
[ext_resource type="PackedScene" uid="uid://qo2ngbnkix85" path="res://objects/fxs/bounce_gfx.tscn" id="3_w2gbr"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ci3ij"]
|
||||
size = Vector2(22, 10)
|
||||
|
||||
[node name="Bouncing Mushrrom" type="Area2D"]
|
||||
modulate = Color(1.1, 1.1, 1.1, 1)
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(0, -13)
|
||||
shape = SubResource("RectangleShape2D_ci3ij")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
position = Vector2(0, -8)
|
||||
texture = ExtResource("1_t1exj")
|
||||
hframes = 2
|
||||
|
||||
[node name="JumpPadComponent" type="Node" parent="." node_paths=PackedStringArray("Area", "Sprite", "Particles")]
|
||||
script = ExtResource("2_w2gbr")
|
||||
JumpForce = 600.0
|
||||
Area = NodePath("..")
|
||||
Sprite = NodePath("../Sprite2D")
|
||||
Particles = NodePath("../BounceGFX")
|
||||
|
||||
[node name="BounceGFX" parent="." instance=ExtResource("3_w2gbr")]
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=52 format=3 uid="uid://bqi5s710xb1ju"]
|
||||
[gd_scene load_steps=58 format=3 uid="uid://bqi5s710xb1ju"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://csel4s0e4g5uf" path="res://scripts/components/PlayerController.cs" id="1_yysbb"]
|
||||
[ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="2_lgb3u"]
|
||||
@@ -16,12 +16,12 @@
|
||||
[ext_resource type="PackedScene" uid="uid://chjbi5mgtwhsh" path="res://objects/movement_abilities/wall_jump_ability.tscn" id="7_bnap0"]
|
||||
[ext_resource type="Script" uid="uid://ck6kmnbwhsttt" path="res://scripts/components/Movement/OneWayPlatformAbility.cs" id="7_uno3u"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhkwyv6ayb5qb" path="res://sprites/flying_ship.png" id="8_6lsog"]
|
||||
[ext_resource type="PackedScene" uid="uid://dre1vit1m4d2n" path="res://objects/movement_abilities/grid_movement_ability.tscn" id="8_xuhvf"]
|
||||
[ext_resource type="Script" uid="uid://dy78ak8eykw6e" path="res://scripts/components/FlipComponent.cs" id="9_yysbb"]
|
||||
[ext_resource type="Script" uid="uid://mnjg3p0aw1ow" path="res://scripts/components/CanPickUpComponent.cs" id="10_yysbb"]
|
||||
[ext_resource type="Script" uid="uid://ccqb8kd5m0eh7" path="res://scripts/components/ScoreComponent.cs" id="11_o1ihh"]
|
||||
[ext_resource type="Script" uid="uid://dgb8bqcri7nsj" path="res://scripts/components/HealthComponent.cs" id="12_ur2y5"]
|
||||
[ext_resource type="Script" uid="uid://byw1legrv1ep2" path="res://scripts/components/PlayerDeathComponent.cs" id="13_7til7"]
|
||||
[ext_resource type="Script" uid="uid://cgfynrn68lp12" path="res://scripts/components/KnockbackComponent.cs" id="14_e5pae"]
|
||||
[ext_resource type="Script" uid="uid://cecelixl41t3j" path="res://scripts/components/InvulnerabilityComponent.cs" id="15_xuhvf"]
|
||||
[ext_resource type="Script" uid="uid://dvyd26ricriql" path="res://scripts/components/FlashingComponent.cs" id="16_uno3u"]
|
||||
[ext_resource type="Script" uid="uid://dtg6115je7b5s" path="res://scripts/components/StompDamageComponent.cs" id="17_bl1gx"]
|
||||
@@ -39,7 +39,13 @@
|
||||
[ext_resource type="PackedScene" uid="uid://dtem8jgcyoqar" path="res://objects/entities/green_laser.tscn" id="36_oxudy"]
|
||||
[ext_resource type="Script" uid="uid://dupnaark1f7gm" path="res://scripts/components/ProgressiveDamageComponent.cs" id="38_dhjci"]
|
||||
[ext_resource type="Script" uid="uid://dssa2taiwktis" path="res://scripts/components/Movement/PlayerInputHandler.cs" id="42_e5pae"]
|
||||
[ext_resource type="Script" uid="uid://c00siqtssccr6" path="res://scripts/components/PacXonGridInteractor.cs" id="42_xuhvf"]
|
||||
[ext_resource type="Script" uid="uid://ceoxet1nqws8w" path="res://scripts/components/SpriteTilterComponent.cs" id="43_xuhvf"]
|
||||
[ext_resource type="Script" uid="uid://cmk4m7mplqnrm" path="res://scripts/components/PacXonTrailComponent.cs" id="44_uno3u"]
|
||||
[ext_resource type="PackedScene" uid="uid://de5emerpbiknb" path="res://objects/fxs/foot_step_gfx.tscn" id="45_bl1gx"]
|
||||
[ext_resource type="Script" uid="uid://d3ksrjt1ek4gi" path="res://scripts/components/FootstepGfx.cs" id="46_6n1ss"]
|
||||
[ext_resource type="Script" uid="uid://bpopfy6m4a0br" path="res://scripts/components/JumpGfxComponent.cs" id="47_oefns"]
|
||||
[ext_resource type="PackedScene" uid="uid://bqhondao5bm6k" path="res://objects/fxs/jump_cloud_fx.tscn" id="48_bnap0"]
|
||||
[ext_resource type="Script" uid="uid://b1h8r5irryxcx" path="res://scripts/components/PlayerSfxComponent.cs" id="49_qec3q"]
|
||||
[ext_resource type="Script" uid="uid://b2aanqykvdnev" path="res://scripts/components/PlayerGraphicsComponent.cs" id="50_dhjci"]
|
||||
|
||||
@@ -98,6 +104,7 @@ GravityScene = ExtResource("4_qec3q")
|
||||
OneWayPlatformScene = ExtResource("5_dhjci")
|
||||
SpaceshipMovementScene = ExtResource("6_721q0")
|
||||
WallJumpScene = ExtResource("7_bnap0")
|
||||
GridMovementScene = ExtResource("8_xuhvf")
|
||||
metadata/_custom_type_script = "uid://csel4s0e4g5uf"
|
||||
|
||||
[node name="Movements" type="Node" parent="."]
|
||||
@@ -182,11 +189,6 @@ script = ExtResource("13_7til7")
|
||||
DeathSfx = NodePath("../sfx_hurt")
|
||||
HealthComponent = NodePath("../HealthComponent")
|
||||
|
||||
[node name="KnockbackComponent" type="Node" parent="." node_paths=PackedStringArray("HealthComponent")]
|
||||
script = ExtResource("14_e5pae")
|
||||
KnockbackForce = 1250.0
|
||||
HealthComponent = NodePath("../HealthComponent")
|
||||
|
||||
[node name="InvulnerabilityComponent" type="Node" parent="." node_paths=PackedStringArray("FlashingComponent")]
|
||||
script = ExtResource("15_xuhvf")
|
||||
FlashingComponent = NodePath("../FlashingComponent Base")
|
||||
@@ -302,3 +304,31 @@ script = ExtResource("38_dhjci")
|
||||
HealthComponent = NodePath("../HealthComponent")
|
||||
Sprite = NodePath("../Graphics/Root/Base")
|
||||
metadata/_custom_type_script = "uid://dupnaark1f7gm"
|
||||
|
||||
[node name="PacXonGridInteractor" type="Node" parent="."]
|
||||
script = ExtResource("42_xuhvf")
|
||||
metadata/_custom_type_script = "uid://c00siqtssccr6"
|
||||
|
||||
[node name="PacXonTrailComponent" type="Line2D" parent="."]
|
||||
script = ExtResource("44_uno3u")
|
||||
metadata/_custom_type_script = "uid://cmk4m7mplqnrm"
|
||||
|
||||
[node name="Feet" type="Marker2D" parent="."]
|
||||
position = Vector2(0, 16)
|
||||
|
||||
[node name="FootstepGfx" type="Node2D" parent="." node_paths=PackedStringArray("_controller", "_marker")]
|
||||
script = ExtResource("46_6n1ss")
|
||||
_particles = ExtResource("45_bl1gx")
|
||||
_controller = NodePath("..")
|
||||
_marker = NodePath("../Feet")
|
||||
_stepInterval = 0.4
|
||||
_stepIntervalRandomness = 0.15
|
||||
_minMoveSpeed = 4.0
|
||||
_randomOffsetRange = 0.3
|
||||
metadata/_custom_type_script = "uid://d3ksrjt1ek4gi"
|
||||
|
||||
[node name="JumpGfxComponent" type="Node2D" parent="." node_paths=PackedStringArray("Controller")]
|
||||
script = ExtResource("47_oefns")
|
||||
ParticleScene = ExtResource("48_bnap0")
|
||||
Controller = NodePath("..")
|
||||
metadata/_custom_type_script = "uid://bpopfy6m4a0br"
|
||||
|
||||
41
objects/entities/cactus.tscn
Normal file
41
objects/entities/cactus.tscn
Normal file
@@ -0,0 +1,41 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://un55bdc2cg2q"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_1nndd"]
|
||||
[ext_resource type="Script" uid="uid://cgfynrn68lp12" path="res://scripts/components/KnockbackComponent.cs" id="2_bljtt"]
|
||||
[ext_resource type="Script" uid="uid://nhu2xd8611fk" path="res://scripts/components/HazardComponent.cs" id="3_bljtt"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_14ml2"]
|
||||
size = Vector2(14, 15)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4q8oh"]
|
||||
size = Vector2(16, 16)
|
||||
|
||||
[node name="Cactus" type="StaticBody2D"]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(0, 0.5)
|
||||
shape = SubResource("RectangleShape2D_14ml2")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture = ExtResource("1_1nndd")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 71
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
collision_mask = 12
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
position = Vector2(-0.5, 0)
|
||||
shape = SubResource("RectangleShape2D_4q8oh")
|
||||
debug_color = Color(0.285572, 0.422655, 0.118384, 0.42)
|
||||
|
||||
[node name="KnockbackComponent" type="Node" parent="."]
|
||||
script = ExtResource("2_bljtt")
|
||||
metadata/_custom_type_script = "uid://cgfynrn68lp12"
|
||||
|
||||
[node name="HazardComponent" type="Node2D" parent="." node_paths=PackedStringArray("KnockbackComponent", "HazardArea")]
|
||||
script = ExtResource("3_bljtt")
|
||||
KnockbackComponent = NodePath("../KnockbackComponent")
|
||||
HazardArea = NodePath("../Area2D")
|
||||
metadata/_custom_type_script = "uid://nhu2xd8611fk"
|
||||
@@ -1,26 +0,0 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://dstko446qydsc"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_6gptm"]
|
||||
[ext_resource type="Script" uid="uid://ctfrbj52ejay4" path="res://scripts/components/DestroyableComponent.cs" id="2_q37h7"]
|
||||
[ext_resource type="Script" uid="uid://dgb8bqcri7nsj" path="res://scripts/components/HealthComponent.cs" id="3_bhwy3"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_j5sus"]
|
||||
size = Vector2(16, 16)
|
||||
|
||||
[node name="Cannon" type="StaticBody2D"]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture = ExtResource("1_6gptm")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 42
|
||||
|
||||
[node name="DestroyableComponent" type="Node" parent="." node_paths=PackedStringArray("Health")]
|
||||
script = ExtResource("2_q37h7")
|
||||
Health = NodePath("../HealthComponent")
|
||||
|
||||
[node name="HealthComponent" type="Node2D" parent="."]
|
||||
script = ExtResource("3_bhwy3")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_j5sus")
|
||||
72
objects/entities/cannon_bullet.tscn
Normal file
72
objects/entities/cannon_bullet.tscn
Normal file
@@ -0,0 +1,72 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://chetx6gmnwbxi"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_alaj6"]
|
||||
[ext_resource type="Script" uid="uid://2i7p7v135u7c" path="res://scripts/components/DamageComponent.cs" id="2_xmjlg"]
|
||||
[ext_resource type="Script" uid="uid://cs6u3sh68f43j" path="res://scripts/components/OutOfScreenComponent.cs" id="3_jege3"]
|
||||
[ext_resource type="Script" uid="uid://oyf25mpc5etr" path="res://scripts/components/LifetimeComponent.cs" id="4_aniyw"]
|
||||
[ext_resource type="Script" uid="uid://cbexrnnj47f87" path="res://scripts/components/LaunchComponent.cs" id="5_3ks47"]
|
||||
[ext_resource type="Script" uid="uid://c7p06t0eax8am" path="res://scripts/components/StraightMotionComponent.cs" id="6_4cg6n"]
|
||||
[ext_resource type="Script" uid="uid://cfw8nbrarex0i" path="res://scripts/components/BulletComponent.cs" id="7_cr5p0"]
|
||||
[ext_resource type="PackedScene" uid="uid://c1iorglk708g0" path="res://objects/fxs/terrain_hit_fx.tscn" id="8_ivkeb"]
|
||||
[ext_resource type="Script" uid="uid://dgb8bqcri7nsj" path="res://scripts/components/HealthComponent.cs" id="9_gx2e5"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_txsw8"]
|
||||
radius = 4.0
|
||||
|
||||
[node name="Bullet" type="Area2D"]
|
||||
collision_layer = 64
|
||||
collision_mask = 85
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("CircleShape2D_txsw8")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
modulate = Color(1.5, 1, 1, 1)
|
||||
scale = Vector2(0.5, 0.5)
|
||||
texture = ExtResource("1_alaj6")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 79
|
||||
|
||||
[node name="VisibleOnScreenNotifier2D" type="VisibleOnScreenNotifier2D" parent="."]
|
||||
position = Vector2(2.38419e-07, 2.38419e-07)
|
||||
scale = Vector2(0.4, 0.4)
|
||||
|
||||
[node name="DamageComponent" type="Node" parent="." node_paths=PackedStringArray("Area", "DamageTimer")]
|
||||
script = ExtResource("2_xmjlg")
|
||||
Area = NodePath("..")
|
||||
DamageTimer = NodePath("../Timer")
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
wait_time = 5.0
|
||||
autostart = true
|
||||
|
||||
[node name="OutOfScreenComponent" type="Node" parent="." node_paths=PackedStringArray("VisibilityNotifier")]
|
||||
script = ExtResource("3_jege3")
|
||||
VisibilityNotifier = NodePath("../VisibleOnScreenNotifier2D")
|
||||
|
||||
[node name="LifetimeComponent" type="Node" parent="."]
|
||||
script = ExtResource("4_aniyw")
|
||||
LifeTime = 3.0
|
||||
|
||||
[node name="LaunchComponent" type="Node2D" parent="."]
|
||||
script = ExtResource("5_3ks47")
|
||||
Speed = 160.0
|
||||
|
||||
[node name="StraightMotionComponent" type="Node" parent="." node_paths=PackedStringArray("LaunchComponent")]
|
||||
script = ExtResource("6_4cg6n")
|
||||
LaunchComponent = NodePath("../LaunchComponent")
|
||||
|
||||
[node name="BulletComponent" type="Node" parent="." node_paths=PackedStringArray("Area", "TerrainHitFx", "BulletSprite")]
|
||||
script = ExtResource("7_cr5p0")
|
||||
Area = NodePath("..")
|
||||
TerrainHitFx = NodePath("../TerrainHitFX")
|
||||
BulletSprite = NodePath("../Sprite2D")
|
||||
|
||||
[node name="TerrainHitFX" parent="." instance=ExtResource("8_ivkeb")]
|
||||
z_index = 3
|
||||
|
||||
[node name="HealthComponent" type="Node2D" parent="."]
|
||||
script = ExtResource("9_gx2e5")
|
||||
Health = 0.1
|
||||
metadata/_custom_type_script = "uid://dgb8bqcri7nsj"
|
||||
48
objects/entities/cannon_down.tscn
Normal file
48
objects/entities/cannon_down.tscn
Normal file
@@ -0,0 +1,48 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://qrbiu1qo4tt5"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_0efvn"]
|
||||
[ext_resource type="Script" uid="uid://bnaxy8cw3wrko" path="res://scripts/components/PeriodicShootingComponent.cs" id="2_4ycs1"]
|
||||
[ext_resource type="PackedScene" uid="uid://chetx6gmnwbxi" path="res://objects/entities/cannon_bullet.tscn" id="3_ab2uh"]
|
||||
[ext_resource type="Script" uid="uid://b3j23e7b7x8ro" path="res://scripts/components/RecoilComponent.cs" id="4_tynaf"]
|
||||
[ext_resource type="Script" uid="uid://c707c53k7c5ae" path="res://scripts/components/SquashAndStretchComponent.cs" id="5_0xigu"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_j5sus"]
|
||||
size = Vector2(16, 16)
|
||||
|
||||
[node name="Cannon" type="StaticBody2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
rotation = 3.14159
|
||||
texture = ExtResource("1_0efvn")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 42
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_j5sus")
|
||||
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("BulletSpawnPointRight")]
|
||||
script = ExtResource("2_4ycs1")
|
||||
BulletScene = ExtResource("3_ab2uh")
|
||||
ShootInterval = 3.0
|
||||
ShootDirection = Vector2(0, 1)
|
||||
BulletSpawnPointRight = NodePath("../Bullet spawn")
|
||||
ShootingIntervalVariation = 0.61
|
||||
metadata/_custom_type_script = "uid://bnaxy8cw3wrko"
|
||||
|
||||
[node name="Bullet spawn" type="Marker2D" parent="."]
|
||||
position = Vector2(0, 12)
|
||||
|
||||
[node name="RecoilComponent" type="Node" parent="." node_paths=PackedStringArray("RecoilTarget")]
|
||||
script = ExtResource("4_tynaf")
|
||||
RecoilTarget = NodePath("../Sprite2D")
|
||||
RecoilDistance = 4.0
|
||||
RecoilDuration = 0.12
|
||||
metadata/_custom_type_script = "uid://b3j23e7b7x8ro"
|
||||
|
||||
[node name="SquashAndStretchComponent" type="Node" parent="." node_paths=PackedStringArray("TargetNode")]
|
||||
script = ExtResource("5_0xigu")
|
||||
TargetNode = NodePath("../Sprite2D")
|
||||
metadata/_custom_type_script = "uid://c707c53k7c5ae"
|
||||
48
objects/entities/cannon_left.tscn
Normal file
48
objects/entities/cannon_left.tscn
Normal file
@@ -0,0 +1,48 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://cm0rd70wafif1"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_hnnrt"]
|
||||
[ext_resource type="Script" uid="uid://bnaxy8cw3wrko" path="res://scripts/components/PeriodicShootingComponent.cs" id="2_cho7n"]
|
||||
[ext_resource type="PackedScene" uid="uid://chetx6gmnwbxi" path="res://objects/entities/cannon_bullet.tscn" id="3_kgmtj"]
|
||||
[ext_resource type="Script" uid="uid://b3j23e7b7x8ro" path="res://scripts/components/RecoilComponent.cs" id="4_nfk87"]
|
||||
[ext_resource type="Script" uid="uid://c707c53k7c5ae" path="res://scripts/components/SquashAndStretchComponent.cs" id="5_43fqe"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_j5sus"]
|
||||
size = Vector2(16, 16)
|
||||
|
||||
[node name="Cannon" type="StaticBody2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
rotation = -1.5708
|
||||
texture = ExtResource("1_hnnrt")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 42
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_j5sus")
|
||||
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("BulletSpawnPointRight")]
|
||||
script = ExtResource("2_cho7n")
|
||||
BulletScene = ExtResource("3_kgmtj")
|
||||
ShootInterval = 3.0
|
||||
ShootDirection = Vector2(-1, 0)
|
||||
BulletSpawnPointRight = NodePath("../Bullet spawn")
|
||||
ShootingIntervalVariation = 0.61
|
||||
metadata/_custom_type_script = "uid://bnaxy8cw3wrko"
|
||||
|
||||
[node name="Bullet spawn" type="Marker2D" parent="."]
|
||||
position = Vector2(-12, 0)
|
||||
|
||||
[node name="RecoilComponent" type="Node" parent="." node_paths=PackedStringArray("RecoilTarget")]
|
||||
script = ExtResource("4_nfk87")
|
||||
RecoilTarget = NodePath("../Sprite2D")
|
||||
RecoilDistance = 4.0
|
||||
RecoilDuration = 0.12
|
||||
metadata/_custom_type_script = "uid://b3j23e7b7x8ro"
|
||||
|
||||
[node name="SquashAndStretchComponent" type="Node" parent="." node_paths=PackedStringArray("TargetNode")]
|
||||
script = ExtResource("5_43fqe")
|
||||
TargetNode = NodePath("../Sprite2D")
|
||||
metadata/_custom_type_script = "uid://c707c53k7c5ae"
|
||||
@@ -1,33 +0,0 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://dfwpha0d18dmn"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_rwgpm"]
|
||||
[ext_resource type="Script" uid="uid://2i7p7v135u7c" path="res://scripts/components/DamageComponent.cs" id="2_hrj61"]
|
||||
[ext_resource type="Script" uid="uid://df1llrbm80e02" path="res://scripts/components/BeamComponent.cs" id="3_hrj61"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ptfn7"]
|
||||
size = Vector2(8, 16)
|
||||
|
||||
[node name="Cannon Ray" type="Area2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 5
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture_repeat = 2
|
||||
texture = ExtResource("1_rwgpm")
|
||||
region_enabled = true
|
||||
region_rect = Rect2(176, 64, 16, 16)
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_ptfn7")
|
||||
|
||||
[node name="DamageComponent" type="Node" parent="." node_paths=PackedStringArray("Area")]
|
||||
script = ExtResource("2_hrj61")
|
||||
Area = NodePath("..")
|
||||
|
||||
[node name="BeamComponent" type="Node2D" parent="." node_paths=PackedStringArray("Root", "Sprite", "CollisionShape")]
|
||||
position = Vector2(0, -8)
|
||||
script = ExtResource("3_hrj61")
|
||||
ExpansionSpeed = 16.0
|
||||
Root = NodePath(".")
|
||||
Sprite = NodePath("../Sprite2D")
|
||||
CollisionShape = NodePath("../CollisionShape2D")
|
||||
@@ -1,35 +0,0 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://d3lt4rhxduv44"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_l5x2w"]
|
||||
[ext_resource type="Script" uid="uid://2i7p7v135u7c" path="res://scripts/components/DamageComponent.cs" id="2_0kbpg"]
|
||||
[ext_resource type="Script" uid="uid://df1llrbm80e02" path="res://scripts/components/BeamComponent.cs" id="3_0kbpg"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ptfn7"]
|
||||
size = Vector2(16, 8)
|
||||
|
||||
[node name="Cannon Ray" type="Area2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 5
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture_repeat = 2
|
||||
rotation = 1.5708
|
||||
texture = ExtResource("1_l5x2w")
|
||||
region_enabled = true
|
||||
region_rect = Rect2(176, 64, 16, 16)
|
||||
region_filter_clip_enabled = true
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_ptfn7")
|
||||
|
||||
[node name="DamageComponent" type="Node" parent="." node_paths=PackedStringArray("Area")]
|
||||
script = ExtResource("2_0kbpg")
|
||||
Area = NodePath("..")
|
||||
|
||||
[node name="BeamComponent" type="Node2D" parent="." node_paths=PackedStringArray("Root", "Sprite", "CollisionShape")]
|
||||
position = Vector2(8, 0)
|
||||
script = ExtResource("3_0kbpg")
|
||||
ExpansionSpeed = 16.0
|
||||
Root = NodePath("..")
|
||||
Sprite = NodePath("../Sprite2D")
|
||||
CollisionShape = NodePath("../CollisionShape2D")
|
||||
47
objects/entities/cannon_right.tscn
Normal file
47
objects/entities/cannon_right.tscn
Normal file
@@ -0,0 +1,47 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://dr6srln4mckwn"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_r5bjs"]
|
||||
[ext_resource type="Script" uid="uid://bnaxy8cw3wrko" path="res://scripts/components/PeriodicShootingComponent.cs" id="2_gd3be"]
|
||||
[ext_resource type="PackedScene" uid="uid://chetx6gmnwbxi" path="res://objects/entities/cannon_bullet.tscn" id="3_1gufj"]
|
||||
[ext_resource type="Script" uid="uid://b3j23e7b7x8ro" path="res://scripts/components/RecoilComponent.cs" id="4_hwc6x"]
|
||||
[ext_resource type="Script" uid="uid://c707c53k7c5ae" path="res://scripts/components/SquashAndStretchComponent.cs" id="5_o674s"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_j5sus"]
|
||||
size = Vector2(16, 16)
|
||||
|
||||
[node name="Cannon" type="StaticBody2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
rotation = 1.5708
|
||||
texture = ExtResource("1_r5bjs")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 42
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_j5sus")
|
||||
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("BulletSpawnPointRight")]
|
||||
script = ExtResource("2_gd3be")
|
||||
BulletScene = ExtResource("3_1gufj")
|
||||
ShootInterval = 3.0
|
||||
BulletSpawnPointRight = NodePath("../Bullet spawn")
|
||||
ShootingIntervalVariation = 0.61
|
||||
metadata/_custom_type_script = "uid://bnaxy8cw3wrko"
|
||||
|
||||
[node name="Bullet spawn" type="Marker2D" parent="."]
|
||||
position = Vector2(12, 0)
|
||||
|
||||
[node name="RecoilComponent" type="Node" parent="." node_paths=PackedStringArray("RecoilTarget")]
|
||||
script = ExtResource("4_hwc6x")
|
||||
RecoilTarget = NodePath("../Sprite2D")
|
||||
RecoilDistance = 4.0
|
||||
RecoilDuration = 0.12
|
||||
metadata/_custom_type_script = "uid://b3j23e7b7x8ro"
|
||||
|
||||
[node name="SquashAndStretchComponent" type="Node" parent="." node_paths=PackedStringArray("TargetNode")]
|
||||
script = ExtResource("5_o674s")
|
||||
TargetNode = NodePath("../Sprite2D")
|
||||
metadata/_custom_type_script = "uid://c707c53k7c5ae"
|
||||
47
objects/entities/cannon_up.tscn
Normal file
47
objects/entities/cannon_up.tscn
Normal file
@@ -0,0 +1,47 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://dstko446qydsc"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="1_6gptm"]
|
||||
[ext_resource type="Script" uid="uid://bnaxy8cw3wrko" path="res://scripts/components/PeriodicShootingComponent.cs" id="2_q37h7"]
|
||||
[ext_resource type="PackedScene" uid="uid://chetx6gmnwbxi" path="res://objects/entities/cannon_bullet.tscn" id="3_ww0hb"]
|
||||
[ext_resource type="Script" uid="uid://b3j23e7b7x8ro" path="res://scripts/components/RecoilComponent.cs" id="4_bhwy3"]
|
||||
[ext_resource type="Script" uid="uid://c707c53k7c5ae" path="res://scripts/components/SquashAndStretchComponent.cs" id="5_ww0hb"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_j5sus"]
|
||||
size = Vector2(16, 16)
|
||||
|
||||
[node name="Cannon" type="StaticBody2D"]
|
||||
collision_layer = 0
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture = ExtResource("1_6gptm")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 42
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_j5sus")
|
||||
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("BulletSpawnPointRight")]
|
||||
script = ExtResource("2_q37h7")
|
||||
BulletScene = ExtResource("3_ww0hb")
|
||||
ShootInterval = 3.0
|
||||
ShootDirection = Vector2(0, -1)
|
||||
BulletSpawnPointRight = NodePath("../Bullet spawn")
|
||||
ShootingIntervalVariation = 0.61
|
||||
metadata/_custom_type_script = "uid://bnaxy8cw3wrko"
|
||||
|
||||
[node name="Bullet spawn" type="Marker2D" parent="."]
|
||||
position = Vector2(0, -16)
|
||||
|
||||
[node name="RecoilComponent" type="Node" parent="." node_paths=PackedStringArray("RecoilTarget")]
|
||||
script = ExtResource("4_bhwy3")
|
||||
RecoilTarget = NodePath("../Sprite2D")
|
||||
RecoilDistance = 4.0
|
||||
RecoilDuration = 0.12
|
||||
metadata/_custom_type_script = "uid://b3j23e7b7x8ro"
|
||||
|
||||
[node name="SquashAndStretchComponent" type="Node" parent="." node_paths=PackedStringArray("TargetNode")]
|
||||
script = ExtResource("5_ww0hb")
|
||||
TargetNode = NodePath("../Sprite2D")
|
||||
metadata/_custom_type_script = "uid://c707c53k7c5ae"
|
||||
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=27 format=3 uid="uid://bwdlmualj6xbw"]
|
||||
[gd_scene load_steps=29 format=3 uid="uid://bwdlmualj6xbw"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="1_ep4yr"]
|
||||
[ext_resource type="Texture2D" uid="uid://cu72810eyk4dx" path="res://sprites/enemy-robot.png" id="2_hjtwe"]
|
||||
@@ -18,6 +18,8 @@
|
||||
[ext_resource type="PackedScene" uid="uid://dx80ivlvuuew4" path="res://objects/fxs/fire_fx.tscn" id="15_mc6rj"]
|
||||
[ext_resource type="PackedScene" uid="uid://ck6nml06tm6ue" path="res://objects/fxs/ice_fx.tscn" id="16_68hnm"]
|
||||
[ext_resource type="PackedScene" uid="uid://b12tppjkkqpt4" path="res://objects/fxs/hit_particles.tscn" id="18_pxaaa"]
|
||||
[ext_resource type="Script" uid="uid://cgfynrn68lp12" path="res://scripts/components/KnockbackComponent.cs" id="19_xku20"]
|
||||
[ext_resource type="Script" uid="uid://bhbgjr8ty2n85" path="res://scripts/components/EnemyControllerComponent.cs" id="20_5lji2"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_pwwji"]
|
||||
size = Vector2(25, 31)
|
||||
@@ -96,13 +98,12 @@ RightRay = NodePath("../Right Ray")
|
||||
LeftWallRay = NodePath("../Left Wall Ray")
|
||||
RightWallRay = NodePath("../Right Wall Ray")
|
||||
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("SideToSideMovement", "BulletSpawnRight", "BulletSpawnLeft")]
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("BulletSpawnPointRight", "BulletSpawnPointLeft")]
|
||||
script = ExtResource("6_lgbyy")
|
||||
BulletScene = ExtResource("7_r48kf")
|
||||
SideToSideMovement = NodePath("../SideToSideMovement")
|
||||
BulletSpawnRight = NodePath("../Sprite2D/right bullet spawn")
|
||||
BulletSpawnLeft = NodePath("../Sprite2D/left bullet spawn")
|
||||
ShootingIntervalVariation = 0.1
|
||||
BulletSpawnPointRight = NodePath("../Sprite2D/right bullet spawn")
|
||||
BulletSpawnPointLeft = NodePath("../Sprite2D/left bullet spawn")
|
||||
ShootingIntervalVariation = 0.3
|
||||
|
||||
[node name="EnemyDeathComponent" type="Node" parent="." node_paths=PackedStringArray("CollisionShape", "Health")]
|
||||
script = ExtResource("8_pxaaa")
|
||||
@@ -182,3 +183,13 @@ visible = false
|
||||
[node name="HitParticles" parent="." instance=ExtResource("18_pxaaa")]
|
||||
position = Vector2(0, 1)
|
||||
process_material = SubResource("ParticleProcessMaterial_pxaaa")
|
||||
|
||||
[node name="KnockbackComponent" type="Node" parent="."]
|
||||
script = ExtResource("19_xku20")
|
||||
metadata/_custom_type_script = "uid://cgfynrn68lp12"
|
||||
|
||||
[node name="EnemyControllerComponent" type="Node" parent="." node_paths=PackedStringArray("MovementComponent", "ShootingComponent")]
|
||||
script = ExtResource("20_5lji2")
|
||||
MovementComponent = NodePath("../SideToSideMovement")
|
||||
ShootingComponent = NodePath("../PeriodicShootingComponent")
|
||||
metadata/_custom_type_script = "uid://bhbgjr8ty2n85"
|
||||
|
||||
78
objects/entities/falling_spike.tscn
Normal file
78
objects/entities/falling_spike.tscn
Normal file
@@ -0,0 +1,78 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://bmk3ddwv33dud"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://ccjihsk6w8sow" path="res://sprites/BFT - Mega Metroidvania Tileset.png" id="1_erbp6"]
|
||||
[ext_resource type="Script" uid="uid://2i7p7v135u7c" path="res://scripts/components/DamageComponent.cs" id="2_fq2gn"]
|
||||
[ext_resource type="Script" uid="uid://v7tt4w6bejux" path="res://scripts/components/CleanupComponent.cs" id="4_mgh1e"]
|
||||
[ext_resource type="Script" uid="uid://nhu2xd8611fk" path="res://scripts/components/HazardComponent.cs" id="5_8g254"]
|
||||
[ext_resource type="Script" uid="uid://chusyr5vwgwf0" path="res://scripts/components/CleanupOnCollisionComponent.cs" id="6_2rpon"]
|
||||
[ext_resource type="Script" uid="uid://cgfynrn68lp12" path="res://scripts/components/KnockbackComponent.cs" id="6_3n0l8"]
|
||||
[ext_resource type="Script" uid="uid://co05ugnvx0v3e" path="res://scripts/components/FallOnDetectionComponent.cs" id="7_mgh1e"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_t3a48"]
|
||||
size = Vector2(16, 8)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fq2gn"]
|
||||
size = Vector2(16, 320)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2rpon"]
|
||||
size = Vector2(17, 9)
|
||||
|
||||
[node name="FallingSpike" type="RigidBody2D"]
|
||||
collision_mask = 5
|
||||
gravity_scale = 0.0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(0, -4)
|
||||
shape = SubResource("RectangleShape2D_t3a48")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
rotation = -3.14159
|
||||
texture = ExtResource("1_erbp6")
|
||||
hframes = 13
|
||||
vframes = 45
|
||||
frame = 9
|
||||
|
||||
[node name="DamageComponent" type="Node" parent="." node_paths=PackedStringArray("Area")]
|
||||
script = ExtResource("2_fq2gn")
|
||||
Area = NodePath("")
|
||||
metadata/_custom_type_script = "uid://2i7p7v135u7c"
|
||||
|
||||
[node name="HazardComponent" type="Node2D" parent="." node_paths=PackedStringArray("KnockbackComponent", "HazardArea")]
|
||||
script = ExtResource("5_8g254")
|
||||
KnockbackComponent = NodePath("../KnockbackComponent")
|
||||
HazardArea = NodePath("../HazardArea")
|
||||
metadata/_custom_type_script = "uid://nhu2xd8611fk"
|
||||
|
||||
[node name="KnockbackComponent" type="Node" parent="."]
|
||||
script = ExtResource("6_3n0l8")
|
||||
metadata/_custom_type_script = "uid://cgfynrn68lp12"
|
||||
|
||||
[node name="FallTriggerArea" type="Area2D" parent="."]
|
||||
collision_mask = 4
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="FallTriggerArea"]
|
||||
position = Vector2(0, 155)
|
||||
shape = SubResource("RectangleShape2D_fq2gn")
|
||||
debug_color = Color(0.916282, 7.47952e-05, 0.709809, 0.42)
|
||||
|
||||
[node name="CleanupComponent" type="Node" parent="."]
|
||||
script = ExtResource("4_mgh1e")
|
||||
metadata/_custom_type_script = "uid://v7tt4w6bejux"
|
||||
|
||||
[node name="CleanupOnCollisionComponent" type="Node" parent="."]
|
||||
script = ExtResource("6_2rpon")
|
||||
metadata/_custom_type_script = "uid://chusyr5vwgwf0"
|
||||
|
||||
[node name="FallOnDetectionComponent" type="Node2D" parent="." node_paths=PackedStringArray("DetectionArea", "TargetBody")]
|
||||
script = ExtResource("7_mgh1e")
|
||||
DetectionArea = NodePath("../FallTriggerArea")
|
||||
TargetBody = NodePath("..")
|
||||
metadata/_custom_type_script = "uid://co05ugnvx0v3e"
|
||||
|
||||
[node name="HazardArea" type="Area2D" parent="."]
|
||||
collision_mask = 4
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="HazardArea"]
|
||||
position = Vector2(0, -4.5)
|
||||
shape = SubResource("RectangleShape2D_2rpon")
|
||||
debug_color = Color(0.73011, 0.468379, 0.188355, 0.42)
|
||||
@@ -123,12 +123,12 @@ bus = &"sfx"
|
||||
script = ExtResource("6_q78ru")
|
||||
Area = NodePath("../Hitbox")
|
||||
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("BulletSpawnRight", "BulletSpawnLeft")]
|
||||
[node name="PeriodicShootingComponent" type="Node" parent="." node_paths=PackedStringArray("BulletSpawnPointRight", "BulletSpawnPointLeft")]
|
||||
script = ExtResource("7_weo6b")
|
||||
BulletScene = ExtResource("7_4ajjm")
|
||||
ShootInterval = 2.0
|
||||
BulletSpawnRight = NodePath("../laser spawn point right")
|
||||
BulletSpawnLeft = NodePath("../laser spawn point left")
|
||||
BulletSpawnPointRight = NodePath("../laser spawn point right")
|
||||
BulletSpawnPointLeft = NodePath("../laser spawn point left")
|
||||
ShootingIntervalVariation = 0.5
|
||||
|
||||
[node name="EnemyDeathComponent" type="Node" parent="." node_paths=PackedStringArray("CollisionShape", "Health")]
|
||||
|
||||
31
objects/entities/ghost.tscn
Normal file
31
objects/entities/ghost.tscn
Normal file
@@ -0,0 +1,31 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://b3877xt5upsj2"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://dpbpjffbdbovp" path="res://sprites/cap.png" id="1_ksysq"]
|
||||
[ext_resource type="Script" uid="uid://7i20oc4cyabl" path="res://scripts/components/GhostMovementComponent.cs" id="2_0qila"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_0xbgb"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_ksysq"]
|
||||
|
||||
[node name="Ghost" type="CharacterBody2D"]
|
||||
collision_layer = 8
|
||||
collision_mask = 5
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("CircleShape2D_0xbgb")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
position = Vector2(2.98023e-08, 0)
|
||||
scale = Vector2(0.609375, 0.78125)
|
||||
texture = ExtResource("1_ksysq")
|
||||
|
||||
[node name="GhostMovementComponent" type="Node2D" parent="."]
|
||||
script = ExtResource("2_0qila")
|
||||
metadata/_custom_type_script = "uid://7i20oc4cyabl"
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
shape = SubResource("CircleShape2D_ksysq")
|
||||
39
objects/entities/ghost_player.tscn
Normal file
39
objects/entities/ghost_player.tscn
Normal file
@@ -0,0 +1,39 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://gknrmek1jmjx"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://bs4xvm4qkurpr" path="res://shaders/hit_flash.tres" id="13_uybbp"]
|
||||
[ext_resource type="Texture2D" uid="uid://0l454rfplmqg" path="res://sprites/MrBrick_base-sheet.png" id="14_4rwar"]
|
||||
[ext_resource type="Texture2D" uid="uid://jl1gwqchhpdc" path="res://sprites/left_eye.png" id="15_qkwlh"]
|
||||
[ext_resource type="Texture2D" uid="uid://iiawtnwmeny3" path="res://sprites/right_eye.png" id="16_kt5il"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhkwyv6ayb5qb" path="res://sprites/flying_ship.png" id="17_i5nnv"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_xoue7"]
|
||||
shader = ExtResource("13_uybbp")
|
||||
shader_parameter/enabled = false
|
||||
shader_parameter/tint = Color(1, 1, 1, 1)
|
||||
|
||||
[node name="Brick Player" type="Node2D"]
|
||||
|
||||
[node name="Graphics" type="Node2D" parent="."]
|
||||
modulate = Color(1, 1, 1, 0.443137)
|
||||
|
||||
[node name="Root" type="Node2D" parent="Graphics"]
|
||||
|
||||
[node name="Base" type="Sprite2D" parent="Graphics/Root"]
|
||||
material = SubResource("ShaderMaterial_xoue7")
|
||||
texture = ExtResource("14_4rwar")
|
||||
hframes = 5
|
||||
|
||||
[node name="Left Eye" type="Sprite2D" parent="Graphics/Root"]
|
||||
position = Vector2(-7, -6)
|
||||
texture = ExtResource("15_qkwlh")
|
||||
hframes = 2
|
||||
|
||||
[node name="Right Eye" type="Sprite2D" parent="Graphics/Root"]
|
||||
position = Vector2(6, -5)
|
||||
texture = ExtResource("16_kt5il")
|
||||
hframes = 2
|
||||
|
||||
[node name="Ship" type="Sprite2D" parent="Graphics"]
|
||||
visible = false
|
||||
position = Vector2(1, 7)
|
||||
texture = ExtResource("17_i5nnv")
|
||||
39
objects/fxs/bounce_gfx.tscn
Normal file
39
objects/fxs/bounce_gfx.tscn
Normal file
@@ -0,0 +1,39 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://qo2ngbnkix85"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_qxp43"]
|
||||
offsets = PackedFloat32Array(0, 0.289256, 0.790634)
|
||||
colors = PackedColorArray(0.635294, 1, 0.952941, 1, 0.380392, 0.827451, 0.890196, 1, 0.188235, 0.317647, 0.509804, 1)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_1jx8o"]
|
||||
gradient = SubResource("Gradient_qxp43")
|
||||
use_hdr = true
|
||||
|
||||
[sub_resource type="Curve" id="Curve_8fwqm"]
|
||||
_data = [Vector2(0.251928, 1), 0.0, -3.43942, 0, 0, Vector2(1, 0.340954), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_365fl"]
|
||||
curve = SubResource("Curve_8fwqm")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_wfuta"]
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 3
|
||||
emission_box_extents = Vector3(10, 1, 1)
|
||||
angle_min = -45.0
|
||||
angle_max = 45.0
|
||||
direction = Vector3(0, 1, 0)
|
||||
spread = 15.0
|
||||
initial_velocity_min = 5.0
|
||||
initial_velocity_max = 10.0
|
||||
gravity = Vector3(0, 98, 0)
|
||||
scale_curve = SubResource("CurveTexture_365fl")
|
||||
color_ramp = SubResource("GradientTexture1D_1jx8o")
|
||||
|
||||
[node name="BounceGFX" type="GPUParticles2D"]
|
||||
emitting = false
|
||||
amount = 52
|
||||
one_shot = true
|
||||
explosiveness = 1.0
|
||||
fixed_fps = 24
|
||||
collision_base_size = 3.32
|
||||
process_material = SubResource("ParticleProcessMaterial_wfuta")
|
||||
52
objects/fxs/foot_step_gfx.tscn
Normal file
52
objects/fxs/foot_step_gfx.tscn
Normal file
@@ -0,0 +1,52 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://de5emerpbiknb"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://v7tt4w6bejux" path="res://scripts/components/CleanupComponent.cs" id="1_lnlfk"]
|
||||
|
||||
[sub_resource type="Curve" id="Curve_lnlfk"]
|
||||
_data = [Vector2(0.00771208, 1), 0.0, 0.0, 0, 0, Vector2(0.347044, 0.89662), -1.20644, -1.20644, 0, 0, Vector2(1, 0.0114315), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_a3r26"]
|
||||
curve = SubResource("Curve_lnlfk")
|
||||
|
||||
[sub_resource type="Curve" id="Curve_et0te"]
|
||||
_data = [Vector2(0, 1), 0.0, -2.46687, 0, 0, Vector2(0.192802, 0.6834), 0.0, 0.0, 0, 0, Vector2(0.449871, 1), -0.471266, -0.471266, 0, 0, Vector2(1, 0), -3.06444, 0.0, 0, 0]
|
||||
point_count = 4
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_lnlfk"]
|
||||
width = 2048
|
||||
curve = SubResource("Curve_et0te")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_a3r26"]
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 1
|
||||
emission_sphere_radius = 1.0
|
||||
direction = Vector3(0, -1, 0)
|
||||
spread = 0.93
|
||||
flatness = 1.0
|
||||
initial_velocity_min = 11.0
|
||||
initial_velocity_max = 11.0
|
||||
angular_velocity_min = -80.0
|
||||
angular_velocity_max = -80.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
scale_min = 1.25
|
||||
scale_max = 1.75
|
||||
scale_curve = SubResource("CurveTexture_lnlfk")
|
||||
color = Color(0.47451, 0.47451, 0.47451, 1)
|
||||
alpha_curve = SubResource("CurveTexture_a3r26")
|
||||
|
||||
[node name="FootStepGfx" type="GPUParticles2D"]
|
||||
emitting = false
|
||||
amount = 42
|
||||
lifetime = 2.0
|
||||
one_shot = true
|
||||
speed_scale = 2.0
|
||||
explosiveness = 1.0
|
||||
fixed_fps = 24
|
||||
process_material = SubResource("ParticleProcessMaterial_a3r26")
|
||||
|
||||
[node name="CleanupComponent" type="Node" parent="."]
|
||||
script = ExtResource("1_lnlfk")
|
||||
metadata/_custom_type_script = "uid://v7tt4w6bejux"
|
||||
|
||||
[connection signal="finished" from="." to="CleanupComponent" method="CleanUp"]
|
||||
52
objects/fxs/jump_cloud_fx.tscn
Normal file
52
objects/fxs/jump_cloud_fx.tscn
Normal file
@@ -0,0 +1,52 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://bqhondao5bm6k"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://v7tt4w6bejux" path="res://scripts/components/CleanupComponent.cs" id="1_0051n"]
|
||||
|
||||
[sub_resource type="Curve" id="Curve_0051n"]
|
||||
_data = [Vector2(0.00771208, 1), 0.0, 0.0, 0, 0, Vector2(0.347044, 0.89662), -1.20644, -1.20644, 0, 0, Vector2(1, 0.0114315), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_oxugj"]
|
||||
curve = SubResource("Curve_0051n")
|
||||
|
||||
[sub_resource type="Curve" id="Curve_cc2b5"]
|
||||
_data = [Vector2(0, 1), 0.0, -2.46687, 0, 0, Vector2(0.192802, 0.6834), 0.0, 0.0, 0, 0, Vector2(0.449871, 1), -0.471266, -0.471266, 0, 0, Vector2(1, 0), -3.06444, 0.0, 0, 0]
|
||||
point_count = 4
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_qdic5"]
|
||||
width = 2048
|
||||
curve = SubResource("Curve_cc2b5")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_vwfwg"]
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 1
|
||||
emission_sphere_radius = 2.25
|
||||
angle_min = 23.1
|
||||
angle_max = 107.8
|
||||
direction = Vector3(0, 1, 0)
|
||||
spread = 4.0
|
||||
initial_velocity_min = 8.0
|
||||
initial_velocity_max = 8.0
|
||||
angular_velocity_min = -80.0
|
||||
angular_velocity_max = -80.0
|
||||
gravity = Vector3(0, 0, 0)
|
||||
scale_min = 3.0
|
||||
scale_max = 4.0
|
||||
scale_curve = SubResource("CurveTexture_qdic5")
|
||||
alpha_curve = SubResource("CurveTexture_oxugj")
|
||||
|
||||
[node name="FootStepGfx" type="GPUParticles2D"]
|
||||
emitting = false
|
||||
amount = 64
|
||||
lifetime = 2.0
|
||||
one_shot = true
|
||||
speed_scale = 4.0
|
||||
explosiveness = 1.0
|
||||
fixed_fps = 24
|
||||
process_material = SubResource("ParticleProcessMaterial_vwfwg")
|
||||
|
||||
[node name="CleanupComponent" type="Node" parent="."]
|
||||
script = ExtResource("1_0051n")
|
||||
metadata/_custom_type_script = "uid://v7tt4w6bejux"
|
||||
|
||||
[connection signal="finished" from="." to="CleanupComponent" method="CleanUp"]
|
||||
8
objects/ghost_manager.tscn
Normal file
8
objects/ghost_manager.tscn
Normal file
@@ -0,0 +1,8 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://ckeu2eddl5b3m"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cgmuod4p2hg5h" path="res://Autoloads/GhostManager.cs" id="1_u0u02"]
|
||||
[ext_resource type="PackedScene" uid="uid://gknrmek1jmjx" path="res://objects/entities/ghost_player.tscn" id="2_jnk6u"]
|
||||
|
||||
[node name="GhostManager" type="Node"]
|
||||
script = ExtResource("1_u0u02")
|
||||
GhostPlayerScene = ExtResource("2_jnk6u")
|
||||
@@ -53,15 +53,19 @@ ease = 2
|
||||
|
||||
[node name="Brick Player" parent="." instance=ExtResource("1_lbnsn")]
|
||||
|
||||
[node name="HitParticles" parent="Brick Player" index="26"]
|
||||
[node name="HitParticles" parent="Brick Player" index="24"]
|
||||
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||
|
||||
[node name="WorldEnvironment" parent="." instance=ExtResource("1_hb5r3")]
|
||||
|
||||
[node name="UI Layer" parent="." instance=ExtResource("2_lbnsn")]
|
||||
|
||||
[node name="Marketplace" parent="UI Layer" index="3" node_paths=PackedStringArray("SkillUnlockerComponent")]
|
||||
[node name="HUD" parent="UI Layer" index="0" node_paths=PackedStringArray("Health")]
|
||||
Health = NodePath("../../Brick Player/HealthComponent")
|
||||
|
||||
[node name="Marketplace" parent="UI Layer" index="3" node_paths=PackedStringArray("SkillUnlockerComponent", "ComponentsToDisable")]
|
||||
SkillUnlockerComponent = NodePath("../../Brick Player/SkillUnlockerComponent")
|
||||
ComponentsToDisable = [NodePath("../../Brick Player")]
|
||||
|
||||
[node name="Global Light" parent="." instance=ExtResource("3_3732a")]
|
||||
|
||||
|
||||
40
objects/level/moving_platform.tscn
Normal file
40
objects/level/moving_platform.tscn
Normal file
@@ -0,0 +1,40 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://dt6rnh7v6dcmd"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://g4ryqvpelmvl" path="res://scripts/components/MovingPlatformComponent.cs" id="1_hd47u"]
|
||||
[ext_resource type="Texture2D" uid="uid://djifxc5x0dyrw" path="res://sprites/ppc_tileset.png" id="2_6wunj"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_1avbh"]
|
||||
size = Vector2(48, 4)
|
||||
|
||||
[node name="MovingPlatformComponent" type="AnimatableBody2D"]
|
||||
script = ExtResource("1_hd47u")
|
||||
metadata/_custom_type_script = "uid://g4ryqvpelmvl"
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("RectangleShape2D_1avbh")
|
||||
|
||||
[node name="Gfx" type="Node2D" parent="."]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="Gfx"]
|
||||
position = Vector2(-16, 6)
|
||||
texture = ExtResource("2_6wunj")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 81
|
||||
|
||||
[node name="Sprite2D2" type="Sprite2D" parent="Gfx"]
|
||||
position = Vector2(0, 6)
|
||||
texture = ExtResource("2_6wunj")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 82
|
||||
|
||||
[node name="Sprite2D3" type="Sprite2D" parent="Gfx"]
|
||||
position = Vector2(16, 6)
|
||||
texture = ExtResource("2_6wunj")
|
||||
hframes = 12
|
||||
vframes = 12
|
||||
frame = 83
|
||||
|
||||
[node name="VisibleOnScreenEnabler2D" type="VisibleOnScreenEnabler2D" parent="."]
|
||||
scale = Vector2(1, 0.2)
|
||||
7
objects/movement_abilities/grid_movement_ability.tscn
Normal file
7
objects/movement_abilities/grid_movement_ability.tscn
Normal file
@@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dre1vit1m4d2n"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://ctm5glmeu502l" path="res://scripts/components/Movement/GridMovementAbility.cs" id="1_xeoy8"]
|
||||
|
||||
[node name="GridMovementAbility" type="Node"]
|
||||
script = ExtResource("1_xeoy8")
|
||||
metadata/_custom_type_script = "uid://ctm5glmeu502l"
|
||||
@@ -1,10 +1,11 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://tgaadui3lvdc"]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://tgaadui3lvdc"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cejjan582nhfn" path="res://scripts/UI/AchievementPopup.cs" id="1_8pd1y"]
|
||||
[ext_resource type="Texture2D" uid="uid://cebeyr4wnibvk" path="res://sprites/achievement.png" id="2_1wq1d"]
|
||||
[ext_resource type="Texture2D" uid="uid://fvgvlqh7vv1l" path="res://sprites/achievement_panel.png" id="2_enx8n"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_enx8n"]
|
||||
bg_color = Color(0, 0, 0, 1)
|
||||
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_enx8n"]
|
||||
texture = ExtResource("2_enx8n")
|
||||
|
||||
[node name="AchievementPopup" type="CanvasLayer" node_paths=PackedStringArray("TitleLabel", "DescriptionLabel", "IconRect")]
|
||||
script = ExtResource("1_8pd1y")
|
||||
@@ -33,7 +34,7 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_enx8n")
|
||||
theme_override_styles/panel = SubResource("StyleBoxTexture_enx8n")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="Container/Panel"]
|
||||
layout_mode = 1
|
||||
@@ -42,22 +43,26 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/margin_left = 4
|
||||
theme_override_constants/margin_top = 4
|
||||
theme_override_constants/margin_right = 4
|
||||
theme_override_constants/margin_bottom = 4
|
||||
theme_override_constants/margin_left = 10
|
||||
theme_override_constants/margin_top = 10
|
||||
theme_override_constants/margin_right = 10
|
||||
theme_override_constants/margin_bottom = 10
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Container/Panel/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="Title" type="Label" parent="Container/Panel/MarginContainer/VBoxContainer"]
|
||||
custom_minimum_size = Vector2(120, 30)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "saaaaaaaaaaaaaaaaaaa"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="Description" type="Label" parent="Container/Panel/MarginContainer/VBoxContainer"]
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(120, 40)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.7, 0.7, 0.7, 1)
|
||||
|
||||
@@ -12,6 +12,8 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
focus_neighbor_bottom = NodePath("PanelContainer/MarginContainer/VBoxContainer/ContinueButton")
|
||||
focus_next = NodePath("PanelContainer/MarginContainer/VBoxContainer/ContinueButton")
|
||||
script = ExtResource("1_epxpl")
|
||||
MainMenuControl = NodePath(".")
|
||||
NewGameButton = NodePath("PanelContainer/MarginContainer/VBoxContainer/NewGameButton")
|
||||
@@ -54,26 +56,42 @@ size_flags_vertical = 3
|
||||
|
||||
[node name="ContinueButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_bottom = NodePath("../NewGameButton")
|
||||
focus_next = NodePath("../NewGameButton")
|
||||
text = "CONTINUE_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="NewGameButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_top = NodePath("../ContinueButton")
|
||||
focus_neighbor_bottom = NodePath("../SettingsButton")
|
||||
focus_next = NodePath("../SettingsButton")
|
||||
focus_previous = NodePath("../ContinueButton")
|
||||
text = "NEW_GAME_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="SettingsButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_top = NodePath("../NewGameButton")
|
||||
focus_neighbor_bottom = NodePath("../CreditsButton")
|
||||
focus_next = NodePath("../CreditsButton")
|
||||
focus_previous = NodePath("../NewGameButton")
|
||||
text = "SETTINGS_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="CreditsButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_top = NodePath("../SettingsButton")
|
||||
focus_neighbor_bottom = NodePath("../QuitButton")
|
||||
focus_next = NodePath("../QuitButton")
|
||||
focus_previous = NodePath("../SettingsButton")
|
||||
text = "CREDITS_BUTTON"
|
||||
flat = true
|
||||
|
||||
[node name="QuitButton" type="Button" parent="PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
focus_neighbor_top = NodePath("../CreditsButton")
|
||||
focus_previous = NodePath("../CreditsButton")
|
||||
text = "QUIT_BUTTON"
|
||||
flat = true
|
||||
|
||||
|
||||
26
objects/ui/speed_run_hud.tscn
Normal file
26
objects/ui/speed_run_hud.tscn
Normal file
@@ -0,0 +1,26 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://kh85xqo6j848"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://0jfdx0hufs55" path="res://scripts/UI/SpeedRunHud.cs" id="1_uwqm0"]
|
||||
|
||||
[node name="SpeedRunHud" type="Control" node_paths=PackedStringArray("_timerLabel")]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_uwqm0")
|
||||
_timerLabel = NodePath("Label")
|
||||
metadata/_custom_type_script = "uid://0jfdx0hufs55"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
text = "00:00:00"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
uppercase = true
|
||||
@@ -19,7 +19,7 @@ config/version="in-dev"
|
||||
run/main_scene="uid://cl00e2ocomk3m"
|
||||
config/use_custom_user_dir=true
|
||||
config/custom_user_dir_name="MrBrickAdventures"
|
||||
config/features=PackedStringArray("4.4", "C#", "GL Compatibility")
|
||||
config/features=PackedStringArray("4.5", "C#", "GL Compatibility")
|
||||
run/max_fps=180
|
||||
boot_splash/bg_color=Color(0, 0, 0, 1)
|
||||
boot_splash/show_image=false
|
||||
@@ -42,6 +42,10 @@ SteamManager="*res://Autoloads/SteamManager.cs"
|
||||
AchievementManager="*res://objects/achievement_manager.tscn"
|
||||
SkillManager="*res://objects/skill_manager.tscn"
|
||||
FloatingTextManager="*res://objects/floating_text_manager.tscn"
|
||||
EventBus="*res://Autoloads/EventBus.cs"
|
||||
StatisticsManager="*res://Autoloads/StatisticsManager.cs"
|
||||
SpeedRunManager="res://Autoloads/SpeedRunManager.cs"
|
||||
GhostManager="res://objects/ghost_manager.tscn"
|
||||
|
||||
[debug]
|
||||
|
||||
@@ -76,6 +80,17 @@ movie_writer/fps=24
|
||||
|
||||
enabled=PackedStringArray("res://addons/dialogue_manager/plugin.cfg", "res://addons/limbo_console/plugin.cfg", "res://addons/phantom_camera/plugin.cfg")
|
||||
|
||||
[file_customization]
|
||||
|
||||
folder_colors={
|
||||
"res://objects/": "red",
|
||||
"res://objects/entities/": "yellow",
|
||||
"res://resources/": "orange",
|
||||
"res://scenes/": "purple",
|
||||
"res://scripts/": "teal",
|
||||
"res://sprites/": "green"
|
||||
}
|
||||
|
||||
[global_group]
|
||||
|
||||
coins=""
|
||||
@@ -85,9 +100,9 @@ Collectables=""
|
||||
|
||||
[gui]
|
||||
|
||||
theme/default_font_antialiasing=0
|
||||
theme/default_theme_scale=0.5
|
||||
theme/custom_font="res://fonts/PressStart2P-Regular.ttf"
|
||||
theme/default_font_antialiasing=0
|
||||
|
||||
[input]
|
||||
|
||||
@@ -99,6 +114,12 @@ ui_accept={
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
}
|
||||
ui_cancel={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194305,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
}
|
||||
left={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
||||
@@ -118,7 +139,6 @@ jump={
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":11,"pressure":0.0,"pressed":true,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":true,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
|
||||
]
|
||||
}
|
||||
up={
|
||||
|
||||
@@ -17,9 +17,6 @@ metadata/_custom_type_script = "uid://dwb0e05pewcsn"
|
||||
script = ExtResource("1_unqwr")
|
||||
Name = "BRICK_ARMOR"
|
||||
Description = "BRICK_ARMOR_DESCRIPTION"
|
||||
IsActive = false
|
||||
Level = 1
|
||||
Type = 1
|
||||
Node = ExtResource("1_aqcna")
|
||||
Upgrades = Array[ExtResource("2_kqsqd")]([SubResource("Resource_xwv1u"), SubResource("Resource_xwv1u")])
|
||||
metadata/_custom_type_script = "uid://d4crrfmbgxnqf"
|
||||
|
||||
@@ -26,8 +26,6 @@ metadata/_custom_type_script = "uid://dwb0e05pewcsn"
|
||||
script = ExtResource("1_m360g")
|
||||
Name = "BRICK_SHIELD"
|
||||
Description = "BRICK_SHIELD_DESCRIPTION"
|
||||
IsActive = false
|
||||
Level = 1
|
||||
Type = 2
|
||||
Node = ExtResource("1_xjknp")
|
||||
Upgrades = Array[ExtResource("2_lr0w4")]([SubResource("Resource_mu2sy"), SubResource("Resource_5ab4a")])
|
||||
|
||||
@@ -8,15 +8,12 @@
|
||||
script = ExtResource("2_kywbf")
|
||||
Cost = 80
|
||||
Description = ""
|
||||
Properties = Dictionary[String, Variant]({})
|
||||
metadata/_custom_type_script = "uid://dwb0e05pewcsn"
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_p5qvt")
|
||||
Name = "DOUBLE_JUMP"
|
||||
Description = "DOUBLE_JUMP_DESCRIPTION"
|
||||
IsActive = false
|
||||
Level = 1
|
||||
Type = 2
|
||||
Node = ExtResource("1_t7o84")
|
||||
Upgrades = Array[ExtResource("2_kywbf")]([SubResource("Resource_0fn2n")])
|
||||
|
||||
@@ -8,15 +8,12 @@
|
||||
script = ExtResource("2_tkhf7")
|
||||
Cost = 300
|
||||
Description = ""
|
||||
Properties = Dictionary[String, Variant]({})
|
||||
metadata/_custom_type_script = "uid://dwb0e05pewcsn"
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_i1qac")
|
||||
Name = "GROUND_POUND_SKILL"
|
||||
Description = "GROUND_POUND_SKILL_DESCRIPTION"
|
||||
IsActive = false
|
||||
Level = 1
|
||||
Type = 2
|
||||
Node = ExtResource("1_auljr")
|
||||
Upgrades = Array[ExtResource("2_tkhf7")]([SubResource("Resource_upxa7")])
|
||||
|
||||
@@ -26,9 +26,6 @@ metadata/_custom_type_script = "uid://dwb0e05pewcsn"
|
||||
script = ExtResource("1_g8qe3")
|
||||
Name = "XRAY_VISION"
|
||||
Description = "XRAY_VISION_DESCRIPTION"
|
||||
IsActive = false
|
||||
Level = 1
|
||||
Type = 1
|
||||
Node = ExtResource("1_ax2d8")
|
||||
Upgrades = Array[ExtResource("2_o726x")]([SubResource("Resource_72ltj"), SubResource("Resource_2kdfi")])
|
||||
metadata/_custom_type_script = "uid://d4crrfmbgxnqf"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,11 @@
|
||||
[gd_scene load_steps=23 format=4 uid="uid://bol7g83v2accs"]
|
||||
[gd_scene load_steps=26 format=4 uid="uid://bol7g83v2accs"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bqi5s710xb1ju" path="res://objects/entities/brick_player.tscn" id="1_dnj2y"]
|
||||
[ext_resource type="PackedScene" uid="uid://cawlpch2lk3a2" path="res://objects/level/world_environment.tscn" id="2_1vw1j"]
|
||||
[ext_resource type="PackedScene" uid="uid://6foggu31cu14" path="res://objects/level/ui_layer.tscn" id="3_4fsls"]
|
||||
[ext_resource type="PackedScene" uid="uid://cywsu7yrtjdog" path="res://objects/level/global_light.tscn" id="4_mc58c"]
|
||||
[ext_resource type="Resource" uid="uid://cqtalsov2bkpo" path="res://resources/levels/village/village_1.tres" id="4_onnch"]
|
||||
[ext_resource type="PackedScene" uid="uid://kh85xqo6j848" path="res://objects/ui/speed_run_hud.tscn" id="5_chnw1"]
|
||||
[ext_resource type="PackedScene" uid="uid://cb0mnye1ki5a6" path="res://objects/level/camera_2d.tscn" id="5_sskgn"]
|
||||
[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="6_18aqg"]
|
||||
[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="7_80vn0"]
|
||||
@@ -16,6 +17,8 @@
|
||||
[ext_resource type="PackedScene" uid="uid://bqom4cm7r18db" path="res://objects/entities/killzone.tscn" id="16_bxal3"]
|
||||
[ext_resource type="PackedScene" uid="uid://12jnkdygpxwc" path="res://objects/entities/exit_level.tscn" id="16_chnw1"]
|
||||
[ext_resource type="PackedScene" uid="uid://b4pdt1gv2ymyi" path="res://objects/tooltip.tscn" id="18_4bhfj"]
|
||||
[ext_resource type="Script" uid="uid://dkqeys6lsf04v" path="res://scripts/Events/GhostEventHandler.cs" id="18_p7e1u"]
|
||||
[ext_resource type="Script" uid="uid://bysxvcvt00t04" path="res://scripts/Events/SpeedRunEventHandler.cs" id="19_84xgs"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_qb72p"]
|
||||
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0)
|
||||
@@ -58,7 +61,7 @@ ease = 2
|
||||
[node name="Brick Player" parent="." instance=ExtResource("1_dnj2y")]
|
||||
z_index = 10
|
||||
|
||||
[node name="HitParticles" parent="Brick Player" index="25"]
|
||||
[node name="HitParticles" parent="Brick Player" index="24"]
|
||||
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||
|
||||
[node name="WorldEnvironment" parent="." instance=ExtResource("2_1vw1j")]
|
||||
@@ -83,6 +86,17 @@ SettingsControl = NodePath("../Settings menu")
|
||||
InputSettingsControl = NodePath("../Input Settings")
|
||||
AudioSettingsControl = NodePath("../Audio settings")
|
||||
|
||||
[node name="SpeedRunHud" parent="UI Layer" instance=ExtResource("5_chnw1")]
|
||||
anchors_preset = 1
|
||||
anchor_left = 1.0
|
||||
anchor_bottom = 0.0
|
||||
offset_left = -40.0
|
||||
offset_top = 38.0
|
||||
offset_right = -40.0
|
||||
offset_bottom = 38.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 1
|
||||
|
||||
[node name="Global Light" parent="." instance=ExtResource("4_mc58c")]
|
||||
|
||||
[node name="Camera2D" parent="." instance=ExtResource("5_sskgn")]
|
||||
@@ -145,6 +159,14 @@ Text = "LEVEL_1_TOOLTIP_3"
|
||||
[node name="Killzone" parent="." instance=ExtResource("16_bxal3")]
|
||||
position = Vector2(704, 337)
|
||||
|
||||
[node name="GhostEventHandler" type="Node" parent="."]
|
||||
script = ExtResource("18_p7e1u")
|
||||
metadata/_custom_type_script = "uid://dkqeys6lsf04v"
|
||||
|
||||
[node name="SpeedRunEventHandler" type="Node" parent="."]
|
||||
script = ExtResource("19_84xgs")
|
||||
metadata/_custom_type_script = "uid://bysxvcvt00t04"
|
||||
|
||||
[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/DeathScreen" method="OnPlayerDeath"]
|
||||
[connection signal="Death" from="Brick Player/HealthComponent" to="UI Layer/GameOverScreen" method="OnPlayerDeath"]
|
||||
|
||||
|
||||
@@ -62,10 +62,10 @@ ease = 2
|
||||
z_index = 1
|
||||
position = Vector2(-203, 9)
|
||||
|
||||
[node name="HitParticles" parent="Brick Player" index="25"]
|
||||
[node name="HitParticles" parent="Brick Player" index="24"]
|
||||
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||
|
||||
[node name="VisibleOnScreenNotifier2D" parent="Brick Player" index="28"]
|
||||
[node name="VisibleOnScreenNotifier2D" parent="Brick Player" index="27"]
|
||||
process_mode = 4
|
||||
|
||||
[node name="WorldEnvironment" parent="." instance=ExtResource("2_ot3dy")]
|
||||
|
||||
225
scenes/level_village_5.tscn
Normal file
225
scenes/level_village_5.tscn
Normal file
File diff suppressed because one or more lines are too long
159
scenes/pac_xon_mini_game.tscn
Normal file
159
scenes/pac_xon_mini_game.tscn
Normal file
@@ -0,0 +1,159 @@
|
||||
[gd_scene load_steps=18 format=3 uid="uid://bljbcv22gq872"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dx4m2ouyvwkir" path="res://scripts/components/PacXonGridManager.cs" id="1_0g620"]
|
||||
[ext_resource type="Texture2D" uid="uid://bolouq7v3acmx" path="res://sprites/pacxon_tileset.png" id="1_7fq4x"]
|
||||
[ext_resource type="Script" uid="uid://b8lu5pdufiy37" path="res://scripts/PacXonLevel.cs" id="2_lbrge"]
|
||||
[ext_resource type="PackedScene" uid="uid://bqi5s710xb1ju" path="res://objects/entities/brick_player.tscn" id="3_tehv8"]
|
||||
[ext_resource type="Texture2D" uid="uid://dedn7c7464pg2" path="res://sprites/brick_pacxon.png" id="5_tn615"]
|
||||
[ext_resource type="PackedScene" uid="uid://b3877xt5upsj2" path="res://objects/entities/ghost.tscn" id="6_8wuxa"]
|
||||
[ext_resource type="Script" uid="uid://d23haq52m7ulv" path="res://addons/phantom_camera/scripts/phantom_camera/phantom_camera_2d.gd" id="7_7j16a"]
|
||||
[ext_resource type="Script" uid="uid://ccfft4b8rwgbo" path="res://addons/phantom_camera/scripts/resources/tween_resource.gd" id="8_2w5m3"]
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_tn615"]
|
||||
texture = ExtResource("1_7fq4x")
|
||||
0:0/0 = 0
|
||||
1:0/0 = 0
|
||||
2:0/0 = 0
|
||||
|
||||
[sub_resource type="TileSet" id="TileSet_8wuxa"]
|
||||
sources/0 = SubResource("TileSetAtlasSource_tn615")
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_qb72p"]
|
||||
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_lgb3u"]
|
||||
gradient = SubResource("Gradient_qb72p")
|
||||
|
||||
[sub_resource type="Curve" id="Curve_82d6e"]
|
||||
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 2
|
||||
|
||||
[sub_resource type="CurveTexture" id="CurveTexture_xoue7"]
|
||||
curve = SubResource("Curve_82d6e")
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_lgb3u"]
|
||||
resource_local_to_scene = true
|
||||
lifetime_randomness = 1.0
|
||||
particle_flag_disable_z = true
|
||||
emission_shape = 1
|
||||
emission_sphere_radius = 8.0
|
||||
direction = Vector3(0.1, -0.5, 0)
|
||||
initial_velocity_min = 200.0
|
||||
initial_velocity_max = 400.0
|
||||
gravity = Vector3(0, 80, 0)
|
||||
damping_min = 400.0
|
||||
damping_max = 800.0
|
||||
scale_max = 3.0
|
||||
scale_curve = SubResource("CurveTexture_xoue7")
|
||||
color = Color(0.764706, 0.443137, 0, 1)
|
||||
color_ramp = SubResource("GradientTexture1D_lgb3u")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_uptla"]
|
||||
script = ExtResource("8_2w5m3")
|
||||
duration = 1.0
|
||||
transition = 0
|
||||
ease = 2
|
||||
|
||||
[sub_resource type="WorldBoundaryShape2D" id="WorldBoundaryShape2D_7j16a"]
|
||||
|
||||
[node name="PacXonMiniGame" type="Node2D"]
|
||||
|
||||
[node name="PacXonGridManager" type="TileMapLayer" parent="."]
|
||||
tile_set = SubResource("TileSet_8wuxa")
|
||||
script = ExtResource("1_0g620")
|
||||
PlayArea = Rect2i(1, 1, 27, 14)
|
||||
metadata/_custom_type_script = "uid://dx4m2ouyvwkir"
|
||||
|
||||
[node name="PacXonLevel" type="Node" parent="." node_paths=PackedStringArray("Player", "GridManager", "GhostContainer", "PercentageLabel")]
|
||||
script = ExtResource("2_lbrge")
|
||||
Player = NodePath("../Brick Player")
|
||||
GridManager = NodePath("../PacXonGridManager")
|
||||
GhostContainer = NodePath("../Ghosts")
|
||||
PercentageLabel = NodePath("../Label")
|
||||
metadata/_custom_type_script = "uid://b8lu5pdufiy37"
|
||||
|
||||
[node name="Brick Player" parent="." instance=ExtResource("3_tehv8")]
|
||||
position = Vector2(101, 213)
|
||||
motion_mode = 1
|
||||
metadata/_edit_group_ = true
|
||||
|
||||
[node name="GroundMovementAbility" parent="Brick Player/Movements" index="0"]
|
||||
process_mode = 4
|
||||
|
||||
[node name="GravityAbility" parent="Brick Player/Movements" index="1"]
|
||||
process_mode = 4
|
||||
|
||||
[node name="VariableJumpAbility" parent="Brick Player/Movements" index="2"]
|
||||
process_mode = 4
|
||||
|
||||
[node name="OneWayPlatformAbility" parent="Brick Player/Movements" index="3"]
|
||||
process_mode = 4
|
||||
|
||||
[node name="Base" parent="Brick Player/Graphics/Root" index="0"]
|
||||
texture = ExtResource("5_tn615")
|
||||
hframes = 1
|
||||
|
||||
[node name="Left Eye" parent="Brick Player/Graphics/Root" index="1"]
|
||||
visible = false
|
||||
|
||||
[node name="Right Eye" parent="Brick Player/Graphics/Root" index="2"]
|
||||
visible = false
|
||||
|
||||
[node name="HitParticles" parent="Brick Player" index="24"]
|
||||
process_material = SubResource("ParticleProcessMaterial_lgb3u")
|
||||
|
||||
[node name="VisibleOnScreenNotifier2D" parent="Brick Player" index="27"]
|
||||
position = Vector2(0, -4.76837e-07)
|
||||
scale = Vector2(0.8, 0.8)
|
||||
|
||||
[node name="Ghosts" type="Node2D" parent="."]
|
||||
|
||||
[node name="Ghost" parent="Ghosts" instance=ExtResource("6_8wuxa")]
|
||||
position = Vector2(252, 155)
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
offset_left = 73.0
|
||||
offset_right = 121.0
|
||||
offset_bottom = 8.0
|
||||
text = "sdsdsd"
|
||||
|
||||
[node name="PhantomCamera2D" type="Node2D" parent="."]
|
||||
position = Vector2(-240, -135)
|
||||
script = ExtResource("7_7j16a")
|
||||
snap_to_pixel = true
|
||||
tween_resource = SubResource("Resource_uptla")
|
||||
draw_limits = true
|
||||
limit_target = NodePath("../PacXonGridManager")
|
||||
metadata/_custom_type_script = "uid://d23haq52m7ulv"
|
||||
|
||||
[node name="Word boundary top" type="StaticBody2D" parent="."]
|
||||
position = Vector2(0, -2)
|
||||
collision_mask = 5
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Word boundary top"]
|
||||
shape = SubResource("WorldBoundaryShape2D_7j16a")
|
||||
|
||||
[node name="Word boundary bottom" type="StaticBody2D" parent="."]
|
||||
position = Vector2(0, 272)
|
||||
collision_mask = 5
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Word boundary bottom"]
|
||||
shape = SubResource("WorldBoundaryShape2D_7j16a")
|
||||
|
||||
[node name="Word boundary left" type="StaticBody2D" parent="."]
|
||||
position = Vector2(0, 272)
|
||||
rotation = 1.5708
|
||||
collision_mask = 5
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Word boundary left"]
|
||||
shape = SubResource("WorldBoundaryShape2D_7j16a")
|
||||
|
||||
[node name="Word boundary right" type="StaticBody2D" parent="."]
|
||||
position = Vector2(482, 272)
|
||||
rotation = -1.5708
|
||||
collision_mask = 5
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Word boundary right"]
|
||||
shape = SubResource("WorldBoundaryShape2D_7j16a")
|
||||
|
||||
[editable path="Brick Player"]
|
||||
31
scripts/Events/GhostEventHandler.cs
Normal file
31
scripts/Events/GhostEventHandler.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Events;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class GhostEventHandler : Node
|
||||
{
|
||||
private GhostManager _ghostManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_ghostManager = GetNode<GhostManager>("/root/GhostManager");
|
||||
var eventBus = GetNode<EventBus>("/root/EventBus");
|
||||
|
||||
eventBus.LevelStarted += OnLevelStarted;
|
||||
eventBus.LevelCompleted += OnLevelCompleted;
|
||||
}
|
||||
|
||||
private void OnLevelStarted(int levelIndex, Node currentScene)
|
||||
{
|
||||
GD.Print($"GhostEventHandler: Level {levelIndex} started.");
|
||||
_ghostManager.StartRecording(levelIndex);
|
||||
_ghostManager.SpawnGhostPlayer(levelIndex, currentScene);
|
||||
}
|
||||
|
||||
private void OnLevelCompleted(int levelIndex, Node currentScene, double completionTime)
|
||||
{
|
||||
_ghostManager.StopRecording(true, completionTime);
|
||||
}
|
||||
}
|
||||
1
scripts/Events/GhostEventHandler.cs.uid
Normal file
1
scripts/Events/GhostEventHandler.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dkqeys6lsf04v
|
||||
23
scripts/Events/SpeedRunEventHandler.cs
Normal file
23
scripts/Events/SpeedRunEventHandler.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.Events;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SpeedRunEventHandler : Node
|
||||
{
|
||||
private SpeedRunManager _speedRunManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_speedRunManager = GetNode<SpeedRunManager>("/root/SpeedRunManager");
|
||||
var eventBus = GetNode<EventBus>("/root/EventBus");
|
||||
|
||||
eventBus.LevelCompleted += OnLevelCompleted;
|
||||
}
|
||||
|
||||
private void OnLevelCompleted(int levelIndex, Node currentScene, double completionTime)
|
||||
{
|
||||
_speedRunManager.Split();
|
||||
}
|
||||
}
|
||||
1
scripts/Events/SpeedRunEventHandler.cs.uid
Normal file
1
scripts/Events/SpeedRunEventHandler.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bysxvcvt00t04
|
||||
9
scripts/GhostFrame.cs
Normal file
9
scripts/GhostFrame.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts;
|
||||
|
||||
public partial class GhostFrame : GodotObject
|
||||
{
|
||||
public double Timestamp { get; set; }
|
||||
public Vector2 Position { get; set; }
|
||||
}
|
||||
1
scripts/GhostFrame.cs.uid
Normal file
1
scripts/GhostFrame.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d2vth3yveucti
|
||||
48
scripts/GhostPlayer.cs
Normal file
48
scripts/GhostPlayer.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class GhostPlayer : Node2D
|
||||
{
|
||||
private List<GhostFrame> _playbackData = [];
|
||||
private double _startTime = 0;
|
||||
private int _currentFrameIndex = 0;
|
||||
private bool _isPlaying = false;
|
||||
|
||||
public void StartPlayback(List<GhostFrame> playbackData)
|
||||
{
|
||||
_playbackData = playbackData;
|
||||
_startTime = Time.GetTicksMsec() / 1000.0;
|
||||
_currentFrameIndex = 0;
|
||||
_isPlaying = true;
|
||||
SetProcess(true);
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (!_isPlaying || _playbackData.Count == 0) return;
|
||||
|
||||
var currentTime = (Time.GetTicksMsec() / 1000.0) - _startTime;
|
||||
|
||||
while (_currentFrameIndex + 1 < _playbackData.Count && _playbackData[_currentFrameIndex + 1].Timestamp <= currentTime)
|
||||
{
|
||||
_currentFrameIndex++;
|
||||
}
|
||||
|
||||
if (_currentFrameIndex + 1 >= _playbackData.Count)
|
||||
{
|
||||
GlobalPosition = _playbackData[_currentFrameIndex].Position;
|
||||
_isPlaying = false;
|
||||
QueueFree();
|
||||
return;
|
||||
}
|
||||
|
||||
var frameA = _playbackData[_currentFrameIndex];
|
||||
var frameB = _playbackData[_currentFrameIndex + 1];
|
||||
var t = (currentTime - frameA.Timestamp) / (frameB.Timestamp - frameA.Timestamp);
|
||||
|
||||
GlobalPosition = frameA.Position.Lerp(frameB.Position, (float)t);
|
||||
}
|
||||
}
|
||||
1
scripts/GhostPlayer.cs.uid
Normal file
1
scripts/GhostPlayer.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cr4bfcpo27e7t
|
||||
59
scripts/PacXonLevel.cs
Normal file
59
scripts/PacXonLevel.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.scripts.components;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class PacXonLevel : Node
|
||||
{
|
||||
[Export] public PlayerController Player { get; set; }
|
||||
[Export] public PacXonGridManager GridManager { get; set; }
|
||||
[Export] public Node GhostContainer { get; set; }
|
||||
[Export] public Label PercentageLabel { get; set; }
|
||||
|
||||
private const float WinPercentage = 0.90f;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
var ghosts = GhostContainer.GetChildren().OfType<Node2D>().ToList();
|
||||
Player.ClearMovementAbilities();
|
||||
Player.SetGridMovement();
|
||||
|
||||
foreach (var ghost in ghosts)
|
||||
{
|
||||
var movement = ghost.GetNode<GhostMovementComponent>("GhostMovementComponent");
|
||||
movement?.Initialize(GridManager, Player);
|
||||
}
|
||||
|
||||
var gridMovement = Player.GetNodeOrNull<GridMovementAbility>("Movements/GridMovementAbility");
|
||||
var gridInteractor = Player.GetNodeOrNull<PacXonGridInteractor>("PacXonGridInteractor");
|
||||
var trailComponent = Player.GetNodeOrNull<PacXonTrailComponent>("PacXonTrailComponent");
|
||||
|
||||
if (gridMovement != null && gridInteractor != null)
|
||||
{
|
||||
gridInteractor.Initialize(GridManager, gridMovement, ghosts);
|
||||
trailComponent?.Initialize(gridInteractor);
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PushError("Could not find GridMovementAbility or PacXonGridInteractor on Player.");
|
||||
}
|
||||
|
||||
GridManager.FillPercentageChanged += OnFillPercentageChanged;
|
||||
OnFillPercentageChanged(GridManager.GetFillPercentage());
|
||||
|
||||
var playerMapPos = GridManager.LocalToMap(Player.Position);
|
||||
Player.GlobalPosition = GridManager.MapToLocal(playerMapPos);
|
||||
}
|
||||
|
||||
private void OnFillPercentageChanged(float percentage)
|
||||
{
|
||||
PercentageLabel.Text = $"Fill: {percentage:P0}";
|
||||
if (percentage >= WinPercentage)
|
||||
{
|
||||
GD.Print("YOU WIN!");
|
||||
GetTree().Paused = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/PacXonLevel.cs.uid
Normal file
1
scripts/PacXonLevel.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b8lu5pdufiy37
|
||||
26
scripts/UI/SpeedRunHud.cs
Normal file
26
scripts/UI/SpeedRunHud.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using Godot;
|
||||
using Mr.BrickAdventures.Autoloads;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.UI;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SpeedRunHud : Control
|
||||
{
|
||||
[Export] private Label _timerLabel;
|
||||
|
||||
private SpeedRunManager _speedRunManager;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_speedRunManager = GetNode<SpeedRunManager>("/root/SpeedRunManager");
|
||||
|
||||
_speedRunManager.TimeUpdated += OnTimerUpdated;
|
||||
|
||||
Visible = _speedRunManager.IsVisible;
|
||||
}
|
||||
|
||||
private void OnTimerUpdated(double totalTime, double levelTime)
|
||||
{
|
||||
_timerLabel.Text = SpeedRunManager.FormatTime(totalTime);
|
||||
}
|
||||
}
|
||||
1
scripts/UI/SpeedRunHud.cs.uid
Normal file
1
scripts/UI/SpeedRunHud.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://0jfdx0hufs55
|
||||
46
scripts/components/CleanupOnCollisionComponent.cs
Normal file
46
scripts/components/CleanupOnCollisionComponent.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class CleanupOnCollisionComponent : Node
|
||||
{
|
||||
[Export(PropertyHint.Range, "0, 5, 0.1")] public float CleanupDelay { get; set; } = 0.5f;
|
||||
|
||||
private RigidBody2D _body;
|
||||
private CleanupComponent _cleanupComponent;
|
||||
private bool _isCleaningUp = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_body = Owner as RigidBody2D;
|
||||
if (_body == null)
|
||||
{
|
||||
GD.PrintErr("CleanupOnCollisionComponent must be attached to a RigidBody2D.");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
|
||||
_cleanupComponent = Owner.GetNode<CleanupComponent>("CleanupComponent");
|
||||
if (_cleanupComponent == null)
|
||||
{
|
||||
GD.PrintErr("CleanupOnCollisionComponent requires a CleanupComponent on the same node.");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
|
||||
_body.BodyEntered += (_) => OnBodyEntered();
|
||||
}
|
||||
|
||||
private async void OnBodyEntered()
|
||||
{
|
||||
if (_isCleaningUp) return;
|
||||
|
||||
_isCleaningUp = true;
|
||||
|
||||
await ToSignal(GetTree().CreateTimer(CleanupDelay), Timer.SignalName.Timeout);
|
||||
|
||||
_cleanupComponent?.CleanUp();
|
||||
}
|
||||
|
||||
}
|
||||
1
scripts/components/CleanupOnCollisionComponent.cs.uid
Normal file
1
scripts/components/CleanupOnCollisionComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://chusyr5vwgwf0
|
||||
@@ -12,11 +12,14 @@ public partial class DamageComponent : Node
|
||||
[Export] public Timer DamageTimer { get; set; }
|
||||
|
||||
private Node _currentTarget = null;
|
||||
private KnockbackComponent _knockbackComponent = null;
|
||||
|
||||
[Signal] public delegate void EffectInflictedEventHandler(Node2D target, StatusEffectDataResource effect);
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_knockbackComponent = Owner.GetNodeOrNull<KnockbackComponent>("KnockbackComponent");
|
||||
|
||||
if (Area != null)
|
||||
{
|
||||
Area.BodyEntered += OnAreaBodyEntered;
|
||||
@@ -93,6 +96,11 @@ public partial class DamageComponent : Node
|
||||
|
||||
DealDamage(health);
|
||||
|
||||
if (_knockbackComponent != null && body is CharacterBody2D characterBody && Owner is Node2D source)
|
||||
{
|
||||
_knockbackComponent.ApplyKnockback(characterBody, source);
|
||||
}
|
||||
|
||||
inv?.Activate();
|
||||
}
|
||||
|
||||
|
||||
20
scripts/components/EnemyControllerComponent.cs
Normal file
20
scripts/components/EnemyControllerComponent.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class EnemyControllerComponent : Node
|
||||
{
|
||||
[Export] public SideToSideMovementComponent MovementComponent { get; set; }
|
||||
[Export] public PeriodicShootingComponent ShootingComponent { get; set; }
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (MovementComponent == null || ShootingComponent == null) return;
|
||||
|
||||
if (MovementComponent.Direction != Vector2.Zero)
|
||||
{
|
||||
ShootingComponent.ShootDirection = MovementComponent.Direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/components/EnemyControllerComponent.cs.uid
Normal file
1
scripts/components/EnemyControllerComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bhbgjr8ty2n85
|
||||
47
scripts/components/FallOnDetectionComponent.cs
Normal file
47
scripts/components/FallOnDetectionComponent.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class FallOnDetectionComponent : Node2D
|
||||
{
|
||||
[Export] public Area2D DetectionArea { get; set; }
|
||||
[Export] public RigidBody2D TargetBody { get; set; }
|
||||
[Export] public float FallDelay { get; set; } = 0.2f;
|
||||
|
||||
private bool _hasTriggered = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (DetectionArea == null)
|
||||
{
|
||||
GD.PrintErr("FallOnDetectionComponent: DetectionArea is not set.");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
if (TargetBody == null)
|
||||
{
|
||||
GD.PrintErr("FallOnDetectionComponent: TargetBody is not set.");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
|
||||
DetectionArea.BodyEntered += OnBodyEntered;
|
||||
}
|
||||
|
||||
private async void OnBodyEntered(Node2D body)
|
||||
{
|
||||
if (_hasTriggered) return;
|
||||
_hasTriggered = true;
|
||||
|
||||
if (FallDelay > 0)
|
||||
{
|
||||
await ToSignal(GetTree().CreateTimer(FallDelay), Timer.SignalName.Timeout);
|
||||
}
|
||||
|
||||
if (IsInstanceValid(TargetBody))
|
||||
{
|
||||
TargetBody.GravityScale = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/components/FallOnDetectionComponent.cs.uid
Normal file
1
scripts/components/FallOnDetectionComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://co05ugnvx0v3e
|
||||
55
scripts/components/FootstepGfx.cs
Normal file
55
scripts/components/FootstepGfx.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class FootstepGfx : Node2D
|
||||
{
|
||||
[Export] private PackedScene _particles;
|
||||
[Export] private PlayerController _controller;
|
||||
[Export] private Marker2D _marker;
|
||||
|
||||
[ExportGroup("Footstep Settings")]
|
||||
[Export] private double _stepInterval = 0.5; // Time in seconds between steps
|
||||
[Export] private double _stepIntervalRandomness = 0.1; // Randomness factor for step interval
|
||||
[Export] private double _minMoveSpeed = 10.0; // Minimum speed to trigger footsteps
|
||||
[Export] private double _randomOffsetRange = 5.0; // Range for random offset
|
||||
|
||||
private double _timeSinceLastStep = 0.0;
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (_controller == null || _particles == null) return;
|
||||
|
||||
var canMakeFootstep = _controller.IsOnFloor() && _controller.Velocity.Length() >= _minMoveSpeed;
|
||||
|
||||
if (canMakeFootstep)
|
||||
{
|
||||
_timeSinceLastStep += delta;
|
||||
var randomFactor = GD.RandRange(-_stepIntervalRandomness, _stepIntervalRandomness);
|
||||
var adjustedStepInterval = _stepInterval + randomFactor;
|
||||
if (_timeSinceLastStep >= adjustedStepInterval)
|
||||
{
|
||||
SpawnFootstep();
|
||||
_timeSinceLastStep = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_timeSinceLastStep = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
private void SpawnFootstep()
|
||||
{
|
||||
if (_marker == null) return;
|
||||
var randomOffset = new Vector2(
|
||||
(float)GD.RandRange(-_randomOffsetRange, _randomOffsetRange),
|
||||
(float)GD.RandRange(-_randomOffsetRange, _randomOffsetRange)
|
||||
);
|
||||
var newParticles = _particles.Instantiate<GpuParticles2D>();
|
||||
newParticles.GlobalPosition = _marker.GlobalPosition + randomOffset;
|
||||
GetTree().CurrentScene.AddChild(newParticles);
|
||||
newParticles.Emitting = true;
|
||||
}
|
||||
}
|
||||
1
scripts/components/FootstepGfx.cs.uid
Normal file
1
scripts/components/FootstepGfx.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d3ksrjt1ek4gi
|
||||
69
scripts/components/GhostMovementComponent.cs
Normal file
69
scripts/components/GhostMovementComponent.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class GhostMovementComponent : Node2D
|
||||
{
|
||||
[Export] public float MoveSpeed { get; set; } = 0.2f;
|
||||
[Export] public int GridSize { get; set; } = 16;
|
||||
|
||||
private CharacterBody2D _body;
|
||||
private Timer _moveTimer;
|
||||
private PacXonGridManager _gridManager;
|
||||
private HealthComponent _playerHealth;
|
||||
private Vector2 _direction;
|
||||
private readonly Vector2[] _directions = { Vector2.Up, Vector2.Down, Vector2.Left, Vector2.Right };
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_body = Owner.GetNode<CharacterBody2D>(".");
|
||||
_moveTimer = new Timer { WaitTime = MoveSpeed, OneShot = false, Autostart = true };
|
||||
AddChild(_moveTimer);
|
||||
_moveTimer.Timeout += OnMoveTimerTimeout;
|
||||
|
||||
var rng = new RandomNumberGenerator();
|
||||
_direction = _directions[rng.RandiRange(0, 3)];
|
||||
}
|
||||
|
||||
public void Initialize(PacXonGridManager gridManager, PlayerController player)
|
||||
{
|
||||
_gridManager = gridManager;
|
||||
_playerHealth = player.GetNode<HealthComponent>("HealthComponent");
|
||||
}
|
||||
|
||||
private void OnMoveTimerTimeout()
|
||||
{
|
||||
if (_gridManager == null || _body == null) return;
|
||||
|
||||
var nextMapPos = _gridManager.LocalToMap(_body.Position + (_direction * GridSize));
|
||||
var cellState = _gridManager.GetCellState(nextMapPos);
|
||||
|
||||
switch (cellState)
|
||||
{
|
||||
case CellState.Solid:
|
||||
PickNewDirection();
|
||||
break;
|
||||
|
||||
case CellState.Trail:
|
||||
_playerHealth?.DecreaseHealth(9999);
|
||||
_moveTimer.Stop();
|
||||
break;
|
||||
|
||||
case CellState.Empty:
|
||||
_body.Position += _direction * GridSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void PickNewDirection()
|
||||
{
|
||||
var rng = new RandomNumberGenerator();
|
||||
Vector2 newDir;
|
||||
do
|
||||
{
|
||||
newDir = _directions[rng.RandiRange(0, 3)];
|
||||
} while (newDir == _direction || newDir == -_direction);
|
||||
_direction = newDir;
|
||||
}
|
||||
}
|
||||
1
scripts/components/GhostMovementComponent.cs.uid
Normal file
1
scripts/components/GhostMovementComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://7i20oc4cyabl
|
||||
31
scripts/components/HazardComponent.cs
Normal file
31
scripts/components/HazardComponent.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class HazardComponent : Node2D
|
||||
{
|
||||
[Export] public KnockbackComponent KnockbackComponent { get; set; }
|
||||
[Export] public Area2D HazardArea { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (KnockbackComponent == null)
|
||||
{
|
||||
GD.PrintErr("HazardComponent requires a KnockbackComponent to function properly.");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
|
||||
HazardArea.BodyEntered += OnBodyEntered;
|
||||
}
|
||||
|
||||
private void OnBodyEntered(Node2D body)
|
||||
{
|
||||
GD.Print($"Node {body.Name} entered hazard area.");
|
||||
if (body is CharacterBody2D characterBody && Owner is Node2D source)
|
||||
{
|
||||
KnockbackComponent.ApplyKnockback(characterBody, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/components/HazardComponent.cs.uid
Normal file
1
scripts/components/HazardComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://nhu2xd8611fk
|
||||
35
scripts/components/JumpGfxComponent.cs
Normal file
35
scripts/components/JumpGfxComponent.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class JumpGfxComponent : Node2D
|
||||
{
|
||||
[Export] public PackedScene ParticleScene { get; set; }
|
||||
[Export] public PlayerController Controller { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (Controller == null)
|
||||
{
|
||||
GD.PrintErr("JumpGfxComponent must have a reference to a PlayerController.");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Controller.JumpInitiated += OnJumpInitiated;
|
||||
}
|
||||
|
||||
private void OnJumpInitiated()
|
||||
{
|
||||
SpawnGfx();
|
||||
}
|
||||
|
||||
private void SpawnGfx()
|
||||
{
|
||||
var particleInstance = ParticleScene.Instantiate<GpuParticles2D>();
|
||||
particleInstance.GlobalPosition = GlobalPosition;
|
||||
GetTree().CurrentScene.AddChild(particleInstance);
|
||||
particleInstance.Emitting = true;
|
||||
}
|
||||
}
|
||||
1
scripts/components/JumpGfxComponent.cs.uid
Normal file
1
scripts/components/JumpGfxComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bpopfy6m4a0br
|
||||
@@ -11,6 +11,7 @@ public partial class JumpPadComponent : Node
|
||||
[Export] public Sprite2D Sprite { get; set; }
|
||||
[Export] public int StartAnimationIndex { get; set; } = 0;
|
||||
[Export] public float AnimationDuration { get; set; } = 0.5f;
|
||||
[Export] public GpuParticles2D Particles { get; set; }
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
@@ -27,6 +28,7 @@ public partial class JumpPadComponent : Node
|
||||
_ = HandleLaunchPadAnimation();
|
||||
player.Velocity = new Vector2(player.Velocity.X, -JumpForce);
|
||||
player.EmitSignal(PlayerController.SignalName.JumpInitiated);
|
||||
Particles?.Restart();
|
||||
}
|
||||
|
||||
private async Task HandleLaunchPadAnimation()
|
||||
|
||||
@@ -5,45 +5,33 @@ namespace Mr.BrickAdventures.scripts.components;
|
||||
[GlobalClass]
|
||||
public partial class KnockbackComponent : Node
|
||||
{
|
||||
[Export] public CharacterBody2D Body { get; set; }
|
||||
[Export] public float KnockbackForce { get; set; } = 25f;
|
||||
[Export] public HealthComponent HealthComponent { get; set; }
|
||||
[Export] public float KnockbackForce { get; set; } = 400f;
|
||||
[Export] public float KnockbackDuration { get; set; } = 0.2f; // Duration in seconds
|
||||
|
||||
private bool _knockbackMode = false;
|
||||
private int _knockbackFrames = 0;
|
||||
|
||||
public override void _Ready()
|
||||
/// <summary>
|
||||
/// Applies a knockback force to a target body, pushing it away from a source.
|
||||
/// </summary>
|
||||
/// <param name="target">The CharacterBody2D to apply the knockback to.</param>
|
||||
/// <param name="source">The Node2D causing the knockback (e.g., the enemy, the cactus).</param>
|
||||
public void ApplyKnockback(CharacterBody2D target, Node2D source)
|
||||
{
|
||||
HealthComponent.HealthChanged += OnHealthChanged;
|
||||
}
|
||||
if (target == null || source == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (_knockbackMode) _knockbackFrames++;
|
||||
var direction = (target.GlobalPosition - source.GlobalPosition).Normalized();
|
||||
|
||||
if (_knockbackFrames <= 1) return;
|
||||
if (direction == Vector2.Zero)
|
||||
{
|
||||
direction = Vector2.Up;
|
||||
}
|
||||
|
||||
_knockbackMode = false;
|
||||
_knockbackFrames = 0;
|
||||
}
|
||||
target.Velocity = direction * KnockbackForce;
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (_knockbackMode) ApplyKnockback((float)delta);
|
||||
}
|
||||
|
||||
private void OnHealthChanged(float delta, float totalHealth)
|
||||
{
|
||||
if (totalHealth <= 0f || delta >= 0f) return;
|
||||
|
||||
_knockbackMode = true;
|
||||
}
|
||||
|
||||
private void ApplyKnockback(float delta)
|
||||
{
|
||||
var velocity = Body.Velocity.Normalized();
|
||||
var knockbackDirection = new Vector2(Mathf.Sign(velocity.X), 0.4f);
|
||||
var knockbackVector = -knockbackDirection * KnockbackForce * delta;
|
||||
Body.Velocity += knockbackVector;
|
||||
var tween = CreateTween();
|
||||
tween.TweenProperty(target, "velocity", Vector2.Zero, KnockbackDuration)
|
||||
.SetEase(Tween.EaseType.Out)
|
||||
.SetTrans(Tween.TransitionType.Quad);
|
||||
}
|
||||
}
|
||||
59
scripts/components/Movement/GridMovementAbility.cs
Normal file
59
scripts/components/Movement/GridMovementAbility.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class GridMovementAbility : MovementAbility
|
||||
{
|
||||
[Export] public float MoveSpeed { get; set; } = 0.15f; // Time in seconds between moves
|
||||
[Export] public int GridSize { get; set; } = 16; // Size of one grid cell in pixels
|
||||
|
||||
private Vector2 _currentDirection = Vector2.Zero;
|
||||
private Vector2 _nextDirection = Vector2.Zero;
|
||||
private Timer _moveTimer;
|
||||
|
||||
[Signal]
|
||||
public delegate void MovedEventHandler(Vector2 newPosition);
|
||||
|
||||
public override void Initialize(PlayerController controller)
|
||||
{
|
||||
base.Initialize(controller);
|
||||
_moveTimer = new Timer { WaitTime = MoveSpeed, OneShot = false };
|
||||
AddChild(_moveTimer);
|
||||
_moveTimer.Timeout += OnMoveTimerTimeout;
|
||||
_moveTimer.Start();
|
||||
}
|
||||
|
||||
public override Vector2 ProcessMovement(Vector2 currentVelocity, double delta)
|
||||
{
|
||||
GD.Print($"Player position: {_body.Position}, {_body.GlobalPosition}");
|
||||
|
||||
var inputDirection = _input.MoveDirection;
|
||||
var newDirection = Vector2.Zero;
|
||||
|
||||
if (Mathf.Abs(inputDirection.Y) > 0.1f)
|
||||
{
|
||||
newDirection = new Vector2(0, Mathf.Sign(inputDirection.Y));
|
||||
}
|
||||
else if (Mathf.Abs(inputDirection.X) > 0.1f)
|
||||
{
|
||||
newDirection = new Vector2(Mathf.Sign(inputDirection.X), 0);
|
||||
}
|
||||
|
||||
if (newDirection != Vector2.Zero && newDirection != -_currentDirection)
|
||||
{
|
||||
_nextDirection = newDirection;
|
||||
}
|
||||
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
private void OnMoveTimerTimeout()
|
||||
{
|
||||
_currentDirection = _nextDirection;
|
||||
if (_currentDirection == Vector2.Zero) return;
|
||||
|
||||
_body.Position += _currentDirection * GridSize;
|
||||
EmitSignal(SignalName.Moved, _body.GlobalPosition);
|
||||
}
|
||||
}
|
||||
1
scripts/components/Movement/GridMovementAbility.cs.uid
Normal file
1
scripts/components/Movement/GridMovementAbility.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ctm5glmeu502l
|
||||
74
scripts/components/MovingPlatformComponent.cs
Normal file
74
scripts/components/MovingPlatformComponent.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class MovingPlatformComponent : AnimatableBody2D
|
||||
{
|
||||
public enum LoopModeEnum { OneShot, Loop, PingPong }
|
||||
|
||||
[Export] public Path2D Path { get; set; }
|
||||
[Export(PropertyHint.Range, "10, 1000, 1")] public float Speed { get; set; } = 100.0f;
|
||||
[Export] public LoopModeEnum LoopMode { get; set; } = LoopModeEnum.PingPong;
|
||||
[Export(PropertyHint.Range, "0, 10, 0.1")] public float WaitTime { get; set; } = 1.0f;
|
||||
|
||||
private PathFollow2D _pathFollower;
|
||||
private Tween _tween;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
if (Path == null)
|
||||
{
|
||||
GD.PrintErr("MovingPlatform: Path is not set. The platform will not move.");
|
||||
return;
|
||||
}
|
||||
|
||||
_pathFollower = new PathFollow2D
|
||||
{
|
||||
Loop = false,
|
||||
Rotates = false
|
||||
};
|
||||
Path.AddChild(_pathFollower);
|
||||
|
||||
StartMovement();
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
if (_pathFollower == null) return;
|
||||
|
||||
GlobalPosition = _pathFollower.GlobalPosition;
|
||||
}
|
||||
|
||||
private void StartMovement()
|
||||
{
|
||||
_tween?.Kill();
|
||||
_tween = CreateTween();
|
||||
_tween.SetParallel(false);
|
||||
|
||||
var pathLength =Path.Curve.GetBakedLength();
|
||||
var duration = pathLength / Speed;
|
||||
|
||||
switch (LoopMode)
|
||||
{
|
||||
case LoopModeEnum.OneShot:
|
||||
_tween.TweenProperty(_pathFollower, "progress", pathLength, duration);
|
||||
break;
|
||||
|
||||
case LoopModeEnum.Loop:
|
||||
_tween.TweenProperty(_pathFollower, "progress", pathLength, duration);
|
||||
_tween.TweenInterval(WaitTime);
|
||||
_tween.TweenCallback(Callable.From(() => _pathFollower.Progress = 0));
|
||||
_tween.SetLoops();
|
||||
break;
|
||||
|
||||
case LoopModeEnum.PingPong:
|
||||
_tween.TweenProperty(_pathFollower, "progress", pathLength, duration);
|
||||
_tween.TweenInterval(WaitTime);
|
||||
_tween.TweenProperty(_pathFollower, "progress", 0, duration);
|
||||
_tween.TweenInterval(WaitTime);
|
||||
_tween.SetLoops();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/components/MovingPlatformComponent.cs.uid
Normal file
1
scripts/components/MovingPlatformComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://g4ryqvpelmvl
|
||||
91
scripts/components/PacXonGridInteractor.cs
Normal file
91
scripts/components/PacXonGridInteractor.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class PacXonGridInteractor : Node
|
||||
{
|
||||
private enum PlayerGridState { OnSolid, DrawingTrail }
|
||||
|
||||
private PacXonGridManager _gridManager;
|
||||
private HealthComponent _healthComponent;
|
||||
private GridMovementAbility _gridMovement;
|
||||
|
||||
private PlayerGridState _currentState = PlayerGridState.OnSolid;
|
||||
private readonly List<Vector2I> _currentTrail = [];
|
||||
private List<Node2D> _ghosts = [];
|
||||
|
||||
[Signal] public delegate void TrailStartedEventHandler(Vector2 startPosition);
|
||||
[Signal] public delegate void TrailExtendedEventHandler(Vector2 newPosition);
|
||||
[Signal] public delegate void TrailClearedEventHandler();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_healthComponent = Owner.GetNodeOrNull<HealthComponent>("HealthComponent");
|
||||
}
|
||||
|
||||
public void Initialize(PacXonGridManager gridManager, GridMovementAbility gridMovement, List<Node2D> ghosts)
|
||||
{
|
||||
_gridManager = gridManager;
|
||||
_gridMovement = gridMovement;
|
||||
_ghosts = ghosts;
|
||||
_gridMovement.Moved += OnPlayerMoved;
|
||||
}
|
||||
|
||||
private void OnPlayerMoved(Vector2 newPosition)
|
||||
{
|
||||
if (_gridManager == null) return;
|
||||
|
||||
var mapCoords = _gridManager.LocalToMap(newPosition);
|
||||
var destinationState = _gridManager.GetCellState(mapCoords);
|
||||
|
||||
if (_currentState == PlayerGridState.DrawingTrail) EmitSignalTrailExtended(newPosition);
|
||||
|
||||
if (destinationState == CellState.Trail)
|
||||
{
|
||||
EmitSignalTrailCleared();
|
||||
_healthComponent?.DecreaseHealth(9999);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentState == PlayerGridState.OnSolid)
|
||||
{
|
||||
if (destinationState == CellState.Empty)
|
||||
{
|
||||
// Moved from solid ground to an empty space, start drawing.
|
||||
_currentState = PlayerGridState.DrawingTrail;
|
||||
_currentTrail.Clear();
|
||||
_currentTrail.Add(mapCoords);
|
||||
_gridManager.SetCellState(mapCoords, CellState.Trail);
|
||||
EmitSignalTrailStarted(newPosition);
|
||||
}
|
||||
}
|
||||
else if (_currentState == PlayerGridState.DrawingTrail)
|
||||
{
|
||||
if (destinationState == CellState.Empty)
|
||||
{
|
||||
// Continue drawing the trail
|
||||
_currentTrail.Add(mapCoords);
|
||||
_gridManager.SetCellState(mapCoords, CellState.Trail);
|
||||
}
|
||||
else if (destinationState == CellState.Solid)
|
||||
{
|
||||
_gridManager.PerformFloodFill(_ghosts);
|
||||
GD.Print("Fill logic triggered!");
|
||||
_currentState = PlayerGridState.OnSolid;
|
||||
SolidifyTrail();
|
||||
_currentTrail.Clear();
|
||||
EmitSignalTrailCleared();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SolidifyTrail()
|
||||
{
|
||||
foreach (var pos in _currentTrail)
|
||||
{
|
||||
_gridManager.SetCellState(pos, CellState.Solid);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/components/PacXonGridInteractor.cs.uid
Normal file
1
scripts/components/PacXonGridInteractor.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c00siqtssccr6
|
||||
121
scripts/components/PacXonGridManager.cs
Normal file
121
scripts/components/PacXonGridManager.cs
Normal file
@@ -0,0 +1,121 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
public enum CellState
|
||||
{
|
||||
Empty = -1,
|
||||
Solid = 0,
|
||||
Trail = 1,
|
||||
Hunted = 2
|
||||
}
|
||||
|
||||
[GlobalClass]
|
||||
public partial class PacXonGridManager : TileMapLayer
|
||||
{
|
||||
[Export] public Rect2I PlayArea { get; set; } = new Rect2I(1, 1, 38, 28);
|
||||
|
||||
private int _solidCellCount = 0;
|
||||
private int _totalPlayableCells = 0;
|
||||
|
||||
[Signal] public delegate void FillPercentageChangedEventHandler(float percentage);
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_totalPlayableCells = PlayArea.Size.X * PlayArea.Size.Y;
|
||||
InitializeGrid();
|
||||
}
|
||||
|
||||
private void InitializeGrid()
|
||||
{
|
||||
Clear();
|
||||
|
||||
for (var x = PlayArea.Position.X - 1; x <= PlayArea.End.X + 1; x++)
|
||||
{
|
||||
for (var y = PlayArea.Position.Y - 1; y <= PlayArea.End.Y + 1; y++)
|
||||
{
|
||||
if (x < PlayArea.Position.X || x > PlayArea.End.X || y < PlayArea.Position.Y || y > PlayArea.End.Y)
|
||||
{
|
||||
SetCell(new Vector2I(x, y), (int)CellState.Solid, Vector2I.Zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CellState GetCellState(Vector2I mapCoords)
|
||||
{
|
||||
var tileId = GetCellSourceId(mapCoords);
|
||||
return (CellState)tileId;
|
||||
}
|
||||
|
||||
public void SetCellState(Vector2I mapCoords, CellState state)
|
||||
{
|
||||
if (GetCellSourceId(mapCoords) != (int)CellState.Solid && state == CellState.Solid) _solidCellCount++;
|
||||
SetCell(mapCoords, (int)state, Vector2I.Zero);
|
||||
}
|
||||
|
||||
public float GetFillPercentage()
|
||||
{
|
||||
return _totalPlayableCells > 0 ? (float)_solidCellCount / _totalPlayableCells : 0;
|
||||
}
|
||||
|
||||
public void PerformFloodFill(List<Node2D> ghosts)
|
||||
{
|
||||
var unsafeCells = new HashSet<Vector2I>();
|
||||
|
||||
foreach (var ghost in ghosts.Where(IsInstanceValid))
|
||||
{
|
||||
var ghostPos = LocalToMap(ghost.Position);
|
||||
FloodFillScan(ghostPos, unsafeCells);
|
||||
}
|
||||
|
||||
var filledCount = 0;
|
||||
for (var x = PlayArea.Position.X; x <= PlayArea.End.X; x++)
|
||||
{
|
||||
for (var y = PlayArea.Position.Y; y <= PlayArea.End.Y; y++)
|
||||
{
|
||||
var currentPos = new Vector2I(x, y);
|
||||
if (GetCellState(currentPos) == CellState.Empty && !unsafeCells.Contains(currentPos))
|
||||
{
|
||||
SetCellState(currentPos, CellState.Solid);
|
||||
filledCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (filledCount > 0)
|
||||
{
|
||||
EmitSignal(SignalName.FillPercentageChanged, GetFillPercentage());
|
||||
}
|
||||
}
|
||||
|
||||
private void FloodFillScan(Vector2I startPos, HashSet<Vector2I> visited)
|
||||
{
|
||||
if (!PlayArea.HasPoint(startPos) || visited.Contains(startPos)) return;
|
||||
|
||||
var q = new Queue<Vector2I>();
|
||||
q.Enqueue(startPos);
|
||||
visited.Add(startPos);
|
||||
|
||||
while (q.Count > 0)
|
||||
{
|
||||
var pos = q.Dequeue();
|
||||
|
||||
var neighbors = new[]
|
||||
{
|
||||
pos + Vector2I.Up, pos + Vector2I.Down, pos + Vector2I.Left, pos + Vector2I.Right
|
||||
};
|
||||
|
||||
foreach (var neighbor in neighbors)
|
||||
{
|
||||
if (PlayArea.HasPoint(neighbor) && !visited.Contains(neighbor) && GetCellState(neighbor) == CellState.Empty)
|
||||
{
|
||||
visited.Add(neighbor);
|
||||
q.Enqueue(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/components/PacXonGridManager.cs.uid
Normal file
1
scripts/components/PacXonGridManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dx4m2ouyvwkir
|
||||
67
scripts/components/PacXonTrailComponent.cs
Normal file
67
scripts/components/PacXonTrailComponent.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class PacXonTrailComponent : Line2D
|
||||
{
|
||||
private PacXonGridInteractor _gridInteractor;
|
||||
private readonly List<Vector2> _trailPoints = [];
|
||||
|
||||
public void Initialize(PacXonGridInteractor interactor)
|
||||
{
|
||||
_gridInteractor = interactor;
|
||||
_gridInteractor.TrailStarted += OnTrailStarted;
|
||||
_gridInteractor.TrailExtended += OnTrailExtended;
|
||||
_gridInteractor.TrailCleared += OnTrailCleared;
|
||||
|
||||
Width = 8;
|
||||
DefaultColor = new Color("#a6f684");
|
||||
JointMode = LineJointMode.Round;
|
||||
BeginCapMode = LineCapMode.Round;
|
||||
EndCapMode = LineCapMode.Round;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (_gridInteractor != null)
|
||||
{
|
||||
_gridInteractor.TrailStarted -= OnTrailStarted;
|
||||
_gridInteractor.TrailExtended -= OnTrailExtended;
|
||||
_gridInteractor.TrailCleared -= OnTrailCleared;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTrailStarted(Vector2 startPosition)
|
||||
{
|
||||
_trailPoints.Clear();
|
||||
_trailPoints.Add(ToLocal(startPosition));
|
||||
_trailPoints.Add(ToLocal(startPosition));
|
||||
UpdateTrail();
|
||||
}
|
||||
|
||||
private void OnTrailExtended(Vector2 newPosition)
|
||||
{
|
||||
if (_trailPoints.Count > 0)
|
||||
{
|
||||
_trailPoints[^1] = ToLocal(newPosition);
|
||||
}
|
||||
UpdateTrail();
|
||||
}
|
||||
|
||||
private void OnTrailCleared()
|
||||
{
|
||||
_trailPoints.Clear();
|
||||
UpdateTrail();
|
||||
}
|
||||
|
||||
private void UpdateTrail()
|
||||
{
|
||||
ClearPoints();
|
||||
foreach (var point in _trailPoints)
|
||||
{
|
||||
AddPoint(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
scripts/components/PacXonTrailComponent.cs.uid
Normal file
1
scripts/components/PacXonTrailComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cmk4m7mplqnrm
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
@@ -8,31 +9,29 @@ public partial class PeriodicShootingComponent : Node
|
||||
[Export] public PackedScene BulletScene { get; set; }
|
||||
[Export] public float ShootInterval { get; set; } = 1.0f;
|
||||
[Export] public Vector2 ShootDirection { get; set; } = Vector2.Right;
|
||||
[Export] public SideToSideMovementComponent SideToSideMovement { get; set; }
|
||||
[Export] public Node2D BulletSpawnRight { get; set; }
|
||||
[Export] public Node2D BulletSpawnLeft { get; set; }
|
||||
[Export] public Node2D BulletSpawnPointRight { get; set; }
|
||||
[Export] public Node2D BulletSpawnPointLeft { get; set; }
|
||||
[Export] public float ShootingIntervalVariation { get; set; } = 0.0f;
|
||||
|
||||
[Signal] public delegate void ShotFiredEventHandler(Vector2 shootDirection);
|
||||
|
||||
private Timer _timer;
|
||||
private RandomNumberGenerator _rng;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_rng = new RandomNumberGenerator();
|
||||
SetupTimer();
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (SideToSideMovement == null) return;
|
||||
|
||||
ShootDirection = SideToSideMovement.Direction != Vector2.Zero ? SideToSideMovement.Direction : Vector2.Right;
|
||||
}
|
||||
|
||||
private void SetupTimer()
|
||||
{
|
||||
_timer = new Timer();
|
||||
_timer.WaitTime = GetShootInterval();
|
||||
_timer.OneShot = false;
|
||||
_timer.Autostart = true;
|
||||
_timer = new Timer
|
||||
{
|
||||
WaitTime = GetNextShootInterval(),
|
||||
OneShot = false,
|
||||
Autostart = true
|
||||
};
|
||||
_timer.Timeout += OnTimerTimeout;
|
||||
AddChild(_timer);
|
||||
}
|
||||
@@ -40,33 +39,53 @@ public partial class PeriodicShootingComponent : Node
|
||||
private void OnTimerTimeout()
|
||||
{
|
||||
Shoot();
|
||||
_timer.Start();
|
||||
_timer.WaitTime = GetNextShootInterval();
|
||||
}
|
||||
|
||||
private double GetShootInterval()
|
||||
private double GetNextShootInterval()
|
||||
{
|
||||
if (ShootingIntervalVariation == 0f) return ShootInterval;
|
||||
if (ShootingIntervalVariation <= 0f)
|
||||
{
|
||||
return ShootInterval;
|
||||
}
|
||||
|
||||
var rng = new RandomNumberGenerator();
|
||||
return ShootInterval + rng.RandfRange(-ShootingIntervalVariation, ShootingIntervalVariation);
|
||||
return Math.Max(0.01, ShootInterval + _rng.RandfRange(-ShootingIntervalVariation, ShootingIntervalVariation));
|
||||
}
|
||||
|
||||
private void Shoot()
|
||||
{
|
||||
if (BulletScene == null)
|
||||
{
|
||||
GD.PushError("PeriodicShootingComponent: BulletScene is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShootDirection == Vector2.Zero) return;
|
||||
|
||||
var root = Owner as Node2D;
|
||||
var spawnNode = (ShootDirection.X >= 0 || BulletSpawnPointLeft == null)
|
||||
? BulletSpawnPointRight
|
||||
: BulletSpawnPointLeft;
|
||||
|
||||
if (spawnNode == null)
|
||||
{
|
||||
GD.PrintErr("PeriodicShootingComponent: A suitable bullet spawn point is not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
var spawnPosition = spawnNode.GlobalPosition;
|
||||
var owner = Owner as Node2D;
|
||||
var ownerRotation = owner?.Rotation ?? 0f;
|
||||
|
||||
var bulletInstance = BulletScene.Instantiate<Node2D>();
|
||||
var launchComponent = bulletInstance.GetNodeOrNull<LaunchComponent>("LaunchComponent");
|
||||
var spawnPosition = ShootDirection == Vector2.Right ? BulletSpawnRight.GlobalPosition : BulletSpawnLeft.GlobalPosition;
|
||||
if (launchComponent != null)
|
||||
if (bulletInstance.GetNodeOrNull<LaunchComponent>("LaunchComponent") is { } launchComponent)
|
||||
{
|
||||
launchComponent.InitialDirection = ShootDirection;
|
||||
launchComponent.SpawnPosition = spawnPosition;
|
||||
if (root != null) launchComponent.SpawnRotation = root.Rotation;
|
||||
launchComponent.SpawnRotation = ownerRotation;
|
||||
}
|
||||
|
||||
bulletInstance.Position = spawnPosition;
|
||||
bulletInstance.GlobalPosition = spawnPosition;
|
||||
GetTree().CurrentScene.AddChild(bulletInstance);
|
||||
EmitSignalShotFired(ShootDirection);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ public partial class PlayerController : CharacterBody2D
|
||||
[Export] public PackedScene OneWayPlatformScene { get; set; }
|
||||
[Export] public PackedScene SpaceshipMovementScene { get; set; }
|
||||
[Export] public PackedScene WallJumpScene { get; set; }
|
||||
[Export] public PackedScene GridMovementScene { get; set; }
|
||||
|
||||
[Signal] public delegate void JumpInitiatedEventHandler();
|
||||
[Signal] public delegate void MovementAbilitiesChangedEventHandler();
|
||||
@@ -75,7 +76,7 @@ public partial class PlayerController : CharacterBody2D
|
||||
_abilities.Add(ability);
|
||||
}
|
||||
|
||||
private void ClearMovementAbilities()
|
||||
public void ClearMovementAbilities()
|
||||
{
|
||||
foreach (var ability in _abilities)
|
||||
{
|
||||
@@ -119,6 +120,13 @@ public partial class PlayerController : CharacterBody2D
|
||||
EmitSignalMovementAbilitiesChanged();
|
||||
}
|
||||
|
||||
public void SetGridMovement()
|
||||
{
|
||||
ClearMovementAbilities();
|
||||
if (GridMovementScene != null) AddAbility(GridMovementScene.Instantiate<MovementAbility>());
|
||||
EmitSignalMovementAbilitiesChanged();
|
||||
}
|
||||
|
||||
private async Task ConnectJumpAndGravityAbilities()
|
||||
{
|
||||
await ToSignal(GetTree(), SceneTree.SignalName.ProcessFrame);
|
||||
|
||||
51
scripts/components/RecoilComponent.cs
Normal file
51
scripts/components/RecoilComponent.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class RecoilComponent : Node
|
||||
{
|
||||
[Export] public Node2D RecoilTarget { get; set; }
|
||||
[Export] public float RecoilDistance { get; set; } = 8f;
|
||||
[Export] public float RecoilDuration { get; set; } = 0.1f;
|
||||
|
||||
private Vector2 _originalPosition;
|
||||
private Tween _recoilTween;
|
||||
private PeriodicShootingComponent _shootingComponent;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
RecoilTarget ??= Owner as Node2D;
|
||||
if (RecoilTarget == null)
|
||||
{
|
||||
GD.PushError("RecoilComponent: RecoilTarget is null");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
|
||||
_originalPosition = RecoilTarget.Position;
|
||||
|
||||
_shootingComponent = Owner.GetNodeOrNull<PeriodicShootingComponent>("PeriodicShootingComponent");
|
||||
if (_shootingComponent != null)
|
||||
{
|
||||
_shootingComponent.ShotFired += TriggerRecoil;
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerRecoil(Vector2 shootDirection)
|
||||
{
|
||||
if (RecoilTarget == null) return;
|
||||
|
||||
_recoilTween?.Kill();
|
||||
|
||||
var recoilDirection = -shootDirection.Normalized();
|
||||
var recoilPosition = _originalPosition + recoilDirection * RecoilDistance;
|
||||
|
||||
_recoilTween = CreateTween();
|
||||
_recoilTween.SetEase(Tween.EaseType.Out);
|
||||
_recoilTween.SetTrans(Tween.TransitionType.Cubic);
|
||||
|
||||
_recoilTween.TweenProperty(RecoilTarget, "position", recoilPosition, RecoilDuration / 2);
|
||||
_recoilTween.TweenProperty(RecoilTarget, "position", _originalPosition, RecoilDuration / 2).SetDelay(RecoilDuration / 2);
|
||||
}
|
||||
}
|
||||
1
scripts/components/RecoilComponent.cs.uid
Normal file
1
scripts/components/RecoilComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b3j23e7b7x8ro
|
||||
71
scripts/components/SquashAndStretchComponent.cs
Normal file
71
scripts/components/SquashAndStretchComponent.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using Godot;
|
||||
|
||||
namespace Mr.BrickAdventures.scripts.components;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class SquashAndStretchComponent : Node
|
||||
{
|
||||
[Export] public Node2D TargetNode { get; set; }
|
||||
[Export(PropertyHint.Range, "0.1, 1.0, 0.01")] public float AnimationDuration { get; set; } = 0.25f;
|
||||
|
||||
[ExportGroup("Effect Strength")]
|
||||
[Export(PropertyHint.Range, "1.0, 2.0, 0.05")] public float SquashFactor { get; set; } = 1.2f;
|
||||
[Export(PropertyHint.Range, "0.5, 1.0, 0.05")] public float StretchFactor { get; set; } = 0.8f;
|
||||
|
||||
private Vector2 _originalScale;
|
||||
private Tween _tween;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
TargetNode ??= Owner as Node2D;
|
||||
|
||||
if (TargetNode == null)
|
||||
{
|
||||
GD.PrintErr("SquashAndStretchComponent: No valid TargetNode found. Disabling component.");
|
||||
SetProcess(false);
|
||||
return;
|
||||
}
|
||||
|
||||
_originalScale = TargetNode.Scale;
|
||||
|
||||
var shootingComponent = Owner.GetNodeOrNull<PeriodicShootingComponent>("PeriodicShootingComponent");
|
||||
if (shootingComponent != null)
|
||||
{
|
||||
shootingComponent.ShotFired += OnShotFired;
|
||||
}
|
||||
else
|
||||
{
|
||||
GD.PrintErr("SquashAndStretchComponent requires a PeriodicShootingComponent on the same owner to function.");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnShotFired(Vector2 shootDirection)
|
||||
{
|
||||
if (TargetNode == null) return;
|
||||
|
||||
_tween?.Kill();
|
||||
|
||||
Vector2 squashScale;
|
||||
Vector2 stretchScale;
|
||||
|
||||
if (Mathf.Abs(shootDirection.X) > Mathf.Abs(shootDirection.Y))
|
||||
{
|
||||
squashScale = new Vector2(StretchFactor, SquashFactor) * _originalScale;
|
||||
stretchScale = new Vector2(SquashFactor, StretchFactor) * _originalScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
squashScale = new Vector2(SquashFactor, StretchFactor) * _originalScale;
|
||||
stretchScale = new Vector2(StretchFactor, SquashFactor) * _originalScale;
|
||||
}
|
||||
|
||||
_tween = CreateTween();
|
||||
_tween.SetTrans(Tween.TransitionType.Elastic).SetEase(Tween.EaseType.Out);
|
||||
|
||||
var partDuration = AnimationDuration / 3.0f;
|
||||
|
||||
_tween.TweenProperty(TargetNode, "scale", squashScale, partDuration);
|
||||
_tween.TweenProperty(TargetNode, "scale", stretchScale, partDuration);
|
||||
_tween.TweenProperty(TargetNode, "scale", _originalScale, partDuration);
|
||||
}
|
||||
}
|
||||
1
scripts/components/SquashAndStretchComponent.cs.uid
Normal file
1
scripts/components/SquashAndStretchComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://c707c53k7c5ae
|
||||
BIN
sprites/BFT - Mega Metroidvania Tileset.png
Normal file
BIN
sprites/BFT - Mega Metroidvania Tileset.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
34
sprites/BFT - Mega Metroidvania Tileset.png.import
Normal file
34
sprites/BFT - Mega Metroidvania Tileset.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ccjihsk6w8sow"
|
||||
path="res://.godot/imported/BFT - Mega Metroidvania Tileset.png-19c14f630afbe7f12271eafb441c25f8.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://sprites/BFT - Mega Metroidvania Tileset.png"
|
||||
dest_files=["res://.godot/imported/BFT - Mega Metroidvania Tileset.png-19c14f630afbe7f12271eafb441c25f8.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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user