Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ConsoleGameLib/ConsoleGameLib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,13 @@
<Compile Include="CoreTypes\Point.cs" />
<Compile Include="CoreTypes\Size.cs" />
<Compile Include="Helpers\GameState.cs" />
<Compile Include="Helpers\MathHelper.cs" />
<Compile Include="PhysicsTypes\PhysicsExtensions.cs" />
<Compile Include="PhysicsTypes\PhysicsObject.cs" />
<Compile Include="PhysicsTypes\PhysicsPoint.cs" />
<Compile Include="PhysicsTypes\PhysicsWorld.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="PhysicsTypes\UserControlledPoint.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
39 changes: 39 additions & 0 deletions ConsoleGameLib/Helpers/MathHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleGameLib.Helpers
{
public static class MathHelper
{
public static float Clamp(float min, float max, float val)
{
if(val > max)
{
return max;
}
if(val < min)
{
return min;
}
return val;
}
public static float ClampMin(float min, float val)
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per discussion with Peter, the idea is a one-side capping of the value, rather than automatic return of a max value, as Math.Max would do.

if(val < min)
{
return min;
}
return val;
}
public static float ClampMax(float max, float val)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per discussion with Peter, the idea is a one-side capping of the value, rather than automatic return of a min value, as Math.Min would do.

{
if(val > max)
{
return max;
}
return val;
}
}
}
59 changes: 59 additions & 0 deletions ConsoleGameLib/PhysicsTypes/PhysicsExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using ConsoleGameLib.CoreTypes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleGameLib.PhysicsTypes
{
public static class PhysicsExtensions
{
public static bool ContainsPoint(this List<PhysicsPoint> points, Point point, bool mustInteractWithEnvironment = true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it could take an IEnumerable<PhysicsPoint> instead of a list, is there any particular reason you need it to be ordered?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, IEnumerable is a better choice here.

{
foreach(PhysicsPoint entry in points)
{
if(entry.Position.X == point.X && entry.Position.Y == point.Y && (mustInteractWithEnvironment == true ? entry.InteractsWithEnvironment : true))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

entry.Position is of type ConsoleGameLib.CoreTypes.Point, which currently does not have equality operators overloaded. I plan to submit a separate pull request which fixes this. If that goes through, I suggest using overloaded equality operators.

In addition, it appears mustInteractWithEnvironment is a boolean. If this is the case, you can eliminate the == true (minor code style comment).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestions, agreed. Will review your PR shortly.

{
return true;
}
}
return false;
}

public static Point BottomLeft(this List<PhysicsPoint> points)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider whether this can take an IEnumerable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, IEnumerable is a better choice here.

{
Point lowest = points[0].Position;

foreach(PhysicsPoint point in points)
{
if(point.Position.X < lowest.X)
{
lowest.X = point.Position.X;
}
if(point.Position.Y < lowest.Y)
{
lowest.Y = point.Position.Y;
}
}
return lowest;
}

public static Point TopRight(this List<PhysicsPoint> points)
{
Point highest = points[0].Position;

foreach (PhysicsPoint point in points)
{
if (point.Position.X > highest.X)
{
highest.X = point.Position.X;
}
if (point.Position.Y > highest.Y)
{
highest.Y = point.Position.Y;
}
}
return highest;
}
}
}
99 changes: 99 additions & 0 deletions ConsoleGameLib/PhysicsTypes/PhysicsObject.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ConsoleGameLib;
using System.Text;
using ConsoleGameLib.CoreTypes;

namespace ConsoleGameLib.PhysicsTypes
{
/// <summary>
/// Work in progress. Will allow for many points treated as one.
/// </summary>
public class PhysicsObject
{
public List<PhysicsPoint> Contents = new List<PhysicsPoint>();

public PhysicsWorld World;

public Point Velocity;

public bool ObeysGravity = false;

/// <summary>
/// True if physics should be calculated for the whole object. False if each point in the object should be calculated individually when it comes to physics.
/// </summary>
public bool Unified = true;


public bool InteractsWithEnvironment = false;

public PhysicsObject()
{

}

public void Update()
{
if (Unified)
{
bool hitsFloor = false;
bool hitsLeft = false;
bool hitsRight = false;
bool hitsTop = false;
Point bottomLeft = Contents.BottomLeft();
Point topRight = Contents.TopRight();
foreach (PhysicsPoint point in Contents)
{
if(InteractsWithEnvironment && point.Position.Y == bottomLeft.Y && World.Contents.ContainsPoint(new Point(point.Position.X,point.Position.Y - 1)))
{
hitsFloor = true;
}
if (InteractsWithEnvironment && point.Position.Y == topRight.Y && World.Contents.ContainsPoint(new Point(point.Position.X, point.Position.Y + 1)))
{
hitsTop = true;
}
if (InteractsWithEnvironment && point.Position.Y == bottomLeft.Y && World.Contents.ContainsPoint(new Point(point.Position.X - 1, point.Position.Y)))
{
hitsLeft = true;
}
if (InteractsWithEnvironment && point.Position.Y == topRight.Y && World.Contents.ContainsPoint(new Point(point.Position.X + 1, point.Position.Y)))
{
hitsRight = true;
}
}


foreach (PhysicsPoint point in Contents)
{
if (hitsTop || hitsFloor)
{
point.Velocity.Y = 0;
}
if(hitsLeft || hitsRight)
{
point.Velocity.X = 0;
}
}

}
else
{
foreach (PhysicsPoint point in Contents)
{
point.Update();
}
}
}

public void Draw()
{
foreach(PhysicsPoint point in Contents)
{
point.Draw();
}
}


}
}
143 changes: 143 additions & 0 deletions ConsoleGameLib/PhysicsTypes/PhysicsPoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
using ConsoleGameLib.CoreTypes;
using ConsoleGameLib.Helpers;
using ConsoleGameLib.PhysicsTypes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleGameLib
{
public class PhysicsPoint
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider overloading Equals, GetHashCode, and the corresponding operators.

{
public bool ObeysGravity = false;

public Point Position;

public Point Velocity = new Point(0,0);

public bool InteractsWithEnvironment = true;

public bool ObeysDrag = true;


public ConsoleColor DrawColor = ConsoleColor.Green;

public PhysicsWorld World;




public PhysicsPoint(bool gravity, Point pos, bool interactsWithEnvironment, ConsoleColor drawColor, PhysicsWorld world)
{
ObeysGravity = gravity;
Position = pos;
InteractsWithEnvironment = interactsWithEnvironment;
DrawColor = drawColor;
World = world;
}



public virtual void Update()
{
Point tempVel = Velocity;
while (tempVel.X != 0 || tempVel.Y != 0)
{
if (tempVel.Y > 0)
{
if (!World.Contents.ContainsPoint(new Point(Position.X, Position.Y + 1)) || !InteractsWithEnvironment)
{
Position.Y++;
tempVel.Y--;
}
else if (InteractsWithEnvironment)
{
Velocity.Y = 0;
tempVel.Y = 0;
}
}
else if (tempVel.Y < 0)
{
if (World.Contents.ContainsPoint(new Point(Position.X, Position.Y - 1)) && InteractsWithEnvironment)
{
Velocity.Y = 0;
tempVel.Y = 0;

}
else
{
Position.Y--;
tempVel.Y++;
}
}

if (tempVel.X > 0)
{
if (!World.Contents.ContainsPoint(new Point(Position.X + 1, Position.Y)) || !InteractsWithEnvironment)
{
Position.X++;
tempVel.X--;
}
else if (InteractsWithEnvironment)
{
Velocity.X = 0;
tempVel.X = 0;
}
}
else if (tempVel.X < 0)
{
if (World.Contents.ContainsPoint(new Point(Position.X - 1, Position.Y)) && InteractsWithEnvironment)
{
Velocity.X = 0;
tempVel.X = 0;

}
else
{
Position.X--;
tempVel.X++;
}
}
}
if(ObeysDrag && World.CurrentDragUpdateInCycle >= World.LinearDragCalculationInterval)
{
int velX = Velocity.X;
if (velX != 0)
{
Velocity.X -= Velocity.X > 0 ? World.LinearDrag : -1 * World.LinearDrag;
}
if(velX > 0 && Velocity.X < 0)
{
Velocity.X = (int)MathHelper.ClampMin(0,Velocity.X);
}
else if(velX < 0 && Velocity.X > 0)
{
Velocity.X = (int)MathHelper.ClampMax(0, Velocity.X);
}

}
if (ObeysGravity && World.CurrentGravityUpdateInCycle >= World.GravityCalculationInterval)
{
Velocity.Y -= Velocity.Y > World.TerminalFallVelocity ? World.GravitationalAcceleration : 0;
Velocity.Y = (int)MathHelper.ClampMin(World.TerminalFallVelocity,Velocity.Y);
}
if(World.Contents.ContainsPoint(new Point(Position.X,Position.Y - 1)) && InteractsWithEnvironment)
{
Velocity.Y = 0;
}

}

public void Draw()
{
Console.ForegroundColor = DrawColor;
if (Position.Y > 0 && Position.X < World.ScreenSize.Width)
{
Console.SetCursorPosition(Position.X, World.ScreenSize.Height - Position.Y);
Console.Write('█');
}
}
}
}
Loading