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

Added AIComponent/AIState code

Sanjay Madhav 8 лет назад
Родитель
Сommit
10efcf8fa3

+ 54 - 0
Chapter04/AIComponent.cpp

@@ -0,0 +1,54 @@
+// ----------------------------------------------------------------
+// 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 "AIComponent.h"
+#include "Actor.h"
+#include "AIState.h"
+#include <SDL/SDL_log.h>
+
+AIComponent::AIComponent(class Actor* owner)
+:Component(owner)
+,mCurrentState(nullptr)
+{
+}
+
+void AIComponent::Update(float deltaTime)
+{
+	if (mCurrentState)
+	{
+		mCurrentState->Update(deltaTime);
+	}
+}
+
+void AIComponent::ChangeState(const std::string& name)
+{
+	// First exit the current state
+	if (mCurrentState)
+	{
+		mCurrentState->OnExit();
+	}
+	
+	// Try to find the new state from the map
+	auto iter = mStateMap.find(name);
+	if (iter != mStateMap.end())
+	{
+		mCurrentState = iter->second;
+		// We're entering the new state
+		mCurrentState->OnEnter();
+	}
+	else
+	{
+		SDL_Log("Could not find AIState %s in state map", name.c_str());
+		mCurrentState = nullptr;
+	}
+}
+
+void AIComponent::RegisterState(AIState* state)
+{
+	mStateMap.emplace(state->GetName(), state);
+}

+ 29 - 0
Chapter04/AIComponent.h

@@ -0,0 +1,29 @@
+// ----------------------------------------------------------------
+// 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 "Component.h"
+#include <unordered_map>
+#include <string>
+
+class AIComponent : public Component
+{
+public:
+	AIComponent(class Actor* owner);
+	
+	void Update(float deltaTime) override;
+	void ChangeState(const std::string& name);
+	
+	// Add a new state to the map
+	void RegisterState(class AIState* state);
+private:
+	// Maps name of state to AIState instance
+	std::unordered_map<std::string, class AIState*> mStateMap;
+	// Current state we're in
+	class AIState* mCurrentState;
+};

+ 61 - 0
Chapter04/AIState.cpp

@@ -0,0 +1,61 @@
+// ----------------------------------------------------------------
+// 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 "AIState.h"
+#include "AIComponent.h"
+#include <SDL/SDL_log.h>
+
+void AIPatrol::Update(float deltaTime)
+{
+	SDL_Log("Updating %s state", GetName());
+	bool dead = true;
+	if (dead)
+	{
+		mOwner->ChangeState("Death");
+	}
+}
+
+void AIPatrol::OnEnter()
+{
+	SDL_Log("Entering %s state", GetName());
+}
+
+void AIPatrol::OnExit()
+{
+	SDL_Log("Exiting %s state", GetName());
+}
+
+void AIDeath::Update(float deltaTime)
+{
+	SDL_Log("Updating %s state", GetName());
+}
+
+void AIDeath::OnEnter()
+{
+	SDL_Log("Entering %s state", GetName());
+}
+
+void AIDeath::OnExit()
+{
+	SDL_Log("Exiting %s state", GetName());
+}
+
+void AIAttack::Update(float deltaTime)
+{
+	SDL_Log("Updating %s state", GetName());
+}
+
+void AIAttack::OnEnter()
+{
+	SDL_Log("Entering %s state", GetName());
+}
+
+void AIAttack::OnExit()
+{
+	SDL_Log("Exiting %s state", GetName());
+}

+ 71 - 0
Chapter04/AIState.h

@@ -0,0 +1,71 @@
+// ----------------------------------------------------------------
+// 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
+
+class AIState
+{
+public:
+	AIState(class AIComponent* owner)
+		:mOwner(owner)
+	{ }
+	// State-specific behavior
+	virtual void Update(float deltaTime) = 0;
+	virtual void OnEnter() = 0;
+	virtual void OnExit() = 0;
+	// Getter for string name of state
+	virtual const char* GetName() const = 0;
+protected:
+	class AIComponent* mOwner;
+};
+
+class AIPatrol : public AIState
+{
+public:
+	AIPatrol(class AIComponent* owner)
+		:AIState(owner)
+	{ }
+
+	// Override with behaviors for this state
+	void Update(float deltaTime) override;
+	void OnEnter() override;
+	void OnExit() override;
+
+	const char* GetName() const override
+	{ return "Patrol"; }
+};
+
+class AIDeath : public AIState
+{
+public:
+	AIDeath(class AIComponent* owner)
+		:AIState(owner)
+	{ }
+
+	void Update(float deltaTime) override;
+	void OnEnter() override;
+	void OnExit() override;
+
+	const char* GetName() const override
+	{ return "Death"; }
+};
+
+class AIAttack : public AIState
+{
+public:
+	AIAttack(class AIComponent* owner)
+		:AIState(owner)
+	{ }
+
+	void Update(float deltaTime) override;
+	void OnEnter() override;
+	void OnExit() override;
+
+	const char* GetName() const override
+	{ return "Attack"; }
+};

+ 12 - 0
Chapter04/Game.cpp

@@ -13,6 +13,8 @@
 #include "SpriteComponent.h"
 #include "Grid.h"
 #include "Enemy.h"
+#include "AIComponent.h"
+#include "AIState.h"
 
 Game::Game()
 :mWindow(nullptr)
@@ -171,6 +173,16 @@ void Game::GenerateOutput()
 void Game::LoadData()
 {
 	mGrid = new Grid(this);
+
+	// For testing AIComponent
+	//Actor* a = new Actor(this);
+	//AIComponent* aic = new AIComponent(a);
+	//// Register states with AIComponent
+	//aic->RegisterState(new AIPatrol(aic));
+	//aic->RegisterState(new AIDeath(aic));
+	//aic->RegisterState(new AIAttack(aic));
+	//// Start in patrol state
+	//aic->ChangeState("Patrol");
 }
 
 void Game::UnloadData()

+ 4 - 0
Chapter04/Game.vcxproj

@@ -12,6 +12,8 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Actor.cpp" />
+    <ClCompile Include="AIComponent.cpp" />
+    <ClCompile Include="AIState.cpp" />
     <ClCompile Include="Bullet.cpp" />
     <ClCompile Include="CircleComponent.cpp" />
     <ClCompile Include="Component.cpp" />
@@ -28,6 +30,8 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Actor.h" />
+    <ClInclude Include="AIComponent.h" />
+    <ClInclude Include="AIState.h" />
     <ClInclude Include="Bullet.h" />
     <ClInclude Include="CircleComponent.h" />
     <ClInclude Include="Component.h" />

+ 12 - 0
Chapter04/Game.vcxproj.filters

@@ -49,6 +49,12 @@
     <ClCompile Include="Tower.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="AIComponent.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="AIState.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="Actor.h">
@@ -90,5 +96,11 @@
     <ClInclude Include="Tower.h">
       <Filter>Source Files</Filter>
     </ClInclude>
+    <ClInclude Include="AIComponent.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
+    <ClInclude Include="AIState.h">
+      <Filter>Source Files</Filter>
+    </ClInclude>
   </ItemGroup>
 </Project>