bunch of stuff
This commit is contained in:
parent
c60ebfcb55
commit
84b21df283
9 changed files with 264 additions and 150 deletions
81
CityGame/Car.cs
Normal file
81
CityGame/Car.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
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; } = 256;
|
||||||
|
public override OCanvas Render()
|
||||||
|
{
|
||||||
|
return new SourcedImage("Car.png");
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,5 +56,10 @@ namespace CityGame
|
||||||
{ "#00000000", "#00b36b00" },
|
{ "#00000000", "#00b36b00" },
|
||||||
{ "#616161", "#00b36b00" }
|
{ "#616161", "#00b36b00" }
|
||||||
};
|
};
|
||||||
|
public static Dictionary<string, string> RoadToHighwayMap = new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{ "#00000000", "#00b36b00" },
|
||||||
|
{ "#616161", "#303030" }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
13
CityGame/Entity.cs
Normal file
13
CityGame/Entity.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
namespace CityGame
|
||||||
|
{
|
||||||
|
public abstract class Entity
|
||||||
|
{
|
||||||
|
public float X { get; set; }
|
||||||
|
public float Y { get; set; }
|
||||||
|
public float Rotation { get; set; }
|
||||||
|
public long Time { get; set; }
|
||||||
|
public OCanvas Object { get; set; }
|
||||||
|
public abstract OCanvas Render();
|
||||||
|
public abstract void Tick(long deltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
25
CityGame/Extensions.cs
Normal file
25
CityGame/Extensions.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace CityGame
|
||||||
|
{
|
||||||
|
public static class Extensions
|
||||||
|
{
|
||||||
|
public static System.Drawing.Point Convert(this Point point)
|
||||||
|
{
|
||||||
|
return new System.Drawing.Point((int)point.X, (int)point.Y);
|
||||||
|
}
|
||||||
|
public static Point Convert(this System.Drawing.Point point)
|
||||||
|
{
|
||||||
|
return new Point(point.X, point.Y);
|
||||||
|
}
|
||||||
|
public static bool CloselyEquals(this double A, double B)
|
||||||
|
{
|
||||||
|
return Math.Round(A) == Math.Round(B);
|
||||||
|
}
|
||||||
|
public static bool CloselyEquals(this float A, double B)
|
||||||
|
{
|
||||||
|
return Math.Round(A) == Math.Round(B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
CityGame/IntPoint.cs
Normal file
25
CityGame/IntPoint.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
namespace CityGame
|
||||||
|
{
|
||||||
|
public struct IntPoint
|
||||||
|
{
|
||||||
|
public int X { get; set; }
|
||||||
|
public int Y { get; set; }
|
||||||
|
public IntPoint(int x, int y)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
}
|
||||||
|
public static IntPoint operator +(IntPoint a, IntPoint b)
|
||||||
|
{
|
||||||
|
return new IntPoint(a.X + b.X, a.Y + b.Y);
|
||||||
|
}
|
||||||
|
public static bool operator !=(IntPoint a, IntPoint b)
|
||||||
|
{
|
||||||
|
return a.X != b.X || a.Y != b.Y;
|
||||||
|
}
|
||||||
|
public static bool operator ==(IntPoint a, IntPoint b)
|
||||||
|
{
|
||||||
|
return a.X == b.X && a.Y == b.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,7 +6,6 @@ using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.WebSockets;
|
using System.Net.WebSockets;
|
||||||
using System.Numerics;
|
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -23,101 +22,6 @@ using System.Windows.Threading;
|
||||||
|
|
||||||
namespace CityGame
|
namespace CityGame
|
||||||
{
|
{
|
||||||
public abstract class Entity
|
|
||||||
{
|
|
||||||
public float X { get; set; }
|
|
||||||
public float Y { get; set; }
|
|
||||||
public float Rotation { get; set; }
|
|
||||||
public long Time { get; set; }
|
|
||||||
public OCanvas Object { get; set; }
|
|
||||||
public abstract OCanvas Render();
|
|
||||||
public abstract void Tick(long deltaTime);
|
|
||||||
}
|
|
||||||
public static class Extensions
|
|
||||||
{
|
|
||||||
public static System.Drawing.Point Convert(this Point point)
|
|
||||||
{
|
|
||||||
return new System.Drawing.Point((int)point.X, (int)point.Y);
|
|
||||||
}
|
|
||||||
public static Point Convert(this System.Drawing.Point point)
|
|
||||||
{
|
|
||||||
return new Point(point.X, point.Y);
|
|
||||||
}
|
|
||||||
public static bool CloselyEquals(this double A, double B)
|
|
||||||
{
|
|
||||||
return Math.Round(A) == Math.Round(B);
|
|
||||||
}
|
|
||||||
public static bool CloselyEquals(this float A, double B)
|
|
||||||
{
|
|
||||||
return Math.Round(A) == Math.Round(B);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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; } = 256;
|
|
||||||
public override OCanvas Render()
|
|
||||||
{
|
|
||||||
return new SourcedImage("Car.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Tick(long deltaTime)
|
|
||||||
{
|
|
||||||
if(Target is not null)
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for MainWindow.xaml
|
/// Interaction logic for MainWindow.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -128,6 +32,7 @@ namespace CityGame
|
||||||
public static Point MousePos = new Point(0, 0);
|
public static Point MousePos = new Point(0, 0);
|
||||||
public static PathFinder pathfinder;
|
public static PathFinder pathfinder;
|
||||||
public static short[,] pathfindingGrid;
|
public static short[,] pathfindingGrid;
|
||||||
|
public static short[,] pathfindingGridDesperate;
|
||||||
public static List<Tile> npcWalkable = new List<Tile>();
|
public static List<Tile> npcWalkable = new List<Tile>();
|
||||||
public static List<Entity> Entities { get; set; } = new List<Entity>();
|
public static List<Entity> Entities { get; set; } = new List<Entity>();
|
||||||
public const int TileSize = 64;
|
public const int TileSize = 64;
|
||||||
|
|
@ -147,6 +52,8 @@ namespace CityGame
|
||||||
ImageConverter.ChangeColor("Building" + code, "Park" + code, ColorConversionMaps.HouseToParkMap);
|
ImageConverter.ChangeColor("Building" + code, "Park" + code, ColorConversionMaps.HouseToParkMap);
|
||||||
ImageConverter.ChangeColor("Road" + code, "Path" + code, ColorConversionMaps.RoadToPathMap);
|
ImageConverter.ChangeColor("Road" + code, "Path" + code, ColorConversionMaps.RoadToPathMap);
|
||||||
ImageConverter.ChangeColor("Road" + code, "Bridge" + code, ColorConversionMaps.RoadToBridgeMap);
|
ImageConverter.ChangeColor("Road" + code, "Bridge" + code, ColorConversionMaps.RoadToBridgeMap);
|
||||||
|
ImageConverter.ChangeColor("Road" + code, "Highway" + code, ColorConversionMaps.RoadToHighwayMap);
|
||||||
|
ImageConverter.ChangeColor("Road" + code, "HighwayBridge" + code, ColorConversionMaps.RoadToHighwayMap);
|
||||||
}
|
}
|
||||||
ImageConverter.ChangeColor("ParkingLot", "ParkingLotDark", ColorConversionMaps.HouseToBuildingDarkMap);
|
ImageConverter.ChangeColor("ParkingLot", "ParkingLotDark", ColorConversionMaps.HouseToBuildingDarkMap);
|
||||||
ImageConverter.ChangeColor("ParkingLot", "ParkingLotBlue", ColorConversionMaps.HouseToBuildingBlueMap);
|
ImageConverter.ChangeColor("ParkingLot", "ParkingLotBlue", ColorConversionMaps.HouseToBuildingBlueMap);
|
||||||
|
|
@ -160,7 +67,7 @@ namespace CityGame
|
||||||
|
|
||||||
#region | Map Generation |
|
#region | Map Generation |
|
||||||
#region | Map Generation Constants |
|
#region | Map Generation Constants |
|
||||||
int seed = 1;
|
int seed = 3;
|
||||||
|
|
||||||
Noise.Seed = seed;
|
Noise.Seed = seed;
|
||||||
|
|
||||||
|
|
@ -186,7 +93,7 @@ namespace CityGame
|
||||||
int minBlockHeight = 3;
|
int minBlockHeight = 3;
|
||||||
int minBlockWidth = 3;
|
int minBlockWidth = 3;
|
||||||
|
|
||||||
int NPCCount = 100;
|
int NPCCount = 1;
|
||||||
|
|
||||||
random = new Random(seed);
|
random = new Random(seed);
|
||||||
|
|
||||||
|
|
@ -236,7 +143,7 @@ namespace CityGame
|
||||||
if (lakeMap[x2, y2] > 214) InitialGrid[x2, y2].Type = TileType.Park;
|
if (lakeMap[x2, y2] > 214) InitialGrid[x2, y2].Type = TileType.Park;
|
||||||
if (lakeMap[x2, y2] > 219) InitialGrid[x2, y2].Type = TileType.Lake;
|
if (lakeMap[x2, y2] > 219) InitialGrid[x2, y2].Type = TileType.Lake;
|
||||||
if (parkMap[x2, y2] > 214 && parkMap[x2, y2] > lakeMap[x2, y2]) InitialGrid[x2, y2].Type = TileType.Park;
|
if (parkMap[x2, y2] > 214 && parkMap[x2, y2] > lakeMap[x2, y2]) InitialGrid[x2, y2].Type = TileType.Park;
|
||||||
if (riverMap[x2, y2] > 128 && riverMap[x2,y2] < 148) InitialGrid[x2, y2].Type = TileType.River;
|
if (riverMap[x2, y2] > 128 && riverMap[x2, y2] < 148) InitialGrid[x2, y2].Type = TileType.River;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -277,6 +184,7 @@ namespace CityGame
|
||||||
#region | Roads and Bridges |
|
#region | Roads and Bridges |
|
||||||
Dictionary<int, bool> decidedBridges = new Dictionary<int, bool>();
|
Dictionary<int, bool> decidedBridges = new Dictionary<int, bool>();
|
||||||
pathfindingGrid = new short[doubleWidth, doubleHeight];
|
pathfindingGrid = new short[doubleWidth, doubleHeight];
|
||||||
|
pathfindingGridDesperate = new short[doubleWidth, doubleHeight];
|
||||||
List<Tile> bridgeTiles = new List<Tile>();
|
List<Tile> bridgeTiles = new List<Tile>();
|
||||||
List<Tile> roadTiles = new List<Tile>();
|
List<Tile> roadTiles = new List<Tile>();
|
||||||
for (int y = 0; y < doubleHeight; y++)
|
for (int y = 0; y < doubleHeight; y++)
|
||||||
|
|
@ -303,11 +211,6 @@ namespace CityGame
|
||||||
if (IntermediateGrid[x, y].Type == TileType.Park) changeTo = TileType.Path;
|
if (IntermediateGrid[x, y].Type == TileType.Park) changeTo = TileType.Path;
|
||||||
if (x < doubleWidth - 1 && IntermediateGrid[x + 1, y].BlockID != myID) IntermediateGrid[x, y].Type = changeTo;
|
if (x < doubleWidth - 1 && IntermediateGrid[x + 1, y].BlockID != myID) IntermediateGrid[x, y].Type = changeTo;
|
||||||
if (y < doubleHeight - 1 && IntermediateGrid[x, y + 1].BlockID != myID) IntermediateGrid[x, y].Type = changeTo;
|
if (y < doubleHeight - 1 && IntermediateGrid[x, y + 1].BlockID != myID) IntermediateGrid[x, y].Type = changeTo;
|
||||||
bool walkable = ((int)IntermediateGrid[x, y].Type) / 100 == 4;
|
|
||||||
pathfindingGrid[y, x] = (short)(walkable ? 1 : 0);
|
|
||||||
if (IntermediateGrid[x, y].Type == TileType.Bridge) bridgeTiles.Add(IntermediateGrid[x, y]);
|
|
||||||
if (IntermediateGrid[x, y].Type == TileType.Road) roadTiles.Add(IntermediateGrid[x, y]);
|
|
||||||
if (IntermediateGrid[x, y].Type == TileType.Road || IntermediateGrid[x, y].Type == TileType.Bridge) npcWalkable.Add(IntermediateGrid[x, y]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -315,26 +218,65 @@ namespace CityGame
|
||||||
|
|
||||||
#region | Pathfinding |
|
#region | Pathfinding |
|
||||||
|
|
||||||
var worldGrid = new WorldGrid(pathfindingGrid);
|
int mainRoadCount = random.Next(1, 5);
|
||||||
pathfinder = new PathFinder(worldGrid, new PathFinderOptions { PunishChangeDirection = true, UseDiagonals = false, SearchLimit = int.MaxValue, HeuristicFormula = AStar.Heuristics.HeuristicFormula.Euclidean });
|
for (int m = 0; m < mainRoadCount; m++)
|
||||||
|
|
||||||
//foreach(var tile in bridgeTiles)
|
|
||||||
//{
|
|
||||||
// List<Tile> sortedRoads = roadTiles.OrderBy(x => Math.Abs(x.X - tile.X) + Math.Abs(x.Y - tile.Y)).ToList();
|
|
||||||
// if(!sortedRoads.Any(x => pathfinder.FindPath(new System.Drawing.Point(x.X, x.Y), new System.Drawing.Point(tile.X, tile.Y)).Length > 0))
|
|
||||||
// {
|
|
||||||
// IntermediateGrid[tile.X, tile.Y].Type = TileType.House;
|
|
||||||
// }
|
|
||||||
// i++;
|
|
||||||
//}
|
|
||||||
|
|
||||||
int mainRoadCount = random.Next(1, 2);
|
|
||||||
for(int m = 0; m < mainRoadCount; m++)
|
|
||||||
{
|
{
|
||||||
int variant = random.Next(0, 2);
|
int variant = random.Next(0, 2);
|
||||||
Point startPoint = new Point(0, 0);
|
IntPoint startPoint = new IntPoint(0, 0);
|
||||||
Point endPoint = new Point(0, 0);
|
IntPoint endPoint = new IntPoint(0, 0);
|
||||||
|
IntPoint step = new IntPoint(0, 0);
|
||||||
|
if (variant == 0)
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
int y = random.Next(0, doubleHeight);
|
||||||
|
startPoint = new IntPoint(x, y);
|
||||||
|
endPoint = new IntPoint(doubleWidth, y);
|
||||||
|
step = new IntPoint(1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int x = random.Next(0, doubleWidth);
|
||||||
|
int y = 0;
|
||||||
|
startPoint = new IntPoint(x, y);
|
||||||
|
endPoint = new IntPoint(x, doubleHeight);
|
||||||
|
step = new IntPoint(0, 1);
|
||||||
|
}
|
||||||
|
while(startPoint != endPoint)
|
||||||
|
{
|
||||||
|
int x = (int)startPoint.X;
|
||||||
|
int y = (int)startPoint.Y;
|
||||||
|
var tile = IntermediateGrid[x, y];
|
||||||
|
IntermediateGrid[x, y].Type = tile.Type == TileType.Lake || tile.Type == TileType.River ? TileType.HighwayBridge : TileType.Highway;
|
||||||
|
var topRoad = IntermediateGrid[x - step.Y, y - step.X];
|
||||||
|
var checkTopRoad = IntermediateGrid[x - step.Y * 2, y - step.X * 2];
|
||||||
|
var bottomRoad = IntermediateGrid[x + step.Y, y + step.X];
|
||||||
|
var checkBottomRoad = IntermediateGrid[x + step.Y * 2, y + step.X * 2];
|
||||||
|
|
||||||
|
if (((int)topRoad.Type) / 100 == 4 && ((int)checkTopRoad.Type) / 100 != 4) IntermediateGrid[x - step.Y, y - step.X].Type = topRoad.Type == TileType.Road ? TileType.Skyscraper : topRoad.Type == TileType.Path ? TileType.Park : TileType.Lake;
|
||||||
|
if (((int)bottomRoad.Type) / 100 == 4 && ((int)checkBottomRoad.Type) / 100 != 4) IntermediateGrid[x + step.Y, y + step.X].Type = TileType.Skyscraper;
|
||||||
|
|
||||||
|
if (((int)topRoad.Type) % 100 / 10 == 1 && ((int)bottomRoad.Type) % 100 / 10 == 1) IntermediateGrid[x, y].Type = TileType.HighwayBridge;
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
@ -445,17 +387,17 @@ namespace CityGame
|
||||||
|
|
||||||
#region | Entities |
|
#region | Entities |
|
||||||
|
|
||||||
DispatcherTimer EntityLoop = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1 / 20) };
|
DispatcherTimer EntityLoop = new DispatcherTimer { Interval = TimeSpan.FromSeconds(1 / 10) };
|
||||||
EntityLoop.Tick += (a, b) =>
|
EntityLoop.Tick += (a, b) =>
|
||||||
{
|
{
|
||||||
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
long milliseconds = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||||
foreach(Entity entity in Entities)
|
foreach (Entity entity in Entities)
|
||||||
{
|
{
|
||||||
long delta = milliseconds - entity.Time;
|
long delta = milliseconds - entity.Time;
|
||||||
entity.Time = milliseconds;
|
entity.Time = milliseconds;
|
||||||
entity.Tick(delta);
|
entity.Tick(delta);
|
||||||
|
|
||||||
if(entity.Object is null)
|
if (entity.Object is null)
|
||||||
{
|
{
|
||||||
entity.Object = entity.Render();
|
entity.Object = entity.Render();
|
||||||
RenderOptions.SetBitmapScalingMode(entity.Object, BitmapScalingMode.NearestNeighbor);
|
RenderOptions.SetBitmapScalingMode(entity.Object, BitmapScalingMode.NearestNeighbor);
|
||||||
|
|
@ -475,7 +417,7 @@ namespace CityGame
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
for(int n = 0; n < NPCCount; n++)
|
for (int n = 0; n < NPCCount; n++)
|
||||||
{
|
{
|
||||||
Car car = new Car();
|
Car car = new Car();
|
||||||
Tile startTile = npcWalkable[random.Next(0, npcWalkable.Count)];
|
Tile startTile = npcWalkable[random.Next(0, npcWalkable.Count)];
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ 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;
|
||||||
if (type == TileType.Skyscraper)
|
if (type == TileType.Skyscraper)
|
||||||
{
|
{
|
||||||
string theme = "";
|
string theme = "";
|
||||||
|
|
@ -29,7 +30,7 @@ namespace CityGame
|
||||||
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);
|
OCanvas canvas = new SourcedImage("Building"+ theme + pattern.PatternCode + ".png:" + pattern.Rotation, tooltip);
|
||||||
|
|
||||||
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 (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)));
|
||||||
|
|
||||||
|
|
@ -37,30 +38,37 @@ namespace CityGame
|
||||||
}
|
}
|
||||||
if (type == TileType.Lake || type == TileType.River)
|
if (type == TileType.Lake || type == TileType.River)
|
||||||
{
|
{
|
||||||
Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Lake, TileType.Bridge, TileType.River);
|
Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Lake, TileType.Bridge, TileType.River, TileType.HighwayBridge);
|
||||||
return new SourcedImage("Lake" + pattern.PatternCode + ".png:" + pattern.Rotation);
|
return new SourcedImage("Lake" + pattern.PatternCode + ".png:" + pattern.Rotation, tooltip);
|
||||||
}
|
}
|
||||||
if (type == TileType.Park)
|
if (type == TileType.Park)
|
||||||
{
|
{
|
||||||
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));
|
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)
|
||||||
{
|
{
|
||||||
Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Path, TileType.Bridge);
|
Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Path, TileType.Bridge, TileType.Highway, TileType.HighwayBridge);
|
||||||
if (pattern.PatternCode == "2c") pattern.Rotation += 270;
|
if (pattern.PatternCode == "2c") pattern.Rotation += 270;
|
||||||
if (pattern.PatternCode == "1") pattern.Rotation += 180;
|
if (pattern.PatternCode == "1") pattern.Rotation += 180;
|
||||||
return new SourcedImage("Road" + pattern.PatternCode + ".png:" + pattern.Rotation);
|
return new SourcedImage("Road" + pattern.PatternCode + ".png:" + pattern.Rotation, tooltip);
|
||||||
|
}
|
||||||
|
if (type == TileType.Highway)
|
||||||
|
{
|
||||||
|
Pattern pattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Path, TileType.Bridge, TileType.Highway, TileType.HighwayBridge);
|
||||||
|
if (pattern.PatternCode == "2c") pattern.Rotation += 270;
|
||||||
|
if (pattern.PatternCode == "1") pattern.Rotation += 180;
|
||||||
|
return new SourcedImage("Highway" + pattern.PatternCode + ".png:" + pattern.Rotation, tooltip);
|
||||||
}
|
}
|
||||||
if (type == TileType.Path)
|
if (type == TileType.Path)
|
||||||
{
|
{
|
||||||
Pattern roadpattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Path, TileType.Bridge);
|
Pattern roadpattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Path, TileType.Bridge, TileType.Highway, TileType.HighwayBridge);
|
||||||
Pattern parkpattern = Pattern.Calculate(Grid, x, y, TileType.Path, TileType.Park);
|
Pattern parkpattern = Pattern.Calculate(Grid, x, y, TileType.Path, TileType.Park);
|
||||||
if (roadpattern.PatternCode == "2c") roadpattern.Rotation += 270;
|
if (roadpattern.PatternCode == "2c") roadpattern.Rotation += 270;
|
||||||
if (roadpattern.PatternCode == "1") roadpattern.Rotation += 180;
|
if (roadpattern.PatternCode == "1") roadpattern.Rotation += 180;
|
||||||
Image path = new SourcedImage("Path" + roadpattern.PatternCode + ".png:" + roadpattern.Rotation);
|
Image path = new SourcedImage("Path" + roadpattern.PatternCode + ".png:" + roadpattern.Rotation, tooltip);
|
||||||
Image park = new SourcedImage("Park" + parkpattern.PatternCode + ".png:" + parkpattern.Rotation);
|
Image park = new SourcedImage("Park" + parkpattern.PatternCode + ".png:" + parkpattern.Rotation);
|
||||||
|
|
||||||
OCanvas result = new OCanvas();
|
OCanvas result = new OCanvas();
|
||||||
|
|
@ -70,11 +78,11 @@ namespace CityGame
|
||||||
}
|
}
|
||||||
if (type == TileType.Bridge)
|
if (type == TileType.Bridge)
|
||||||
{
|
{
|
||||||
Pattern roadpattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Bridge, TileType.Path);
|
Pattern roadpattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Bridge, TileType.Path, TileType.Highway, TileType.HighwayBridge);
|
||||||
Pattern parkpattern = Pattern.Calculate(Grid, x, y, TileType.Bridge, TileType.Lake, TileType.River);
|
Pattern parkpattern = Pattern.Calculate(Grid, x, y, TileType.Bridge, TileType.Lake, TileType.River, TileType.HighwayBridge);
|
||||||
if (roadpattern.PatternCode == "2c") roadpattern.Rotation += 270;
|
if (roadpattern.PatternCode == "2c") roadpattern.Rotation += 270;
|
||||||
if (roadpattern.PatternCode == "1") roadpattern.Rotation += 180;
|
if (roadpattern.PatternCode == "1") roadpattern.Rotation += 180;
|
||||||
Image path = new SourcedImage("Bridge" + roadpattern.PatternCode + ".png:" + roadpattern.Rotation);
|
Image path = new SourcedImage("Bridge" + roadpattern.PatternCode + ".png:" + roadpattern.Rotation, tooltip);
|
||||||
Image park = new SourcedImage("Lake" + parkpattern.PatternCode + ".png:" + parkpattern.Rotation);
|
Image park = new SourcedImage("Lake" + parkpattern.PatternCode + ".png:" + parkpattern.Rotation);
|
||||||
|
|
||||||
OCanvas result = new OCanvas();
|
OCanvas result = new OCanvas();
|
||||||
|
|
@ -82,7 +90,21 @@ namespace CityGame
|
||||||
result.Children.Add(path);
|
result.Children.Add(path);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return new SourcedImage("Error.png");
|
if (type == TileType.HighwayBridge)
|
||||||
|
{
|
||||||
|
Pattern roadpattern = Pattern.Calculate(Grid, x, y, TileType.Road, TileType.Bridge, TileType.Path, TileType.Highway, TileType.HighwayBridge);
|
||||||
|
Pattern parkpattern = Pattern.Calculate(Grid, x, y, TileType.Bridge, TileType.Lake, TileType.River, TileType.HighwayBridge);
|
||||||
|
if (roadpattern.PatternCode == "2c") roadpattern.Rotation += 270;
|
||||||
|
if (roadpattern.PatternCode == "1") roadpattern.Rotation += 180;
|
||||||
|
Image path = new SourcedImage("HighwayBridge" + roadpattern.PatternCode + ".png:" + roadpattern.Rotation, tooltip);
|
||||||
|
Image park = new SourcedImage("Lake" + parkpattern.PatternCode + ".png:" + parkpattern.Rotation);
|
||||||
|
|
||||||
|
OCanvas result = new OCanvas();
|
||||||
|
result.Children.Add(park);
|
||||||
|
result.Children.Add(path);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return new SourcedImage("Error.png", tooltip);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12,15 +12,17 @@ namespace CityGame
|
||||||
{
|
{
|
||||||
public class SourcedImage : Image
|
public class SourcedImage : Image
|
||||||
{
|
{
|
||||||
public Dictionary<string, List<string>> Alternatives = new Dictionary<string, List<string>>()
|
public Dictionary<string, string> Alternatives = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
{"Path3.png", "Path3c.png" }
|
||||||
};
|
};
|
||||||
|
|
||||||
public static Dictionary<string, BitmapSource> loadedSources = new Dictionary<string, BitmapSource>();
|
public static Dictionary<string, BitmapSource> loadedSources = new Dictionary<string, BitmapSource>();
|
||||||
|
|
||||||
public SourcedImage(string source)
|
public SourcedImage(string source, string tooltip = "")
|
||||||
{
|
{
|
||||||
Source = SourceToImage(source);
|
Source = SourceToImage(source);
|
||||||
|
ToolTip = source + "\n" + tooltip;
|
||||||
Height = 64;
|
Height = 64;
|
||||||
Width = 64;
|
Width = 64;
|
||||||
|
|
||||||
|
|
@ -43,12 +45,9 @@ namespace CityGame
|
||||||
uri = string.Join(":", src.Split(':').Take(src.Split(':').Count() - 1).ToArray());
|
uri = string.Join(":", src.Split(':').Take(src.Split(':').Count() - 1).ToArray());
|
||||||
}
|
}
|
||||||
string last = "";
|
string last = "";
|
||||||
while (Alternatives.ContainsKey(uri) && uri != last)
|
if(Alternatives.ContainsKey(uri))
|
||||||
{
|
{
|
||||||
last = uri;
|
uri = Alternatives[uri];
|
||||||
List<string> alts = Alternatives[uri];
|
|
||||||
alts.Add(uri);
|
|
||||||
uri = alts[MainWindow.random.Next(0, alts.Count)];
|
|
||||||
}
|
}
|
||||||
uri = Environment.CurrentDirectory + "\\Resources\\" + uri;
|
uri = Environment.CurrentDirectory + "\\Resources\\" + uri;
|
||||||
if (loadedSources.ContainsKey(src))
|
if (loadedSources.ContainsKey(src))
|
||||||
|
|
@ -57,7 +56,7 @@ namespace CityGame
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!File.Exists(uri))
|
if (!File.Exists(uri))
|
||||||
{
|
{
|
||||||
uri = Environment.CurrentDirectory + "\\Resources\\ErrorRed.png";
|
uri = Environment.CurrentDirectory + "\\Resources\\ErrorRed.png";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,15 @@
|
||||||
Skyscraper = 100,
|
Skyscraper = 100,
|
||||||
House = 101,
|
House = 101,
|
||||||
|
|
||||||
Park = 200,
|
Park = 220,
|
||||||
|
|
||||||
Lake = 300,
|
Lake = 310,
|
||||||
River = 301,
|
River = 311,
|
||||||
|
|
||||||
Road = 400,
|
Road = 400,
|
||||||
Path = 401,
|
Path = 421,
|
||||||
Bridge = 410
|
Highway = 402,
|
||||||
|
Bridge = 410,
|
||||||
|
HighwayBridge = 411
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue