From 6a4ed4b3a8b532ceda3c7b678b7de273641d3742 Mon Sep 17 00:00:00 2001 From: riedel Date: Wed, 10 May 2023 12:52:53 +0200 Subject: [PATCH] =?UTF-8?q?Added=20curvature=20to=20cars=20taking=20turns?= =?UTF-8?q?=20(90=C2=B0=20only)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CityGame/CityGame.csproj | 11 +++- CityGame/Classes/Entities/Car.cs | 81 +++++++++++++++++++++++++++-- CityGame/Classes/Entities/Entity.cs | 7 +++ CityGame/MainWindow.xaml.cs | 11 ++-- CityGame/Program.cs | 2 +- 5 files changed, 102 insertions(+), 10 deletions(-) diff --git a/CityGame/CityGame.csproj b/CityGame/CityGame.csproj index e26751f..1db0ac5 100644 --- a/CityGame/CityGame.csproj +++ b/CityGame/CityGame.csproj @@ -15,7 +15,6 @@ - @@ -151,4 +150,14 @@ + + + + + + + ..\..\..\RE-UI-a-Monogame-GUI\MGUI\bin\Debug\net6.0\MGUI.dll + + + diff --git a/CityGame/Classes/Entities/Car.cs b/CityGame/Classes/Entities/Car.cs index 2056284..790154b 100644 --- a/CityGame/Classes/Entities/Car.cs +++ b/CityGame/Classes/Entities/Car.cs @@ -90,9 +90,13 @@ namespace CityGame.Classes.Entities Move += c => { }; } public event CarEvent Move; + private int curveMode; + private float curveModePixelDuration; + private int curveModeStartedAt; public override void Tick(long deltaTime) { + //deltaTime /= 10; //deltaTime *= 500; Tuple[] fullBlockTiles = new Tuple[] { @@ -101,7 +105,7 @@ namespace CityGame.Classes.Entities new Tuple(TileType.Road, "1"), new Tuple(TileType.Garage, null) }; - if (this == MainWindow.Selected) Debug.WriteLine("Selected."); + //if (this == MainWindow.Selected) Debug.WriteLine("Selected."); Tile myTile = MainWindow.Grid[Point.X, Point.Y]; bool fullBlock = fullBlockTiles.Any(x => (x.Item1 == myTile.Type || (x.Item1 == TileType.Road && (myTile.Type == TileType.Path || myTile.Type == TileType.Highway || myTile.Type == TileType.Bridge || myTile.Type == TileType.HighwayBridge))) && (x.Item2 == myTile.Pattern.PatternCode || x.Item2 is null)); if (myTile.Type == TileType.Garage) @@ -120,7 +124,7 @@ namespace CityGame.Classes.Entities Path = pf.FindPath(Point.Convert(), new Point((int)(Target.X() / MainWindow.TileSize), (int)(Target.Y() / MainWindow.TileSize)).Convert()).Select(x => x.Convert()).ToArray(); NextTarget = 0; } - if(new Point(Target.X() / 64, Target.Y() / 64) != Point) Move(this); + if (new Point(Target.X() / 64, Target.Y() / 64) != Point) Move(this); if (Path.Length == 0) { JourneyImpossible(this); @@ -192,14 +196,85 @@ namespace CityGame.Classes.Entities var resetFunc = MainWindow.UpdatePathfinding(targetTile, 0, 3); blockingCar.Move += resetFunc; } - } else + } + else { RerouteTimePassed = 0; } + if (Path is not null && Path.Length > NextTarget + 1 && curveMode == 0) + { + var actPoint = Path[NextTarget + 1]; + var afterCurveTile = MainWindow.Grid[actPoint.X, actPoint.Y]; + // North + if (Rotation == 0 && afterCurveTile.X == nextTarget.X - 1 && afterCurveTile.Y == nextTarget.Y) curveMode = -1; // Left + else if (Rotation == 0 && afterCurveTile.X == nextTarget.X + 1 && afterCurveTile.Y == nextTarget.Y) curveMode = 1; // Right + + // East + else if (Rotation == 90 && afterCurveTile.X == nextTarget.X && afterCurveTile.Y == nextTarget.Y - 1) curveMode = -1; // Left + else if (Rotation == 90 && afterCurveTile.X == nextTarget.X && afterCurveTile.Y == nextTarget.Y + 1) curveMode = 1; // Right + + // South + else if (Rotation == 180 && afterCurveTile.X == nextTarget.X + 1 && afterCurveTile.Y == nextTarget.Y) curveMode = -1; // Left + else if (Rotation == 180 && afterCurveTile.X == nextTarget.X - 1 && afterCurveTile.Y == nextTarget.Y) curveMode = 1; // Right + + // West + else if (Rotation == 270 && afterCurveTile.X == nextTarget.X && afterCurveTile.Y == nextTarget.Y + 1) curveMode = -1; // Left + else if (Rotation == 270 && afterCurveTile.X == nextTarget.X && afterCurveTile.Y == nextTarget.Y - 1) curveMode = 1; // Right + + if (curveMode != 0) + { + curveModePixelDuration = MainWindow.TileSize * 2; + curveModeStartedAt = NextTarget; + } + } + var possibleDistance = Speed * deltaTime / 1000 * SpeedMulti; var finalDistance = Math.Min(possibleDistance, travel.Length()); Vector2 travelFinal = direction * finalDistance; + + UseVisualPosition = false; + if (curveMode != 0) + { + float rotationStart = MainWindow.TileSize * 1.25f; + float rotationEnd = MainWindow.TileSize * 0.75f; + + curveModePixelDuration -= travelFinal.Length(); + if (curveModePixelDuration <= rotationEnd) curveMode = 0; + else + { + UseVisualPosition = true; + + if (curveModePixelDuration < rotationStart && curveModePixelDuration > rotationEnd) + { + float percentage = (curveModePixelDuration - rotationEnd) / (rotationStart - rotationEnd); + if (this == MainWindow.Selected) Debug.WriteLine(percentage); + float vRotDeg = 0; + if (NextTarget == curveModeStartedAt) + { + float percentage2 = percentage - 0.5f; + percentage2 *= 2; + vRotDeg = (45 - 45 * percentage2) * curveMode; + } + else + { + float percentage2 = percentage * 2; + vRotDeg = (-45 * percentage2) * curveMode; + } + if (this == MainWindow.Selected) Debug.WriteLine(vRotDeg); + visualX = X; + visualY = Y; + visualRotation = Rotation + vRotDeg; + } + else + { + visualX = X; + visualY = Y; + visualRotation = Rotation; + } + } + } + X += travelFinal.X; Y += travelFinal.Y; } diff --git a/CityGame/Classes/Entities/Entity.cs b/CityGame/Classes/Entities/Entity.cs index ffeec78..8726c61 100644 --- a/CityGame/Classes/Entities/Entity.cs +++ b/CityGame/Classes/Entities/Entity.cs @@ -7,6 +7,13 @@ namespace CityGame.Classes.Entities { public float X { get; set; } public float Y { get; set; } + protected float visualX; + protected float visualY; + protected float visualRotation; + public float VisualX { get => UseVisualPosition ? visualX : X; set => X = visualX = value; } + public float VisualY { get => UseVisualPosition ? visualY : Y; set => Y = visualY = value; } + public float VisualRotation { get => UseVisualPosition ? visualRotation : Rotation; set => Rotation = visualRotation = value; } + public bool UseVisualPosition { get; set; } public float Rotation { get; set; } public long Time { get; set; } public OCanvas Object { get; set; } diff --git a/CityGame/MainWindow.xaml.cs b/CityGame/MainWindow.xaml.cs index 6434b13..5262c0e 100644 --- a/CityGame/MainWindow.xaml.cs +++ b/CityGame/MainWindow.xaml.cs @@ -37,7 +37,7 @@ namespace CityGame if (x < 0 || y < 0) return null; if (x > Grid.GetLength(0) - 1 || y > Grid.GetLength(1) - 1) return null; - Debug.WriteLine(Grid[x, y]); + //Debug.WriteLine(Grid[x, y]); return Grid[x, y]; } public static Entity GetEntityFromImage(Image image) @@ -478,7 +478,7 @@ namespace CityGame swv = state.ScrollWheelValue; if (delta != 0) { - Debug.WriteLine(delta); + //Debug.WriteLine(delta); } float multi = 1.05f; if (delta < 0) multi = 1 / multi; @@ -513,6 +513,7 @@ namespace CityGame foreach (Entity entity in Entities) { long deltaTime = milliseconds - entity.Time; + deltaTime = (long)time.ElapsedGameTime.TotalMilliseconds; entity.Time = milliseconds; entity.Tick(deltaTime); @@ -521,9 +522,9 @@ namespace CityGame entity.Object = entity.Render(); GameCanvas.Children.Add(entity.Object); } - entity.Object.Rotation = (int)entity.Rotation; - Canvas.SetLeft(entity.Object, entity.X); - Canvas.SetTop(entity.Object, entity.Y); + entity.Object.Rotation = (int)entity.VisualRotation; + Canvas.SetLeft(entity.Object, entity.VisualX); + Canvas.SetTop(entity.Object, entity.VisualY); } Car.OccupiedTiles = Car.OccupiedTilesFill; Car.OccupiedTilesFill = new Dictionary(); diff --git a/CityGame/Program.cs b/CityGame/Program.cs index fab28b1..9c5faea 100644 --- a/CityGame/Program.cs +++ b/CityGame/Program.cs @@ -5,7 +5,7 @@ namespace CityGame { public class Program { public static void Main() { - var menu = new MenuWindow(); + var menu = new MainWindow(); } } public class MenuWindow : Window