Просмотр исходного кода

Changed chapter 5 to use asteroids instead of tower def

Sanjay Madhav 8 лет назад
Родитель
Сommit
78a262b83a
49 измененных файлов с 477 добавлено и 761 удалено
  1. BIN
      Chapter05/Assets/Airplane.png
  2. BIN
      Chapter05/Assets/Asteroid.png
  3. BIN
      Chapter05/Assets/Base.png
  4. 0 3
      Chapter05/Assets/LICENSE.txt
  5. BIN
      Chapter05/Assets/Laser.png
  6. BIN
      Chapter05/Assets/Missile.png
  7. BIN
      Chapter05/Assets/Projectile.png
  8. BIN
      Chapter05/Assets/Ship.png
  9. BIN
      Chapter05/Assets/ShipWithThrust.png
  10. BIN
      Chapter05/Assets/TileBrown.png
  11. BIN
      Chapter05/Assets/TileBrownSelected.png
  12. BIN
      Chapter05/Assets/TileGreen.png
  13. BIN
      Chapter05/Assets/TileGreenSelected.png
  14. BIN
      Chapter05/Assets/TileGrey.png
  15. BIN
      Chapter05/Assets/TileGreySelected.png
  16. BIN
      Chapter05/Assets/TileTan.png
  17. BIN
      Chapter05/Assets/TileTanSelected.png
  18. BIN
      Chapter05/Assets/Tower.png
  19. 46 0
      Chapter05/Asteroid.cpp
  20. 4 5
      Chapter05/Asteroid.h
  21. 0 53
      Chapter05/Bullet.cpp
  22. 0 56
      Chapter05/Enemy.cpp
  23. 29 39
      Chapter05/Game.cpp
  24. 6 6
      Chapter05/Game.h
  25. 12 12
      Chapter05/Game.vcxproj
  26. 24 24
      Chapter05/Game.vcxproj.filters
  27. 0 246
      Chapter05/Grid.cpp
  28. 0 58
      Chapter05/Grid.h
  29. 47 0
      Chapter05/InputComponent.cpp
  30. 45 0
      Chapter05/InputComponent.h
  31. 56 0
      Chapter05/Laser.cpp
  32. 4 4
      Chapter05/Laser.h
  33. 7 1
      Chapter05/MoveComponent.cpp
  34. 0 49
      Chapter05/NavComponent.cpp
  35. 0 23
      Chapter05/NavComponent.h
  36. 51 0
      Chapter05/Random.cpp
  37. 36 0
      Chapter05/Random.h
  38. 3 3
      Chapter05/Shader.cpp
  39. 1 2
      Chapter05/Shader.h
  40. 20 0
      Chapter05/Shaders/Basic.frag
  41. 23 0
      Chapter05/Shaders/Basic.vert
  42. 2 2
      Chapter05/Shaders/Sprite.frag
  43. 2 2
      Chapter05/Shaders/Sprite.vert
  44. 50 0
      Chapter05/Ship.cpp
  45. 6 8
      Chapter05/Ship.h
  46. 0 66
      Chapter05/Tile.cpp
  47. 0 46
      Chapter05/Tile.h
  48. 0 53
      Chapter05/Tower.cpp
  49. 3 0
      Chapter05/VertexArray.h

BIN
Chapter05/Assets/Airplane.png


BIN
Chapter05/Assets/Asteroid.png


BIN
Chapter05/Assets/Base.png


+ 0 - 3
Chapter05/Assets/LICENSE.txt

@@ -1,3 +0,0 @@
-These sprites created by Kenney.nl
-
-Used under CC0 license.

BIN
Chapter05/Assets/Laser.png


BIN
Chapter05/Assets/Missile.png


BIN
Chapter05/Assets/Projectile.png


BIN
Chapter05/Assets/Ship.png


BIN
Chapter05/Assets/ShipWithThrust.png


BIN
Chapter05/Assets/TileBrown.png


BIN
Chapter05/Assets/TileBrownSelected.png


BIN
Chapter05/Assets/TileGreen.png


BIN
Chapter05/Assets/TileGreenSelected.png


BIN
Chapter05/Assets/TileGrey.png


BIN
Chapter05/Assets/TileGreySelected.png


BIN
Chapter05/Assets/TileTan.png


BIN
Chapter05/Assets/TileTanSelected.png


BIN
Chapter05/Assets/Tower.png


+ 46 - 0
Chapter05/Asteroid.cpp

@@ -0,0 +1,46 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+#include "Asteroid.h"
+#include "SpriteComponent.h"
+#include "MoveComponent.h"
+#include "Game.h"
+#include "Random.h"
+#include "CircleComponent.h"
+
+Asteroid::Asteroid(Game* game)
+	:Actor(game)
+	,mCircle(nullptr)
+{
+	// Initialize to random position/orientation
+	Vector2 randPos = Random::GetVector(Vector2(-512.0f, -384.0f),
+		Vector2(512.0f, 384.0f));
+	SetPosition(randPos);
+
+	SetRotation(Random::GetFloatRange(0.0f, Math::TwoPi));
+
+	// Create a sprite component
+	SpriteComponent* sc = new SpriteComponent(this);
+	sc->SetTexture(game->GetTexture("Assets/Asteroid.png"));
+
+	// Create a move component, and set a forward speed
+	MoveComponent* mc = new MoveComponent(this);
+	mc->SetForwardSpeed(150.0f);
+
+	// Create a circle component (for collision)
+	mCircle = new CircleComponent(this);
+	mCircle->SetRadius(40.0f);
+
+	// Add to mAsteroids in game
+	game->AddAsteroid(this);
+}
+
+Asteroid::~Asteroid()
+{
+	GetGame()->RemoveAsteroid(this);
+}

+ 4 - 5
Chapter05/Enemy.h → Chapter05/Asteroid.h

@@ -8,13 +8,12 @@
 
 #pragma once
 #include "Actor.h"
-
-class Enemy : public Actor
+class Asteroid : public Actor
 {
 public:
-	Enemy(class Game* game);
-	~Enemy();
-	void UpdateActor(float deltaTime) override;
+	Asteroid(class Game* game);
+	~Asteroid();
+	
 	class CircleComponent* GetCircle() { return mCircle; }
 private:
 	class CircleComponent* mCircle;

+ 0 - 53
Chapter05/Bullet.cpp

@@ -1,53 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#include "Bullet.h"
-#include "SpriteComponent.h"
-#include "MoveComponent.h"
-#include "CircleComponent.h"
-#include "Game.h"
-#include "Enemy.h"
-
-Bullet::Bullet(class Game* game)
-:Actor(game)
-{
-	SpriteComponent* sc = new SpriteComponent(this);
-	sc->SetTexture(game->GetTexture("Assets/Projectile.png"));
-	
-	MoveComponent* mc = new MoveComponent(this);
-	mc->SetForwardSpeed(400.0f);
-	
-	mCircle = new CircleComponent(this);
-	mCircle->SetRadius(5.0f);
-	
-	mLiveTime = 1.0f;
-}
-
-void Bullet::UpdateActor(float deltaTime)
-{
-	Actor::UpdateActor(deltaTime);
-	
-	// Check for collision vs enemies
-	for (Enemy* e : GetGame()->GetEnemies())
-	{
-		if (Intersect(*mCircle, *(e->GetCircle())))
-		{
-			// We both die on collision
-			e->SetState(EDead);
-			SetState(EDead);
-			break;
-		}
-	}
-	
-	mLiveTime -= deltaTime;
-	if (mLiveTime <= 0.0f)
-	{
-		// Time limit hit, die
-		SetState(EDead);
-	}
-}

+ 0 - 56
Chapter05/Enemy.cpp

@@ -1,56 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#include "Enemy.h"
-#include "Game.h"
-#include "SpriteComponent.h"
-#include "NavComponent.h"
-#include "Grid.h"
-#include "Tile.h"
-#include "CircleComponent.h"
-#include <algorithm>
-
-Enemy::Enemy(class Game* game)
-:Actor(game)
-{
-	// Add to enemy vector
-	game->GetEnemies().emplace_back(this);
-	
-	SpriteComponent* sc = new SpriteComponent(this);
-	sc->SetTexture(game->GetTexture("Assets/Airplane.png"));
-	// Set position at start tile
-	SetPosition(GetGame()->GetGrid()->GetStartTile()->GetPosition());
-	// Setup a nav component at the start tile
-	NavComponent* nc = new NavComponent(this);
-	nc->SetForwardSpeed(150.0f);
-	nc->StartPath(GetGame()->GetGrid()->GetStartTile());
-	// Setup a circle for collision
-	mCircle = new CircleComponent(this);
-	mCircle->SetRadius(25.0f);
-}
-
-Enemy::~Enemy()
-{
-	// Remove from enemy vector
-	auto iter = std::find(GetGame()->GetEnemies().begin(),
-						  GetGame()->GetEnemies().end(),
-						  this);
-	GetGame()->GetEnemies().erase(iter);
-}
-
-void Enemy::UpdateActor(float deltaTime)
-{
-	Actor::UpdateActor(deltaTime);
-	
-	// Am I near the end tile?
-	Vector2 diff = GetPosition() - GetGame()->GetGrid()->GetEndTile()->GetPosition();
-	if (Math::NearZero(diff.Length(), 10.0f))
-	{
-		SetState(EDead);
-	}
-}

+ 29 - 39
Chapter05/Game.cpp

@@ -14,9 +14,10 @@
 #include <algorithm>
 #include "Actor.h"
 #include "SpriteComponent.h"
-#include "Grid.h"
-#include "Enemy.h"
 #include "Actor.h"
+#include "Ship.h"
+#include "Asteroid.h"
+#include "Random.h"
 
 Game::Game()
 :mWindow(nullptr)
@@ -119,18 +120,6 @@ void Game::ProcessInput()
 	{
 		mIsRunning = false;
 	}
-	if (keyState[SDL_SCANCODE_B])
-	{
-		mGrid->BuildTower();
-	}
-	
-	// Process mouse
-	int x, y;
-	Uint32 buttons = SDL_GetMouseState(&x, &y);
-	if (SDL_BUTTON(buttons) & SDL_BUTTON_LEFT)
-	{
-		mGrid->ProcessClick(x, y);
-	}
 
 	mUpdatingActors = true;
 	for (auto actor : mActors)
@@ -190,7 +179,7 @@ void Game::UpdateGame()
 void Game::GenerateOutput()
 {
 	// Set the clear color to dark green
-	glClearColor(0.13f, 0.54f, 0.13f, 1.0f);
+	glClearColor(0.86f, 0.86f, 0.86f, 1.0f);
 	// Clear the color buffer
 	glClear(GL_COLOR_BUFFER_BIT);
 	
@@ -246,7 +235,16 @@ void Game::CreateSpriteVerts()
 
 void Game::LoadData()
 {
-	mGrid = new Grid(this);
+	// Create player's ship
+	mShip = new Ship(this);
+	mShip->SetRotation(Math::PiOver2);
+
+	// Create asteroids
+	const int numAsteroids = 20;
+	for (int i = 0; i < numAsteroids; i++)
+	{
+		new Asteroid(this);
+	}
 }
 
 void Game::UnloadData()
@@ -291,6 +289,21 @@ Texture* Game::GetTexture(const std::string& fileName)
 	return tex;
 }
 
+void Game::AddAsteroid(Asteroid* ast)
+{
+	mAsteroids.emplace_back(ast);
+}
+
+void Game::RemoveAsteroid(Asteroid* ast)
+{
+	auto iter = std::find(mAsteroids.begin(),
+		mAsteroids.end(), ast);
+	if (iter != mAsteroids.end())
+	{
+		mAsteroids.erase(iter);
+	}
+}
+
 void Game::Shutdown()
 {
 	UnloadData();
@@ -361,26 +374,3 @@ void Game::RemoveSprite(SpriteComponent* sprite)
 	auto iter = std::find(mSprites.begin(), mSprites.end(), sprite);
 	mSprites.erase(iter);
 }
-
-Enemy* Game::GetNearestEnemy(const Vector2& pos)
-{
-	Enemy* best = nullptr;
-	
-	if (mEnemies.size() > 0)
-	{
-		best = mEnemies[0];
-		// Save the distance squared of first enemy, and test if others are closer
-		float bestDistSq = (pos - mEnemies[0]->GetPosition()).LengthSq();
-		for (size_t i = 1; i < mEnemies.size(); i++)
-		{
-			float newDistSq = (pos - mEnemies[i]->GetPosition()).LengthSq();
-			if (newDistSq < bestDistSq)
-			{
-				bestDistSq = newDistSq;
-				best = mEnemies[i];
-			}
-		}
-	}
-	
-	return best;
-}

+ 6 - 6
Chapter05/Game.h

@@ -29,9 +29,10 @@ public:
 	
 	class Texture* GetTexture(const std::string& fileName);
 	
-	class Grid* GetGrid() { return mGrid; }
-	std::vector<class Enemy*>& GetEnemies() { return mEnemies; }
-	class Enemy* GetNearestEnemy(const Vector2& pos);
+	// Game-specific (add/remove asteroid)
+	void AddAsteroid(class Asteroid* ast);
+	void RemoveAsteroid(class Asteroid* ast);
+	std::vector<class Asteroid*>& GetAsteroids() { return mAsteroids; }
 private:
 	void ProcessInput();
 	void UpdateGame();
@@ -65,7 +66,6 @@ private:
 	bool mUpdatingActors;
 
 	// Game-specific
-	std::vector<class Enemy*> mEnemies;
-	class Grid* mGrid;
-	float mNextEnemy;
+	class Ship* mShip;
+	std::vector<class Asteroid*> mAsteroids;
 };

+ 12 - 12
Chapter05/Game.vcxproj

@@ -12,42 +12,42 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Actor.cpp" />
-    <ClCompile Include="Bullet.cpp" />
+    <ClCompile Include="Asteroid.cpp" />
     <ClCompile Include="CircleComponent.cpp" />
     <ClCompile Include="Component.cpp" />
-    <ClCompile Include="Enemy.cpp" />
     <ClCompile Include="Game.cpp" />
-    <ClCompile Include="Grid.cpp" />
+    <ClCompile Include="InputComponent.cpp" />
+    <ClCompile Include="Laser.cpp" />
     <ClCompile Include="Main.cpp" />
     <ClCompile Include="Math.cpp" />
     <ClCompile Include="MoveComponent.cpp" />
-    <ClCompile Include="NavComponent.cpp" />
+    <ClCompile Include="Random.cpp" />
     <ClCompile Include="Shader.cpp" />
+    <ClCompile Include="Ship.cpp" />
     <ClCompile Include="SpriteComponent.cpp" />
     <ClCompile Include="Texture.cpp" />
-    <ClCompile Include="Tile.cpp" />
-    <ClCompile Include="Tower.cpp" />
     <ClCompile Include="VertexArray.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Actor.h" />
-    <ClInclude Include="Bullet.h" />
+    <ClInclude Include="Asteroid.h" />
     <ClInclude Include="CircleComponent.h" />
     <ClInclude Include="Component.h" />
-    <ClInclude Include="Enemy.h" />
     <ClInclude Include="Game.h" />
-    <ClInclude Include="Grid.h" />
+    <ClInclude Include="InputComponent.h" />
+    <ClInclude Include="Laser.h" />
     <ClInclude Include="Math.h" />
     <ClInclude Include="MoveComponent.h" />
-    <ClInclude Include="NavComponent.h" />
+    <ClInclude Include="Random.h" />
     <ClInclude Include="Shader.h" />
+    <ClInclude Include="Ship.h" />
     <ClInclude Include="SpriteComponent.h" />
     <ClInclude Include="Texture.h" />
-    <ClInclude Include="Tile.h" />
-    <ClInclude Include="Tower.h" />
     <ClInclude Include="VertexArray.h" />
   </ItemGroup>
   <ItemGroup>
+    <None Include="Shaders\Basic.frag" />
+    <None Include="Shaders\Basic.vert" />
     <None Include="Shaders\Sprite.frag" />
     <None Include="Shaders\Sprite.vert" />
   </ItemGroup>

+ 24 - 24
Chapter05/Game.vcxproj.filters

@@ -28,37 +28,34 @@
     <ClCompile Include="SpriteComponent.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Bullet.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="CircleComponent.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Enemy.cpp">
+    <ClCompile Include="MoveComponent.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Grid.cpp">
+    <ClCompile Include="Shader.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="MoveComponent.cpp">
+    <ClCompile Include="Texture.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="NavComponent.cpp">
+    <ClCompile Include="VertexArray.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Shader.cpp">
+    <ClCompile Include="Asteroid.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Texture.cpp">
+    <ClCompile Include="Laser.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Tile.cpp">
+    <ClCompile Include="Ship.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="Tower.cpp">
+    <ClCompile Include="InputComponent.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="VertexArray.cpp">
+    <ClCompile Include="Random.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>
@@ -78,37 +75,34 @@
     <ClInclude Include="SpriteComponent.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="Bullet.h">
-      <Filter>Source Files</Filter>
-    </ClInclude>
     <ClInclude Include="CircleComponent.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="Enemy.h">
+    <ClInclude Include="MoveComponent.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="Grid.h">
+    <ClInclude Include="Shader.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="MoveComponent.h">
+    <ClInclude Include="Texture.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="NavComponent.h">
+    <ClInclude Include="VertexArray.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="Shader.h">
+    <ClInclude Include="Asteroid.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="Texture.h">
+    <ClInclude Include="Laser.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="Tile.h">
+    <ClInclude Include="Ship.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="Tower.h">
+    <ClInclude Include="InputComponent.h">
       <Filter>Source Files</Filter>
     </ClInclude>
-    <ClInclude Include="VertexArray.h">
+    <ClInclude Include="Random.h">
       <Filter>Source Files</Filter>
     </ClInclude>
   </ItemGroup>
@@ -119,5 +113,11 @@
     <None Include="Shaders\Sprite.vert">
       <Filter>Shaders</Filter>
     </None>
+    <None Include="Shaders\Basic.frag">
+      <Filter>Shaders</Filter>
+    </None>
+    <None Include="Shaders\Basic.vert">
+      <Filter>Shaders</Filter>
+    </None>
   </ItemGroup>
 </Project>

+ 0 - 246
Chapter05/Grid.cpp

@@ -1,246 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#include "Grid.h"
-#include "Tile.h"
-#include "Tower.h"
-#include "Enemy.h"
-#include <algorithm>
-
-Grid::Grid(class Game* game)
-:Actor(game)
-,mSelectedTile(nullptr)
-{
-	// 7 rows, 16 columns
-	mTiles.resize(NumRows);
-	for (size_t i = 0; i < mTiles.size(); i++)
-	{
-		mTiles[i].resize(NumCols);
-	}
-	
-	// Create tiles
-	for (size_t i = 0; i < NumRows; i++)
-	{
-		for (size_t j = 0; j < NumCols; j++)
-		{
-			mTiles[i][j] = new Tile(GetGame());
-			mTiles[i][j]->SetPosition(Vector2(StartX + TileSize/2.0f + j * TileSize, StartY - i * TileSize));
-		}
-	}
-	
-	// Set start/end tiles
-	GetStartTile()->SetTileState(Tile::EStart);
-	GetEndTile()->SetTileState(Tile::EBase);
-	
-	// Set up adjacency lists
-	for (size_t i = 0; i < NumRows; i++)
-	{
-		for (size_t j = 0; j < NumCols; j++)
-		{
-			if (i > 0)
-			{
-				mTiles[i][j]->mAdjacent.push_back(mTiles[i-1][j]);
-			}
-			if (i < NumRows - 1)
-			{
-				mTiles[i][j]->mAdjacent.push_back(mTiles[i+1][j]);
-			}
-			if (j > 0)
-			{
-				mTiles[i][j]->mAdjacent.push_back(mTiles[i][j-1]);
-			}
-			if (j < NumCols - 1)
-			{
-				mTiles[i][j]->mAdjacent.push_back(mTiles[i][j+1]);
-			}
-		}
-	}
-	
-	// Find path (in reverse)
-	FindPath(GetEndTile(), GetStartTile());
-	UpdatePathTiles(GetStartTile());
-	
-	mNextEnemy = EnemyTime;
-}
-
-void Grid::SelectTile(size_t row, size_t col)
-{
-	// Make sure it's a valid selection
-	Tile::TileState tstate = mTiles[row][col]->GetTileState();
-	if (tstate != Tile::EStart && tstate != Tile::EBase)
-	{
-		// Deselect previous one
-		if (mSelectedTile)
-		{
-			mSelectedTile->ToggleSelect();
-		}
-		mSelectedTile = mTiles[row][col];
-		mSelectedTile->ToggleSelect();
-	}
-}
-
-void Grid::ProcessClick(int x, int y)
-{
-	y -= static_cast<int>(StartY - TileSize / 2);
-	if (y >= 0)
-	{
-		x /= static_cast<int>(TileSize);
-		y /= static_cast<int>(TileSize);
-		if (x >= 0 && x < static_cast<int>(NumCols) && y >= 0 && y < static_cast<int>(NumRows))
-		{
-			SelectTile(y, x);
-		}
-	}
-}
-
-// Implements A* pathfinding
-bool Grid::FindPath(Tile* start, Tile* goal)
-{
-	for (size_t i = 0; i < NumRows; i++)
-	{
-		for (size_t j = 0; j < NumCols; j++)
-		{
-			mTiles[i][j]->g = 0.0f;
-			mTiles[i][j]->mInOpenSet = false;
-			mTiles[i][j]->mInClosedSet = false;
-		}
-	}
-	
-	std::vector<Tile*> openSet;
-	
-	// Set current node to start, and add to closed set
-	Tile* current = start;
-	current->mInClosedSet = true;
-	
-	do
-	{
-		// Add adjacent nodes to open set
-		for (Tile* neighbor : current->mAdjacent)
-		{
-			if (neighbor->mBlocked)
-			{
-				continue;
-			}
-			
-			// Only check nodes that aren't in the closed set
-			if (!neighbor->mInClosedSet)
-			{
-				if (!neighbor->mInOpenSet)
-				{
-					// Not in the open set, so set parent
-					neighbor->mParent = current;
-					neighbor->h = (neighbor->GetPosition() - goal->GetPosition()).Length();
-					// g(x) is the parent's g plus cost of traversing edge
-					neighbor->g = current->g + TileSize;
-					neighbor->f = neighbor->g + neighbor->h;
-					openSet.emplace_back(neighbor);
-					neighbor->mInOpenSet = true;
-				}
-				else
-				{
-					// Compute g(x) cost if current becomes the parent
-					float newG = current->g + TileSize;
-					if (newG < neighbor->g)
-					{
-						// Adopt this node
-						neighbor->mParent = current;
-						neighbor->g = newG;
-						// f(x) changes because g(x) changes
-						neighbor->f = neighbor->g + neighbor->h;
-					}
-				}
-			}
-		}
-		
-		// If open set is empty, all possible paths are exhausted
-		if (openSet.empty())
-		{
-			break;
-		}
-		
-		// Find lowest cost node in open set
-		auto iter = std::min_element(openSet.begin(), openSet.end(),
-									 [](Tile* a, Tile* b) {
-										 return a->f < b->f;
-									 });
-		// Set to current and move from open to closed
-		current = *iter;
-		openSet.erase(iter);
-		current->mInOpenSet = false;
-		current->mInClosedSet = true;
-	}
-	while (current != goal);
-	
-	// Did we find a path?
-	return (current == goal) ? true : false;
-}
-
-void Grid::UpdatePathTiles(class Tile* start)
-{
-	// Reset all tiles to normal (except for start/end)
-	for (size_t i = 0; i < NumRows; i++)
-	{
-		for (size_t j = 0; j < NumCols; j++)
-		{
-			if (!(i == 3 && j == 0) && !(i == 3 && j == 15))
-			{
-				mTiles[i][j]->SetTileState(Tile::EDefault);
-			}
-		}
-	}
-	
-	Tile* t = start->mParent;
-	while (t != GetEndTile())
-	{
-		t->SetTileState(Tile::EPath);
-		t = t->mParent;
-	}
-}
-
-void Grid::BuildTower()
-{
-	if (mSelectedTile && !mSelectedTile->mBlocked)
-	{
-		mSelectedTile->mBlocked = true;
-		if (FindPath(GetEndTile(), GetStartTile()))
-		{
-			Tower* t = new Tower(GetGame());
-			t->SetPosition(mSelectedTile->GetPosition());
-		}
-		else
-		{
-			// This tower would block the path, so don't allow build
-			mSelectedTile->mBlocked = false;
-			FindPath(GetEndTile(), GetStartTile());
-		}
-		UpdatePathTiles(GetStartTile());
-	}
-}
-
-Tile* Grid::GetStartTile()
-{
-	return mTiles[3][0];
-}
-
-Tile* Grid::GetEndTile()
-{
-	return mTiles[3][15];
-}
-
-void Grid::UpdateActor(float deltaTime)
-{
-	Actor::UpdateActor(deltaTime);
-	
-	// Is it time to spawn a new enemy?
-	mNextEnemy -= deltaTime;
-	if (mNextEnemy <= 0.0f)
-	{
-		new Enemy(GetGame());
-		mNextEnemy += EnemyTime;
-	}
-}

+ 0 - 58
Chapter05/Grid.h

@@ -1,58 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#pragma once
-#include "Actor.h"
-#include <vector>
-
-class Grid : public Actor
-{
-public:
-	Grid(class Game* game);
-	
-	// Handle a mouse click at the x/y screen locations
-	void ProcessClick(int x, int y);
-	
-	// Use A* to find a path
-	bool FindPath(class Tile* start, class Tile* goal);
-	
-	// Try to build a tower
-	void BuildTower();
-	
-	// Get start/end tile
-	class Tile* GetStartTile();
-	class Tile* GetEndTile();
-
-	void UpdateActor(float deltaTime) override;
-private:
-	// Select a specific tile
-	void SelectTile(size_t row, size_t col);
-	
-	// Update textures for tiles on path
-	void UpdatePathTiles(class Tile* start);
-	
-	// Currently selected tile
-	class Tile* mSelectedTile;
-	
-	// 2D vector of tiles in grid
-	std::vector<std::vector<class Tile*>> mTiles;
-	
-	// Time until next enemy
-	float mNextEnemy;
-	
-	// Rows/columns in grid
-	const size_t NumRows = 7;
-	const size_t NumCols = 16;
-	// Start y position of top left corner
-	const float StartY = 192.0f;
-	const float StartX = -512.0f;
-	// Width/height of each tile
-	const float TileSize = 64.0f;
-	// Time between enemies
-	const float EnemyTime = 1.5f;
-};

+ 47 - 0
Chapter05/InputComponent.cpp

@@ -0,0 +1,47 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+#include "InputComponent.h"
+#include "Actor.h"
+
+InputComponent::InputComponent(class Actor* owner)
+:MoveComponent(owner)
+,mForwardKey(0)
+,mBackKey(0)
+,mClockwiseKey(0)
+,mCounterClockwiseKey(0)
+{
+	
+}
+
+void InputComponent::ProcessInput(const uint8_t* keyState)
+{
+	// Calculate forward speed for MoveComponent
+	float forwardSpeed = 0.0f;
+	if (keyState[mForwardKey])
+	{
+		forwardSpeed += mMaxForwardSpeed;
+	}
+	if (keyState[mBackKey])
+	{
+		forwardSpeed -= mMaxForwardSpeed;
+	}
+	SetForwardSpeed(forwardSpeed);
+
+	// Calculate angular speed for MoveComponent
+	float angularSpeed = 0.0f;
+	if (keyState[mClockwiseKey])
+	{
+		angularSpeed += mMaxAngularSpeed;
+	}
+	if (keyState[mCounterClockwiseKey])
+	{
+		angularSpeed -= mMaxAngularSpeed;
+	}
+	SetAngularSpeed(angularSpeed);
+}

+ 45 - 0
Chapter05/InputComponent.h

@@ -0,0 +1,45 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+#pragma once
+#include "MoveComponent.h"
+#include <cstdint>
+
+class InputComponent : public MoveComponent
+{
+public:
+	// Lower update order to update first
+	InputComponent(class Actor* owner);
+
+	void ProcessInput(const uint8_t* keyState) override;
+	
+	// Getters/setters for private variables
+	float GetMaxForward() const { return mMaxForwardSpeed; }
+	float GetMaxAngular() const { return mMaxAngularSpeed; }
+	int GetForwardKey() const { return mForwardKey; }
+	int GetBackKey() const { return mBackKey; }
+	int GetClockwiseKey() const { return mClockwiseKey; }
+	int GetCounterClockwiseKey() const { return mCounterClockwiseKey; }
+
+	void SetMaxForwardSpeed(float speed) { mMaxForwardSpeed = speed; }
+	void SetMaxAngularSpeed(float speed) { mMaxAngularSpeed = speed; }
+	void SetForwardKey(int key) { mForwardKey = key; }
+	void SetBackKey(int key) { mBackKey = key; }
+	void SetClockwiseKey(int key) { mClockwiseKey = key; }
+	void SetCounterClockwiseKey(int key) { mCounterClockwiseKey = key; }
+private:
+	// The maximum forward/angular speeds
+	float mMaxForwardSpeed;
+	float mMaxAngularSpeed;
+	// Keys for forward/back movement
+	int mForwardKey;
+	int mBackKey;
+	// Keys for angular movement
+	int mClockwiseKey;
+	int mCounterClockwiseKey;
+};

+ 56 - 0
Chapter05/Laser.cpp

@@ -0,0 +1,56 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+#include "Laser.h"
+#include "SpriteComponent.h"
+#include "MoveComponent.h"
+#include "Game.h"
+#include "CircleComponent.h"
+#include "Asteroid.h"
+
+Laser::Laser(Game* game)
+	:Actor(game)
+	,mDeathTimer(1.0f)
+{
+	// Create a sprite component
+	SpriteComponent* sc = new SpriteComponent(this);
+	sc->SetTexture(game->GetTexture("Assets/Laser.png"));
+
+	// Create a move component, and set a forward speed
+	MoveComponent* mc = new MoveComponent(this);
+	mc->SetForwardSpeed(800.0f);
+
+	// Create a circle component (for collision)
+	mCircle = new CircleComponent(this);
+	mCircle->SetRadius(11.0f);
+}
+
+void Laser::UpdateActor(float deltaTime)
+{
+	// If we run out of time, laser is dead
+	mDeathTimer -= deltaTime;
+	if (mDeathTimer <= 0.0f)
+	{
+		SetState(EDead);
+	}
+	else
+	{
+		// Do we intersect with an asteroid?
+		for (auto ast : GetGame()->GetAsteroids())
+		{
+			if (Intersect(*mCircle, *(ast->GetCircle())))
+			{
+				// The first asteroid we intersect with,
+				// set ourselves and the asteroid to dead
+				SetState(EDead);
+				ast->SetState(EDead);
+				break;
+			}
+		}
+	}
+}

+ 4 - 4
Chapter05/Bullet.h → Chapter05/Laser.h

@@ -8,13 +8,13 @@
 
 #pragma once
 #include "Actor.h"
-
-class Bullet : public Actor
+class Laser : public Actor
 {
 public:
-	Bullet(class Game* game);
+	Laser(class Game* game);
+
 	void UpdateActor(float deltaTime) override;
 private:
 	class CircleComponent* mCircle;
-	float mLiveTime;
+	float mDeathTimer;
 };

+ 7 - 1
Chapter05/MoveComponent.cpp

@@ -29,7 +29,13 @@ void MoveComponent::Update(float deltaTime)
 	if (!Math::NearZero(mForwardSpeed))
 	{
 		Vector2 pos = mOwner->GetPosition();
-		pos += mOwner->GetForward() * mForwardSpeed * deltaTime;		
+		pos += mOwner->GetForward() * mForwardSpeed * deltaTime;
+
+		// Screen wrapping (for asteroids)
+		if (pos.x < -512.0f) { pos.x = 510.0f; }
+		else if (pos.x > 512.0f) { pos.x = -510.0f; }
+		if (pos.y < -384.0f) { pos.y = 382.0f; }
+		else if (pos.y > 384.0f) { pos.y = -382.0f; }
 		mOwner->SetPosition(pos);
 	}
 }

+ 0 - 49
Chapter05/NavComponent.cpp

@@ -1,49 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#include "NavComponent.h"
-#include "Tile.h"
-
-NavComponent::NavComponent(class Actor* owner, int updateOrder)
-:MoveComponent(owner, updateOrder)
-,mNextNode(nullptr)
-{
-	
-}
-
-void NavComponent::Update(float deltaTime)
-{
-	if (mNextNode)
-	{
-		// If we're at the next node, advance along path
-		Vector2 diff = mOwner->GetPosition() - mNextNode->GetPosition();
-		if (Math::NearZero(diff.Length(), 2.0f))
-		{
-			mNextNode = mNextNode->GetParent();
-			TurnTo(mNextNode->GetPosition());
-		}
-	}
-	
-	MoveComponent::Update(deltaTime);
-}
-
-void NavComponent::StartPath(const Tile* start)
-{
-	mNextNode = start->GetParent();
-	TurnTo(mNextNode->GetPosition());
-}
-
-void NavComponent::TurnTo(const Vector2& pos)
-{
-	// Vector from me to pos
-	Vector2 dir = pos - mOwner->GetPosition();
-	// New angle is just atan2 of this dir vector
-	// (Negate y because +y is down on screen)
-	float angle = Math::Atan2(dir.y, dir.x);
-	mOwner->SetRotation(angle);
-}

+ 0 - 23
Chapter05/NavComponent.h

@@ -1,23 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#pragma once
-#include "MoveComponent.h"
-#include "Math.h"
-
-class NavComponent : public MoveComponent
-{
-public:
-	// Lower update order to update first
-	NavComponent(class Actor* owner, int updateOrder = 10);
-	void Update(float deltaTime) override;
-	void StartPath(const class Tile* start);
-	void TurnTo(const Vector2& pos);
-private:
-	const class Tile* mNextNode;
-};

+ 51 - 0
Chapter05/Random.cpp

@@ -0,0 +1,51 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+#include "Random.h"
+
+void Random::Init()
+{
+	std::random_device rd;
+	Random::Seed(rd());
+}
+
+void Random::Seed(unsigned int seed)
+{
+	sGenerator.seed(seed);
+}
+
+float Random::GetFloat()
+{
+	return GetFloatRange(0.0f, 1.0f);
+}
+
+float Random::GetFloatRange(float min, float max)
+{
+	std::uniform_real_distribution<float> dist(min, max);
+	return dist(sGenerator);
+}
+
+int Random::GetIntRange(int min, int max)
+{
+	std::uniform_int_distribution<int> dist(min, max);
+	return dist(sGenerator);
+}
+
+Vector2 Random::GetVector(const Vector2& min, const Vector2& max)
+{
+	Vector2 r = Vector2(GetFloat(), GetFloat());
+	return min + (max - min) * r;
+}
+
+Vector3 Random::GetVector(const Vector3& min, const Vector3& max)
+{
+	Vector3 r = Vector3(GetFloat(), GetFloat(), GetFloat());
+	return min + (max - min) * r;
+}
+
+std::mt19937 Random::sGenerator;

+ 36 - 0
Chapter05/Random.h

@@ -0,0 +1,36 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+#pragma  once
+#include <random>
+#include "Math.h"
+
+class Random
+{
+public:
+	static void Init();
+
+	// Seed the generator with the specified int
+	// NOTE: You should generally not need to manually use this
+	static void Seed(unsigned int seed);
+
+	// Get a float between 0.0f and 1.0f
+	static float GetFloat();
+	
+	// Get a float from the specified range
+	static float GetFloatRange(float min, float max);
+
+	// Get an int from the specified range
+	static int GetIntRange(int min, int max);
+
+	// Get a random vector given the min/max bounds
+	static Vector2 GetVector(const Vector2& min, const Vector2& max);
+	static Vector3 GetVector(const Vector3& min, const Vector3& max);
+private:
+	static std::mt19937 sGenerator;
+};

+ 3 - 3
Chapter05/Shader.cpp

@@ -77,14 +77,14 @@ void Shader::SetMatrixUniform(const char* name, const Matrix4& matrix)
 }
 
 bool Shader::CompileShader(const std::string& fileName,
-				   GLenum shaderType,
-				   GLuint& outShader)
+	GLenum shaderType,
+	GLuint& outShader)
 {
 	// Open file
 	std::ifstream shaderFile(fileName);
 	if (shaderFile.is_open())
 	{
-		// Read all of the text into a string
+		// Read all the text into a string
 		std::stringstream sstream;
 		sstream << shaderFile.rdbuf();
 		std::string contents = sstream.str();

+ 1 - 2
Chapter05/Shader.h

@@ -16,8 +16,7 @@ class Shader
 public:
 	Shader();
 	~Shader();
-	// Load shader of the specified name, excluding
-	// the .frag/.vert extension
+	// Load the vertex/fragment shaders with the given names
 	bool Load(const std::string& vertName, const std::string& fragName);
 	void Unload();
 	// Set this as the active shader program

+ 20 - 0
Chapter05/Shaders/Basic.frag

@@ -0,0 +1,20 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+// Request GLSL 3.3
+#version 330
+
+// This corresponds to the output color
+// to the color buffer
+out vec4 outColor;
+
+void main()
+{
+	// RGBA of 100% blue, 100% opaque
+    outColor = vec4(0.0, 0.0, 1.0, 1.0);
+}

+ 23 - 0
Chapter05/Shaders/Basic.vert

@@ -0,0 +1,23 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+// Request GLSL 3.3
+#version 330
+
+// This should correspond to the data stored
+// for each vertex in the vertex buffer.
+// For now, just a position.
+in vec3 inPosition;
+
+void main()
+{
+	// The vertex shader needs to output a 4D
+	// coordinate.
+	// For now set the 4th coordinate to 1.0
+	gl_Position = vec4(inPosition, 1.0);
+}

+ 2 - 2
Chapter05/Shaders/Sprite.frag

@@ -1,9 +1,9 @@
 // ----------------------------------------------------------------
 // From Game Programming in C++ by Sanjay Madhav
 // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-//
+// 
 // Released under the BSD License
-// See LICENSE.txt for full details.
+// See LICENSE in root directory for full details.
 // ----------------------------------------------------------------
 
 // Request GLSL 3.3

+ 2 - 2
Chapter05/Shaders/Sprite.vert

@@ -1,9 +1,9 @@
 // ----------------------------------------------------------------
 // From Game Programming in C++ by Sanjay Madhav
 // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-//
+// 
 // Released under the BSD License
-// See LICENSE.txt for full details.
+// See LICENSE in root directory for full details.
 // ----------------------------------------------------------------
 
 // Request GLSL 3.3

+ 50 - 0
Chapter05/Ship.cpp

@@ -0,0 +1,50 @@
+// ----------------------------------------------------------------
+// From Game Programming in C++ by Sanjay Madhav
+// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
+// 
+// Released under the BSD License
+// See LICENSE in root directory for full details.
+// ----------------------------------------------------------------
+
+#include "Ship.h"
+#include "SpriteComponent.h"
+#include "InputComponent.h"
+#include "Game.h"
+#include "Laser.h"
+
+Ship::Ship(Game* game)
+	:Actor(game)
+	,mLaserCooldown(0.0f)
+{
+	// Create a sprite component
+	SpriteComponent* sc = new SpriteComponent(this, 150);
+	sc->SetTexture(game->GetTexture("Assets/Ship.png"));
+
+	// Create an input component and set keys/speed
+	InputComponent* ic = new InputComponent(this);
+	ic->SetForwardKey(SDL_SCANCODE_W);
+	ic->SetBackKey(SDL_SCANCODE_S);
+	ic->SetClockwiseKey(SDL_SCANCODE_A);
+	ic->SetCounterClockwiseKey(SDL_SCANCODE_D);
+	ic->SetMaxForwardSpeed(300.0f);
+	ic->SetMaxAngularSpeed(Math::TwoPi);
+}
+
+void Ship::UpdateActor(float deltaTime)
+{
+	mLaserCooldown -= deltaTime;
+}
+
+void Ship::ActorInput(const uint8_t* keyState)
+{
+	if (keyState[SDL_SCANCODE_SPACE] && mLaserCooldown <= 0.0f)
+	{
+		// Create a laser and set its position/rotation to mine
+		Laser* laser = new Laser(GetGame());
+		laser->SetPosition(GetPosition());
+		laser->SetRotation(GetRotation());
+
+		// Reset laser cooldown (half second)
+		mLaserCooldown = 0.5f;
+	}
+}

+ 6 - 8
Chapter05/Tower.h → Chapter05/Ship.h

@@ -8,15 +8,13 @@
 
 #pragma once
 #include "Actor.h"
-
-class Tower : public Actor
+class Ship : public Actor
 {
 public:
-	Tower(class Game* game);
+	Ship(class Game* game);
+
 	void UpdateActor(float deltaTime) override;
+	void ActorInput(const uint8_t* keyState) override;
 private:
-	class MoveComponent* mMove;
-	float mNextAttack;
-	const float AttackTime = 2.5f;
-	const float AttackRange = 100.0f;
-};
+	float mLaserCooldown;
+};

+ 0 - 66
Chapter05/Tile.cpp

@@ -1,66 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#include "Tile.h"
-#include "SpriteComponent.h"
-#include "Game.h"
-
-Tile::Tile(class Game* game)
-:Actor(game)
-,mParent(nullptr)
-,f(0.0f)
-,g(0.0f)
-,h(0.0f)
-,mBlocked(false)
-,mSprite(nullptr)
-,mTileState(EDefault)
-,mSelected(false)
-{
-	mSprite = new SpriteComponent(this);
-	UpdateTexture();
-}
-
-void Tile::SetTileState(TileState state)
-{
-	mTileState = state;
-	UpdateTexture();
-}
-
-void Tile::ToggleSelect()
-{
-	mSelected = !mSelected;
-	UpdateTexture();
-}
-
-void Tile::UpdateTexture()
-{
-	std::string text;
-	switch (mTileState)
-	{
-		case EStart:
-			text = "Assets/TileTan.png";
-			break;
-		case EBase:
-			text = "Assets/TileGreen.png";
-			break;
-		case EPath:
-			if (mSelected)
-				text = "Assets/TileGreySelected.png";
-			else
-				text = "Assets/TileGrey.png";
-			break;
-		case EDefault:
-		default:
-			if (mSelected)
-				text = "Assets/TileBrownSelected.png";
-			else
-				text = "Assets/TileBrown.png";
-			break;
-	}
-	mSprite->SetTexture(GetGame()->GetTexture(text));
-}

+ 0 - 46
Chapter05/Tile.h

@@ -1,46 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#pragma once
-#include "Actor.h"
-#include <vector>
-
-class Tile : public Actor
-{
-public:
-	friend class Grid;
-	enum TileState
-	{
-		EDefault,
-		EPath,
-		EStart,
-		EBase
-	};
-	
-	Tile(class Game* game);
-	
-	void SetTileState(TileState state);
-	TileState GetTileState() const { return mTileState; }
-	void ToggleSelect();
-	const Tile* GetParent() const { return mParent; }
-private:
-	// For pathfinding
-	std::vector<Tile*> mAdjacent;
-	Tile* mParent;
-	float f;
-	float g;
-	float h;
-	bool mInOpenSet;
-	bool mInClosedSet;
-	bool mBlocked;
-	
-	void UpdateTexture();
-	class SpriteComponent* mSprite;
-	TileState mTileState;
-	bool mSelected;
-};

+ 0 - 53
Chapter05/Tower.cpp

@@ -1,53 +0,0 @@
-// ----------------------------------------------------------------
-// From Game Programming in C++ by Sanjay Madhav
-// Copyright (C) 2017 Sanjay Madhav. All rights reserved.
-// 
-// Released under the BSD License
-// See LICENSE in root directory for full details.
-// ----------------------------------------------------------------
-
-#include "Tower.h"
-#include "SpriteComponent.h"
-#include "MoveComponent.h"
-#include "Game.h"
-#include "Enemy.h"
-#include "Bullet.h"
-
-Tower::Tower(class Game* game)
-:Actor(game)
-{
-	SpriteComponent* sc = new SpriteComponent(this, 200);
-	sc->SetTexture(game->GetTexture("Assets/Tower.png"));
-	
-	mMove = new MoveComponent(this);
-	//mMove->SetAngularSpeed(Math::Pi);
-	
-	mNextAttack = AttackTime;
-}
-
-void Tower::UpdateActor(float deltaTime)
-{
-	Actor::UpdateActor(deltaTime);
-	
-	mNextAttack -= deltaTime;
-	if (mNextAttack <= 0.0f)
-	{
-		Enemy* e = GetGame()->GetNearestEnemy(GetPosition());
-		if (e != nullptr)
-		{
-			// Vector from me to enemy
-			Vector2 dir = e->GetPosition() - GetPosition();
-			float dist = dir.Length();
-			if (dist < AttackRange)
-			{
-				// Rotate to face enemy
-				SetRotation(Math::Atan2(dir.y, dir.x));
-				// Spawn bullet at tower position facing enemy
-				Bullet* b = new Bullet(GetGame());
-				b->SetPosition(GetPosition());
-				b->SetRotation(GetRotation());
-			}
-		}
-		mNextAttack += AttackTime;
-	}
-}

+ 3 - 0
Chapter05/VertexArray.h

@@ -16,6 +16,9 @@ public:
 
 	// Activate this vertex array (so we can draw it)
 	void SetActive();
+
+	unsigned int GetNumIndices() const { return mNumIndices; }
+	unsigned int GetNumVerts() const { return mNumVerts; }
 private:
 	// How many vertices in the vertex buffer?
 	unsigned int mNumVerts;