private IList <Collision> GetMovementCollisions(PhysicalMovement physicalMovement) { var movementsCollisions = new List <Collision>(); foreach (var movement in physicalMovement.CornersMovements) { if (movement == physicalMovement.CornersMovements[2] && movement.P2.Y > -35) { //Logger.Log($"from {movement.P1.Y} to {movement.P2.Y}"); } var eligibleBlocks = BlockGeometryHelper.GetAllBlocksCrossedBySegment(movement, _mapData, _blockSize); foreach (var eligibleBlock in eligibleBlocks) { var blockSegments = BlockGeometryHelper.GetBlockSegments(eligibleBlock, _blockSize); foreach (var blockSegment in blockSegments) { if (PhysicalHelper.GetCollisionPoint(movement, blockSegment, out var collision)) { movementsCollisions.Add(collision); } } } } return(movementsCollisions); }
public void RefreshPhysics() { foreach (var physicalView in _physicalViews) { if (physicalView.IsInAir) { } var nextPos = physicalView.ComputeNextPosition(); var physicalMovement = new PhysicalMovement( new Point(physicalView.RealX, physicalView.RealY), nextPos, physicalView.CollisionPoints); // Logger.Log($"InitalX :{physicalMovement.InitialPos.X} FinalX : {physicalMovement.FinalPos.X}"); var movementsCollisions = GetMovementCollisions(physicalMovement); var count = 0; var inTheAir = true; while (movementsCollisions.Any()) { if (count > 0) { int test = 0; } var closerCollision = movementsCollisions.OrderBy(c => c.DistanceToInitialS1).First(); //Logger.Log($"Collision detected {closerCollision.Point.X} | {closerCollision.Point.Y}"); double reflectionDistance = 0.1; var reflectionAngle = closerCollision.ReflectionAngle; if (physicalView.CanBounce) { reflectionDistance = closerCollision.S1.Distance - closerCollision.DistanceToInitialS1; } var newCornerPosX = closerCollision.Point.X + Math.Cos(reflectionAngle) * reflectionDistance * 1; var newCornerPosY = closerCollision.Point.Y + Math.Sin(reflectionAngle) * reflectionDistance * 1; var xTraveledBeforeImpact = closerCollision.Point.X - closerCollision.S1.P1.X; var yTraveledBeforeImpact = closerCollision.Point.Y - closerCollision.S1.P1.Y; var posXAtImpact = physicalMovement.InitialPos.X + xTraveledBeforeImpact * 0.99f; var posYAtImpact = physicalMovement.InitialPos.Y + yTraveledBeforeImpact * 0.99f; var newPosX = posXAtImpact + Math.Cos(reflectionAngle) * reflectionDistance; var newPosY = posYAtImpact + Math.Sin(reflectionAngle) * reflectionDistance; var previousMovement = physicalMovement; if (physicalView.CanBounce) { var deltaX = closerCollision.S1.P2.X - newCornerPosX; var deltaY = closerCollision.S1.P2.Y - newCornerPosY; newPosX += -deltaX; newPosY += -deltaY; physicalView.V.Amount = physicalView.V.Amount * 0.5f; physicalView.V.Angle = reflectionAngle; } else { // Horizontal if (closerCollision.S2.P1.Y == closerCollision.S2.P2.Y) { newPosX += previousMovement.FinalPos.X - previousMovement.InitialPos.X; physicalView.V.Amount = 0; inTheAir = false; } // Vertical surface else { physicalView.V.X = 0; newPosY += previousMovement.FinalPos.Y - previousMovement.InitialPos.Y; } } physicalMovement = new PhysicalMovement( new Point(posXAtImpact, posYAtImpact), new Point(newPosX, newPosY), physicalView.CollisionPoints); movementsCollisions = GetMovementCollisions(physicalMovement); //Logger.Log($"new pos {physicalMovement.FinalPos.X} | {physicalMovement.FinalPos.Y}"); count++; } physicalView.IsInAir = inTheAir; physicalView.RealX = physicalMovement.FinalPos.X; physicalView.RealY = physicalMovement.FinalPos.Y; } }