mirror of
https://github.com/MaddyThorson/StrawberryBF.git
synced 2025-07-18 19:41:54 +08:00
Moved example physics stuff into the sample game
This commit is contained in:
@ -40,7 +40,7 @@ namespace Strawberry
|
||||
|
||||
}
|
||||
|
||||
public void Add(TIndex state, delegate TIndex() enter = null, delegate TIndex() update = null, delegate TIndex() exit = null)
|
||||
public void Add(TIndex state, delegate void() enter = null, delegate TIndex() update = null, delegate void() exit = null)
|
||||
{
|
||||
let s = new State();
|
||||
s.Enter = enter;
|
||||
@ -63,12 +63,9 @@ namespace Strawberry
|
||||
if (to != state)
|
||||
{
|
||||
NextState = to;
|
||||
if (CallExit())
|
||||
return true;
|
||||
|
||||
CallExit();
|
||||
PreviousState = state;
|
||||
state = to;
|
||||
|
||||
CallEnter();
|
||||
return true;
|
||||
}
|
||||
@ -76,18 +73,15 @@ namespace Strawberry
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CallEnter()
|
||||
private void CallEnter()
|
||||
{
|
||||
let s = states[state];
|
||||
if (s != null && s.Enter != null)
|
||||
{
|
||||
inStateCall = true;
|
||||
let set = s.Enter();
|
||||
s.Enter();
|
||||
inStateCall = false;
|
||||
return Set(set);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CallUpdate()
|
||||
@ -104,25 +98,22 @@ namespace Strawberry
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CallExit()
|
||||
private void CallExit()
|
||||
{
|
||||
let s = states[state];
|
||||
if (s != null && s.Exit != null)
|
||||
{
|
||||
inStateCall = true;
|
||||
let set = s.Exit();
|
||||
s.Exit();
|
||||
inStateCall = false;
|
||||
return Set(set);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public class State
|
||||
{
|
||||
public delegate TIndex() Enter;
|
||||
public delegate void() Enter;
|
||||
public delegate TIndex() Update;
|
||||
public delegate TIndex() Exit;
|
||||
public delegate void() Exit;
|
||||
|
||||
public ~this()
|
||||
{
|
||||
|
@ -303,16 +303,6 @@ namespace Strawberry
|
||||
return SceneHitbox.Intersects(rect);
|
||||
}
|
||||
|
||||
public bool Check(Scene scene)
|
||||
{
|
||||
return scene.SolidGrid != null && Check(scene.SolidGrid);
|
||||
}
|
||||
|
||||
public bool Check(Scene scene, Point offset)
|
||||
{
|
||||
return scene.SolidGrid != null && Check(scene.SolidGrid, offset);
|
||||
}
|
||||
|
||||
public bool Check(Grid grid)
|
||||
{
|
||||
return grid != null && grid.Check(SceneHitbox);
|
||||
@ -426,6 +416,12 @@ namespace Strawberry
|
||||
Game.Batcher.Rect(SceneHitbox, color);
|
||||
}
|
||||
|
||||
public T SceneAs<T>() where T : Scene
|
||||
{
|
||||
Runtime.Assert(Scene is T, "Scene type mismatch!");
|
||||
return Scene as T;
|
||||
}
|
||||
|
||||
static public int Compare(Entity a, Entity b)
|
||||
{
|
||||
return a.Priority <=> b.Priority;
|
||||
|
@ -6,7 +6,6 @@ namespace Strawberry
|
||||
public class Scene
|
||||
{
|
||||
public float TimeStarted { get; private set; }
|
||||
public Grid SolidGrid;
|
||||
public Rect Bounds;
|
||||
|
||||
private List<Entity> entities;
|
||||
@ -32,9 +31,6 @@ namespace Strawberry
|
||||
|
||||
public ~this()
|
||||
{
|
||||
if (SolidGrid != null)
|
||||
delete SolidGrid;
|
||||
|
||||
for (var e in entities)
|
||||
if (e.DeleteOnRemove)
|
||||
delete e;
|
||||
@ -183,6 +179,22 @@ namespace Strawberry
|
||||
return entityTracker[typeof(T)].Count;
|
||||
}
|
||||
|
||||
public bool Check<T>(Point point) where T : Entity
|
||||
{
|
||||
for (let e in entityTracker[typeof(T)])
|
||||
if (e.Check(point))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Check<T>(Rect rect) where T : Entity
|
||||
{
|
||||
for (let e in entityTracker[typeof(T)])
|
||||
if (e.Check(rect))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public T First<T>() where T : Entity
|
||||
{
|
||||
for (let e in entityTracker[typeof(T)])
|
||||
@ -229,11 +241,14 @@ namespace Strawberry
|
||||
return into;
|
||||
}
|
||||
|
||||
// Finding Components
|
||||
/*
|
||||
Finding Components
|
||||
*/
|
||||
|
||||
public int Count<T>() where T : Component
|
||||
{
|
||||
return componentTracker[typeof(T)].Count;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -26,6 +26,9 @@ namespace Strawberry
|
||||
return T.Parse<T>(String, true);
|
||||
}
|
||||
|
||||
public Point Point => .(this["x"].Int, this["y"].Int);
|
||||
public Vector Vector => .(this["x"].Number, this["y"].Number);
|
||||
|
||||
private List<JSON> array;
|
||||
private Dictionary<String, JSON> children;
|
||||
|
||||
|
@ -1,231 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
[Reflect]
|
||||
public class Actor : Entity
|
||||
{
|
||||
private Vector remainder;
|
||||
|
||||
// The amount that geometry has pushed or carried this Actor since the last frame
|
||||
public Point MovedByGeometry { get; private set; }
|
||||
|
||||
public this(Point position)
|
||||
: base(position)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public bool GroundCheck(int distance = 1)
|
||||
{
|
||||
return Check<Solid>(.(0, distance)) || Check(Scene, .(0, distance)) || CheckOutside<JumpThru>(.(0, distance));
|
||||
}
|
||||
|
||||
public virtual bool IsRiding(Solid solid)
|
||||
{
|
||||
return Check(solid, .(0, 1));
|
||||
}
|
||||
|
||||
public virtual bool IsRiding(JumpThru jumpThru)
|
||||
{
|
||||
return CheckOutside(jumpThru, .(0, 1));
|
||||
}
|
||||
|
||||
public virtual void Squish(Collision collision)
|
||||
{
|
||||
RemoveSelf();
|
||||
}
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
MovedByGeometry = Point.Zero;
|
||||
}
|
||||
|
||||
public bool MoveX(float amount, delegate void(Collision) onCollide = null)
|
||||
{
|
||||
remainder.X += amount;
|
||||
let move = (int)Math.Round(remainder.X);
|
||||
if (move != 0)
|
||||
{
|
||||
remainder.X -= move;
|
||||
return MoveExactX(move, onCollide);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool MoveY(float amount, delegate void(Collision) onCollide = null)
|
||||
{
|
||||
remainder.Y += amount;
|
||||
let move = (int)Math.Round(remainder.Y);
|
||||
if (move != 0)
|
||||
{
|
||||
remainder.Y -= move;
|
||||
return MoveExactY(move, onCollide);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public void MoveToX(float x)
|
||||
{
|
||||
MoveX(x - (X + remainder.X), null);
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public void MoveToY(float y)
|
||||
{
|
||||
MoveY(y - (Y + remainder.Y), null);
|
||||
}
|
||||
|
||||
public bool MoveExactX(int amount, delegate void(Collision) onCollide = null, Geometry pusher = null, Geometry carrier = null)
|
||||
{
|
||||
int move = amount;
|
||||
int sign = Math.Sign(amount);
|
||||
bool byGeometry = carrier != null || pusher != null;
|
||||
|
||||
while (move != 0)
|
||||
{
|
||||
let hit = First<Solid>(.(sign, 0));
|
||||
if (hit != null)
|
||||
{
|
||||
let c = Collision(
|
||||
Point.Right * sign,
|
||||
Math.Abs(amount),
|
||||
Math.Abs(amount - move),
|
||||
hit,
|
||||
pusher
|
||||
);
|
||||
|
||||
onCollide?.Invoke(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Check(Scene, .(sign, 0)))
|
||||
{
|
||||
let c = Collision(
|
||||
Point.Right * sign,
|
||||
Math.Abs(amount),
|
||||
Math.Abs(amount - move),
|
||||
null,
|
||||
pusher
|
||||
);
|
||||
|
||||
onCollide?.Invoke(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
X += sign;
|
||||
if (byGeometry)
|
||||
MovedByGeometry.X += sign;
|
||||
move -= sign;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool MoveExactY(int amount, delegate void(Collision) onCollide = null, Geometry pusher = null, Geometry carrier = null)
|
||||
{
|
||||
int move = amount;
|
||||
int sign = Math.Sign(amount);
|
||||
bool byGeometry = carrier != null || pusher != null;
|
||||
|
||||
while (move != 0)
|
||||
{
|
||||
Geometry hit = First<Solid>(.(0, sign));
|
||||
if (hit == null && sign == 1)
|
||||
hit = FirstOutside<JumpThru>(.(0, sign));
|
||||
|
||||
if (hit != null)
|
||||
{
|
||||
let c = Collision(
|
||||
Point.Right * sign,
|
||||
Math.Abs(amount),
|
||||
Math.Abs(amount - move),
|
||||
hit,
|
||||
pusher
|
||||
);
|
||||
|
||||
onCollide?.Invoke(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Check(Scene, .(0, sign)))
|
||||
{
|
||||
let c = Collision(
|
||||
Point.Right * sign,
|
||||
Math.Abs(amount),
|
||||
Math.Abs(amount - move),
|
||||
null,
|
||||
pusher
|
||||
);
|
||||
|
||||
onCollide?.Invoke(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
Y += sign;
|
||||
if (byGeometry)
|
||||
MovedByGeometry.Y += sign;
|
||||
move -= sign;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ZeroRemainderX()
|
||||
{
|
||||
remainder.X = 0;
|
||||
}
|
||||
|
||||
public void ZeroRemainderY()
|
||||
{
|
||||
remainder.Y = 0;
|
||||
}
|
||||
|
||||
public void ZeroRemainders()
|
||||
{
|
||||
remainder = Vector.Zero;
|
||||
}
|
||||
|
||||
private void MoveByGeometry(Point amount)
|
||||
{
|
||||
MovedByGeometry += amount;
|
||||
}
|
||||
|
||||
|
||||
public bool CornerCorrection(Cardinals direction, int maxAmount, int lookAhead = 1, int onlySign = 0)
|
||||
{
|
||||
Point dir = direction;
|
||||
Point perp = dir.Perpendicular();
|
||||
perp.X = Math.Abs(perp.X);
|
||||
perp.Y = Math.Abs(perp.Y);
|
||||
|
||||
delegate bool(Point) checker;
|
||||
if (dir == Point.Down)
|
||||
checker = scope:: (p) => !Check(Scene, p) && !Check<Solid>(p) && !CheckOutside<JumpThru>(p);
|
||||
else
|
||||
checker = scope:: (p) => !Check(Scene, p) && !Check<Solid>(p);
|
||||
|
||||
for (int i = 1; i <= maxAmount; i++)
|
||||
{
|
||||
for (int j = -1; j <= 1; j += 2)
|
||||
{
|
||||
if (onlySign != 0 && onlySign != j)
|
||||
continue;
|
||||
|
||||
let offset = dir * lookAhead + perp * i * j;
|
||||
if (checker(offset))
|
||||
{
|
||||
Position += offset;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
namespace Strawberry
|
||||
{
|
||||
public struct Collision
|
||||
{
|
||||
public Point Direction;
|
||||
public int Magnitude;
|
||||
public int Completed;
|
||||
public Geometry Stopper;
|
||||
public Geometry Pusher;
|
||||
|
||||
public this(Point direction, int magnitude, int completed, Geometry stopper, Geometry pusher)
|
||||
{
|
||||
Direction = direction;
|
||||
Magnitude = magnitude;
|
||||
Completed = completed;
|
||||
Stopper = stopper;
|
||||
Pusher = pusher;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public abstract class Geometry : Entity
|
||||
{
|
||||
private Vector remainder;
|
||||
|
||||
public this(Point position)
|
||||
: base(position)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void MoveX(float amount)
|
||||
{
|
||||
remainder.X += amount;
|
||||
let move = (int)Math.Round(remainder.X);
|
||||
if (move != 0)
|
||||
{
|
||||
remainder.X -= move;
|
||||
MoveExactX(move);
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveY(float amount)
|
||||
{
|
||||
remainder.Y += amount;
|
||||
let move = (int)Math.Round(remainder.Y);
|
||||
if (move != 0)
|
||||
{
|
||||
remainder.Y -= move;
|
||||
MoveExactY(move);
|
||||
}
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public void Move(Vector amount)
|
||||
{
|
||||
MoveX(amount.X);
|
||||
MoveY(amount.Y);
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public void MoveToX(float x)
|
||||
{
|
||||
MoveX(x - (X + remainder.X));
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public void MoveToY(float y)
|
||||
{
|
||||
MoveY(y - (Y + remainder.Y));
|
||||
}
|
||||
|
||||
[Inline]
|
||||
public void MoveTo(Vector target)
|
||||
{
|
||||
MoveToX(target.X);
|
||||
MoveToY(target.Y);
|
||||
}
|
||||
|
||||
public abstract void MoveExactX(int amount);
|
||||
public abstract void MoveExactY(int amount);
|
||||
public abstract List<Actor> GetRiders(List<Actor> into);
|
||||
|
||||
public void ZeroRemainderX()
|
||||
{
|
||||
remainder.X = 0;
|
||||
}
|
||||
|
||||
public void ZeroRemainderY()
|
||||
{
|
||||
remainder.Y = 0;
|
||||
}
|
||||
|
||||
public void ZeroRemainders()
|
||||
{
|
||||
remainder = Vector.Zero;
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,10 @@ namespace Strawberry
|
||||
CellSize = .(cellWidth, cellHeight);
|
||||
Offset = .(offsetX, offsetY);
|
||||
|
||||
contents = new char8[cellsX, cellsY];
|
||||
contents = new char8[cellsX, cellsY];
|
||||
for (let x < CellsX)
|
||||
for (let y < CellsY)
|
||||
contents[x, y] = '0';
|
||||
}
|
||||
|
||||
public this(JSON ogmoJson)
|
||||
@ -68,6 +71,13 @@ namespace Strawberry
|
||||
}
|
||||
}
|
||||
|
||||
public void Set(Rect r, char8 val)
|
||||
{
|
||||
for (let x < r.Width)
|
||||
for (let y < r.Height)
|
||||
contents[r.X + x, r.Y + y] = val;
|
||||
}
|
||||
|
||||
public int CellsX => contents.GetLength(0);
|
||||
public int CellsY => contents.GetLength(1);
|
||||
|
||||
|
@ -1,79 +0,0 @@
|
||||
using System.Collections;
|
||||
using System;
|
||||
namespace Strawberry
|
||||
{
|
||||
public class JumpThru : Geometry
|
||||
{
|
||||
public this(Point position, int width)
|
||||
: base(position)
|
||||
{
|
||||
Hitbox = Rect(0, 0, width, 2);
|
||||
}
|
||||
|
||||
public this(JSON json)
|
||||
: this(.(json), json["width"])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public override void MoveExactX(int amount)
|
||||
{
|
||||
if (Collidable)
|
||||
{
|
||||
let riders = GetRiders(scope List<Actor>());
|
||||
|
||||
X += amount;
|
||||
for (var a in riders)
|
||||
a.MoveExactX(amount, null, null, this);
|
||||
}
|
||||
else
|
||||
X += amount;
|
||||
}
|
||||
|
||||
public override void MoveExactY(int amount)
|
||||
{
|
||||
if (Collidable)
|
||||
{
|
||||
let riders = GetRiders(scope List<Actor>());
|
||||
|
||||
if (amount < 0)
|
||||
{
|
||||
for (var a in Scene.All<Actor>(scope List<Actor>()))
|
||||
{
|
||||
if (riders.Contains(a) || CheckOutside(a, Point.UnitY * amount))
|
||||
{
|
||||
let move = (Top + amount) - a.Bottom;
|
||||
a.MoveExactY(move, null, null, this);
|
||||
}
|
||||
}
|
||||
Y += amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
Collidable = false;
|
||||
|
||||
for (var a in riders)
|
||||
a.MoveExactY(amount, null, null, this);
|
||||
|
||||
Collidable = true;
|
||||
Y += amount;
|
||||
}
|
||||
}
|
||||
else
|
||||
Y += amount;
|
||||
}
|
||||
|
||||
public override List<Actor> GetRiders(List<Actor> into)
|
||||
{
|
||||
for (var a in Scene.All<Actor>(scope List<Actor>()))
|
||||
if (a.IsRiding(this))
|
||||
into.Add(a);
|
||||
return into;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
DrawHitbox(.LightGray);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace Strawberry
|
||||
{
|
||||
public class Solid : Geometry
|
||||
{
|
||||
public this(Point position, Rect hitbox)
|
||||
: base(position)
|
||||
{
|
||||
Hitbox = hitbox;
|
||||
}
|
||||
|
||||
public override List<Actor> GetRiders(List<Actor> into)
|
||||
{
|
||||
for (var a in Scene.All<Actor>(scope List<Actor>()))
|
||||
if (a.IsRiding(this))
|
||||
into.Add(a);
|
||||
return into;
|
||||
}
|
||||
|
||||
public override void MoveExactX(int amount)
|
||||
{
|
||||
if (Collidable)
|
||||
{
|
||||
let riders = GetRiders(scope List<Actor>());
|
||||
|
||||
X += amount;
|
||||
Collidable = false;
|
||||
|
||||
for (Actor a in Scene.All<Actor>(scope List<Actor>()))
|
||||
{
|
||||
if (Check(a))
|
||||
{
|
||||
//Push
|
||||
int move;
|
||||
if (amount > 0)
|
||||
move = Right - a.Left;
|
||||
else
|
||||
move = Left - a.Right;
|
||||
a.MoveExactX(move, scope => a.Squish, this);
|
||||
}
|
||||
else if (riders.Contains(a))
|
||||
{
|
||||
//Carry
|
||||
a.MoveExactX(amount, null, null, this);
|
||||
}
|
||||
}
|
||||
|
||||
Collidable = true;
|
||||
}
|
||||
else
|
||||
X += amount;
|
||||
}
|
||||
|
||||
public override void MoveExactY(int amount)
|
||||
{
|
||||
if (Collidable)
|
||||
{
|
||||
let riders = GetRiders(scope List<Actor>());
|
||||
|
||||
Y += amount;
|
||||
Collidable = false;
|
||||
|
||||
for (Actor a in Scene.All<Actor>(scope List<Actor>()))
|
||||
{
|
||||
if (Check(a))
|
||||
{
|
||||
//Push
|
||||
int move;
|
||||
if (amount > 0)
|
||||
move = Bottom - a.Top;
|
||||
else
|
||||
move = Top - a.Bottom;
|
||||
a.MoveExactY(move, scope => a.Squish, this);
|
||||
}
|
||||
else if (riders.Contains(a))
|
||||
{
|
||||
//Carry
|
||||
a.MoveExactY(amount, null, null, this);
|
||||
}
|
||||
}
|
||||
|
||||
Collidable = true;
|
||||
}
|
||||
else
|
||||
Y += amount;
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
DrawHitbox(.White);
|
||||
}
|
||||
}
|
||||
}
|
@ -56,6 +56,7 @@ namespace Strawberry.SDL2
|
||||
int32 num = 0;
|
||||
GL.glUniform1iv(platformLayer.TextureMatrixLocation, 1, &num);
|
||||
}
|
||||
|
||||
GL.glDrawElements(GL.GL_TRIANGLES, b.IndicesCount, GL.GL_UNSIGNED_INT, (void*)(b.IndicesStart * sizeof(uint32)));
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,21 @@ namespace Strawberry
|
||||
}
|
||||
}
|
||||
|
||||
static public implicit operator Vector(Cardinals c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case .Right:
|
||||
return Vector.Right;
|
||||
case .Left:
|
||||
return Vector.Left;
|
||||
case .Up:
|
||||
return Vector.Up;
|
||||
case .Down:
|
||||
return Vector.Down;
|
||||
}
|
||||
}
|
||||
|
||||
static public Result<Cardinals> FromPoint(Point p)
|
||||
{
|
||||
if (p.X > 0 && p.Y == 0)
|
||||
|
@ -41,6 +41,11 @@ namespace Strawberry
|
||||
public float Length => Math.Sqrt(LengthSquared);
|
||||
public int LengthSquared => X * X + Y * Y;
|
||||
|
||||
public Vector Normalized()
|
||||
{
|
||||
return ((Vector)this).Normalized();
|
||||
}
|
||||
|
||||
public override void ToString(String strBuffer)
|
||||
{
|
||||
strBuffer.Set("Point [ ");
|
||||
|
@ -139,32 +139,32 @@ namespace Strawberry
|
||||
|
||||
static public Rect operator+(Rect a, Point b)
|
||||
{
|
||||
return Rect(a.X + b.X, a.Y + b.Y, a.Width, a.Height);
|
||||
return .(a.X + b.X, a.Y + b.Y, a.Width, a.Height);
|
||||
}
|
||||
|
||||
static public Rect operator-(Rect a, Point b)
|
||||
{
|
||||
return Rect(a.X - b.X, a.Y - b.Y, a.Width, a.Height);
|
||||
return .(a.X - b.X, a.Y - b.Y, a.Width, a.Height);
|
||||
}
|
||||
|
||||
static public Rect operator/(Rect a, int b)
|
||||
{
|
||||
return Rect(a.X / b, a.Y / b, a.Width / b, a.Height / b);
|
||||
return .(a.X / b, a.Y / b, a.Width / b, a.Height / b);
|
||||
}
|
||||
|
||||
static public Rect operator/(Rect a, Point b)
|
||||
{
|
||||
return Rect(a.X / b.X, a.Y / b.Y, a.Width / b.X, a.Height / b.Y);
|
||||
return .(a.X / b.X, a.Y / b.Y, a.Width / b.X, a.Height / b.Y);
|
||||
}
|
||||
|
||||
static public Rect operator*(Rect a, int b)
|
||||
{
|
||||
return Rect(a.X * b, a.Y * b, a.Width * b, a.Height * b);
|
||||
return .(a.X * b, a.Y * b, a.Width * b, a.Height * b);
|
||||
}
|
||||
|
||||
static public Rect operator*(Rect a, Point b)
|
||||
{
|
||||
return Rect(a.X * b.X, a.Y * b.Y, a.Width * b.X, a.Height * b.Y);
|
||||
return .(a.X * b.X, a.Y * b.Y, a.Width * b.X, a.Height * b.Y);
|
||||
}
|
||||
|
||||
static public implicit operator SDL2.SDL.Rect(Rect r)
|
||||
|
@ -33,6 +33,11 @@ namespace Strawberry
|
||||
return .(-Y, X);
|
||||
}
|
||||
|
||||
public Vector Normalized()
|
||||
{
|
||||
return this / Length;
|
||||
}
|
||||
|
||||
public float Length => Math.Sqrt(LengthSquared);
|
||||
public float LengthSquared => X * X + Y * Y;
|
||||
|
||||
@ -90,5 +95,19 @@ namespace Strawberry
|
||||
{
|
||||
return Vector(a.X / b, a.Y / b);
|
||||
}
|
||||
|
||||
static public Vector Approach(Vector value, Vector target, float maxDelta)
|
||||
{
|
||||
Vector diff = target - value;
|
||||
if (diff.Length < maxDelta)
|
||||
return target;
|
||||
else
|
||||
return value + diff.Normalized() * maxDelta;
|
||||
}
|
||||
|
||||
static public void Approach(Vector* value, Vector target, float maxDelta)
|
||||
{
|
||||
*value = Approach(*value, target, maxDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user