Skip to content

Commit

Permalink
Merge pull request #94 from Panxuc/new-collision
Browse files Browse the repository at this point in the history
feat: ✨ collision with slide
  • Loading branch information
asdawej authored Feb 4, 2024
2 parents f4bb5f3 + 9e2dbc4 commit cd65dc6
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 17 deletions.
4 changes: 2 additions & 2 deletions logic/GameEngine/CollisionChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ internal class CollisionChecker
/// 寻找最大可能移动距离
/// </summary>
/// <param name="obj">移动物体,默认obj.Rigid为true</param>
/// <param name="nextPos">下一步要到达的位置</param>
/// <param name="moveVec">移动的位移向量,默认与nextPos协调</param>
/// <returns>最大可能的移动距离</returns>
public double FindMax(IMovable obj, XY nextPos, XY moveVec)
public double FindMax(IMovable obj, XY moveVec)
{
XY nextPos = obj.Position + moveVec;
double tmpMax = uint.MaxValue; // 暂存最大值

double maxDistance = uint.MaxValue;
Expand Down
33 changes: 31 additions & 2 deletions logic/GameEngine/MoveEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,38 @@ Action<IMovable> EndMove
private bool MoveMax(IMovable obj, XY moveVec, long stateNum)
{
/*由于四周是墙,所以人物永远不可能与越界方块碰撞*/
XY nextPos = obj.Position + moveVec;
double maxLen = collisionChecker.FindMax(obj, nextPos, moveVec);
double maxLen = collisionChecker.FindMax(obj, moveVec);
maxLen = Math.Min(maxLen, obj.MoveSpeed / GameData.NumOfStepPerSecond);
if (maxLen == 0)
{
// 尝试滑动
IGameObj? collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, moveVec);
XY slideVec = new(0, 0);
switch (collisionObj.Shape)

Check warning on line 65 in logic/GameEngine/MoveEngine.cs

View workflow job for this annotation

GitHub Actions / dotnet-build-logic

Dereference of a possibly null reference.
{
case ShapeType.Circle:
XY connectVec = collisionObj.Position - obj.Position;
slideVec = new XY(
connectVec.Perpendicular(),
moveVec.Length() * Math.Cos(connectVec.Angle() - moveVec.Angle())
);
break;
case ShapeType.Square:
if (Math.Abs(collisionObj.Position.x - obj.Position.x) == collisionObj.Radius + obj.Radius)
{
slideVec = new XY(0, moveVec.y * Math.Sign(collisionObj.Position.y - obj.Position.y));
}
else if (Math.Abs(collisionObj.Position.y - obj.Position.y) == collisionObj.Radius + obj.Radius)
{
slideVec = new XY(moveVec.x * Math.Sign(collisionObj.Position.x - obj.Position.x), 0);
}
break;
}
double slideLen = collisionChecker.FindMax(obj, slideVec);
slideLen = Math.Min(slideLen, slideVec.Length());
slideLen = Math.Min(slideLen, obj.MoveSpeed / GameData.NumOfStepPerSecond);
return (obj.MovingSetPos(new XY(slideVec, slideLen), stateNum)) >= 0;
}
return (obj.MovingSetPos(new XY(moveVec, maxLen), stateNum)) >= 0;
}

Expand Down
26 changes: 13 additions & 13 deletions logic/Gaming/ActionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ private class ActionManager(Map gameMap, ShipManager shipManager)
gameMap: gameMap,
OnCollision: (obj, collisionObj, moveVec) =>
{
Ship ship = (Ship)obj;
switch (collisionObj.Type)
{
case GameObjType.Bullet:
if (((Bullet)collisionObj).Parent != ship)
{
// TODO
gameMap.Remove((GameObj)collisionObj);
}
break;
default:
break;
}
//Ship ship = (Ship)obj;
//switch (collisionObj.Type)
//{
// case GameObjType.Bullet:
// if (((Bullet)collisionObj).Parent != ship)
// {
// // TODO
// gameMap.Remove((GameObj)collisionObj);
// }
// break;
// default:
// break;
//}
return MoveEngine.AfterCollision.MoveMax;
},
EndMove: obj =>
Expand Down
8 changes: 8 additions & 0 deletions logic/Preparation/Utility/XY.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,14 @@ public double Angle()
return Math.Atan2(y, x);
}

/// <summary>
/// 逆时针旋转90°
/// </summary>
public XY Perpendicular()
{
return new XY(-y, x);
}

public override bool Equals(object? obj) => obj is not null && obj is XY xy && this == xy;

public override int GetHashCode()
Expand Down

0 comments on commit cd65dc6

Please sign in to comment.