diff --git a/Player.cpp b/Player.cpp index 4f2024d..b6fa26c 100644 --- a/Player.cpp +++ b/Player.cpp @@ -25,4 +25,21 @@ void Player::rotate(float alpha) { 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; } diff --git a/Player.h b/Player.h index d39e571..eab2795 100644 --- a/Player.h +++ b/Player.h @@ -17,6 +17,14 @@ public: float y; float orientation; + float moveSpeed = 5; + float rotationSpeed = 180; + + float currentMoveSpeedX = 0; + float currentMoveSpeedY = 0; + + float currentRotationSpeed = 0; + /* View properties. */ float fov = 70; float sensorSize = 0.035; /* 35mm, about equivalent to human eye ? */ @@ -24,6 +32,7 @@ public: void move(float dx, float dy); void rotate(float alpha); + void updateSpeed(float localX, float localY); }; diff --git a/World.cpp b/World.cpp index 84be37c..f632b86 100644 --- a/World.cpp +++ b/World.cpp @@ -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); } diff --git a/World.h b/World.h index 91236c0..c098e68 100644 --- a/World.h +++ b/World.h @@ -30,11 +30,17 @@ public: int getW() 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 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); private: int w; diff --git a/main.cpp b/main.cpp index 19879b2..73c4dfc 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,6 @@ #include "World.h" -// TODO: Handle inputs to move player // TODO: Find a way to go to edges instead of just equally split (?) int main() @@ -18,16 +17,53 @@ int main() world.render(window); window.display(); + sf::Event event{}; + sf::Clock frameTime; while (window.isOpen()) { - sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) 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(); + world.step(frameTime.restart().asSeconds()); world.render(window); window.display(); }