fix: Use incrementing instead of continuous
parent
b1af0e709c
commit
fe2fe20a58
117
as5/as5.cpp
117
as5/as5.cpp
|
|
@ -28,6 +28,14 @@ raylib::Degree angle_normalize(raylib::Degree angle) {
|
|||
return raylib::Degree(normalized + decimal);
|
||||
}
|
||||
|
||||
float shortest_angle_delta(raylib::Degree from, raylib::Degree to) {
|
||||
float diff = std::fmod(float(to) - float(from) + 180.0f, 360.0f);
|
||||
if (diff < 0.0f) {
|
||||
diff += 360.0f;
|
||||
}
|
||||
return diff - 180.0f;
|
||||
}
|
||||
|
||||
raylib::Vector3 velocity_from_speed_heading(float speed, raylib::Degree heading) {
|
||||
return raylib::Vector3{speed * std::sin(heading.RadianValue()), 0.0f,
|
||||
speed * std::cos(heading.RadianValue())};
|
||||
|
|
@ -264,22 +272,46 @@ struct InputComponent : public Component {
|
|||
raylib::BufferedInput *input = nullptr;
|
||||
bool isActive = false;
|
||||
|
||||
float axisForward = 0.0f;
|
||||
float axisTurn = 0.0f;
|
||||
bool keySpace = false;
|
||||
bool wishInitialized = false;
|
||||
float wishSpeed = 0.0f;
|
||||
raylib::Degree wishHeading = 0.0f;
|
||||
|
||||
// these do not actually indicate any acceleration or angular velocity, it
|
||||
// just updates the target velocity/heading, but the rate the character
|
||||
// turns to this target is limited by its PhysicsComponent
|
||||
float speedStep = 40.0f;
|
||||
float headingStep = 18.0f;
|
||||
|
||||
void Setup() override {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
|
||||
input->actions["forward"].AddCallback(
|
||||
[this](float state, float delta) { axisForward = state; });
|
||||
|
||||
input->actions["turn"].AddCallback([this](float state, float delta) { axisTurn = state; });
|
||||
|
||||
input->actions["space"].AddCallback(
|
||||
[this](float state, float delta) { keySpace = (state > 0.0f); });
|
||||
input->actions["forward_pos"].AddPressedCallback([this]() {
|
||||
if (isActive) {
|
||||
wishSpeed += speedStep;
|
||||
}
|
||||
});
|
||||
input->actions["forward_neg"].AddPressedCallback([this]() {
|
||||
if (isActive) {
|
||||
wishSpeed -= speedStep;
|
||||
}
|
||||
});
|
||||
input->actions["turn_pos"].AddPressedCallback([this]() {
|
||||
if (isActive) {
|
||||
wishHeading = angle_normalize(wishHeading + raylib::Degree(headingStep));
|
||||
}
|
||||
});
|
||||
input->actions["turn_neg"].AddPressedCallback([this]() {
|
||||
if (isActive) {
|
||||
wishHeading = angle_normalize(wishHeading - raylib::Degree(headingStep));
|
||||
}
|
||||
});
|
||||
input->actions["space"].AddPressedCallback([this]() {
|
||||
if (isActive) {
|
||||
wishSpeed = 0.0f;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Cleanup() override {}
|
||||
|
|
@ -296,19 +328,36 @@ struct InputComponent : public Component {
|
|||
return;
|
||||
}
|
||||
|
||||
// this is so we start with whatever velocity we had before as our wish
|
||||
// heading and velocity. otherwise at the start of the game, it just
|
||||
// moves you towards whatever wish was initialized with rather than
|
||||
// what the actual velocity/heading was.
|
||||
if (!wishInitialized) {
|
||||
wishHeading = tf->get().heading;
|
||||
|
||||
if (auto orientedInit = entity->GetComponent<OrientedPhysicsComponent>()) {
|
||||
wishSpeed = orientedInit->get().speed;
|
||||
} else if (auto physInit = entity->GetComponent<PhysicsComponent>()) {
|
||||
PhysicsComponent &p = physInit->get();
|
||||
wishSpeed = std::sqrt(p.velocity.x * p.velocity.x + p.velocity.z * p.velocity.z);
|
||||
}
|
||||
|
||||
wishInitialized = true;
|
||||
}
|
||||
|
||||
if (oriented) {
|
||||
OrientedPhysicsComponent &phys = oriented->get();
|
||||
|
||||
float forward = axisForward;
|
||||
float turn = axisTurn;
|
||||
wishSpeed = std::clamp(wishSpeed, -phys.maxSpeed, phys.maxSpeed);
|
||||
|
||||
phys.speed += forward * phys.acceleration * dt;
|
||||
tf->get().heading =
|
||||
angle_normalize(tf->get().heading + raylib::Degree(turn * phys.turningRate * dt));
|
||||
float speedDiff = wishSpeed - phys.speed;
|
||||
float maxSpeedStep = phys.acceleration * dt;
|
||||
phys.speed += std::clamp(speedDiff, -maxSpeedStep, maxSpeedStep);
|
||||
|
||||
if (keySpace) {
|
||||
phys.speed *= std::pow(0.05f, dt);
|
||||
}
|
||||
float headingDiff = shortest_angle_delta(tf->get().heading, wishHeading);
|
||||
float maxHeadingStep = phys.turningRate * dt;
|
||||
float headingStepNow = std::clamp(headingDiff, -maxHeadingStep, maxHeadingStep);
|
||||
tf->get().heading = angle_normalize(tf->get().heading + raylib::Degree(headingStepNow));
|
||||
} else {
|
||||
auto phys = entity->GetComponent<PhysicsComponent>();
|
||||
if (!phys) {
|
||||
|
|
@ -317,20 +366,20 @@ struct InputComponent : public Component {
|
|||
|
||||
PhysicsComponent &p = phys->get();
|
||||
|
||||
float spd = std::sqrt(p.velocity.x * p.velocity.x + p.velocity.z * p.velocity.z);
|
||||
float forward = axisForward;
|
||||
float turn = axisTurn;
|
||||
wishSpeed = std::clamp(wishSpeed, -p.maxSpeed, p.maxSpeed);
|
||||
|
||||
spd += forward * p.acceleration * dt;
|
||||
tf->get().heading =
|
||||
angle_normalize(tf->get().heading + raylib::Degree(turn * p.turningRate * dt));
|
||||
float currentSpeed =
|
||||
std::sqrt(p.velocity.x * p.velocity.x + p.velocity.z * p.velocity.z);
|
||||
float speedDiff = wishSpeed - currentSpeed;
|
||||
float maxSpeedStep = p.acceleration * dt;
|
||||
currentSpeed += std::clamp(speedDiff, -maxSpeedStep, maxSpeedStep);
|
||||
|
||||
if (keySpace) {
|
||||
spd *= std::pow(0.05f, dt);
|
||||
}
|
||||
float headingDiff = shortest_angle_delta(tf->get().heading, wishHeading);
|
||||
float maxHeadingStep = p.turningRate * dt;
|
||||
float headingStepNow = std::clamp(headingDiff, -maxHeadingStep, maxHeadingStep);
|
||||
tf->get().heading = angle_normalize(tf->get().heading + raylib::Degree(headingStepNow));
|
||||
|
||||
spd = std::clamp(spd, -p.maxSpeed, p.maxSpeed);
|
||||
p.velocity = velocity_from_speed_heading(spd, tf->get().heading);
|
||||
p.velocity = velocity_from_speed_heading(currentSpeed, tf->get().heading);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -357,12 +406,10 @@ int main() {
|
|||
|
||||
raylib::BufferedInput input;
|
||||
|
||||
input.actions["forward"] =
|
||||
raylib::Action::button_axis({raylib::Button::key(KEY_W)}, {raylib::Button::key(KEY_S)})
|
||||
.move();
|
||||
input.actions["turn"] =
|
||||
raylib::Action::button_axis({raylib::Button::key(KEY_A)}, {raylib::Button::key(KEY_D)})
|
||||
.move();
|
||||
input.actions["forward_pos"] = raylib::Action::key(KEY_W).move();
|
||||
input.actions["forward_neg"] = raylib::Action::key(KEY_S).move();
|
||||
input.actions["turn_pos"] = raylib::Action::key(KEY_A).move();
|
||||
input.actions["turn_neg"] = raylib::Action::key(KEY_D).move();
|
||||
input.actions["space"] = raylib::Action::key(KEY_SPACE).move();
|
||||
input.actions["tab"] = raylib::Action::key(KEY_TAB).move();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue