1
0
Fork 0

Implement moving the player

Player: Add rotation and linear speeds, as well as their current state.
Player: Allow to move in the local coordinates and compute
    world-speed equivalent.
Player: Update movement axis while rotating.

World: Add a function to advance a step.
Main: Handle key events, add world step in the main loop.
This commit is contained in:
Teo-CD 2024-01-21 22:11:46 +00:00
parent cad775f88e
commit b47052aa4d
5 changed files with 80 additions and 3 deletions

View file

@ -25,4 +25,21 @@ void Player::rotate(float alpha)
{ {
orientation += 360; orientation += 360;
} }
/*
* Rotate the movement vector along the new angle, assumes that the only
* speed influencing the player is its own movement.
*/
float prevSpeedX = currentMoveSpeedX;
float prevSpeedY = currentMoveSpeedY;
currentMoveSpeedX = cosf(-alpha * deg_to_rad) * prevSpeedX
- sinf(-alpha * deg_to_rad) * prevSpeedY;
currentMoveSpeedY = sinf(-alpha * deg_to_rad) * prevSpeedX
+ cosf(-alpha * deg_to_rad) * prevSpeedY;
}
void Player::updateSpeed(float localX, float localY) {
// TODO: Support strafing.
currentMoveSpeedX = localX * sinf(orientation*deg_to_rad)*moveSpeed;
currentMoveSpeedY = localX * cosf(orientation*deg_to_rad)*moveSpeed;
} }

View file

@ -17,6 +17,14 @@ public:
float y; float y;
float orientation; float orientation;
float moveSpeed = 5;
float rotationSpeed = 180;
float currentMoveSpeedX = 0;
float currentMoveSpeedY = 0;
float currentRotationSpeed = 0;
/* View properties. */ /* View properties. */
float fov = 70; float fov = 70;
float sensorSize = 0.035; /* 35mm, about equivalent to human eye ? */ float sensorSize = 0.035; /* 35mm, about equivalent to human eye ? */
@ -24,6 +32,7 @@ public:
void move(float dx, float dy); void move(float dx, float dy);
void rotate(float alpha); void rotate(float alpha);
void updateSpeed(float localX, float localY);
}; };

View file

@ -243,4 +243,13 @@ void World::render(sf::RenderWindow& window) const
} }
} }
void World::step(const float& stepTime) {
player.move(player.currentMoveSpeedX*stepTime,
player.currentMoveSpeedY*stepTime);
/* Undo last move if the player would end up in a wall. */
if (getBlock((int)player.x, (int)player.y) != BlockType::AIR) {
player.move(-player.currentMoveSpeedX*stepTime,
-player.currentMoveSpeedY*stepTime);
}
player.rotate(player.currentRotationSpeed*stepTime);
} }

View file

@ -30,11 +30,17 @@ public:
int getW() const; int getW() const;
int getH() const; int getH() const;
BlockType getBlock(float x, float y) const; inline BlockType getBlock(float x, float y) const;
void setBlock(BlockType block, int x, int y, int width = 1, int height = 1); void setBlock(BlockType block, int x, int y, int width = 1, int height = 1);
void render(sf::RenderWindow&) const; void render(sf::RenderWindow&) const;
/**
* Move the world one step forward.
* @param stepTime delta time since last step, in seconds
*/
void step(const float& stepTime);
friend std::ostream& operator<<(std::ostream& ostream, World const & world); friend std::ostream& operator<<(std::ostream& ostream, World const & world);
private: private:
int w; int w;

View file

@ -3,7 +3,6 @@
#include "World.h" #include "World.h"
// TODO: Handle inputs to move player
// TODO: Find a way to go to edges instead of just equally split (?) // TODO: Find a way to go to edges instead of just equally split (?)
int main() int main()
@ -18,16 +17,53 @@ int main()
world.render(window); world.render(window);
window.display(); window.display();
sf::Event event{};
sf::Clock frameTime;
while (window.isOpen()) while (window.isOpen())
{ {
sf::Event event;
while (window.pollEvent(event)) while (window.pollEvent(event))
{ {
if (event.type == sf::Event::Closed) if (event.type == sf::Event::Closed)
window.close(); window.close();
else if (event.type == sf::Event::KeyPressed) {
switch (event.key.code) {
case sf::Keyboard::Key::Escape:
window.close();
break;
case sf::Keyboard::Key::Left:
world.player.currentRotationSpeed = -world.player.rotationSpeed;
break;
case sf::Keyboard::Key::Right:
world.player.currentRotationSpeed = world.player.rotationSpeed;
break;
case sf::Keyboard::Key::Up:
world.player.updateSpeed(1, 0);
break;
case sf::Keyboard::Key::Down:
world.player.updateSpeed(-1, 0);
break;
default:
break;
}
}
else if (event.type == sf::Event::KeyReleased) {
switch (event.key.code) {
case sf::Keyboard::Key::Left:
case sf::Keyboard::Key::Right:
world.player.currentRotationSpeed = 0;
break;
case sf::Keyboard::Key::Up:
case sf::Keyboard::Key::Down:
world.player.updateSpeed(0, 0);
break;
default:
break;
}
}
} }
window.clear(); window.clear();
world.step(frameTime.restart().asSeconds());
world.render(window); world.render(window);
window.display(); window.display();
} }