You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.8 KiB
C++

#include <cmath>
#include "player.hpp"
#include "vec2util.hpp"
namespace Proto4 {
Player::Player() : sf::CircleShape(30, 3) {
setFillColor(sf::Color(50, 150, 150));
setOrigin(30, 30);
}
void Player::update(sf::Time timeStep, sf::Vector2f mousePos) {
updateRotation(timeStep.asSeconds(), mousePos);
updateSpeed(timeStep.asSeconds(), keyboard2Acceleration());
}
void Player::reset() {
speed = sf::Vector2f{0, 0};
setRotation(0.f);
}
sf::Vector2f Player::keyboard2Acceleration() {
sf::Vector2f acceleration = sf::Vector2f(0, 0);
if (
sf::Keyboard::isKeyPressed(sf::Keyboard::Left) ||
sf::Keyboard::isKeyPressed(sf::Keyboard::A)
) acceleration.x -= 100.f;
if (
sf::Keyboard::isKeyPressed(sf::Keyboard::Right) ||
sf::Keyboard::isKeyPressed(sf::Keyboard::D)
) acceleration.x += 100.f;
if (
sf::Keyboard::isKeyPressed(sf::Keyboard::Up) ||
sf::Keyboard::isKeyPressed(sf::Keyboard::W)
) acceleration.y -= 100.f;
if (
sf::Keyboard::isKeyPressed(sf::Keyboard::Down) ||
sf::Keyboard::isKeyPressed(sf::Keyboard::S)
) acceleration.y += 100.f;
return normalized(acceleration);
}
void Player::updateSpeed(float timeStep, sf::Vector2f accel) {
accel *= acceleration * timeStep;
float decel = 1 - deceleration * timeStep;
// x / y accelerate & decelerate separately
// to allow for exponential deceleration
if (accel.y == 0.f) speed.y *= decel;
else speed.y += accel.y;
if (accel.x == 0.f) speed.x *= decel;
else speed.x += accel.x;
// normalize with speed limit * timeStep
float currentSpeed = magnitude(speed);
if (currentSpeed > maxSpeed)
speed *= maxSpeed / currentSpeed;
move(speed * timeStep);
}
void Player::updateRotation(float timeStep, sf::Vector2f mousePos) {
sf::Vector2f playerPos = getPosition();
if (playerPos == mousePos) return;
//calc mouse<>player angle
float targetRotation = -180 - atan2(mousePos.x - playerPos.x, mousePos.y - playerPos.y) * 180 / PI;
float rot = getRotation();
float rotationDiff = std::remainder(targetRotation - rot + 180, 360);
//limit rotationspeed
if (rotationDiff > maxRotationSpeed * timeStep)
rot -= maxRotationSpeed * timeStep;
else if (rotationDiff < -maxRotationSpeed * timeStep)
rot += maxRotationSpeed * timeStep;
else
rot = targetRotation;
//bring the value back down into the interval [0, 360]
if (rot < 0) rot += 360;
else if (rot > 360) rot -= 360;
setRotation(rot);
}
}