Lots of nonsense

This commit is contained in:
riedel 2023-05-08 17:02:19 +02:00
parent 9584420f6c
commit bd93ae2f5f
19 changed files with 334 additions and 178 deletions

View file

@ -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;
}
}
}
}

View file

@ -12,6 +12,7 @@
<PackageReference Include="Microsoft.HLSL.CSharpVB" Version="1.0.2" /> <PackageReference Include="Microsoft.HLSL.CSharpVB" Version="1.0.2" />
<PackageReference Include="SimplexNoise" Version="2.0.0" /> <PackageReference Include="SimplexNoise" Version="2.0.0" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" /> <PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Speech" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -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<PoliceCar> Cars = new List<PoliceCar>();
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<Tile, Car> OccupiedTilesFill = new Dictionary<Tile, Car>();
public static Dictionary<Tile, Car> OccupiedTiles = new Dictionary<Tile, Car>();
public static Dictionary<Tile, Car> OccupiedTilesFill2 = new Dictionary<Tile, Car>();
public static Dictionary<Tile, Car> OccupiedTiles2 = new Dictionary<Tile, Car>();
protected string PNGFile = "NPCCar.png";
protected ColoredRectangle debugRect;
protected Tile lastTile;
protected List<LightSource> lights = new List<LightSource>();
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;
}
}
}
}

View file

@ -1,4 +1,7 @@
namespace CityGame using CityGame.Classes.Rendering;
using CityGame.Classes.World;
namespace CityGame.Classes.Entities
{ {
public abstract class Entity : ISelectable public abstract class Entity : ISelectable
{ {
@ -17,11 +20,16 @@
public bool RunAction(ISelectable target) public bool RunAction(ISelectable target)
{ {
if(this is Helicopter heli) if (this is Helicopter heli)
{ {
heli.Target = target; heli.Target = target;
return true; return true;
} }
if(this is PoliceCar car)
{
car.Path = null;
car.Target = target;
}
return false; return false;
} }

View file

@ -1,12 +1,15 @@
using Microsoft.Xna.Framework; using CityGame.Classes.Rendering;
using CityGame.Classes.World;
using Microsoft.Xna.Framework;
using System; using System;
using WPFGame; using WPFGame;
namespace CityGame namespace CityGame.Classes.Entities
{ {
public class Helicopter : Entity public class Helicopter : Entity
{ {
public float Speed { get; set; } = 256; public float Speed { get; set; } = 256;
public float RotSpeed { get; set; } = 1;
public bool Landed = false; public bool Landed = false;
Image Heli1; Image Heli1;
Image Heli2; Image Heli2;
@ -32,11 +35,16 @@ namespace CityGame
canvas.Children.Add(Blades1); canvas.Children.Add(Blades1);
canvas.Children.Add(Blades2); 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.SetTop(Spotlight, 7);
Canvas.SetLeft(Spotlight, 32); 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(Spotlight);
canvas.Children.Add(PointLight);
return canvas; return canvas;
} }
@ -44,35 +52,58 @@ namespace CityGame
public override void Tick(long deltaTime) public override void Tick(long deltaTime)
{ {
if (Heli1 is null) return; if (Heli1 is null) return;
long ms = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; Tile myTile = MainWindow.Grid[(int)(X / MainWindow.TileSize), (int)(Y / MainWindow.TileSize)];
if (ms / 250 % 2 == 0) if (myTile.Type != TileType.Helipad)
{ {
Blades1.Visible = false; Spotlight.Visible = true;
Blades2.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 } else
{ {
Spotlight.Visible = false;
Blades1.Visible = true; Blades1.Visible = true;
Blades2.Visible = false; Blades2.Visible = false;
Heli1.Visible = true;
Heli2.Visible = false;
} }
if (Target is not null) if (Target is not null)
{ {
IntPoint nextTarget = new IntPoint(Target.X(), Target.Y()); Vector2 nextTarget = new Vector2(Target.X(), Target.Y());
if(Target is Car car) 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))); var correctionvector = new Vector2((float)Math.Cos(MathHelper.ToRadians(car.Rotation)), (float)Math.Sin(MathHelper.ToRadians(car.Rotation)));
correctionvector *= MainWindow.TileSize / 4; correctionvector *= MainWindow.TileSize / 5;
nextTarget += correctionvector; 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; float minDistance = MainWindow.TileSize * 1;
if (Target is Tile) minDistance = 0; if (Target is Tile) minDistance = 0;
float minSpeedyDistance = MainWindow.TileSize * 3; 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() < minDistance) Move = false;
if (travel.Length() > minSpeedyDistance) Move = true; if (travel.Length() > minSpeedyDistance) Move = true;
Vector2 direction = Vector2.Normalize(travel); Vector2 direction = Vector2.Normalize(travel);
float degrees = (float)(Math.Atan2(direction.Y, direction.X) * (180 / Math.PI)) + 90; 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; float Speedmulti = 1;
if (travel.Length() < minSpeedyDistance) Speedmulti = (travel.Length() - minDistance) / (minSpeedyDistance - minDistance); if (travel.Length() < minSpeedyDistance) Speedmulti = (travel.Length() - minDistance) / (minSpeedyDistance - minDistance);
var possibleDistance = Speed * Speedmulti * deltaTime / 1000; var possibleDistance = Speed * Speedmulti * deltaTime / 1000;

View file

@ -22,5 +22,9 @@ namespace CityGame
{ {
return Math.Round(A) == Math.Round(B); return Math.Round(A) == Math.Round(B);
} }
public static bool CloselyEquals(this int A, int B)
{
return A == B;
}
} }
} }

View file

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace CityGame namespace CityGame.Classes.Rendering
{ {
public class ColorConversionMaps public class ColorConversionMaps
{ {
@ -34,7 +34,7 @@ namespace CityGame
{ "#616161", "#816161" }, { "#616161", "#816161" },
{ "#3b3b3b", "#5b3b3b" } { "#3b3b3b", "#5b3b3b" }
}; };
public static Dictionary<string, string> HouseToBuildingGreenMap = new Dictionary<string, string> public static Dictionary<string, string> HouseToBuildingGreenMap = new Dictionary<string, string>
{ {
{ "#616161", "#618161" }, { "#616161", "#618161" },
{ "#3b3b3b", "#3b5b3b" } { "#3b3b3b", "#3b5b3b" }
@ -61,5 +61,17 @@ namespace CityGame
{ "#00000000", "#00b36b00" }, { "#00000000", "#00b36b00" },
{ "#616161", "#303030" } { "#616161", "#303030" }
}; };
public static Dictionary<string, string> CarToNPCCar = new Dictionary<string, string>()
{
{ "#ff0000", "#888888" },
{ "#fc4141", "#fcfcfc" },
{ "#b80000", "#b8b8b8" }
};
public static Dictionary<string, string> CarToPoliceCar = new Dictionary<string, string>()
{
{ "#ff0000", "#0000ff" },
{ "#fc4141", "#4141fc" },
{ "#b80000", "#0000b8" }
};
} }
} }

View file

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
namespace CityGame namespace CityGame.Classes.Rendering
{ {
public class ImageConverter public class ImageConverter
{ {
@ -15,7 +15,7 @@ namespace CityGame
if (!File.Exists(srcFile)) return; if (!File.Exists(srcFile)) return;
Dictionary<System.Drawing.Color, System.Drawing.Color> Conversions = conversions.Select(x => new KeyValuePair<System.Drawing.Color, System.Drawing.Color>(System.Drawing.ColorTranslator.FromHtml(x.Key), System.Drawing.ColorTranslator.FromHtml(x.Value))).ToDictionary(x => x.Key, x => x.Value); Dictionary<System.Drawing.Color, System.Drawing.Color> Conversions = conversions.Select(x => new KeyValuePair<System.Drawing.Color, System.Drawing.Color>(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 x = 0; x < bmp.Width; x++)
{ {
for (int y = 0; y < bmp.Height; y++) for (int y = 0; y < bmp.Height; y++)

View file

@ -1,4 +1,4 @@
namespace CityGame namespace CityGame.Classes.Rendering
{ {
public struct IntPoint public struct IntPoint
{ {

View file

@ -1,6 +1,6 @@
using WPFGame; using WPFGame;
namespace CityGame namespace CityGame.Classes.Rendering
{ {
public class OCanvas : Canvas public class OCanvas : Canvas
{ {

View file

@ -1,7 +1,8 @@
using System; using System;
using System.Linq; using System.Linq;
using CityGame.Classes.World;
namespace CityGame namespace CityGame.Classes.Rendering
{ {
public class Pattern public class Pattern
{ {

View file

@ -1,6 +1,7 @@
using WPFGame; using CityGame.Classes.World;
using WPFGame;
namespace CityGame namespace CityGame.Classes.Rendering
{ {
public class Renderer public class Renderer
{ {
@ -19,23 +20,27 @@ namespace CityGame
public static OCanvas Render(TileType type, int x, int y, Tile[,] Grid) public static OCanvas Render(TileType type, int x, int y, Tile[,] Grid)
{ {
string tooltip = x + ":" + y; string tooltip = x + ":" + y;
if (type == TileType.Skyscraper) if (type == TileType.Skyscraper || type == TileType.Garage || type == TileType.Helipad)
{ {
string theme = ""; string theme = "";
if (Grid[x, y].BlockID % 2 == 1) theme = "Dark"; if (Grid[x, y].BlockID % 2 == 1) theme = "Dark";
if (Grid[x, y].BlockID % 30 == 1) theme = "Blue"; if (Grid[x, y].BlockID % 30 == 1) theme = "Blue";
if (Grid[x, y].BlockID % 30 == 2) theme = "Red"; if (Grid[x, y].BlockID % 30 == 2) theme = "Red";
if (Grid[x, y].BlockID % 30 == 3) theme = "Green"; if (Grid[x, y].BlockID % 30 == 3) theme = "Green";
Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Skyscraper); 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 == "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) == 0) pattern.PatternCode = "3a";
if (pattern.PatternCode == "3" && MainWindow.random.Next(0, 12) == 1) pattern.PatternCode = "3ab"; 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")); 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) canvas.Children.Add(new SourcedImage("Garage.png:" + pattern.Rotation)); 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") canvas.Children.Add(new SourcedImage("Garage.png:270")); 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))); 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; return canvas;
} }
@ -48,7 +53,7 @@ namespace CityGame
{ {
Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Park, TileType.Path); Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Park, TileType.Path);
OCanvas canvas = new SourcedImage("Park" + pattern.PatternCode + ".png:" + pattern.Rotation); 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; return canvas;
} }
if (type == TileType.Road) if (type == TileType.Road)

View file

@ -1,4 +1,6 @@
namespace CityGame using CityGame.Classes.Rendering;
namespace CityGame.Classes.World
{ {
public interface ISelectable public interface ISelectable
{ {

View file

@ -1,4 +1,7 @@
namespace CityGame using CityGame.Classes.Rendering;
using WPFGame;
namespace CityGame.Classes.World
{ {
public struct Tile : ISelectable public struct Tile : ISelectable
{ {
@ -6,6 +9,7 @@
public TileType Type; public TileType Type;
public int X; public int X;
public int Y; public int Y;
public UIElement Element;
public OCanvas GetImage() public OCanvas GetImage()
{ {
@ -26,5 +30,9 @@
{ {
return Y * MainWindow.TileSize; return Y * MainWindow.TileSize;
} }
public override string ToString()
{
return Type.ToString() + " at " + X + ";" + Y;
}
} }
} }

View file

@ -1,9 +1,10 @@
namespace CityGame namespace CityGame.Classes.World
{ {
public enum TileType public enum TileType
{ {
Skyscraper = 100, Skyscraper = 100,
House = 101, House = 101,
Helipad = 102,
Park = 220, Park = 220,
@ -14,6 +15,7 @@
Path = 421, Path = 421,
Highway = 402, Highway = 402,
Bridge = 410, Bridge = 410,
HighwayBridge = 411 HighwayBridge = 411,
Garage = 430
} }
} }

View file

@ -1,12 +1,17 @@
using AStar; using AStar;
using AStar.Options; using AStar.Options;
using CityGame.Classes.Entities;
using CityGame.Classes.Rendering;
using CityGame.Classes.World;
using Microsoft.Xna.Framework; using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Input;
using SimplexNoise; using SimplexNoise;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Speech.Synthesis;
using WPFGame; using WPFGame;
namespace CityGame namespace CityGame
@ -20,22 +25,21 @@ namespace CityGame
{ {
public ISelectable GetSelectableFromClick(MouseState click) public ISelectable GetSelectableFromClick(MouseState click)
{ {
Point point = new Point(click.X, click.Y); Vector2 point = new Vector2(click.X, click.Y);
point.X -= (int)Canvas.GetLeft(CameraCanvas);
point.Y -= (int)Canvas.GetTop(CameraCanvas); point = Vector2.Transform(point, InvCamera);
point.X = (int)(point.X / CameraCanvas.ScaleX);
point.Y = (int)(point.Y / CameraCanvas.ScaleY);
foreach (Entity entity in Entities) foreach (Entity entity in Entities)
{ {
double diff = new Vector2((int)entity.X + TileSize / 2 - point.X, (int)entity.Y + TileSize / 2 - point.Y).Length(); 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; if (diff < TileSize / 2) return entity;
} }
int x = point.X / TileSize; int x = (int)(point.X / TileSize);
int y = point.Y / TileSize; int y = (int)(point.Y / TileSize);
if (x < 0 || y < 0) return null; if (x < 0 || y < 0) return null;
if (x > Grid.GetLength(0) - 1 || y > Grid.GetLength(1) - 1) return null; if (x > Grid.GetLength(0) - 1 || y > Grid.GetLength(1) - 1) return null;
Debug.WriteLine(Grid[x, y]);
return Grid[x, y]; return Grid[x, y];
} }
public static Entity GetEntityFromImage(Image image) public static Entity GetEntityFromImage(Image image)
@ -55,7 +59,7 @@ namespace CityGame
} }
public static Random random; public static Random random;
public static bool MouseIsDown = false; 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 PathFinder pathfinder;
public static short[,] pathfindingGrid; public static short[,] pathfindingGrid;
public static short[,] pathfindingGridDesperate; public static short[,] pathfindingGridDesperate;
@ -68,7 +72,7 @@ namespace CityGame
Canvas MainCanvas = new OCanvas(); Canvas MainCanvas = new OCanvas();
Canvas BGCanvas = new OCanvas(); Canvas BGCanvas = new OCanvas();
Canvas GameCanvas = new OCanvas(); internal static Canvas GameCanvas = new OCanvas();
Canvas CameraCanvas = new OCanvas(); Canvas CameraCanvas = new OCanvas();
Canvas UICanvas = new OCanvas(); Canvas UICanvas = new OCanvas();
public MainWindow() public MainWindow()
@ -98,6 +102,8 @@ namespace CityGame
ImageConverter.ChangeColor("ParkingLot", "ParkingLotGreen", ColorConversionMaps.HouseToBuildingGreenMap); ImageConverter.ChangeColor("ParkingLot", "ParkingLotGreen", ColorConversionMaps.HouseToBuildingGreenMap);
ImageConverter.ChangeColor("Error", "ErrorRed", new Dictionary<string, string> { { "#000000", "#ff0000" } }); ImageConverter.ChangeColor("Error", "ErrorRed", new Dictionary<string, string> { { "#000000", "#ff0000" } });
ImageConverter.ChangeColor("Car", "NPCCar", ColorConversionMaps.CarToNPCCar);
ImageConverter.ChangeColor("Car", "PoliceCar", ColorConversionMaps.CarToPoliceCar);
#endregion #endregion
int seed = 8; int seed = 8;
@ -285,24 +291,6 @@ namespace CityGame
startPoint += step; 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 #endregion
Grid = IntermediateGrid; Grid = IntermediateGrid;
@ -336,6 +324,7 @@ namespace CityGame
for (int y = 0; y < mapHeight; y++) for (int y = 0; y < mapHeight; y++)
{ {
Canvas image = Renderer.Render(Grid[x, y].Type, x, y, Grid); Canvas image = Renderer.Render(Grid[x, y].Type, x, y, Grid);
Grid[x, y].Element = image;
Canvas.SetLeft(image, x * tileSize); Canvas.SetLeft(image, x * tileSize);
Canvas.SetTop(image, y * tileSize); Canvas.SetTop(image, y * tileSize);
@ -347,6 +336,24 @@ namespace CityGame
GameCanvas.Children.Add(image); 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")) foreach (Image image in SourcedImage.GetObjectsBySourceFile("Helipad.png"))
{ {
@ -356,6 +363,14 @@ namespace CityGame
Entities.Add(new Helicopter { X = x, Y = y }); 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++) for (int n = 0; n < NPCCount; n++)
{ {
Car car = new Car(); Car car = new Car();
@ -364,12 +379,12 @@ namespace CityGame
car.Point = new Point(startTile.X, startTile.Y); car.Point = new Point(startTile.X, startTile.Y);
car.Target = new Point(targetTile.X, targetTile.Y); car.Target = targetTile;
Car.CarEvent reset = car => Car.CarEvent reset = car =>
{ {
Tile targetTile = npcWalkable[random.Next(0, npcWalkable.Count)]; Tile targetTile = npcWalkable[random.Next(0, npcWalkable.Count)];
car.Target = new Point(targetTile.X, targetTile.Y); car.Target = targetTile;
}; };
car.JourneyFinished += reset; car.JourneyFinished += reset;
@ -381,18 +396,22 @@ namespace CityGame
Show(); Show();
} }
int swv; int swv;
protected override Color SkyColor(long SpeedFactor)
{
return base.SkyColor(180);
}
protected override void Update(GameTime time) protected override void Update(GameTime time)
{ {
MouseState state = Mouse.GetState(); MouseState state = Mouse.GetState();
if (state.MiddleButton == ButtonState.Pressed) 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; var diff = newpos - MousePos;
Canvas.SetLeft(CameraCanvas, Canvas.GetLeft(CameraCanvas) + diff.X); diff /= CameraZoom;
Canvas.SetTop(CameraCanvas, Canvas.GetTop(CameraCanvas) + diff.Y); CameraPosition += diff;
} }
MousePos = new Point(state.X, state.Y); MousePos = new Vector2(state.X, state.Y);
float delta = state.ScrollWheelValue - swv; float delta = state.ScrollWheelValue - swv;
@ -406,8 +425,7 @@ namespace CityGame
if (delta != 0) if (delta != 0)
{ {
CameraCanvas.ScaleX *= multi; CameraZoom *= multi;
CameraCanvas.ScaleY *= multi;
} }
if (state.LeftButton == ButtonState.Pressed) if (state.LeftButton == ButtonState.Pressed)
@ -444,8 +462,11 @@ namespace CityGame
entity.Object.Rotation = (int)entity.Rotation; entity.Object.Rotation = (int)entity.Rotation;
Canvas.SetLeft(entity.Object, entity.X); Canvas.SetLeft(entity.Object, entity.X);
Canvas.SetTop(entity.Object, entity.Y); Canvas.SetTop(entity.Object, entity.Y);
} }
Car.OccupiedTiles = Car.OccupiedTilesFill;
Car.OccupiedTilesFill = new Dictionary<Tile, Car>();
Car.OccupiedTiles2 = Car.OccupiedTilesFill2;
Car.OccupiedTilesFill2 = new Dictionary<Tile, Car>();
} }
} }
} }