Commit 40ac3f77 authored by Jonas Johan Solsvik's avatar Jonas Johan Solsvik 🎮
Browse files

Collision between two enemies working ok

- Still some way to go
- A lot of tunneling is happening
parent b7b2117b
......@@ -16,17 +16,27 @@ struct Thing
sf::RectangleShape shape{};
};
struct Controller
{
ThingID thingID{};
bool up{};
bool down{};
bool left{};
bool right{};
uint debounceUpMs{};
uint debounceDownMs{};
uint debounceLeftMs{};
uint debounceRightMs{};
};
using ThingVector = std::vector<Thing>;
using ThingIDVector = std::vector<ThingID>;
auto eventsUpdate(
sf::RenderWindow &window,
sf::View &camera) -> void;
auto physicsUpdate(
ThingVector &things,
const ThingIDVector &dynamicThings,
const ThingIDVector &staticThings) -> void;
sf::View &camera,
std::vector<Controller> &controllers,
const sf::Clock gameClock) -> void;
auto physicsUpdate(
ThingVector &things,
......@@ -41,6 +51,7 @@ auto physicsTestCollision(
auto animationUpdate(
ThingVector &things,
std::vector<Controller> &controllers,
const sf::Time deltaTime) -> void;
auto renderUpdate(
......@@ -91,15 +102,21 @@ auto main() -> int
things.push_back(ground);
}
sf::Clock clock; // starts the clock
std::vector<Controller> controllers{
Controller{thingID : 0},
Controller{thingID : 1}}; // One controller for each player
sf::Clock gameClock{}; // Never restart
sf::Clock frameClock{}; // Restart every frame
while (window.isOpen())
{
const auto deltaTime = clock.getElapsedTime();
clock.restart();
const auto deltaTime = frameClock.getElapsedTime();
frameClock.restart();
eventsUpdate(window, camera);
eventsUpdate(window, camera, controllers, gameClock);
physicsUpdate(things, deltaTime, dynamicThings, staticThings);
animationUpdate(things, deltaTime);
animationUpdate(things, controllers, deltaTime);
renderUpdate(window, things);
}
......@@ -108,8 +125,13 @@ auto main() -> int
auto eventsUpdate(
sf::RenderWindow &window,
sf::View &camera) -> void
sf::View &camera,
std::vector<Controller> &controllers,
const sf::Clock gameClock) -> void
{
auto &controller1 = controllers[0];
auto &controller2 = controllers[1];
// # Process events
sf::Event event;
while (window.pollEvent(event))
......@@ -121,7 +143,75 @@ auto eventsUpdate(
{
window.close();
}
if (event.type == sf::Event::Resized)
else if (event.type == sf::Event::KeyPressed)
{
const auto elapsedMs = gameClock.getElapsedTime().asMilliseconds();
const uint KEY_DEBOUNCE = 400;
/**
* Controller 1 - W + A + S + D
*/
if (
event.key.code == sf::Keyboard::W &&
controller1.debounceUpMs < elapsedMs)
{
controller1.up = true;
controller1.debounceUpMs = elapsedMs + KEY_DEBOUNCE;
}
else if (
event.key.code == sf::Keyboard::A &&
controller1.debounceLeftMs < elapsedMs)
{
controller1.left = true;
controller1.debounceLeftMs = elapsedMs + KEY_DEBOUNCE;
}
else if (
event.key.code == sf::Keyboard::S &&
controller1.debounceDownMs < elapsedMs)
{
controller1.down = true;
controller1.debounceDownMs = elapsedMs + KEY_DEBOUNCE;
}
else if (
event.key.code == sf::Keyboard::D &&
controller1.debounceRightMs < elapsedMs)
{
controller1.right = true;
controller1.debounceRightMs = elapsedMs + KEY_DEBOUNCE;
}
/**
* Controller 2 - Up + Left + Down + Right
*/
else if (
event.key.code == sf::Keyboard::Up &&
controller2.debounceUpMs < elapsedMs)
{
controller2.up = true;
controller2.debounceUpMs = elapsedMs + KEY_DEBOUNCE;
}
else if (
event.key.code == sf::Keyboard::Left &&
controller2.debounceLeftMs < elapsedMs)
{
controller2.left = true;
controller2.debounceLeftMs = elapsedMs + KEY_DEBOUNCE;
}
else if (
event.key.code == sf::Keyboard::Down &&
controller2.debounceDownMs < elapsedMs)
{
controller2.down = true;
controller2.debounceDownMs = elapsedMs + KEY_DEBOUNCE;
}
else if (
event.key.code == sf::Keyboard::Right &&
controller2.debounceRightMs < elapsedMs)
{
controller2.right = true;
controller2.debounceRightMs = elapsedMs + KEY_DEBOUNCE;
}
}
else if (event.type == sf::Event::Resized)
{
sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
camera.setSize(event.size.width, event.size.height);
......@@ -136,8 +226,6 @@ auto physicsUpdate(
const ThingIDVector &dynamicThings,
const ThingIDVector &staticThings) -> void
{
const auto GRAVITY = 10.0f * 50;
const auto MAX_Y = 10.0f * 100;
const auto dt = deltaTime.asSeconds();
for (const auto dynamicThingID : dynamicThings)
......@@ -145,7 +233,12 @@ auto physicsUpdate(
auto &dynamicThing = things[dynamicThingID];
// Add gravity to velocity
{
dynamicThing.velocity.y = std::min(dynamicThing.velocity.y + GRAVITY * dt, MAX_Y);
const float DRAG_COEFFISIENT = 1.0 - dt * 2;
const float GRAVITY = 10.0f * 50;
const float SPEED_OF_CAUSALITY_Y = 10.0f * 100;
const float SPEED_OF_CAUSALITY_X = 10.0f * 100;
dynamicThing.velocity.x = std::min(dynamicThing.velocity.x * DRAG_COEFFISIENT, SPEED_OF_CAUSALITY_X);
dynamicThing.velocity.y = std::min(dynamicThing.velocity.y + GRAVITY * dt * DRAG_COEFFISIENT, SPEED_OF_CAUSALITY_Y);
}
for (const auto otherDynamicThingID : dynamicThings)
......@@ -165,8 +258,8 @@ auto physicsUpdate(
}
/**
* @function physicsTestCollision - Test collision between two rectangles (things)
* physicsTestCollision() - Test collision between two rectangles (things)
*
* The algorithm is explained step-by-step by inline block comments below
*
* Assumptions:
......@@ -299,12 +392,6 @@ auto physicsTestCollision(
}
else
{
std::cout << "----OUTSIDE: "
<< collidingThing.id
<< " -> " << impactThing.id
<< " cy: " << collidingThing.shape.getPosition().y
<< " iy: " << impactThing.shape.getPosition().y
<< "\n";
return; // ...return early if no `insideCorner` found
}
......@@ -454,15 +541,46 @@ auto physicsTestCollision(
}
}
const float BOUNCINESS = 400.f;
const sf::Vector2f JUMP_UP{0, -BOUNCINESS};
const sf::Vector2f JUMP_DOWN{0, BOUNCINESS};
const sf::Vector2f JUMP_LEFT{-BOUNCINESS, 0};
const sf::Vector2f JUMP_RIGHT{BOUNCINESS, 0};
auto animationUpdate(
ThingVector &things,
std::vector<Controller> &controllers,
const sf::Time deltaTime) -> void
{
for (auto &controller : controllers)
{
if (controller.up)
{
things[controller.thingID].velocity += JUMP_UP;
controller.up = false; // Event consumed
}
if (controller.left)
{
things[controller.thingID].velocity += JUMP_LEFT;
controller.left = false; // Event consumed
}
if (controller.down)
{
things[controller.thingID].velocity += JUMP_DOWN;
controller.down = false; // Event consumed
}
if (controller.right)
{
things[controller.thingID].velocity += JUMP_RIGHT;
controller.right = false; // Event consumed
}
}
const auto dt = deltaTime.asSeconds();
for (auto &thing : things)
{
const auto position = thing.shape.getPosition();
const auto velocity = thing.velocity;
const auto dt = deltaTime.asSeconds();
thing.shape.setPosition(
position.x + velocity.x * dt,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment