diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/AI.h | 14 | ||||
| -rw-r--r-- | src/crepe/system/AISystem.cpp | 34 | ||||
| -rw-r--r-- | src/crepe/system/AISystem.h | 2 | ||||
| -rw-r--r-- | src/example/AITest.cpp | 21 | 
4 files changed, 60 insertions, 11 deletions
| diff --git a/src/crepe/api/AI.h b/src/crepe/api/AI.h index d4bd9d3..35b8998 100644 --- a/src/crepe/api/AI.h +++ b/src/crepe/api/AI.h @@ -36,6 +36,8 @@ public:  		if (on(PATH_FOLLOW)) flags ^= PATH_FOLLOW;  	} +	void add_path_node(vec2 node) { path.push_back(node); } +  public:  	float max_force; @@ -47,9 +49,21 @@ public:  	float square_flee_panic_distance = 200.0f * 200.0f;  	// The deceleration rate for the arrive behavior (higher values will make the entity decelerate faster (less overshoot))  	float arrive_deceleration = 40.0f; +	// The path to follow +	std::vector<vec2> path; +	// The distance from the path node at which the entity will move to the next node +	float path_node_distance = 400.0f; +	// Looping behavior for the path +	bool path_loop = true;  private: +	// The flags for the behaviors  	int flags = 0; +	// The current path index +	size_t path_index = 0; + +	// The AISystem is the only class that can access the private members of AI +	friend class AISystem;  };  } // namespace crepe diff --git a/src/crepe/system/AISystem.cpp b/src/crepe/system/AISystem.cpp index ce3147f..55dc14c 100644 --- a/src/crepe/system/AISystem.cpp +++ b/src/crepe/system/AISystem.cpp @@ -55,11 +55,11 @@ vec2 AISystem::calculate(AI & ai) {  		}  	}  	if (ai.on(AI::BehaviorType::PATH_FOLLOW)) { -		/*vec2 force_to_add = this->path_follow(ai); +		vec2 force_to_add = this->path_follow(ai);  		if (!this->accumulate_force(ai, force, force_to_add)) {  			return force; -		}*/ +		}  	}  	return force; @@ -138,3 +138,33 @@ vec2 AISystem::arrive(const AI & ai) {  	return vec2{0, 0};  } + +vec2 AISystem::path_follow(AI & ai) { +	const Mediator & mediator = this->mediator; +	ComponentManager & mgr = mediator.component_manager; +	RefVector<Transform> transforms = mgr.get_components_by_id<Transform>(ai.game_object_id); +	Transform & transform = transforms.front().get(); +	RefVector<Rigidbody> rigidbodies = mgr.get_components_by_id<Rigidbody>(ai.game_object_id); +	Rigidbody & rigidbody = rigidbodies.front().get(); + +	if (ai.path.empty()) { +		return vec2{0, 0}; +	} + +	vec2 to_target = ai.path.at(ai.path_index) - transform.position; +	if (to_target.length_squared() > ai.path_node_distance * ai.path_node_distance) { +		ai.seek_target = ai.path.at(ai.path_index); +	} else { +		ai.path_index++; +		if (ai.path_index >= ai.path.size()) { +			if (ai.path_loop) { +				ai.path_index = 0; +			} else { +				ai.path_index = ai.path.size() - 1; +				return this->arrive(ai); +			} +		} +	} + +	return this->seek(ai); +} diff --git a/src/crepe/system/AISystem.h b/src/crepe/system/AISystem.h index 18f1c61..27861d9 100644 --- a/src/crepe/system/AISystem.h +++ b/src/crepe/system/AISystem.h @@ -20,7 +20,7 @@ private:  	vec2 seek(const AI & ai);  	vec2 flee(const AI & ai);  	vec2 arrive(const AI & ai); -	vec2 path_follow(const AI & ai); +	vec2 path_follow(AI & ai);  };  } // namespace crepe diff --git a/src/example/AITest.cpp b/src/example/AITest.cpp index 319d0fe..d12a99a 100644 --- a/src/example/AITest.cpp +++ b/src/example/AITest.cpp @@ -25,10 +25,10 @@ class Script1 : public Script {  	}  	bool mousemove(const MouseMoveEvent & event) { -		RefVector<AI> aivec = this->get_components<AI>(); +		/*RefVector<AI> aivec = this->get_components<AI>();  		AI & ai = aivec.front().get();  		ai.flee_target -			= vec2{static_cast<float>(event.mouse_x), static_cast<float>(event.mouse_y)}; +			= vec2{static_cast<float>(event.mouse_x), static_cast<float>(event.mouse_y)};*/  		return true;  	} @@ -46,21 +46,26 @@ public:  		Mediator & mediator = this->mediator;  		ComponentManager & mgr = mediator.component_manager; -		GameObject game_object1 = mgr.new_object("", "", vec2{250, 250}, 0, 1); +		GameObject game_object1 = mgr.new_object("", "", vec2{0, 0}, 0, 1);  		GameObject game_object2 = mgr.new_object("", "", vec2{0, 0}, 0, 1);  		Texture img = Texture("asset/texture/test_ap43.png");  		game_object1.add_component<Sprite>(img, Color::MAGENTA,  										   Sprite::FlipSettings{false, false}, 1, 1, 195); -		AI & ai = game_object1.add_component<AI>(30); -		ai.arrive_on(); -		ai.flee_on(); +		AI & ai = game_object1.add_component<AI>(300); +		// ai.arrive_on(); +		// ai.flee_on(); +		ai.path_follow_on(); +		ai.add_path_node(vec2{1200, 1200}); +		ai.add_path_node(vec2{-1200, 1200}); +		ai.add_path_node(vec2{1200, -1200}); +		ai.add_path_node(vec2{-1200, -1200});  		game_object1.add_component<Rigidbody>(Rigidbody::Data{ -			.mass = 0.5f, .max_linear_velocity = {21, 21}, // sqrt(21^2 + 21^2) = 30 +			.mass = 0.5f, .max_linear_velocity = {50, 50}, // sqrt(21^2 + 21^2) = 30  		});  		game_object1.add_component<BehaviorScript>().set_script<Script1>(); -		game_object2.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{1036, 780}, +		game_object2.add_component<Camera>(Color::WHITE, ivec2{1080, 720}, vec2{5000, 5000},  										   1.0f);  	} |