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

Code updated to include chapter 4 changes

Sanjay Madhav 8 лет назад
Родитель
Сommit
bc6f997174
6 измененных файлов с 125 добавлено и 49 удалено
  1. 35 5
      Chapter05/Actor.cpp
  2. 8 1
      Chapter05/Actor.h
  3. 1 1
      Chapter05/Component.cpp
  4. 5 1
      Chapter05/Component.h
  5. 72 40
      Chapter05/Game.cpp
  6. 4 1
      Chapter05/Game.h

+ 35 - 5
Chapter05/Actor.cpp

@@ -3,7 +3,7 @@
 // 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.
 // ----------------------------------------------------------------
 
 #include "Actor.h"
@@ -53,6 +53,24 @@ void Actor::UpdateActor(float deltaTime)
 {
 }
 
+void Actor::ProcessInput(const uint8_t* keyState)
+{
+	if (mState == EActive)
+	{
+		// First process input for components
+		for (auto comp : mComponents)
+		{
+			comp->ProcessInput(keyState);
+		}
+
+		ActorInput(keyState);
+	}
+}
+
+void Actor::ActorInput(const uint8_t* keyState)
+{
+}
+
 void Actor::ComputeWorldTransform()
 {
 	mWorldTransform = Matrix4::CreateScale(mScale);
@@ -62,10 +80,22 @@ void Actor::ComputeWorldTransform()
 
 void Actor::AddComponent(Component* component)
 {
-	mComponents.emplace_back(component);
-	std::sort(mComponents.begin(), mComponents.end(), [](Component* a, Component* b) {
-		return a->GetUpdateOrder() < b->GetUpdateOrder();
-	});
+	// Find the insertion point in the sorted vector
+	// (The first element with a order higher than me)
+	int myOrder = component->GetUpdateOrder();
+	auto iter = mComponents.begin();
+	for (;
+		iter != mComponents.end();
+		++iter)
+	{
+		if (myOrder < (*iter)->GetUpdateOrder())
+		{
+			break;
+		}
+	}
+
+	// Inserts element before position of iterator
+	mComponents.insert(iter, component);
 }
 
 void Actor::RemoveComponent(Component* component)

+ 8 - 1
Chapter05/Actor.h

@@ -3,12 +3,14 @@
 // 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.
 // ----------------------------------------------------------------
 
 #pragma once
 #include <vector>
 #include "Math.h"
+#include <cstdint>
+
 class Actor
 {
 public:
@@ -29,6 +31,11 @@ public:
 	// Any actor-specific update code (overridable)
 	virtual void UpdateActor(float deltaTime);
 
+	// ProcessInput function called from Game (not overridable)
+	void ProcessInput(const uint8_t* keyState);
+	// Any actor-specific input code (overridable)
+	virtual void ActorInput(const uint8_t* keyState);
+
 	// Getters/setters
 	const Vector2& GetPosition() const { return mPosition; }
 	void SetPosition(const Vector2& pos) { mPosition = pos; ComputeWorldTransform(); }

+ 1 - 1
Chapter05/Component.cpp

@@ -3,7 +3,7 @@
 // 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.
 // ----------------------------------------------------------------
 
 #include "Component.h"

+ 5 - 1
Chapter05/Component.h

@@ -3,10 +3,12 @@
 // 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.
 // ----------------------------------------------------------------
 
 #pragma once
+#include <cstdint>
+
 class Component
 {
 public:
@@ -17,6 +19,8 @@ public:
 	virtual ~Component();
 	// Update this component by delta time
 	virtual void Update(float deltaTime);
+	// Process input for this component
+	virtual void ProcessInput(const uint8_t* keyState) {}
 
 	int GetUpdateOrder() const { return mUpdateOrder; }
 protected:

+ 72 - 40
Chapter05/Game.cpp

@@ -16,11 +16,13 @@
 #include "SpriteComponent.h"
 #include "Grid.h"
 #include "Enemy.h"
+#include "Actor.h"
 
 Game::Game()
 :mWindow(nullptr)
 ,mSpriteShader(nullptr)
 ,mIsRunning(true)
+,mUpdatingActors(false)
 {
 	
 }
@@ -112,12 +114,12 @@ void Game::ProcessInput()
 		}
 	}
 	
-	const Uint8* state = SDL_GetKeyboardState(NULL);
-	if (state[SDL_SCANCODE_ESCAPE])
+	const Uint8* keyState = SDL_GetKeyboardState(NULL);
+	if (keyState[SDL_SCANCODE_ESCAPE])
 	{
 		mIsRunning = false;
 	}
-	if (state[SDL_SCANCODE_B])
+	if (keyState[SDL_SCANCODE_B])
 	{
 		mGrid->BuildTower();
 	}
@@ -129,6 +131,13 @@ void Game::ProcessInput()
 	{
 		mGrid->ProcessClick(x, y);
 	}
+
+	mUpdatingActors = true;
+	for (auto actor : mActors)
+	{
+		actor->ProcessInput(keyState);
+	}
+	mUpdatingActors = false;
 }
 
 void Game::UpdateGame()
@@ -145,15 +154,20 @@ void Game::UpdateGame()
 	}
 	mTicksCount = SDL_GetTicks();
 
-	// Make copy of actor vector
-	// (iterate over this in case new actors are created)
-	std::vector<Actor*> copy = mActors;
-
 	// Update all actors
-	for (auto actor : copy)
+	mUpdatingActors = true;
+	for (auto actor : mActors)
 	{
 		actor->Update(deltaTime);
 	}
+	mUpdatingActors = false;
+
+	// Move any pending actors to mActors
+	for (auto pending : mPendingActors)
+	{
+		mActors.emplace_back(pending);
+	}
+	mPendingActors.clear();
 
 	// Add any dead actors to a temp vector
 	std::vector<Actor*> deadActors;
@@ -165,8 +179,7 @@ void Game::UpdateGame()
 		}
 	}
 
-	// Delete any of the dead actors (which will
-	// remove them from mActors)
+	// Delete dead actors (which removes them from mActors)
 	for (auto actor : deadActors)
 	{
 		delete actor;
@@ -232,20 +245,6 @@ void Game::CreateSpriteVerts()
 
 void Game::LoadData()
 {
-	// Load textures
-	LoadTexture("Assets/TileBrown.png");
-	LoadTexture("Assets/TileGreen.png");
-	LoadTexture("Assets/TileGrey.png");
-	LoadTexture("Assets/TileTan.png");
-	LoadTexture("Assets/TileBrownSelected.png");
-	LoadTexture("Assets/TileGreenSelected.png");
-	LoadTexture("Assets/TileGreySelected.png");
-	LoadTexture("Assets/TileTanSelected.png");
-	LoadTexture("Assets/Base.png");
-	LoadTexture("Assets/Tower.png");
-	LoadTexture("Assets/Airplane.png");
-	LoadTexture("Assets/Projectile.png");
-	
 	mGrid = new Grid(this);
 }
 
@@ -267,15 +266,6 @@ void Game::UnloadData()
 	mTextures.clear();
 }
 
-void Game::LoadTexture(const char* fileName)
-{
-	Texture* tex = new Texture();
-	if (tex->Load(fileName))
-	{
-		mTextures.emplace(fileName, tex);
-	}
-}
-
 Texture* Game::GetTexture(const std::string& fileName)
 {
 	Texture* tex = nullptr;
@@ -284,6 +274,19 @@ Texture* Game::GetTexture(const std::string& fileName)
 	{
 		tex = iter->second;
 	}
+	else
+	{
+		tex = new Texture();
+		if (tex->Load(fileName))
+		{
+			mTextures.emplace(fileName, tex);
+		}
+		else
+		{
+			delete tex;
+			tex = nullptr;
+		}
+	}
 	return tex;
 }
 
@@ -300,12 +303,30 @@ void Game::Shutdown()
 
 void Game::AddActor(Actor* actor)
 {
-	mActors.emplace_back(actor);
+	// If we're updating actors, need to add to pending
+	if (mUpdatingActors)
+	{
+		mPendingActors.emplace_back(actor);
+	}
+	else
+	{
+		mActors.emplace_back(actor);
+	}
 }
 
 void Game::RemoveActor(Actor* actor)
 {
-	auto iter = std::find(mActors.begin(), mActors.end(), actor);
+	// Is it in pending actors?
+	auto iter = std::find(mPendingActors.begin(), mPendingActors.end(), actor);
+	if (iter != mPendingActors.end())
+	{
+		// Swap to end of vector and pop off (avoid erase copies)
+		std::iter_swap(iter, mPendingActors.end() - 1);
+		mPendingActors.pop_back();
+	}
+
+	// Is it in actors?
+	iter = std::find(mActors.begin(), mActors.end(), actor);
 	if (iter != mActors.end())
 	{
 		// Swap to end of vector and pop off (avoid erase copies)
@@ -316,11 +337,22 @@ void Game::RemoveActor(Actor* actor)
 
 void Game::AddSprite(SpriteComponent* sprite)
 {
-	mSprites.emplace_back(sprite);
-	// Resort sprites by draw order
-	std::sort(mSprites.begin(), mSprites.end(), [](SpriteComponent* a, SpriteComponent* b) {
-		return a->GetDrawOrder() < b->GetDrawOrder();
-	});
+	// Find the insertion point in the sorted vector
+	// (The first element with a higher draw order than me)
+	int myDrawOrder = sprite->GetDrawOrder();
+	auto iter = mSprites.begin();
+	for (;
+		iter != mSprites.end();
+		++iter)
+	{
+		if (myDrawOrder < (*iter)->GetDrawOrder())
+		{
+			break;
+		}
+	}
+
+	// Inserts element before position of iterator
+	mSprites.insert(iter, sprite);
 }
 
 void Game::RemoveSprite(SpriteComponent* sprite)

+ 4 - 1
Chapter05/Game.h

@@ -27,7 +27,6 @@ public:
 	void AddSprite(class SpriteComponent* sprite);
 	void RemoveSprite(class SpriteComponent* sprite);
 	
-	void LoadTexture(const char* fileName);
 	class Texture* GetTexture(const std::string& fileName);
 	
 	class Grid* GetGrid() { return mGrid; }
@@ -47,6 +46,8 @@ private:
 
 	// All the actors in the game
 	std::vector<class Actor*> mActors;
+	// Any pending actors
+	std::vector<class Actor*> mPendingActors;
 
 	// All the sprite components drawn
 	std::vector<class SpriteComponent*> mSprites;
@@ -60,6 +61,8 @@ private:
 	SDL_GLContext mContext;
 	Uint32 mTicksCount;
 	bool mIsRunning;
+	// Track if we're updating actors right now
+	bool mUpdatingActors;
 
 	// Game-specific
 	std::vector<class Enemy*> mEnemies;