Collision-with-condition checkers. Entity/Component Awake timing fixes. Batcher.Pixel()

This commit is contained in:
Maddy Thorson 2021-02-06 16:37:38 -08:00
parent 3d5130b45b
commit 86b05c648b
7 changed files with 241 additions and 35 deletions

View File

@ -10,3 +10,9 @@ DefaultNamespace = "Strawberry.Sample"
[[Project.DistinctOptions]] [[Project.DistinctOptions]]
Filter = "" Filter = ""
ReflectAlwaysInclude = "IncludeAll" ReflectAlwaysInclude = "IncludeAll"
[[ProjectFolder.Items]]
Type = "Folder"
Name = "Physics"
AutoInclude = true
Source = ["Physics.bf", "Solid.bf", "JumpThru.bf"]

View File

@ -112,7 +112,9 @@ namespace Strawberry
} }
} }
// ===== Collisions ===== /*
Single Collisions
*/
public bool Check(Point point) public bool Check(Point point)
{ {
@ -164,6 +166,10 @@ namespace Strawberry
return CheckOutside(other.Hitbox, offset); return CheckOutside(other.Hitbox, offset);
} }
/*
Type Collisions
*/
public bool Check<T>() where T : Component, IHasHitbox public bool Check<T>() where T : Component, IHasHitbox
{ {
for (var e in Scene.All<T>(scope List<T>())) for (var e in Scene.All<T>(scope List<T>()))
@ -284,5 +290,130 @@ namespace Strawberry
return into; return into;
} }
/*
Type Collision w/ Conditions
*/
public bool Check<T>(delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && Check(e.Hitbox))
return true;
return false;
}
public bool Check<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && Check(e.Hitbox, offset))
return true;
return false;
}
public bool CheckOutside<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && CheckOutside(e.Hitbox, offset))
return true;
return false;
}
public T First<T>(delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && Check(e.Hitbox))
return e;
return null;
}
public T First<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && Check(e.Hitbox, offset))
return e;
return null;
}
public T FirstOutside<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && CheckOutside(e.Hitbox, offset))
return e;
return null;
}
public T LeftmostOutside<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
T ret = null;
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Left < ret.Hitbox.Left))
ret = e;
return ret;
}
public T RightmostOutside<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
T ret = null;
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Right > ret.Hitbox.Right))
ret = e;
return ret;
}
public T TopmostOutside<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
T ret = null;
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Top < ret.Hitbox.Top))
ret = e;
return ret;
}
public T BottommostOutside<T>(Point offset, delegate bool(T) condition) where T : Component, IHasHitbox
{
T ret = null;
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && CheckOutside(e.Hitbox, offset) && (ret == null || e.Hitbox.Bottom > ret.Hitbox.Bottom))
ret = e;
return ret;
}
public List<T> All<T>(List<T> into, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && Check(e.Hitbox))
into.Add(e);
return into;
}
public List<T> All<T>(Point offset, List<T> into, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && Check(e.Hitbox, offset))
into.Add(e);
return into;
}
public List<T> AllOutside<T>(Point offset, List<T> into, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (var e in Scene.All<T>(scope List<T>()))
if (condition(e) && CheckOutside(e.Hitbox, offset))
into.Add(e);
return into;
}
} }
} }

View File

@ -24,7 +24,7 @@ namespace Strawberry
delete s; delete s;
} }
public override void Started() public override void Awake()
{ {
CallEnter(); CallEnter();
} }

View File

@ -5,19 +5,11 @@ namespace Strawberry
public abstract class Component public abstract class Component
{ {
public Entity Entity { get; private set; } public Entity Entity { get; private set; }
public bool IsAwake { get; private set; }
private void Added(Entity entity) public virtual void Added() { }
{ public virtual void Awake() { }
Entity = entity; public virtual void End() { }
}
private void Removed()
{
Entity = null;
}
public virtual void Started() { }
public virtual void Ended() { }
[Inline] [Inline]
public void RemoveSelf() public void RemoveSelf()

View File

@ -6,6 +6,7 @@ namespace Strawberry
public sealed class Entity public sealed class Entity
{ {
public Scene Scene { get; private set; } public Scene Scene { get; private set; }
public bool IsAwake { get; private set; }
public bool DeleteOnRemove = true; public bool DeleteOnRemove = true;
private List<Component> components = new List<Component>() ~ delete _; private List<Component> components = new List<Component>() ~ delete _;
@ -32,20 +33,27 @@ namespace Strawberry
private void Removed() private void Removed()
{ {
Ended(); for (var c in components)
{
c.End();
c.[Friend]IsAwake = false;
}
Scene = null; Scene = null;
IsAwake = false;
} }
public void Started() private void AwakeCheck()
{ {
for (var c in components) for (var c in components)
c.Started(); {
} if (!c.[Friend]IsAwake)
{
c.Awake();
c.[Friend]IsAwake = true;
}
}
public void Ended() IsAwake = true;
{
for (var c in components)
c.Ended();
} }
[Inline] [Inline]
@ -78,7 +86,7 @@ namespace Strawberry
{ {
components.Remove(c); components.Remove(c);
Scene.[Friend]UntrackComponent(c); Scene.[Friend]UntrackComponent(c);
c.[Friend]Removed(); c.[Friend]Entity = null;
delete c; delete c;
} }
@ -91,7 +99,17 @@ namespace Strawberry
{ {
components.Add(c); components.Add(c);
Scene.[Friend]TrackComponent(c); Scene.[Friend]TrackComponent(c);
c.[Friend]Added(this); c.[Friend]Entity = this;
c.Added();
}
if (IsAwake)
{
for (var c in toAdd)
{
c.Awake();
c.[Friend]IsAwake = true;
}
} }
toAdd.Clear(); toAdd.Clear();

View File

@ -97,17 +97,13 @@ namespace Strawberry
entities.Add(e); entities.Add(e);
e.[Friend]Added(this); e.[Friend]Added(this);
} }
toAdd.Clear();
} }
for (let e in entities) for (let e in entities)
e.[Friend]UpdateLists(); e.[Friend]UpdateLists();
for (let e in entities)
if (toAdd.Count > 0) e.[Friend]AwakeCheck();
{
for (let e in toAdd)
e.Started();
toAdd.Clear();
}
} }
// Tracking // Tracking
@ -148,6 +144,24 @@ namespace Strawberry
return componentTracker[typeof(T)].Count; return componentTracker[typeof(T)].Count;
} }
public int Count<T>(delegate bool(T) condition) where T : Component
{
int count = 0;
for (T c in componentTracker[typeof(T)])
if (condition(c))
count++;
return count;
}
public bool Check<T>(delegate bool(T) condition) where T : Component
{
for (T c in componentTracker[typeof(T)])
if (condition(c))
return true;
return false;
}
public bool Check<T>(Point point) where T : Component, IHasHitbox public bool Check<T>(Point point) where T : Component, IHasHitbox
{ {
for (T c in componentTracker[typeof(T)]) for (T c in componentTracker[typeof(T)])
@ -164,13 +178,21 @@ namespace Strawberry
return false; return false;
} }
public T First<T>() where T : Component, IHasHitbox public T First<T>() where T : Component
{ {
for (T c in componentTracker[typeof(T)]) for (T c in componentTracker[typeof(T)])
return c; return c;
return null; return null;
} }
public T First<T>(delegate bool(T) condition) where T : Component
{
for (T c in componentTracker[typeof(T)])
if (condition(c))
return c;
return null;
}
public T First<T>(Point point) where T : Component, IHasHitbox public T First<T>(Point point) where T : Component, IHasHitbox
{ {
for (T c in componentTracker[typeof(T)]) for (T c in componentTracker[typeof(T)])
@ -179,6 +201,14 @@ namespace Strawberry
return null; return null;
} }
public T First<T>(Point point, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (T c in componentTracker[typeof(T)])
if (condition(c) && c.Hitbox.Check(point))
return c as T;
return null;
}
public T First<T>(Rect rect) where T : Component, IHasHitbox public T First<T>(Rect rect) where T : Component, IHasHitbox
{ {
for (T c in componentTracker[typeof(T)]) for (T c in componentTracker[typeof(T)])
@ -187,13 +217,29 @@ namespace Strawberry
return null; return null;
} }
public List<T> All<T>(List<T> into) where T : Component, IHasHitbox public T First<T>(Rect rect, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (T c in componentTracker[typeof(T)])
if (condition(c) && c.Hitbox.Check(rect))
return c as T;
return null;
}
public List<T> All<T>(List<T> into) where T : Component
{ {
for (T c in componentTracker[typeof(T)]) for (T c in componentTracker[typeof(T)])
into.Add(c as T); into.Add(c as T);
return into; return into;
} }
public List<T> All<T>(List<T> into, delegate bool(T) condition) where T : Component
{
for (T c in componentTracker[typeof(T)])
if (condition(c))
into.Add(c as T);
return into;
}
public List<T> All<T>(Point point, List<T> into) where T : Component, IHasHitbox public List<T> All<T>(Point point, List<T> into) where T : Component, IHasHitbox
{ {
for (T c in componentTracker[typeof(T)]) for (T c in componentTracker[typeof(T)])
@ -202,10 +248,18 @@ namespace Strawberry
return into; return into;
} }
public List<T> All<T>(Rect rect, List<T> into) where T : Component, IHasHitbox public List<T> All<T>(Point point, List<T> into, delegate bool(T) condition) where T : Component, IHasHitbox
{ {
for (T c in componentTracker[typeof(T)]) for (T c in componentTracker[typeof(T)])
if (c.Hitbox.Check(rect)) if (condition(c) && c.Hitbox.Check(point))
into.Add(c as T);
return into;
}
public List<T> All<T>(Rect rect, List<T> into, delegate bool(T) condition) where T : Component, IHasHitbox
{
for (T c in componentTracker[typeof(T)])
if (condition(c) && c.Hitbox.Check(rect))
into.Add(c as T); into.Add(c as T);
return into; return into;
} }

View File

@ -49,6 +49,11 @@ namespace Strawberry
Rect(rect.X, rect.Y, rect.Width, rect.Height, color); Rect(rect.X, rect.Y, rect.Width, rect.Height, color);
} }
public void Pixel(int x, int y, Color color)
{
Rect(x, y, 1, 1, color);
}
public void Tri(Vector a, Vector b, Vector c, Color color) public void Tri(Vector a, Vector b, Vector c, Color color)
{ {
PushTri(.Shape, null, PushTri(.Shape, null,