Skip to content

Commit

Permalink
Enemies and horror!
Browse files Browse the repository at this point in the history
- Split off WallSide into Renderable
- Based Enemy off of Renderable
- Level has the enemies array, which is loads in from a second layer in Tiled
- Enemies walk around just randomly
  • Loading branch information
TechnicJelle committed Jan 27, 2022
1 parent c5b729e commit 5f6ee8c
Show file tree
Hide file tree
Showing 13 changed files with 321 additions and 108 deletions.
3 changes: 3 additions & 0 deletions DoomGame.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Renderable/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Renderables/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
2 changes: 2 additions & 0 deletions DoomGame/DoomGame.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="GXPEngine\UVOffsetSprite.cs" />
<Compile Include="MyGame\Enemy.cs" />
<Compile Include="MyGame\Level.cs" />
<Compile Include="MyGame\Minimap.cs" />
<Compile Include="MyGame\MyGame.cs" />
Expand Down Expand Up @@ -82,6 +83,7 @@
<Compile Include="GXPEngine\SoLoud\Soloud.cs" />
<Compile Include="GXPEngine\SoLoud\SoloudSoundSystem.cs" />
<Compile Include="MyGame\Player.cs" />
<Compile Include="MyGame\Renderable.cs" />
<Compile Include="MyGame\Tile.cs" />
<Compile Include="MyGame\TileWall.cs" />
<Compile Include="MyGame\WallSide.cs" />
Expand Down
42 changes: 42 additions & 0 deletions DoomGame/MyGame/Enemy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using GXPEngine.Core;

namespace GXPEngine.MyGame
{
public class Enemy : Renderable
{
public Vector2 enemyPosition => position;
public Vector2 edge1 => p1;
public Vector2 edge2 => p2;

private Sprite minimapTexture { get; }

private const float MOVE_STEP = 0.01f;

public Enemy(string filename, float x, float y) : base(filename)
{
position = new Vector2(x, y);
minimapTexture = new Sprite(filename, true, false);
}

public void Move()
{
float xMove = Utils.Random(-MOVE_STEP, MOVE_STEP) * Time.deltaTime;
float yMove = Utils.Random(-MOVE_STEP, MOVE_STEP) * Time.deltaTime;

if (MyGame.level.GetTileAtPosition(Mathf.Floor(position.x + xMove), Mathf.Floor(position.y + yMove)).GetType()
== typeof(TileWall)) return;
position.x += xMove;
position.y += yMove;
}

public override void RefreshVisuals()
{
normal = Player.heading.Copy().Mult(-1.0f);

Minimap.DrawEnemy(minimapTexture, position);

CalculatePointsInWorldSpace();
base.RefreshVisuals();
}
}
}
87 changes: 79 additions & 8 deletions DoomGame/MyGame/Level.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ namespace GXPEngine.MyGame
{
public class Level
{
private const float RENDER_DISTANCE = 32.0f;
private const float RENDER_DISTANCE = 4.0f;

private Tile[,] tiles;
public int tilesColumns { get; private set; }
public int tilesRows { get; private set; }
private Enemy[] enemies;

public Level(int w, int h, string mapContent)
{
Expand Down Expand Up @@ -42,27 +43,47 @@ public Level(string tiledFile)
public void LoadTiledFile(string tiledFile)
{
Map levelData = MapParser.ReadMap(tiledFile);
if (levelData.Layers == null || levelData.Layers.Length <= 0)
if (levelData.Layers == null || levelData.Layers.Length < 1)
throw new Exception("Tile file " + tiledFile + " does not contain a layer!");
Layer mainLayer = levelData.Layers[0];
tilesColumns = mainLayer.Width;
tilesRows = mainLayer.Height;
Layer tileLayer = levelData.Layers[0];

short[,] tileNumbers = mainLayer.GetTileArray();
tilesColumns = tileLayer.Width;
tilesRows = tileLayer.Height;

short[,] enemyArray = new short[tilesColumns, tilesRows];
if (levelData.Layers.Length >= 2)
{
Layer enemyLayer = levelData.Layers[1];
Console.WriteLine("Enemies:");
enemyArray = enemyLayer.GetTileArray();
for (int row = 0; row < tilesRows; row++)
{
for (int col = 0; col < tilesColumns; col++)
{
Console.Write(enemyArray[col, row]);
}

Console.WriteLine("");
}
}

Console.WriteLine("Tiles:");
short[,] tileArray = tileLayer.GetTileArray();
for (int row = 0; row < tilesRows; row++)
{
for (int col = 0; col < tilesColumns; col++)
{
Console.Write(tileNumbers[col, row]);
Console.Write(tileArray[col, row]);
}
Console.WriteLine("");
}

tiles = new Tile[tilesColumns, tilesRows];
List<Enemy> tempEnemies = new List<Enemy>();
for (int row = 0; row < tilesRows; row++)
for (int col = 0; col < tilesColumns; col++)
{
switch (tileNumbers[col, row])
switch (tileArray[col, row])
{
case 0:
tiles[col, row] = new Tile();
Expand All @@ -82,10 +103,60 @@ public void LoadTiledFile(string tiledFile)
case 5:
tiles[col, row] = new TileWall(col, row, "noise.png");
break;
default:
throw new Exception("Found unexpected items in tileArray: " + tileArray[col, row]);
}

switch (enemyArray[col, row])
{
case 0:
break;
case 7:
tempEnemies.Add(new Enemy("circle.png", col + 0.5f, row + 0.5f));
break;
case 8:
tempEnemies.Add(new Enemy("triangle.png", col + 0.5f, row + 0.5f));
break;
default:
throw new Exception("Found unexpected items in enemyArray: " + enemyArray[col, row]);
}
}

enemies = tempEnemies.ToArray();
}

public void MoveEnemies()
{
foreach (Enemy enemy in enemies)
{
enemy.Move();
}
}

public IEnumerable<Enemy> FindVisibleEnemies()
{
foreach (Enemy enemy in enemies)
{
enemy.SetVisibility(false);
if (!(CanPlayerSee(enemy.enemyPosition) || CanPlayerSee(enemy.edge1) || CanPlayerSee(enemy.edge2))) continue;
enemy.SetVisibility(true);
yield return enemy;
}
}

private static bool CanPlayerSee(Vector2 target)
{
Vector2 toTarget = Vector2.Sub(target, Player.position);
float angleBetween = Vector2.AngleBetween(Player.heading, toTarget);

if (angleBetween > MyGame.FIELD_OF_VIEW / 1.5f) //TODO: Find better value for this
return false; //Skip all enemies that are outside of the FOV + an extra margin

(TileWall _, Vector2 _, float dist) = TileWall.DDA(Player.position, toTarget.Copy().Normalize(),
Mathf.Min(toTarget.Mag(), RENDER_DISTANCE));
return toTarget.MagSq() < dist*dist;
}

public List<TileWall> FindOnscreenTileWalls()
{
//Reset all visible tiles
Expand Down
48 changes: 36 additions & 12 deletions DoomGame/MyGame/Minimap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ public static class Minimap
{
private static float originX;
private static float originY;
private static EasyDraw layerPlayer;
private static EasyDraw layerLevel;
private static EasyDraw layerPlayer;
private static EasyDraw layerEnemies;
private static EasyDraw layerDebug;

private static float w;
Expand All @@ -31,6 +32,13 @@ public static void Setup(int x, int y, int width, int height)
};
Game.main.AddChild(layerPlayer);

layerEnemies = new EasyDraw(width, height, false)
{
x = originX,
y = originY,
};
Game.main.AddChild(layerEnemies);

if (MyGame.DEBUG_MODE)
{
layerDebug = new EasyDraw(width, height, false)
Expand All @@ -50,32 +58,36 @@ public static void Setup(int x, int y, int width, int height)

public static void UpdateLevel()
{
//layer level
layerLevel.ClearTransparent();
layerLevel.Stroke(0);
layerLevel.StrokeWeight(1);
layerLevel.ShapeAlign(CenterMode.Min, CenterMode.Min);
for (int col = 0; col < MyGame.level.tilesColumns; col++)
for (int row = 0; row < MyGame.level.tilesRows; row++)
{
Tile t = MyGame.level.GetTileAtPosition(col, row);
if (t.GetType() != typeof(TileWall)) continue;
TileWall tw = (TileWall) t;
tw.minimapTexture.x = col * w + w / 2.0f;
tw.minimapTexture.y = row * h + h / 2.0f;
tw.minimapTexture.scaleX = w / tw.minimapTexture.width;
tw.minimapTexture.scaleY = h / tw.minimapTexture.height;
layerLevel.DrawSprite(tw.minimapTexture);
DrawSprite(layerLevel, tw.minimapTexture, col + 0.5f, row + 0.5f);
}
}

private static void DrawSprite(Canvas layer, Sprite sprite, float x, float y)
{
sprite.x = x * w;
sprite.y = y * h;
float tempSpriteScaleX = sprite.scaleX;
float tempSpriteScaleY = sprite.scaleY;
sprite.scaleX = w / sprite.width;
sprite.scaleY = h / sprite.height;
layer.DrawSprite(sprite);
sprite.scaleX = tempSpriteScaleX;
sprite.scaleY = tempSpriteScaleY;
}

public static void UpdatePlayer()
{
//layer player
layerPlayer.ClearTransparent();

layerPlayer.NoStroke();
layerPlayer.Fill(255, 0, 0);
//draw point on position and cone in player direction
layerPlayer.Ellipse(
Player.position.x * w,
Player.position.y * h,
Expand All @@ -89,6 +101,16 @@ public static void UpdatePlayer()
//TODO: Player FOV cone
}

public static void ClearEnemies()
{
layerEnemies.ClearTransparent();
}

public static void DrawEnemy(Sprite sprite, Vector2 position)
{
DrawSprite(layerEnemies, sprite, position.x, position.y);
}

public static void ClearDebug()
{
layerDebug.ClearTransparent();
Expand All @@ -98,9 +120,11 @@ public static void ReOverlay()
{
Game.main.RemoveChild(layerLevel);
Game.main.RemoveChild(layerPlayer);
Game.main.RemoveChild(layerEnemies);

Game.main.AddChild(layerLevel);
Game.main.AddChild(layerPlayer);
Game.main.AddChild(layerEnemies);

if (!MyGame.DEBUG_MODE) return;
Game.main.RemoveChild(layerDebug);
Expand Down
33 changes: 22 additions & 11 deletions DoomGame/MyGame/MyGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class MyGame : Game

public const bool DEBUG_MODE = false;

private MyGame(bool pixelArt) : base(WIDTH, HEIGHT, true, pPixelArt: pixelArt)
private MyGame(bool pixelArt) : base(WIDTH, HEIGHT, false, pPixelArt: pixelArt)
{
//Player
Player player = new Player(1.5f, 1.5f, Mathf.HALF_PI);
Expand All @@ -31,13 +31,13 @@ private MyGame(bool pixelArt) : base(WIDTH, HEIGHT, true, pPixelArt: pixelArt)
if (iy < HEIGHT / 2)
{
// Ceiling
float fac = Mathf.Map(iy, 0, HEIGHT, 1.0f, 0.4f);
float fac = Mathf.Clamp(Mathf.Map(iy, 0, HEIGHT, 1.0f, -3), 0.0f, 1.0f);
background.Stroke(0, (int) (150 * fac), (int) (255 * fac));
}
else
{
//Floor
background.Stroke((int) Mathf.Map(iy, 0, HEIGHT, 0, 64));
background.Stroke((int) Mathf.Clamp(Mathf.Map(iy, 0, HEIGHT, -300, 64), 0, 255));
}

background.Line(0, iy, WIDTH, iy);
Expand Down Expand Up @@ -93,28 +93,39 @@ private void Update()
if(DEBUG_MODE)
Minimap.ClearDebug();

Minimap.ClearEnemies();

Player.MoveInput();
level.MoveEnemies();

//Make the render pool
List<Renderable> visibleRenderables = new List<Renderable>();

//First we get all tiles that are on screen
List<TileWall> onscreenTileWalls = level.FindOnscreenTileWalls();

//Then we loop through those tiles and see which sides are actually visible
List<WallSide> visibleSides = new List<WallSide>();
foreach (TileWall tileWall in onscreenTileWalls)
{
visibleSides.AddRange(tileWall.FindVisibleSides());
//And we add those visible sides to the rendering pool
visibleRenderables.AddRange(tileWall.FindVisibleSides());
}

//We sort the sides by their distance to the player, to make sure they're rendered in the correct order
List<WallSide> sorted = visibleSides.OrderByDescending(side => side.distToPlayer).ToList();
//Enemies need to be rendered too, of course
visibleRenderables.AddRange(level.FindVisibleEnemies());

//We sort the renderables by their distance to the player, to make sure they're rendered in the correct order
List<Renderable> sorted = visibleRenderables.OrderByDescending(renderable => renderable.distToPlayer).ToList();

//Then we render all those visible sides
foreach (WallSide side in sorted)
//Then we refresh all those renderables
foreach (Renderable renderable in sorted)
{
side.Refresh();
renderable.RefreshVisuals();
}

Minimap.ReOverlay();
if(Input.GetKeyDown(Key.P))
Console.WriteLine(GetDiagnostics());
}

public static (int, float) WorldToScreen(Vector2 p)
Expand All @@ -137,7 +148,7 @@ public static (int, float) WorldToScreen(Vector2 p)

private static void Main() // Main() is the first method that's called when the program is run
{
new MyGame(false).Start(); // Create a "MyGame" and start it
new MyGame(true).Start(); // Create a "MyGame" and start it
}
}
}
2 changes: 1 addition & 1 deletion DoomGame/MyGame/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class Player : GameObject
private const float MOVE_SPEED = 0.005f;
private const float WALL_PADDING = 0.3f;

public const float VIEW_DEPTH = 16.0f;
public const float VIEW_DEPTH = 4.0f;

public Player(float startX, float startY, float startAngle)
{
Expand Down
Loading

0 comments on commit 5f6ee8c

Please sign in to comment.