From bd93ae2f5f69beb7b3c4bbf6a1dc21eaeced02d1 Mon Sep 17 00:00:00 2001 From: riedel Date: Mon, 8 May 2023 17:02:19 +0200 Subject: [PATCH] Lots of nonsense --- CityGame/Car.cs | 104 ----------- CityGame/CityGame.csproj | 1 + CityGame/Classes/Entities/Car.cs | 165 ++++++++++++++++++ CityGame/{ => Classes/Entities}/Entity.cs | 12 +- CityGame/{ => Classes/Entities}/Helicopter.cs | 59 +++++-- CityGame/{ => Classes/Misc}/AssemblyInfo.cs | 0 CityGame/{ => Classes/Misc}/Extensions.cs | 4 + .../Rendering}/ColorConversionMaps.cs | 16 +- .../{ => Classes/Rendering}/CustomShader.cs | 0 .../{ => Classes/Rendering}/ImageConverter.cs | 4 +- CityGame/{ => Classes/Rendering}/IntPoint.cs | 2 +- CityGame/{ => Classes/Rendering}/OCanvas.cs | 2 +- CityGame/{ => Classes/Rendering}/Pattern.cs | 3 +- CityGame/{ => Classes/Rendering}/Renderer.cs | 27 +-- .../{ => Classes/Rendering}/SourcedImage.cs | 0 CityGame/{ => Classes/World}/ISelectable.cs | 4 +- CityGame/{ => Classes/World}/Tile.cs | 10 +- CityGame/{ => Classes/World}/TileType.cs | 6 +- CityGame/MainWindow.xaml.cs | 93 ++++++---- 19 files changed, 334 insertions(+), 178 deletions(-) delete mode 100644 CityGame/Car.cs create mode 100644 CityGame/Classes/Entities/Car.cs rename CityGame/{ => Classes/Entities}/Entity.cs (73%) rename CityGame/{ => Classes/Entities}/Helicopter.cs (50%) rename CityGame/{ => Classes/Misc}/AssemblyInfo.cs (100%) rename CityGame/{ => Classes/Misc}/Extensions.cs (86%) rename CityGame/{ => Classes/Rendering}/ColorConversionMaps.cs (79%) rename CityGame/{ => Classes/Rendering}/CustomShader.cs (100%) rename CityGame/{ => Classes/Rendering}/ImageConverter.cs (94%) rename CityGame/{ => Classes/Rendering}/IntPoint.cs (94%) rename CityGame/{ => Classes/Rendering}/OCanvas.cs (89%) rename CityGame/{ => Classes/Rendering}/Pattern.cs (98%) rename CityGame/{ => Classes/Rendering}/Renderer.cs (84%) rename CityGame/{ => Classes/Rendering}/SourcedImage.cs (100%) rename CityGame/{ => Classes/World}/ISelectable.cs (71%) rename CityGame/{ => Classes/World}/Tile.cs (69%) rename CityGame/{ => Classes/World}/TileType.cs (68%) diff --git a/CityGame/Car.cs b/CityGame/Car.cs deleted file mode 100644 index a55c200..0000000 --- a/CityGame/Car.cs +++ /dev/null @@ -1,104 +0,0 @@ -using Microsoft.Xna.Framework; -using System; -using System.Linq; -using System.Windows; -using WPFGame; - -namespace CityGame -{ - public class Car : Entity - { - public delegate void CarEvent(Car car); - public event CarEvent JourneyFinished; - public event CarEvent JourneyImpossible; - public Point? Target { get; set; } = null; - public int NextTarget { get; set; } = 0; - public Point[]? Path { get; set; } = null; - public Point Point - { - get - { - return new Point((int)X / MainWindow.TileSize, (int)Y / MainWindow.TileSize); - } - set - { - X = (float)value.X * MainWindow.TileSize; - Y = (float)value.Y * MainWindow.TileSize; - } - } - public float Speed { get; set; } = 128; - public override OCanvas Render() - { - OCanvas canvas = new OCanvas(); - Image car = new SourcedImage("Car.png"); - - canvas.Children.Add(car); - var light = new LightSource { Radius = 64, Intensity = 2, Color = Color.White, Type = LightSourceType.Spotlight, Rotation = -90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; - var light2 = new LightSource { Radius = 64, Intensity = 2, Color = Color.White, Type = LightSourceType.Spotlight, Rotation = -90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; - Canvas.SetLeft(light, 39); - Canvas.SetTop(light, 19); - Canvas.SetLeft(light2, 46); - Canvas.SetTop(light2, 19); - canvas.Children.Add(light); - canvas.Children.Add(light2); - - var blight = new LightSource { Radius = 12, Intensity = 0.5f, Color = Color.Red, Type = LightSourceType.PointLight, Rotation = 90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; - var blight2 = new LightSource { Radius = 12, Intensity = 0.5f, Color = Color.Red, Type = LightSourceType.PointLight, Rotation = 90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; - Canvas.SetLeft(blight, 39); - Canvas.SetTop(blight, 46); - Canvas.SetLeft(blight2, 46); - Canvas.SetTop(blight2, 46); - canvas.Children.Add(blight); - canvas.Children.Add(blight2); - - return canvas; - } - public Car() - { - JourneyFinished += c => { }; - JourneyImpossible += c => { }; - } - - public override void Tick(long deltaTime) - { - if (Target is not null) - { - //if(Object is not null) Object.ToolTip = Target.ToString(); - if (Path is null) - { - Path = MainWindow.pathfinder.FindPath(Point.Convert(), ((Point)Target).Convert()).Select(x => x.Convert()).ToArray(); - NextTarget = 0; - } - if (Path.Length == 0) - { - JourneyImpossible(this); - return; - } - Point nextTarget = Path[NextTarget]; - if (X.CloselyEquals(nextTarget.X * MainWindow.TileSize) && Y.CloselyEquals(nextTarget.Y * MainWindow.TileSize)) - { - NextTarget++; - } - if (NextTarget == Path.Length) - { - Path = null; - Target = null; - NextTarget = 0; - JourneyFinished(this); - return; - } - if (X.CloselyEquals(nextTarget.X * MainWindow.TileSize) && Y.CloselyEquals(nextTarget.Y * MainWindow.TileSize)) - return; - Vector2 travel = new Vector2((float)nextTarget.X * 64 - X, (float)nextTarget.Y * 64 - Y); - Vector2 direction = Vector2.Normalize(travel); - float degrees = (float)(Math.Atan2(direction.Y, direction.X) * (180 / Math.PI)) + 90; - Rotation = degrees; - var possibleDistance = Speed * deltaTime / 1000; - var finalDistance = Math.Min(possibleDistance, travel.Length()); - Vector2 travelFinal = direction * finalDistance; - X += travelFinal.X; - Y += travelFinal.Y; - } - } - } -} \ No newline at end of file diff --git a/CityGame/CityGame.csproj b/CityGame/CityGame.csproj index dd3bdf2..2e02cb2 100644 --- a/CityGame/CityGame.csproj +++ b/CityGame/CityGame.csproj @@ -12,6 +12,7 @@ + diff --git a/CityGame/Classes/Entities/Car.cs b/CityGame/Classes/Entities/Car.cs new file mode 100644 index 0000000..6df70c5 --- /dev/null +++ b/CityGame/Classes/Entities/Car.cs @@ -0,0 +1,165 @@ +using CityGame.Classes.Rendering; +using CityGame.Classes.World; +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.ConstrainedExecution; +using System.Windows; +using WPFGame; + +namespace CityGame.Classes.Entities +{ + public class PoliceCar : Car + { + public static List Cars = new List(); + public PoliceCar() : base() + { + Cars.Add(this); + Speed = 192; + PNGFile = "PoliceCar.png"; + } + public override void Tick(long deltaTime) + { + + base.Tick(deltaTime); + } + } + public class Car : Entity + { + public delegate void CarEvent(Car car); + public event CarEvent JourneyFinished; + public event CarEvent JourneyImpossible; + public ISelectable Target { get; set; } = null; + public int NextTarget { get; set; } = 0; + public Point[]? Path { get; set; } = null; + public Point Point + { + get + { + return new Point((int)X / MainWindow.TileSize, (int)Y / MainWindow.TileSize); + } + set + { + X = (float)value.X * MainWindow.TileSize; + Y = (float)value.Y * MainWindow.TileSize; + } + } + public float Speed { get; set; } = 128; + float currentSpeed = 0; + public static Dictionary OccupiedTilesFill = new Dictionary(); + public static Dictionary OccupiedTiles = new Dictionary(); + public static Dictionary OccupiedTilesFill2 = new Dictionary(); + public static Dictionary OccupiedTiles2 = new Dictionary(); + protected string PNGFile = "NPCCar.png"; + protected ColoredRectangle debugRect; + protected Tile lastTile; + protected List lights = new List(); + public override OCanvas Render() + { + OCanvas canvas = new OCanvas(); + Image car = new SourcedImage(PNGFile); + + canvas.Children.Add(car); + var light = new LightSource { Radius = 128, Angle = 64, Intensity = 2, Color = Color.White, Type = LightSourceType.Spotlight, Rotation = -90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; + var light2 = new LightSource { Radius = 128, Angle = 64, Intensity = 2, Color = Color.White, Type = LightSourceType.Spotlight, Rotation = -90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; + Canvas.SetLeft(light, 39); + Canvas.SetTop(light, 19); + Canvas.SetLeft(light2, 46); + Canvas.SetTop(light2, 19); + canvas.Children.Add(light); + canvas.Children.Add(light2); + + var blight = new LightSource { Radius = 12, Angle = 12, Intensity = 0.5f, Color = Color.Red, Type = LightSourceType.PointLight, Rotation = 90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; + var blight2 = new LightSource { Radius = 12, Angle = 12, Intensity = 0.5f, Color = Color.Red, Type = LightSourceType.PointLight, Rotation = 90, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; + Canvas.SetLeft(blight, 39); + Canvas.SetTop(blight, 46); + Canvas.SetLeft(blight2, 46); + Canvas.SetTop(blight2, 46); + canvas.Children.Add(blight); + canvas.Children.Add(blight2); + + lights.Add(light); + lights.Add(light2); + lights.Add(blight); + lights.Add(blight2); + + debugRect = new ColoredRectangle(); + MainWindow.GameCanvas.Children.Add(debugRect); + + return canvas; + } + public Car() + { + JourneyFinished += c => { }; + JourneyImpossible += c => { }; + } + + public override void Tick(long deltaTime) + { + Tile myTile = MainWindow.Grid[Point.X, Point.Y]; + if (myTile.Type == TileType.Garage) + { + Rotation = ((Canvas)myTile.Element).Children[1].Rotation-90; + lights.ForEach(x => x.Visible = false); + } + else lights.ForEach(x => x.Visible = true); + if (Target is not null) + { + //if(Object is not null) Object.ToolTip = Target.ToString(); + if (Path is null) + { + Path = MainWindow.pathfinder.FindPath(Point.Convert(), new Point((int)(Target.X() / MainWindow.TileSize), (int)(Target.Y() / MainWindow.TileSize)).Convert()).Select(x => x.Convert()).ToArray(); + NextTarget = 0; + } + if (Path.Length == 0) + { + JourneyImpossible(this); + return; + } + Point nextTarget = Path[NextTarget]; + if (X.CloselyEquals(nextTarget.X * MainWindow.TileSize) && Y.CloselyEquals(nextTarget.Y * MainWindow.TileSize)) + { + lastTile = myTile; + NextTarget++; + } + if (NextTarget == Path.Length) + { + Path = null; + NextTarget = 0; + JourneyFinished(this); + return; + } + if (X.CloselyEquals(nextTarget.X * MainWindow.TileSize) && Y.CloselyEquals(nextTarget.Y * MainWindow.TileSize)) + return; + float SpeedMulti = 1; + + if (myTile.Type == TileType.Highway || myTile.Type == TileType.HighwayBridge) SpeedMulti = 2; + + Vector2 travel = new Vector2((float)nextTarget.X * 64 - X, (float)nextTarget.Y * 64 - Y); + Vector2 direction = Vector2.Normalize(travel); + + float degrees = (float)(Math.Atan2(direction.Y, direction.X) * (180 / Math.PI)) + 90; + Rotation = degrees; + Tile targetTile = MainWindow.Grid[nextTarget.X, nextTarget.Y]; + + if (Math.Round(Rotation) == 0 || Math.Round(Rotation) == 90) + { + if (!OccupiedTilesFill.ContainsKey(myTile)) OccupiedTilesFill.Add(myTile, this); + if (OccupiedTiles.ContainsKey(targetTile) && OccupiedTiles[targetTile] != this) SpeedMulti = 0; + } + if (Math.Round(Rotation) == 180 || Math.Round(Rotation) == 270) + { + if (!OccupiedTilesFill2.ContainsKey(myTile)) OccupiedTilesFill2.Add(myTile, this); + if (OccupiedTiles2.ContainsKey(targetTile) && OccupiedTiles2[targetTile] != this) SpeedMulti = 0; + } + + var possibleDistance = Speed * deltaTime / 1000 * SpeedMulti; + var finalDistance = Math.Min(possibleDistance, travel.Length()); + Vector2 travelFinal = direction * finalDistance; + X += travelFinal.X; + Y += travelFinal.Y; + } + } + } +} \ No newline at end of file diff --git a/CityGame/Entity.cs b/CityGame/Classes/Entities/Entity.cs similarity index 73% rename from CityGame/Entity.cs rename to CityGame/Classes/Entities/Entity.cs index 1631935..ffeec78 100644 --- a/CityGame/Entity.cs +++ b/CityGame/Classes/Entities/Entity.cs @@ -1,4 +1,7 @@ -namespace CityGame +using CityGame.Classes.Rendering; +using CityGame.Classes.World; + +namespace CityGame.Classes.Entities { public abstract class Entity : ISelectable { @@ -17,11 +20,16 @@ public bool RunAction(ISelectable target) { - if(this is Helicopter heli) + if (this is Helicopter heli) { heli.Target = target; return true; } + if(this is PoliceCar car) + { + car.Path = null; + car.Target = target; + } return false; } diff --git a/CityGame/Helicopter.cs b/CityGame/Classes/Entities/Helicopter.cs similarity index 50% rename from CityGame/Helicopter.cs rename to CityGame/Classes/Entities/Helicopter.cs index dcc20cd..f20a0d6 100644 --- a/CityGame/Helicopter.cs +++ b/CityGame/Classes/Entities/Helicopter.cs @@ -1,12 +1,15 @@ -using Microsoft.Xna.Framework; +using CityGame.Classes.Rendering; +using CityGame.Classes.World; +using Microsoft.Xna.Framework; using System; using WPFGame; -namespace CityGame +namespace CityGame.Classes.Entities { public class Helicopter : Entity { public float Speed { get; set; } = 256; + public float RotSpeed { get; set; } = 1; public bool Landed = false; Image Heli1; Image Heli2; @@ -32,11 +35,16 @@ namespace CityGame canvas.Children.Add(Blades1); canvas.Children.Add(Blades2); - Spotlight = new LightSource { Type = LightSourceType.Spotlight, Color = Color.White, Intensity = 3, Rotation = -90, Radius = MainWindow.TileSize * 3, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; + Spotlight = new LightSource { Type = LightSourceType.Spotlight, Color = Color.White, Intensity = 3, Rotation = -90, Radius = MainWindow.TileSize * 3, Angle = MainWindow.TileSize * 3, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; Canvas.SetTop(Spotlight, 7); Canvas.SetLeft(Spotlight, 32); + LightSource PointLight = new LightSource { Type = LightSourceType.PointLight, Color = Color.White, Radius = MainWindow.TileSize, Angle = MainWindow.TileSize, RotationOrigin = new Point(MainWindow.TileSize / 2, MainWindow.TileSize / 2) }; + Canvas.SetLeft(PointLight, 32); + Canvas.SetTop(PointLight, 28); + canvas.Children.Add(Spotlight); + canvas.Children.Add(PointLight); return canvas; } @@ -44,35 +52,58 @@ namespace CityGame public override void Tick(long deltaTime) { if (Heli1 is null) return; - long ms = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; - if (ms / 250 % 2 == 0) + Tile myTile = MainWindow.Grid[(int)(X / MainWindow.TileSize), (int)(Y / MainWindow.TileSize)]; + if (myTile.Type != TileType.Helipad) { - Blades1.Visible = false; - Blades2.Visible = true; + Spotlight.Visible = true; + Heli2.Visible = true; + Heli1.Visible = false; + long ms = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; + if (ms / 250 % 2 == 0) + { + Blades1.Visible = false; + Blades2.Visible = true; + } + else + { + Blades1.Visible = true; + Blades2.Visible = false; + } } else { + Spotlight.Visible = false; Blades1.Visible = true; Blades2.Visible = false; + Heli1.Visible = true; + Heli2.Visible = false; } if (Target is not null) { - IntPoint nextTarget = new IntPoint(Target.X(), Target.Y()); - if(Target is Car car) + Vector2 nextTarget = new Vector2(Target.X(), Target.Y()); + if (Target is Car car) { - var correctionvector = new IntPoint((int)Math.Cos(Microsoft.Xna.Framework.MathHelper.ToRadians(car.Rotation)), (int)Math.Sin(Microsoft.Xna.Framework.MathHelper.ToRadians(car.Rotation))); - correctionvector *= MainWindow.TileSize / 4; + var correctionvector = new Vector2((float)Math.Cos(MathHelper.ToRadians(car.Rotation)), (float)Math.Sin(MathHelper.ToRadians(car.Rotation))); + correctionvector *= MainWindow.TileSize / 5; nextTarget += correctionvector; } - Vector2 travel = new Vector2((float)nextTarget.X - X, (float)nextTarget.Y - Y); + Vector2 travel = new Vector2(nextTarget.X - X, nextTarget.Y - Y); float minDistance = MainWindow.TileSize * 1; if (Target is Tile) minDistance = 0; float minSpeedyDistance = MainWindow.TileSize * 3; - Spotlight.Radius = (int)Math.Min(minSpeedyDistance, travel.Length()); + Spotlight.Radius = (int)Math.Max(minDistance, Math.Min(minSpeedyDistance, travel.Length())); + if (Spotlight.Radius < minSpeedyDistance) Spotlight.Angle = Spotlight.Radius; if (travel.Length() < minDistance) Move = false; if (travel.Length() > minSpeedyDistance) Move = true; Vector2 direction = Vector2.Normalize(travel); float degrees = (float)(Math.Atan2(direction.Y, direction.X) * (180 / Math.PI)) + 90; - Rotation = degrees; + if (Rotation != degrees) + { + bool dir = degrees - (Rotation % 360) > 0; + float dis = Math.Abs(degrees - Rotation); + float tra = Math.Min(dis, RotSpeed); + Rotation += dir ? tra : -tra; + } + Spotlight.Rotation = (int)(Math.Max(-90, Math.Min(90, degrees - Rotation))) - 90; float Speedmulti = 1; if (travel.Length() < minSpeedyDistance) Speedmulti = (travel.Length() - minDistance) / (minSpeedyDistance - minDistance); var possibleDistance = Speed * Speedmulti * deltaTime / 1000; diff --git a/CityGame/AssemblyInfo.cs b/CityGame/Classes/Misc/AssemblyInfo.cs similarity index 100% rename from CityGame/AssemblyInfo.cs rename to CityGame/Classes/Misc/AssemblyInfo.cs diff --git a/CityGame/Extensions.cs b/CityGame/Classes/Misc/Extensions.cs similarity index 86% rename from CityGame/Extensions.cs rename to CityGame/Classes/Misc/Extensions.cs index 0bcf6a5..296dfbb 100644 --- a/CityGame/Extensions.cs +++ b/CityGame/Classes/Misc/Extensions.cs @@ -22,5 +22,9 @@ namespace CityGame { return Math.Round(A) == Math.Round(B); } + public static bool CloselyEquals(this int A, int B) + { + return A == B; + } } } \ No newline at end of file diff --git a/CityGame/ColorConversionMaps.cs b/CityGame/Classes/Rendering/ColorConversionMaps.cs similarity index 79% rename from CityGame/ColorConversionMaps.cs rename to CityGame/Classes/Rendering/ColorConversionMaps.cs index 301f247..4d7212d 100644 --- a/CityGame/ColorConversionMaps.cs +++ b/CityGame/Classes/Rendering/ColorConversionMaps.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace CityGame +namespace CityGame.Classes.Rendering { public class ColorConversionMaps { @@ -34,7 +34,7 @@ namespace CityGame { "#616161", "#816161" }, { "#3b3b3b", "#5b3b3b" } }; - public static Dictionary HouseToBuildingGreenMap = new Dictionary + public static Dictionary HouseToBuildingGreenMap = new Dictionary { { "#616161", "#618161" }, { "#3b3b3b", "#3b5b3b" } @@ -61,5 +61,17 @@ namespace CityGame { "#00000000", "#00b36b00" }, { "#616161", "#303030" } }; + public static Dictionary CarToNPCCar = new Dictionary() + { + { "#ff0000", "#888888" }, + { "#fc4141", "#fcfcfc" }, + { "#b80000", "#b8b8b8" } + }; + public static Dictionary CarToPoliceCar = new Dictionary() + { + { "#ff0000", "#0000ff" }, + { "#fc4141", "#4141fc" }, + { "#b80000", "#0000b8" } + }; } } diff --git a/CityGame/CustomShader.cs b/CityGame/Classes/Rendering/CustomShader.cs similarity index 100% rename from CityGame/CustomShader.cs rename to CityGame/Classes/Rendering/CustomShader.cs diff --git a/CityGame/ImageConverter.cs b/CityGame/Classes/Rendering/ImageConverter.cs similarity index 94% rename from CityGame/ImageConverter.cs rename to CityGame/Classes/Rendering/ImageConverter.cs index 7b030a7..fb01a52 100644 --- a/CityGame/ImageConverter.cs +++ b/CityGame/Classes/Rendering/ImageConverter.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; -namespace CityGame +namespace CityGame.Classes.Rendering { public class ImageConverter { @@ -15,7 +15,7 @@ namespace CityGame if (!File.Exists(srcFile)) return; Dictionary Conversions = conversions.Select(x => new KeyValuePair(System.Drawing.ColorTranslator.FromHtml(x.Key), System.Drawing.ColorTranslator.FromHtml(x.Value))).ToDictionary(x => x.Key, x => x.Value); - System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)System.Drawing.Bitmap.FromFile(srcFile); + System.Drawing.Bitmap bmp = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(srcFile); for (int x = 0; x < bmp.Width; x++) { for (int y = 0; y < bmp.Height; y++) diff --git a/CityGame/IntPoint.cs b/CityGame/Classes/Rendering/IntPoint.cs similarity index 94% rename from CityGame/IntPoint.cs rename to CityGame/Classes/Rendering/IntPoint.cs index ac36957..ff3a1af 100644 --- a/CityGame/IntPoint.cs +++ b/CityGame/Classes/Rendering/IntPoint.cs @@ -1,4 +1,4 @@ -namespace CityGame +namespace CityGame.Classes.Rendering { public struct IntPoint { diff --git a/CityGame/OCanvas.cs b/CityGame/Classes/Rendering/OCanvas.cs similarity index 89% rename from CityGame/OCanvas.cs rename to CityGame/Classes/Rendering/OCanvas.cs index a6b089f..6cf953f 100644 --- a/CityGame/OCanvas.cs +++ b/CityGame/Classes/Rendering/OCanvas.cs @@ -1,6 +1,6 @@ using WPFGame; -namespace CityGame +namespace CityGame.Classes.Rendering { public class OCanvas : Canvas { diff --git a/CityGame/Pattern.cs b/CityGame/Classes/Rendering/Pattern.cs similarity index 98% rename from CityGame/Pattern.cs rename to CityGame/Classes/Rendering/Pattern.cs index 64dc2ef..6e08721 100644 --- a/CityGame/Pattern.cs +++ b/CityGame/Classes/Rendering/Pattern.cs @@ -1,7 +1,8 @@ using System; using System.Linq; +using CityGame.Classes.World; -namespace CityGame +namespace CityGame.Classes.Rendering { public class Pattern { diff --git a/CityGame/Renderer.cs b/CityGame/Classes/Rendering/Renderer.cs similarity index 84% rename from CityGame/Renderer.cs rename to CityGame/Classes/Rendering/Renderer.cs index f109ff9..ab10677 100644 --- a/CityGame/Renderer.cs +++ b/CityGame/Classes/Rendering/Renderer.cs @@ -1,6 +1,7 @@ -using WPFGame; +using CityGame.Classes.World; +using WPFGame; -namespace CityGame +namespace CityGame.Classes.Rendering { public class Renderer { @@ -19,23 +20,27 @@ namespace CityGame public static OCanvas Render(TileType type, int x, int y, Tile[,] Grid) { string tooltip = x + ":" + y; - if (type == TileType.Skyscraper) + if (type == TileType.Skyscraper || type == TileType.Garage || type == TileType.Helipad) { string theme = ""; if (Grid[x, y].BlockID % 2 == 1) theme = "Dark"; if (Grid[x, y].BlockID % 30 == 1) theme = "Blue"; if (Grid[x, y].BlockID % 30 == 2) theme = "Red"; if (Grid[x, y].BlockID % 30 == 3) theme = "Green"; - Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Skyscraper); - if (pattern.PatternCode == "1" && MainWindow.random.Next(0, 3) == 0) return new SourcedImage("ParkingLot"+theme+".png:" + pattern.Rotation); + Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Skyscraper, TileType.Garage, TileType.Helipad); + if (pattern.PatternCode == "1" && MainWindow.random.Next(0, 3) == 0) return new SourcedImage("ParkingLot" + theme + ".png:" + pattern.Rotation); if (pattern.PatternCode == "3" && MainWindow.random.Next(0, 12) == 0) pattern.PatternCode = "3a"; if (pattern.PatternCode == "3" && MainWindow.random.Next(0, 12) == 1) pattern.PatternCode = "3ab"; - OCanvas canvas = new SourcedImage("Building"+ theme + pattern.PatternCode + ".png:" + pattern.Rotation, tooltip); + OCanvas canvas = new SourcedImage("Building" + theme + pattern.PatternCode + ".png:" + pattern.Rotation, tooltip); - if (theme == "Blue" && pattern.PatternCode == "8" && MainWindow.random.Next(0, 4) == 0) canvas.Children.Add(new SourcedImage("Helipad.png")); - else if (theme == "Blue" && pattern.PatternCode == "5" && MainWindow.random.Next(0, 2) == 0) canvas.Children.Add(new SourcedImage("Garage.png:" + pattern.Rotation)); - else if (theme == "Blue" && pattern.PatternCode == "0") canvas.Children.Add(new SourcedImage("Garage.png:270")); - else if (MainWindow.random.Next(0, 10) == 0 && pattern.PatternCode != "3a") canvas.Children.Add(new SourcedImage("Vent" + (MainWindow.random.Next(0, 3) + 1) + ".png:" + (MainWindow.random.Next(0, 4) * 90))); + if (theme == "Blue" && pattern.PatternCode == "8" && MainWindow.random.Next(0, 4) == 0) Grid[x, y].Type = TileType.Helipad; + else if (theme == "Blue" && pattern.PatternCode == "5" && MainWindow.random.Next(0, 2) == 0) Grid[x, y].Type = TileType.Garage; + else if (theme == "Blue" && pattern.PatternCode == "0") Grid[x, y].Type = TileType.Garage; + else if (MainWindow.random.Next(0, 10) == 0 && pattern.PatternCode != "3a") canvas.Children.Add(new SourcedImage("Vent" + (MainWindow.random.Next(0, 3) + 1) + ".png:" + MainWindow.random.Next(0, 4) * 90)); + + if (pattern.PatternCode == "5" && Grid[x, y].Type == TileType.Garage) canvas.Children.Add(new SourcedImage("Garage.png:" + pattern.Rotation)); + if (pattern.PatternCode == "0" && Grid[x, y].Type == TileType.Garage) canvas.Children.Add(new SourcedImage("Garage.png:270")); + if (Grid[x,y].Type == TileType.Helipad) canvas.Children.Add(new SourcedImage("Helipad.png")); return canvas; } @@ -48,7 +53,7 @@ namespace CityGame { Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Park, TileType.Path); OCanvas canvas = new SourcedImage("Park" + pattern.PatternCode + ".png:" + pattern.Rotation); - if (MainWindow.random.Next(0, 4) == 0) canvas.Children.Add(new SourcedImage("Tree.png:" + MainWindow.random.Next(0,4) * 90, tooltip)); + if (MainWindow.random.Next(0, 4) == 0) canvas.Children.Add(new SourcedImage("Tree.png:" + MainWindow.random.Next(0, 4) * 90, tooltip)); return canvas; } if (type == TileType.Road) diff --git a/CityGame/SourcedImage.cs b/CityGame/Classes/Rendering/SourcedImage.cs similarity index 100% rename from CityGame/SourcedImage.cs rename to CityGame/Classes/Rendering/SourcedImage.cs diff --git a/CityGame/ISelectable.cs b/CityGame/Classes/World/ISelectable.cs similarity index 71% rename from CityGame/ISelectable.cs rename to CityGame/Classes/World/ISelectable.cs index 36299f3..b51872d 100644 --- a/CityGame/ISelectable.cs +++ b/CityGame/Classes/World/ISelectable.cs @@ -1,4 +1,6 @@ -namespace CityGame +using CityGame.Classes.Rendering; + +namespace CityGame.Classes.World { public interface ISelectable { diff --git a/CityGame/Tile.cs b/CityGame/Classes/World/Tile.cs similarity index 69% rename from CityGame/Tile.cs rename to CityGame/Classes/World/Tile.cs index c77eece..2e1de78 100644 --- a/CityGame/Tile.cs +++ b/CityGame/Classes/World/Tile.cs @@ -1,4 +1,7 @@ -namespace CityGame +using CityGame.Classes.Rendering; +using WPFGame; + +namespace CityGame.Classes.World { public struct Tile : ISelectable { @@ -6,6 +9,7 @@ public TileType Type; public int X; public int Y; + public UIElement Element; public OCanvas GetImage() { @@ -26,5 +30,9 @@ { return Y * MainWindow.TileSize; } + public override string ToString() + { + return Type.ToString() + " at " + X + ";" + Y; + } } } \ No newline at end of file diff --git a/CityGame/TileType.cs b/CityGame/Classes/World/TileType.cs similarity index 68% rename from CityGame/TileType.cs rename to CityGame/Classes/World/TileType.cs index 6c03e2e..f140721 100644 --- a/CityGame/TileType.cs +++ b/CityGame/Classes/World/TileType.cs @@ -1,9 +1,10 @@ -namespace CityGame +namespace CityGame.Classes.World { public enum TileType { Skyscraper = 100, House = 101, + Helipad = 102, Park = 220, @@ -14,6 +15,7 @@ Path = 421, Highway = 402, Bridge = 410, - HighwayBridge = 411 + HighwayBridge = 411, + Garage = 430 } } \ No newline at end of file diff --git a/CityGame/MainWindow.xaml.cs b/CityGame/MainWindow.xaml.cs index 7854907..25271c0 100644 --- a/CityGame/MainWindow.xaml.cs +++ b/CityGame/MainWindow.xaml.cs @@ -1,12 +1,17 @@ using AStar; using AStar.Options; +using CityGame.Classes.Entities; +using CityGame.Classes.Rendering; +using CityGame.Classes.World; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Input; using SimplexNoise; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Globalization; using System.Linq; +using System.Speech.Synthesis; using WPFGame; namespace CityGame @@ -20,22 +25,21 @@ namespace CityGame { public ISelectable GetSelectableFromClick(MouseState click) { - Point point = new Point(click.X, click.Y); - point.X -= (int)Canvas.GetLeft(CameraCanvas); - point.Y -= (int)Canvas.GetTop(CameraCanvas); - point.X = (int)(point.X / CameraCanvas.ScaleX); - point.Y = (int)(point.Y / CameraCanvas.ScaleY); + Vector2 point = new Vector2(click.X, click.Y); + + point = Vector2.Transform(point, InvCamera); foreach (Entity entity in Entities) { double diff = new Vector2((int)entity.X + TileSize / 2 - point.X, (int)entity.Y + TileSize / 2 - point.Y).Length(); if (diff < TileSize / 2) return entity; } - int x = point.X / TileSize; - int y = point.Y / TileSize; + int x = (int)(point.X / TileSize); + int y = (int)(point.Y / TileSize); 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]); return Grid[x, y]; } public static Entity GetEntityFromImage(Image image) @@ -55,7 +59,7 @@ namespace CityGame } public static Random random; public static bool MouseIsDown = false; - public static Point MousePos = new Point(0, 0); + public static Vector2 MousePos = new Vector2(0, 0); public static PathFinder pathfinder; public static short[,] pathfindingGrid; public static short[,] pathfindingGridDesperate; @@ -68,7 +72,7 @@ namespace CityGame Canvas MainCanvas = new OCanvas(); Canvas BGCanvas = new OCanvas(); - Canvas GameCanvas = new OCanvas(); + internal static Canvas GameCanvas = new OCanvas(); Canvas CameraCanvas = new OCanvas(); Canvas UICanvas = new OCanvas(); public MainWindow() @@ -98,6 +102,8 @@ namespace CityGame ImageConverter.ChangeColor("ParkingLot", "ParkingLotGreen", ColorConversionMaps.HouseToBuildingGreenMap); ImageConverter.ChangeColor("Error", "ErrorRed", new Dictionary { { "#000000", "#ff0000" } }); + ImageConverter.ChangeColor("Car", "NPCCar", ColorConversionMaps.CarToNPCCar); + ImageConverter.ChangeColor("Car", "PoliceCar", ColorConversionMaps.CarToPoliceCar); #endregion int seed = 8; @@ -285,24 +291,6 @@ namespace CityGame startPoint += step; } } - for (int y = 0; y < doubleHeight; y++) - { - for (int x = 0; x < doubleWidth; x++) - { - var type = IntermediateGrid[x, y].Type; - bool walkable = ((int)type) / 100 == 4; - pathfindingGridDesperate[y, x] = (short)(walkable ? 1 : 0); - if (type == TileType.Path) walkable = false; - pathfindingGrid[y, x] = (short)(walkable ? 1 : 0); - if (type == TileType.Bridge) bridgeTiles.Add(IntermediateGrid[x, y]); - if (type == TileType.Road) roadTiles.Add(IntermediateGrid[x, y]); - if (type == TileType.Road || type == TileType.Bridge) npcWalkable.Add(IntermediateGrid[x, y]); - } - } - - var worldGrid = new WorldGrid(pathfindingGrid); - pathfinder = new PathFinder(worldGrid, new PathFinderOptions { PunishChangeDirection = true, UseDiagonals = false, SearchLimit = int.MaxValue, HeuristicFormula = AStar.Heuristics.HeuristicFormula.Euclidean }); - #endregion Grid = IntermediateGrid; @@ -336,6 +324,7 @@ namespace CityGame for (int y = 0; y < mapHeight; y++) { Canvas image = Renderer.Render(Grid[x, y].Type, x, y, Grid); + Grid[x, y].Element = image; Canvas.SetLeft(image, x * tileSize); Canvas.SetTop(image, y * tileSize); @@ -347,6 +336,24 @@ namespace CityGame GameCanvas.Children.Add(image); } } + for (int y = 0; y < doubleHeight; y++) + { + for (int x = 0; x < doubleWidth; x++) + { + var type = IntermediateGrid[x, y].Type; + bool walkable = ((int)type) / 100 == 4; + pathfindingGridDesperate[y, x] = (short)(walkable ? 1 : 0); + if (type == TileType.Path) walkable = false; + pathfindingGrid[y, x] = (short)(walkable ? 1 : 0); + if (type == TileType.Bridge) bridgeTiles.Add(IntermediateGrid[x, y]); + if (type == TileType.Road) roadTiles.Add(IntermediateGrid[x, y]); + if (type == TileType.Road || type == TileType.Bridge) npcWalkable.Add(IntermediateGrid[x, y]); + } + } + + var worldGrid = new WorldGrid(pathfindingGrid); + pathfinder = new PathFinder(worldGrid, new PathFinderOptions { PunishChangeDirection = true, UseDiagonals = false, SearchLimit = int.MaxValue, HeuristicFormula = AStar.Heuristics.HeuristicFormula.Euclidean }); + foreach (Image image in SourcedImage.GetObjectsBySourceFile("Helipad.png")) { @@ -356,6 +363,14 @@ namespace CityGame Entities.Add(new Helicopter { X = x, Y = y }); } + foreach (Image image in SourcedImage.GetObjectsBySourceFile("Garage.png")) + { + float x = (float)Canvas.GetLeft(image.Parent); + float y = (float)Canvas.GetTop(image.Parent); + + Entities.Add(new PoliceCar { X = x, Y = y }); + } + for (int n = 0; n < NPCCount; n++) { Car car = new Car(); @@ -364,12 +379,12 @@ namespace CityGame car.Point = new Point(startTile.X, startTile.Y); - car.Target = new Point(targetTile.X, targetTile.Y); + car.Target = targetTile; Car.CarEvent reset = car => { Tile targetTile = npcWalkable[random.Next(0, npcWalkable.Count)]; - car.Target = new Point(targetTile.X, targetTile.Y); + car.Target = targetTile; }; car.JourneyFinished += reset; @@ -381,18 +396,22 @@ namespace CityGame Show(); } int swv; + protected override Color SkyColor(long SpeedFactor) + { + return base.SkyColor(180); + } protected override void Update(GameTime time) { MouseState state = Mouse.GetState(); if (state.MiddleButton == ButtonState.Pressed) { - var newpos = new Point(state.X, state.Y); + var newpos = new Vector2(state.X, state.Y); var diff = newpos - MousePos; - Canvas.SetLeft(CameraCanvas, Canvas.GetLeft(CameraCanvas) + diff.X); - Canvas.SetTop(CameraCanvas, Canvas.GetTop(CameraCanvas) + diff.Y); + diff /= CameraZoom; + CameraPosition += diff; } - MousePos = new Point(state.X, state.Y); + MousePos = new Vector2(state.X, state.Y); float delta = state.ScrollWheelValue - swv; @@ -406,8 +425,7 @@ namespace CityGame if (delta != 0) { - CameraCanvas.ScaleX *= multi; - CameraCanvas.ScaleY *= multi; + CameraZoom *= multi; } if (state.LeftButton == ButtonState.Pressed) @@ -444,8 +462,11 @@ namespace CityGame entity.Object.Rotation = (int)entity.Rotation; Canvas.SetLeft(entity.Object, entity.X); Canvas.SetTop(entity.Object, entity.Y); - } + Car.OccupiedTiles = Car.OccupiedTilesFill; + Car.OccupiedTilesFill = new Dictionary(); + Car.OccupiedTiles2 = Car.OccupiedTilesFill2; + Car.OccupiedTilesFill2 = new Dictionary(); } } } \ No newline at end of file