Add new methods to input handler, add RectangleShape2d, modify test game.

This commit is contained in:
2023-09-25 17:31:33 +02:00
parent 0b018e081e
commit ddf62f1834
12 changed files with 318 additions and 77 deletions

View File

@@ -4,6 +4,7 @@ namespace DaggerFramework
{ {
public abstract bool IsDown(InputHandler inputHandler); public abstract bool IsDown(InputHandler inputHandler);
public abstract bool IsPressed(InputHandler inputHandler); public abstract bool IsPressed(InputHandler inputHandler);
public abstract bool IsReleased(InputHandler inputHandler);
} }
public class KeyInputAction : InputAction public class KeyInputAction : InputAction
@@ -24,6 +25,12 @@ namespace DaggerFramework
return inputHandler.KeyboardKeyJustPressed(_keyboardKey); return inputHandler.KeyboardKeyJustPressed(_keyboardKey);
} }
public override bool IsReleased(InputHandler inputHandler)
{
return inputHandler.KeyboardKeyJustReleased(_keyboardKey);
}
private KeyboardKey _keyboardKey; private KeyboardKey _keyboardKey;
} }
} }

View File

@@ -1,4 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Numerics; using System.Numerics;
using DaggerFramework.Utils;
namespace DaggerFramework namespace DaggerFramework
{ {
@@ -7,16 +9,20 @@ namespace DaggerFramework
public InputHandler() public InputHandler()
{ {
inputMappings = new Dictionary<string, IEnumerable<InputAction>>(); inputMappings = new Dictionary<string, IEnumerable<InputAction>>();
CreateDefaultMappings();
} }
public Action OnInput; public Action OnInput;
public bool Handled { get => _handled; set => _handled = value; } public bool Handled { get => _handled; set => _handled = value; }
public abstract bool IsKeyboardKeyDown(KeyboardKey key); public abstract bool IsKeyboardKeyDown(KeyboardKey key);
public abstract bool KeyboardKeyJustPressed(KeyboardKey key); public abstract bool KeyboardKeyJustPressed(KeyboardKey key);
public abstract bool KeyboardKeyJustReleased(KeyboardKey key);
public abstract Vector2 GetInputDirection(KeyboardKey leftKey, KeyboardKey rightKey, KeyboardKey upKey, KeyboardKey downKey); public abstract Vector2 GetInputDirection(KeyboardKey leftKey, KeyboardKey rightKey, KeyboardKey upKey, KeyboardKey downKey);
public abstract Vector2 GetInputDirection(string leftAction, string rightAction, string upAction, string downAction);
public abstract int GetCharPressed(); public abstract int GetCharPressed();
public abstract bool IsActionDown(string action); public abstract bool IsActionDown(string action);
public abstract bool IsActionJustPressed(string action); public abstract bool IsActionPressed(string action);
public abstract bool IsActionReleased(string action);
public abstract bool IsMouseButtonDown(MouseButton button); public abstract bool IsMouseButtonDown(MouseButton button);
public abstract float GetMouseWheelMovement(); public abstract float GetMouseWheelMovement();
@@ -33,8 +39,46 @@ namespace DaggerFramework
inputMappings.Add(actionName, inputActions); inputMappings.Add(actionName, inputActions);
} }
private void CreateDefaultMappings()
{
AddInputMapping("up", new InputAction[] {
new KeyInputAction(KeyboardKey.W),
new KeyInputAction(KeyboardKey.Up),
});
AddInputMapping("down", new InputAction[] {
new KeyInputAction(KeyboardKey.S),
new KeyInputAction(KeyboardKey.Down),
});
AddInputMapping("left", new InputAction[] {
new KeyInputAction(KeyboardKey.A),
new KeyInputAction(KeyboardKey.Left),
});
AddInputMapping("right", new InputAction[] {
new KeyInputAction(KeyboardKey.D),
new KeyInputAction(KeyboardKey.Right),
});
}
protected bool TryGetInputMappings(string forAction, [NotNullWhen(true)] out IEnumerable<InputAction>? inputActions)
{
var contains = inputMappings.ContainsKey(forAction);
inputActions = null;
if (!contains)
{
_logger.Error($"The action \"{forAction}\" is not present in the input mappings!");
return false;
}
inputActions = inputMappings[forAction];
return true;
}
private bool _handled; private bool _handled;
protected Dictionary<string, IEnumerable<InputAction>> inputMappings; protected Dictionary<string, IEnumerable<InputAction>> inputMappings;
private Logger _logger = new(nameof(InputHandler));
} }
public enum KeyboardKey public enum KeyboardKey

View File

@@ -26,6 +26,23 @@ namespace DaggerFramework
return dir == Vector2.Zero ? Vector2.Zero : Vector2.Normalize(dir); return dir == Vector2.Zero ? Vector2.Zero : Vector2.Normalize(dir);
} }
public override Vector2 GetInputDirection(string leftAction, string rightAction, string upAction, string downAction)
{
Vector2 dir = Vector2.Zero;
if (IsActionDown(leftAction))
dir += new Vector2(-1, 0);
if (IsActionDown(rightAction))
dir += new Vector2(1, 0);
if (IsActionDown(upAction))
dir += new Vector2(0, -1);
if (IsActionDown(downAction))
dir += new Vector2(0, 1);
return dir == Vector2.Zero ? Vector2.Zero : Vector2.Normalize(dir);
}
public override Vector2 GetMousePosition() public override Vector2 GetMousePosition()
{ {
return Raylib.GetMousePosition(); return Raylib.GetMousePosition();
@@ -43,18 +60,39 @@ namespace DaggerFramework
public override bool IsActionDown(string action) public override bool IsActionDown(string action)
{ {
// throw new NotImplementedException(); IEnumerable<InputAction>? mappings;
// return inputMappings[action].IsPressed();
foreach (InputAction inputAction in inputMappings[action]) if (TryGetInputMappings(action, out mappings))
{
foreach (InputAction inputAction in mappings)
if (inputAction.IsDown(this)) return true; if (inputAction.IsDown(this)) return true;
}
return false; return false;
} }
public override bool IsActionJustPressed(string action) public override bool IsActionPressed(string action)
{ {
foreach (InputAction inputAction in inputMappings[action]) IEnumerable<InputAction>? mappings;
if (TryGetInputMappings(action, out mappings))
{
foreach (InputAction inputAction in mappings)
if (inputAction.IsPressed(this)) return true; if (inputAction.IsPressed(this)) return true;
}
return false;
}
public override bool IsActionReleased(string action)
{
IEnumerable<InputAction>? mappings;
if (TryGetInputMappings(action, out mappings))
{
foreach (InputAction inputAction in mappings)
if (inputAction.IsReleased(this)) return true;
}
return false; return false;
} }
@@ -77,6 +115,11 @@ namespace DaggerFramework
return Raylib.IsKeyPressed(rayKey); return Raylib.IsKeyPressed(rayKey);
} }
public override bool KeyboardKeyJustReleased(KeyboardKey key)
{
return Raylib.IsKeyReleased((Raylib_cs.KeyboardKey)key);
}
public override void SetMousePosition(Vector2 position) public override void SetMousePosition(Vector2 position)
{ {
Raylib.SetMousePosition((int)position.X, (int)position.Y); Raylib.SetMousePosition((int)position.X, (int)position.Y);

View File

@@ -12,7 +12,7 @@ namespace DaggerFramework.SceneGraph
renderer.DrawCircle(_radius, _color); renderer.DrawCircle(_radius, _color);
} }
private float _radius; private float _radius = 16;
private Color _color; private Color _color = Color.White;
} }
} }

View File

@@ -0,0 +1,14 @@
using System.Numerics;
using DaggerFramework.Rendering;
namespace DaggerFramework.SceneGraph;
public class RectangleShape2d : Drawable2d
{
public Vector2 Size { get; set; } = Vector2.One * 32;
public Color Color { get; set; } = Color.White;
public override void OnDraw(Renderer renderer)
{
renderer.DrawRectangle(Size, Color);
}
}

View File

@@ -5,17 +5,41 @@ namespace DaggerFramework.SceneGraph
{ {
public class Text2d : Drawable2d public class Text2d : Drawable2d
{ {
public string Contents { get => _contents; set => _contents = value; } public string Text { get => _text; set => _text = value; }
public int FontSize { get => _fontSize; set => _fontSize = value; } public int FontSize { get => _fontSize; set => _fontSize = value; }
public Color FontColor { get => _fontColor; set => _fontColor = value; } public Color FontColor { get => _fontColor; set => _fontColor = value; }
public Font Font
{
get => _font; set
{
_isDirty = true;
_font = value;
}
}
public override void OnDraw(Renderer renderer) public override void OnDraw(Renderer renderer)
{ {
renderer.DrawDebugText(_contents, _fontSize, _fontColor); if (_isDirty)
{
_fontHandle = renderer.LoadFont(_font);
_isDirty = false;
} }
private string _contents = string.Empty; if (_font == null)
{
renderer.DrawDebugText(_text, _fontSize, _fontColor);
}
else
{
renderer.DrawText(_fontHandle, _text, _fontSize, _fontColor);
}
}
private string _text = string.Empty;
private int _fontSize = 16; private int _fontSize = 16;
private Color _fontColor = Color.White; private Color _fontColor = Color.White;
private Font _font;
private int _fontHandle;
private bool _isDirty;
} }
} }

View File

@@ -1,3 +1,4 @@
using DaggerFramework.Resources;
using DaggerFramework.Rendering; using DaggerFramework.Rendering;
namespace DaggerFramework.SceneGraph namespace DaggerFramework.SceneGraph
@@ -6,6 +7,7 @@ namespace DaggerFramework.SceneGraph
{ {
public Scene Scene { get; set; } public Scene Scene { get; set; }
public InputHandler Input { get; set; } public InputHandler Input { get; set; }
public ResourceManager ResourceManager => Scene.ResourceManager;
public void Draw(Renderer renderer) => OnDraw(renderer); public void Draw(Renderer renderer) => OnDraw(renderer);

View File

@@ -1,7 +1,7 @@
using System.Drawing;
using System.Numerics; using System.Numerics;
using DaggerFramework.Audio; using DaggerFramework.Audio;
using DaggerFramework.Rendering; using DaggerFramework.Rendering;
using DaggerFramework.Resources;
namespace DaggerFramework.SceneGraph namespace DaggerFramework.SceneGraph
@@ -11,14 +11,17 @@ namespace DaggerFramework.SceneGraph
public Renderer Renderer { get => _renderer; set => _renderer = value; } public Renderer Renderer { get => _renderer; set => _renderer = value; }
public InputHandler Input { get => _input; set => _input = value; } public InputHandler Input { get => _input; set => _input = value; }
public AudioBackend Audio => _audioBackend; public AudioBackend Audio => _audioBackend;
public ResourceManager ResourceManager => _resourceManager;
public double DeltaTime => Renderer.GetFrameTime(); public double DeltaTime => Renderer.GetFrameTime();
public Scene(Renderer renderer, InputHandler input, AudioBackend audioBackend) public Scene(Renderer renderer, InputHandler input, AudioBackend audioBackend, ResourceManager resourceManager)
{ {
_renderer = renderer; _renderer = renderer;
_input = input; _input = input;
_audioBackend = audioBackend; _audioBackend = audioBackend;
_resourceManager = resourceManager;
_layers = new Dictionary<string, Layer>(); _layers = new Dictionary<string, Layer>();
} }
@@ -43,6 +46,7 @@ namespace DaggerFramework.SceneGraph
{ {
layer.Value.Update(DeltaTime); layer.Value.Update(DeltaTime);
} }
Draw(); Draw();
} }
@@ -58,10 +62,12 @@ namespace DaggerFramework.SceneGraph
{ {
Renderer.BeginFrame(); Renderer.BeginFrame();
Renderer.ClearBackground(Color.Black); Renderer.ClearBackground(Color.Black);
foreach (var layer in _layers.Values) foreach (var layer in _layers.Values)
{ {
layer.Draw(_renderer); layer.Draw(_renderer);
} }
Renderer.EndFrame(); Renderer.EndFrame();
Audio.Update(); Audio.Update();
@@ -78,5 +84,8 @@ namespace DaggerFramework.SceneGraph
private Renderer _renderer; private Renderer _renderer;
private AudioBackend _audioBackend; private AudioBackend _audioBackend;
private InputHandler _input; private InputHandler _input;
private ResourceManager _resourceManager;
private bool _inputDirty;
} }
} }

View File

@@ -7,11 +7,18 @@ namespace DaggerFramework.Utils
{ {
_className = className; _className = className;
} }
public void Echo(object what)
{
LogConsole((string)what, LogType.Echo);
OnLog?.Invoke((string)what, LogType.Echo);
}
public void Info(object what) public void Info(object what)
{ {
LogType logType = LogType.Info; LogType logType = LogType.Info;
string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}"; string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}";
LogConsole(message); LogConsole(message, logType);
OnLog?.Invoke(message, logType); OnLog?.Invoke(message, logType);
} }
@@ -19,7 +26,7 @@ namespace DaggerFramework.Utils
{ {
LogType logType = LogType.Warn; LogType logType = LogType.Warn;
string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}"; string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}";
LogConsole(message); LogConsole(message, logType);
OnLog?.Invoke(message, logType); OnLog?.Invoke(message, logType);
} }
@@ -27,19 +34,47 @@ namespace DaggerFramework.Utils
{ {
LogType logType = LogType.Error; LogType logType = LogType.Error;
string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}"; string message = $"({DateFormat}) [{logType.ToString().ToUpper()}/{_className}] {what}";
LogConsole(message); LogConsole(message, logType);
OnLog?.Invoke(message, logType); OnLog?.Invoke(message, logType);
} }
private static string DateFormat => $"{DateTime.Now:t}"; private static string DateFormat => $"{DateTime.Now:t}";
private static void LogConsole(string what) => Console.WriteLine(what); private static void LogConsole(string what, LogType logType)
{
Console.ForegroundColor = GetConsoleColorForLog(logType);
Console.WriteLine(what);
Console.ForegroundColor = ConsoleColor.White;
}
private static ConsoleColor GetConsoleColorForLog(LogType logType)
{
ConsoleColor color = ConsoleColor.White;
switch (logType)
{
case LogType.Info:
color = ConsoleColor.Cyan;
break;
case LogType.Warn:
color = ConsoleColor.Yellow;
break;
case LogType.Error:
color = ConsoleColor.Red;
break;
}
return color;
}
private readonly string _className; private readonly string _className;
} }
public enum LogType public enum LogType
{ {
Echo,
Info, Info,
Warn, Warn,
Error Error

View File

@@ -4,6 +4,7 @@ using DaggerFramework;
using DaggerFramework.Rendering; using DaggerFramework.Rendering;
using DaggerFramework.Audio; using DaggerFramework.Audio;
using DaggerFramework.Resources; using DaggerFramework.Resources;
using DaggerFramework.SceneGraph;
public class TestGame : Game public class TestGame : Game
@@ -20,56 +21,17 @@ public class TestGame : Game
{ {
Title = "Test Game", Title = "Test Game",
Size = new Vector2(1280, 720) Size = new Vector2(1280, 720)
}, RendererSettings.Default); }, new RendererSettings()
_renderer.SetTargetFps(60); {
UseVSync = false
});
_audioBackend.Initialize(); _audioBackend.Initialize();
}
protected override void LoadResources() _scene = new Scene(_renderer, _inputHandler, _audioBackend, _resourceManager);
{
if (_resourceManager.TryLoad<Sound>("my_sound", "sounds/test_sound.ogg"))
{
_resourceManager.TryGetResource<Sound>("my_sound", out _testSound);
}
if (_resourceManager.TryLoad<Font>("inter_regular", "fonts/Inter-Regular.ttf")) _uiLayer = new UiLayer();
{ _worldLayer = new EntityLayer();
_resourceManager.TryGetResource<Font>("inter_regular", out _font);
}
}
protected override void Ready()
{
// _audioBackend.AddBusEffect<AudioEffectReverb>(new AudioEffectReverb());
_inputHandler.AddInputMapping("play", new InputAction[] { new KeyInputAction(KeyboardKey.Spacebar) });
_fontHandle = _renderer.LoadFont(_font);
}
protected override void Run()
{
while (_renderer.ShouldRun)
{
_renderer.BeginFrame();
_renderer.ClearBackground(Color.Black);
if (_inputHandler.IsActionJustPressed("play"))
{
var instance = _audioBackend.CreateInstance(_testSound)
.PitchVariation(min: 0.9f, max: 1.2f)
.VolumeVariation(min: 0.90f, max: 1.0f);
instance.Play();
}
_audioBackend.Update();
_renderer.SetTransform(new Vector2(640, 480));
_renderer.DrawCircle(16f, Color.Chocolate);
_renderer.DrawText(_fontHandle, "Hello World!", 24, Color.White);
_renderer.EndFrame();
}
} }
public override void Shutdown() public override void Shutdown()
@@ -78,6 +40,60 @@ public class TestGame : Game
_audioBackend.Shutdown(); _audioBackend.Shutdown();
} }
protected override void LoadResources()
{
if (_resourceManager.TryLoad<Sound>("my_sound", "sounds/test_sound.ogg"))
{
_resourceManager.TryGetResource("my_sound", out _testSound);
}
if (_resourceManager.TryLoad<Font>("inter_regular", "fonts/Inter-Regular.ttf"))
{
_resourceManager.TryGetResource("inter_regular", out _font);
}
}
protected override void Ready()
{
_inputHandler.AddInputMapping("play", new InputAction[] { new KeyInputAction(KeyboardKey.Spacebar) });
_inputHandler.AddInputMapping("sprint", new InputAction[] { new KeyInputAction(KeyboardKey.LeftShift) });
_fontHandle = _renderer.LoadFont(_font);
_scene.AddLayer("World", _worldLayer);
_scene.AddLayer("UI", _uiLayer);
_worldLayer.AddEntity(new TestPlayer());
_scene.Start();
}
protected override void Run()
{
while (!_scene.ShouldStop())
{
// _renderer.BeginFrame();
// _renderer.ClearBackground(Color.Black);
// if (_inputHandler.IsActionJustPressed("play"))
// {
// var instance = _audioBackend.CreateInstance(_testSound)
// .PitchVariation(min: 0.9f, max: 1.2f)
// .VolumeVariation(min: 0.90f, max: 1.0f);
// instance.Play();
// }
// _audioBackend.Update();
// _renderer.SetTransform(new Vector2(32, 32));
// _renderer.DrawCircle(16f, Color.Chocolate);
// _renderer.DrawText(_fontHandle, $"{(int)(1 / _renderer.GetFrameTime())} FPS", 20, Color.White);
// _renderer.EndFrame();
_scene.Update();
}
}
private Renderer _renderer; private Renderer _renderer;
private ResourceManager _resourceManager = new(); private ResourceManager _resourceManager = new();
private Sound? _testSound; private Sound? _testSound;
@@ -85,4 +101,8 @@ public class TestGame : Game
private int _fontHandle; private int _fontHandle;
private FmodAudioBackend _audioBackend; private FmodAudioBackend _audioBackend;
private InputHandler _inputHandler; private InputHandler _inputHandler;
private Scene _scene;
private UiLayer _uiLayer;
private EntityLayer _worldLayer;
} }

25
TestGame/TestPlayer.cs Normal file
View File

@@ -0,0 +1,25 @@
using DaggerFramework;
using DaggerFramework.SceneGraph;
using DaggerFramework.Utils;
public class TestPlayer : RectangleShape2d
{
protected override void OnStart()
{
base.OnStart();
Color = Color.Cyan;
}
protected override void OnUpdate(double dt)
{
base.OnUpdate(dt);
var sprinting = Input.IsActionDown("sprint");
_speed = sprinting ? 400f : 200f;
var velocity = Input.GetInputDirection("left", "right", "up", "down") * _speed;
Position += velocity * (float)dt;
}
private float _speed = 200f;
}

View File

@@ -1,23 +1,41 @@
using System.Numerics; using System.Numerics;
using DaggerFramework; using DaggerFramework;
using DaggerFramework.Rendering;
using DaggerFramework.SceneGraph; using DaggerFramework.SceneGraph;
public class UiLayer : Layer public class UiLayer : EntityLayer
{ {
protected override void OnStart()
{
base.OnStart();
GetResources();
CreateAndAddEntities();
}
protected override void OnUpdate(double dt) protected override void OnUpdate(double dt)
{ {
base.OnUpdate(dt); base.OnUpdate(dt);
_time += dt;
} _fpsText.Text = $"{MathF.Round(1 / (float)dt)} FPS";
protected override void OnDraw(Renderer renderer)
{
renderer.SetTransform(Vector2.Zero);
renderer.DrawRectangle(new Vector2(720 / 2, 1280), Color.Green);
renderer.SetTransform(new Vector2(720 / 4 - 24, 64));
renderer.DrawDebugText("UI :)", 24, Color.White);
} }
private double _time; private void CreateAndAddEntities()
{
_fpsText = new Text2d()
{
Font = _defaultFont,
Position = Vector2.One * 16,
FontSize = 20
};
AddEntity(_fpsText);
}
private void GetResources()
{
ResourceManager.TryGetResource("inter_regular", out _defaultFont);
}
private Text2d _fpsText;
private Font _defaultFont;
} }