enhance the AI movement process
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
#include "player/AI.h"
|
||||
|
||||
#include <InputEventAction.hpp>
|
||||
|
||||
void alai::player::AI::_register_methods()
|
||||
{
|
||||
godot::register_method("_ready", &AI::_ready);
|
||||
godot::register_method("_physics_process", &AI::_physics_process);
|
||||
godot::register_method("_on_object_report", &AI::_on_object_report);
|
||||
godot::register_method("_on_timer_timeout", &AI::_on_timer_timeout);
|
||||
}
|
||||
|
||||
alai::player::AI::AI()
|
||||
@@ -27,78 +30,142 @@ void alai::player::AI::_ready()
|
||||
|
||||
event = get_node<alai::Event>("/root/Event");
|
||||
event->connect("report_object", this, "_on_object_report");
|
||||
|
||||
add_child(timer);
|
||||
timer->set_wait_time(1);
|
||||
auto err = timer->connect("timeout", this, "_on_timer_timeout");
|
||||
if (err != godot::Error::OK)
|
||||
{
|
||||
godot::Godot::print("Timer could not be connected!");
|
||||
}
|
||||
}
|
||||
|
||||
void alai::player::AI::_physics_process(float delta)
|
||||
{
|
||||
auto player_position = parent->get_global_position();
|
||||
auto player_direction = parent->get_velocity();
|
||||
bool walking = false;
|
||||
|
||||
std::sort(entities.begin(), entities.end(), [](const Entity &a, const Entity &b) -> bool
|
||||
{
|
||||
return a.position.x < b.position.x;
|
||||
});
|
||||
|
||||
while (!entities.empty())
|
||||
{
|
||||
const auto& entity = entities.front();
|
||||
const auto &entity = entities.front();
|
||||
|
||||
if (obelisk->query(entity.name.utf8().get_data(), "is", "touchable") > 0)
|
||||
auto entityName = entity.name.utf8().get_data();
|
||||
|
||||
double distance = std::abs(player_position.x - entity.position.x);
|
||||
|
||||
int jump_distance = -1;
|
||||
auto action = obelisk->queryAction(entityName, "is", "bouncable");
|
||||
if (action == "jump on")
|
||||
{
|
||||
jump_distance = 100;
|
||||
}
|
||||
else if (action == "jump over")
|
||||
{
|
||||
jump_distance = 50;
|
||||
}
|
||||
|
||||
if (lastEntity == "")
|
||||
{
|
||||
if (jump_distance != -1 && distance < jump_distance)
|
||||
{
|
||||
lastEntity = entity.originalName;
|
||||
timer->start();
|
||||
if (player_position.x < entity.position.x)
|
||||
{
|
||||
auto ev = godot::InputEventAction()._new();
|
||||
ev->set_action("jump");
|
||||
ev->set_pressed(true);
|
||||
_input->parse_input_event(ev);
|
||||
}
|
||||
else if (player_position.x > entity.position.x)
|
||||
{
|
||||
auto ev = godot::InputEventAction()._new();
|
||||
ev->set_action("jump");
|
||||
ev->set_pressed(true);
|
||||
_input->parse_input_event(ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obelisk->query(entityName, "is", "gold") > 0 && obelisk->query(std::string("gold ") + entityName, "is", "collectable") > 0)
|
||||
{
|
||||
auto player_position = parent->get_global_position();
|
||||
if (entity.position.x > player_position.x)
|
||||
{
|
||||
_input->action_press("right");
|
||||
if (!walking && !_input->is_action_pressed("left") && !_input->is_action_pressed("right"))
|
||||
{
|
||||
walking = true;
|
||||
_input->action_press("right");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_input->action_press("left");
|
||||
}
|
||||
}
|
||||
|
||||
if (obelisk->query(entity.name.utf8().get_data(), "is", "bouncable") > 0)
|
||||
{
|
||||
auto player_position = parent->get_global_position();
|
||||
auto distance = sqrt(pow(player_position.x - entity.position.x, 2) + pow(player_position.y - entity.position.y, 2));
|
||||
int jump_distance = 0;
|
||||
|
||||
auto player_direction = parent->get_velocity();
|
||||
|
||||
auto action = obelisk->queryAction(entity.name.utf8().get_data(), "is", "bouncable");
|
||||
if (action == "jump on")
|
||||
{
|
||||
jump_distance = 100;
|
||||
}
|
||||
else if (action == "jump over")
|
||||
{
|
||||
jump_distance = 50;
|
||||
}
|
||||
|
||||
if (distance < jump_distance)
|
||||
{
|
||||
if (_input->is_action_pressed("right") && player_position.x < entity.position.x)
|
||||
if (!walking && !_input->is_action_pressed("left") && !_input->is_action_pressed("right"))
|
||||
{
|
||||
_input->action_press("jump");
|
||||
}
|
||||
else if (_input->is_action_pressed("left") && player_position.x > entity.position.x)
|
||||
{
|
||||
_input->action_press("jump");
|
||||
walking = true;
|
||||
_input->action_press("left");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (obelisk->query(entity.name.utf8().get_data(), "is", "gold") > 0 && obelisk->query(std::string("gold ") + entity.name.utf8().get_data(), "is", "collectable") > 0)
|
||||
{
|
||||
auto player_position = parent->get_global_position();
|
||||
float distance = player_position.x - entity.position.x;
|
||||
if (distance > -10 && distance < 10 && player_position.y - entity.position.y > 20)
|
||||
{
|
||||
_input->action_press("jump");
|
||||
timer->stop();
|
||||
lastEntity = "";
|
||||
if (!_input->is_action_pressed("jump"))
|
||||
{
|
||||
_input->action_press("jump");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entities.pop();
|
||||
if (obelisk->query(entityName, "is", "touchable") > 0)
|
||||
{
|
||||
if (!walking && !_input->is_action_pressed("left") && !_input->is_action_pressed("right"))
|
||||
{
|
||||
walking = true;
|
||||
if (entity.position.x > player_position.x)
|
||||
{
|
||||
_input->action_press("right");
|
||||
}
|
||||
else
|
||||
{
|
||||
_input->action_press("left");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entities.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
void alai::player::AI::unset_action(godot::String action)
|
||||
{
|
||||
auto ev = godot::InputEventAction()._new();
|
||||
ev->set_action(action);
|
||||
ev->set_pressed(false);
|
||||
_input->parse_input_event(ev);
|
||||
}
|
||||
|
||||
void alai::player::AI::_on_timer_timeout()
|
||||
{
|
||||
unset_action("left");
|
||||
unset_action("right");
|
||||
unset_action("jump");
|
||||
lastEntity = "";
|
||||
}
|
||||
|
||||
void alai::player::AI::_on_object_report(godot::String name, godot::String state, godot::Vector2 position, godot::Vector2 velocity)
|
||||
{
|
||||
auto entity = Entity();
|
||||
entity.name = name.to_lower().rstrip("0123456789");
|
||||
entity.state = state;
|
||||
entity.position = position;
|
||||
entity.velocity = velocity;
|
||||
entities.push(entity);
|
||||
auto entity = Entity();
|
||||
entity.originalName = name;
|
||||
entity.name = name.to_lower().rstrip("0123456789");
|
||||
entity.state = state;
|
||||
entity.position = position;
|
||||
entity.velocity = velocity;
|
||||
entities.emplace_front(entity);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <Godot.hpp>
|
||||
#include <Input.hpp>
|
||||
#include <Node.hpp>
|
||||
#include <Timer.hpp>
|
||||
#include <Vector2.hpp>
|
||||
#include <queue>
|
||||
|
||||
@@ -18,6 +19,7 @@ namespace alai
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
godot::String originalName;
|
||||
godot::String name;
|
||||
godot::String state;
|
||||
godot::Vector2 position;
|
||||
@@ -43,10 +45,14 @@ namespace alai
|
||||
|
||||
alai::Event* event;
|
||||
|
||||
std::queue<alai::player::Entity> entities;
|
||||
std::deque<alai::player::Entity> entities;
|
||||
|
||||
alai::player::Player* parent;
|
||||
|
||||
godot::String lastEntity;
|
||||
|
||||
godot::Timer* timer = godot::Timer()._new();
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief This method registers classes with Godot.
|
||||
@@ -56,7 +62,16 @@ namespace alai
|
||||
static void
|
||||
_register_methods();
|
||||
|
||||
/**
|
||||
* @brief Construct a new AI object.
|
||||
*
|
||||
*/
|
||||
AI();
|
||||
|
||||
/**
|
||||
* @brief Destroy the AI object.
|
||||
*
|
||||
*/
|
||||
~AI();
|
||||
|
||||
/**
|
||||
@@ -80,6 +95,18 @@ namespace alai
|
||||
*/
|
||||
void _physics_process(float delta);
|
||||
|
||||
void _on_timer_timeout();
|
||||
|
||||
void unset_action(godot::String action);
|
||||
|
||||
/**
|
||||
* @brief Callback that receives information about the game environment.
|
||||
*
|
||||
* @param[in] name The name of the object.
|
||||
* @param[in] state The state the object is in.
|
||||
* @param[in] position The position of the object.
|
||||
* @param[in] velocity The object's velocity.
|
||||
*/
|
||||
void _on_object_report(godot::String name, godot::String state, godot::Vector2 position, godot::Vector2 velocity);
|
||||
};
|
||||
} // namespace player
|
||||
|
||||
Reference in New Issue
Block a user