mirror of
https://github.com/MaddyThorson/StrawberryBF.git
synced 2025-07-06 20:45:26 +08:00
Big restructuring - sample game is currently broken
This commit is contained in:
288
src/Components/Collision/Hitbox.bf
Normal file
288
src/Components/Collision/Hitbox.bf
Normal file
@ -0,0 +1,288 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public class Hitbox : Component, IDebugDraw
|
||||
{
|
||||
public bool Collidable = true;
|
||||
public Rect Rect;
|
||||
|
||||
public void DebugDraw()
|
||||
{
|
||||
Game.Batcher.Rect(SceneHitbox, .Red);
|
||||
}
|
||||
|
||||
public int Width
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Rect.Width;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set
|
||||
{
|
||||
Rect.Width = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Height
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Rect.Height;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set
|
||||
{
|
||||
Rect.Height = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Rect SceneHitbox
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Rect + Entity.Position;
|
||||
}
|
||||
}
|
||||
|
||||
public int Left
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Entity.X + Rect.Left;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set
|
||||
{
|
||||
Entity.X = value - Rect.Left;
|
||||
}
|
||||
}
|
||||
|
||||
public int Right
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Entity.X + Rect.Right;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set
|
||||
{
|
||||
Entity.X = value - Rect.Right;
|
||||
}
|
||||
}
|
||||
|
||||
public int Top
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Entity.Y + Rect.Top;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set
|
||||
{
|
||||
Entity.Y = value - Rect.Top;
|
||||
}
|
||||
}
|
||||
|
||||
public int Bottom
|
||||
{
|
||||
[Inline]
|
||||
get
|
||||
{
|
||||
return Entity.Y + Rect.Bottom;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
set
|
||||
{
|
||||
Entity.Y = value - Rect.Bottom;
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Collisions =====
|
||||
|
||||
public bool Check(Point point)
|
||||
{
|
||||
return SceneHitbox.Contains(point);
|
||||
}
|
||||
|
||||
public bool Check(Rect rect)
|
||||
{
|
||||
return SceneHitbox.Intersects(rect);
|
||||
}
|
||||
|
||||
public bool Check(Grid grid)
|
||||
{
|
||||
return grid != null && grid.Check(SceneHitbox);
|
||||
}
|
||||
|
||||
public bool Check(Grid grid, Point offset)
|
||||
{
|
||||
return grid != null && grid.Check(SceneHitbox + offset);
|
||||
}
|
||||
|
||||
public bool Check(Hitbox other)
|
||||
{
|
||||
return other.Collidable && SceneHitbox.Intersects(other.SceneHitbox);
|
||||
}
|
||||
|
||||
public bool Check(Hitbox other, Point offset)
|
||||
{
|
||||
return other.Collidable && (SceneHitbox + offset).Intersects(other.SceneHitbox);
|
||||
}
|
||||
|
||||
public bool CheckOutside(Hitbox other, Point offset)
|
||||
{
|
||||
return other.Collidable && !SceneHitbox.Intersects(other.SceneHitbox) && (SceneHitbox + offset).Intersects(other.SceneHitbox);
|
||||
}
|
||||
|
||||
public bool Check<T>(T other) where T : Component, IHasHitbox
|
||||
{
|
||||
return Check(other.Hitbox);
|
||||
}
|
||||
|
||||
public bool Check<T>(T other, Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
return Check(other.Hitbox, offset);
|
||||
}
|
||||
|
||||
public bool CheckOutside<T>(T other, Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
return CheckOutside(other.Hitbox, offset);
|
||||
}
|
||||
|
||||
public bool Check<T>() where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (Check(e.Hitbox))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Check<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (Check(e.Hitbox, offset))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CheckOutside<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (CheckOutside(e.Hitbox, offset))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public T First<T>() where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (Check(e.Hitbox))
|
||||
return e;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public T First<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (Check(e.Hitbox, offset))
|
||||
return e;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public T FirstOutside<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (CheckOutside(e.Hitbox, offset))
|
||||
return e;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public T LeftmostOutside<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
T ret = null;
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Left < ret.Hitbox.Left))
|
||||
ret = e;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public T RightmostOutside<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
T ret = null;
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Right > ret.Hitbox.Right))
|
||||
ret = e;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public T TopmostOutside<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
T ret = null;
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Top < ret.Hitbox.Top))
|
||||
ret = e;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public T BottommostOutside<T>(Point offset) where T : Component, IHasHitbox
|
||||
{
|
||||
T ret = null;
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Bottom > ret.Hitbox.Bottom))
|
||||
ret = e;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public List<T> All<T>(List<T> into) where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (Check(e.Hitbox))
|
||||
into.Add(e);
|
||||
|
||||
return into;
|
||||
}
|
||||
|
||||
public List<T> All<T>(Point offset, List<T> into) where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (Check(e.Hitbox, offset))
|
||||
into.Add(e);
|
||||
|
||||
return into;
|
||||
}
|
||||
|
||||
public List<T> AllOutside<T>(Point offset, List<T> into) where T : Component, IHasHitbox
|
||||
{
|
||||
for (var e in Scene.All<T>(scope List<T>()))
|
||||
if (CheckOutside(e.Hitbox, offset))
|
||||
into.Add(e);
|
||||
|
||||
return into;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
using System.Collections;
|
||||
namespace Strawberry
|
||||
{
|
||||
public class OnCollide<T> : Component where T : Entity
|
||||
public class OnCollide<T> : Component, IHasHitbox, IUpdate where T : Component, IHasHitbox
|
||||
{
|
||||
public Hitbox Hitbox { get; private set; }
|
||||
|
||||
// Takes as parameter the T collided with. Return false to stop checking for collisions until next frame.
|
||||
public delegate bool(T) Action;
|
||||
|
||||
public this(delegate bool(T) action)
|
||||
: base(true, false)
|
||||
public this(Hitbox hitbox, delegate bool(T) action)
|
||||
{
|
||||
Hitbox = hitbox;
|
||||
Action = action;
|
||||
}
|
||||
|
||||
@ -17,13 +19,13 @@ namespace Strawberry
|
||||
delete Action;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
public void Update()
|
||||
{
|
||||
if (Action != null)
|
||||
{
|
||||
let list = Entity.Scene.All<T>(scope List<T>());
|
||||
for (let t in list)
|
||||
if (Entity.Check(t) && !Action(t))
|
||||
if (Hitbox.Check(t) && !Action(t))
|
||||
break;
|
||||
}
|
||||
}
|
19
src/Components/Drawing/DrawHitbox.bf
Normal file
19
src/Components/Drawing/DrawHitbox.bf
Normal file
@ -0,0 +1,19 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
public class DrawHitbox : Component, IHasHitbox, IDraw
|
||||
{
|
||||
public Hitbox Hitbox { get; private set; }
|
||||
public Color Color;
|
||||
|
||||
public this(Hitbox hitbox, Color color)
|
||||
{
|
||||
Hitbox = hitbox;
|
||||
Color = color;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
Game.Batcher.Rect(Hitbox.SceneHitbox, Color);
|
||||
}
|
||||
}
|
||||
}
|
8
src/Components/Interfaces/IDebugDraw.bf
Normal file
8
src/Components/Interfaces/IDebugDraw.bf
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
[ComponentInterface]
|
||||
public interface IDebugDraw
|
||||
{
|
||||
public void DebugDraw();
|
||||
}
|
||||
}
|
8
src/Components/Interfaces/IDraw.bf
Normal file
8
src/Components/Interfaces/IDraw.bf
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
[ComponentInterface]
|
||||
public interface IDraw
|
||||
{
|
||||
public void Draw();
|
||||
}
|
||||
}
|
8
src/Components/Interfaces/IHasHitbox.bf
Normal file
8
src/Components/Interfaces/IHasHitbox.bf
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
[ComponentInterface]
|
||||
public interface IHasHitbox
|
||||
{
|
||||
public Hitbox Hitbox { get; }
|
||||
}
|
||||
}
|
8
src/Components/Interfaces/ILateUpdate.bf
Normal file
8
src/Components/Interfaces/ILateUpdate.bf
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
[ComponentInterface]
|
||||
public interface ILateUpdate
|
||||
{
|
||||
public void LateUpdate();
|
||||
}
|
||||
}
|
8
src/Components/Interfaces/IUpdate.bf
Normal file
8
src/Components/Interfaces/IUpdate.bf
Normal file
@ -0,0 +1,8 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
[ComponentInterface]
|
||||
public interface IUpdate
|
||||
{
|
||||
public void Update();
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ using System.Diagnostics;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public class StateMachine<TIndex> : Component where TIndex : struct, IHashable
|
||||
public class StateMachine<TIndex> : Component, IUpdate where TIndex : struct, IHashable
|
||||
{
|
||||
private Dictionary<TIndex, State> states = new Dictionary<TIndex, State>() ~ delete _;
|
||||
private TIndex state;
|
||||
@ -14,7 +14,6 @@ namespace Strawberry
|
||||
public TIndex NextState { get; private set; }
|
||||
|
||||
public this(TIndex startState)
|
||||
: base(true, false)
|
||||
{
|
||||
NextState = PreviousState = state = startState;
|
||||
}
|
||||
@ -30,7 +29,7 @@ namespace Strawberry
|
||||
CallEnter();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
public void Update()
|
||||
{
|
||||
CallUpdate();
|
||||
}
|
||||
|
@ -3,35 +3,27 @@ using System.Diagnostics;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public class Timer : Component
|
||||
public class Timer : Component, IUpdate
|
||||
{
|
||||
private float value;
|
||||
|
||||
public Action OnComplete ~ delete _;
|
||||
public bool RemoveOnComplete;
|
||||
|
||||
public this()
|
||||
: base(false, false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public this(Action onComplete, bool destroyOnComplete = false)
|
||||
: base(false, false)
|
||||
{
|
||||
OnComplete = onComplete;
|
||||
RemoveOnComplete = destroyOnComplete;
|
||||
}
|
||||
|
||||
public this(float value, Action onComplete, bool destroyOnComplete = false)
|
||||
: base(false, false)
|
||||
{
|
||||
Value = value;
|
||||
OnComplete = onComplete;
|
||||
RemoveOnComplete = destroyOnComplete;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
public void Update()
|
||||
{
|
||||
if (value > 0)
|
||||
{
|
||||
@ -39,8 +31,6 @@ namespace Strawberry
|
||||
if (value <= 0)
|
||||
{
|
||||
value = 0;
|
||||
Active = false;
|
||||
|
||||
OnComplete?.Invoke();
|
||||
if (RemoveOnComplete)
|
||||
RemoveSelf();
|
||||
@ -60,7 +50,6 @@ namespace Strawberry
|
||||
set
|
||||
{
|
||||
this.value = Math.Max(0, value);
|
||||
Active = (this.value > 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +57,6 @@ namespace Strawberry
|
||||
public void Clear()
|
||||
{
|
||||
value = 0;
|
||||
Active = false;
|
||||
}
|
||||
|
||||
static public implicit operator bool(Timer timer)
|
||||
|
@ -1,33 +1,42 @@
|
||||
using System;
|
||||
namespace Strawberry
|
||||
{
|
||||
public class Tween : Component
|
||||
public class Tween : Component, IUpdate
|
||||
{
|
||||
public Ease.Easer Easer ~ delete _;
|
||||
public delegate void(float) OnUpdate ~ delete _;
|
||||
public delegate void() OnComplete ~ delete _;
|
||||
public bool RemoveOnComplete;
|
||||
|
||||
public bool Playing { get; private set; }
|
||||
public float T { get; private set; }
|
||||
|
||||
public this(Ease.Easer easer = null, delegate void(float) onUpdate = null, delegate void() onComplete = null, bool removeOnComplete = true, bool start = true)
|
||||
: base(start, false)
|
||||
{
|
||||
Playing = start;
|
||||
Easer = easer;
|
||||
OnUpdate = onUpdate;
|
||||
OnComplete = onComplete;
|
||||
RemoveOnComplete = removeOnComplete;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public float Eased => Easer != null ? Easer(T) : T;
|
||||
|
||||
[Inline]
|
||||
public void Play()
|
||||
{
|
||||
T = 0;
|
||||
Active = true;
|
||||
Playing = true;
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
[Inline]
|
||||
public void Stop()
|
||||
{
|
||||
Playing = false;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
T = Math.Min(T + Time.Delta, 1);
|
||||
OnUpdate?.Invoke(Eased);
|
||||
@ -35,7 +44,7 @@ namespace Strawberry
|
||||
if (T >= 1)
|
||||
{
|
||||
OnComplete?.Invoke();
|
||||
Active = false;
|
||||
Playing = false;
|
||||
if (RemoveOnComplete)
|
||||
RemoveSelf();
|
||||
}
|
||||
|
Reference in New Issue
Block a user