Made player radius dynamic

This commit is contained in:
Maximilian Giller 2023-06-11 15:18:22 +02:00
parent 74ca505b60
commit 4b96f4f9be
11 changed files with 108 additions and 41 deletions

View file

@ -88,7 +88,7 @@ set(SOURCES
src/game/level/level_config.hpp
src/game/level/level_loader.cpp
src/game/level/level_loader.hpp
src/levels.hpp)
src/levels.hpp src/game/physics/map_player.cpp)
set(PHYSICS_00_SOURCES
src/prototypes/physics_00.cpp)

View file

@ -8,6 +8,7 @@
// Player
#define DEFAULT_PLAYER_SPEED 5.f // World units per second
#define DEFAULT_PLAYER_RADIUS .5f // In World units
#define PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED 0.4f
// FPS
#define FRAME_RATE 60

View file

@ -13,7 +13,7 @@ WorldCoordinates TranslatedCoordinates::world() const {
}
IsometricCoordinates TranslatedCoordinates::isometric() const {
return coordTransformer->worldToIsometric(world());
return CoordinateTransformer::worldToIsometric(world());
}
GridCoordinates TranslatedCoordinates::grid() const {
@ -28,7 +28,7 @@ void TranslatedCoordinates::set(WorldCoordinates newWorldCoordinates) {
}
void TranslatedCoordinates::set(IsometricCoordinates newIsometricCoordinates) {
this->worldCoordinates = coordTransformer->isometricToWorld(newIsometricCoordinates);
this->worldCoordinates = CoordinateTransformer::isometricToWorld(newIsometricCoordinates);
}
void TranslatedCoordinates::set(const TranslatedCoordinates& newCoordinates) {
@ -58,3 +58,13 @@ void TranslatedCoordinates::set(GridCoordinates newGridCoordinates)
{
this->worldCoordinates = {newGridCoordinates.x / worldToGridFactor, newGridCoordinates.y / worldToGridFactor, 0};
}
void TranslatedCoordinates::setWorldOffset(WorldCoordinates offset)
{
this->worldCoordinates = offset;
}
void TranslatedCoordinates::setScreenOffset(IsometricCoordinates offset)
{
setWorldOffset(CoordinateTransformer::isometricToWorld(offset));
}

View file

@ -36,10 +36,13 @@ public:
void setParent(std::shared_ptr<TranslatedCoordinates> parent, WorldCoordinates offset = {0, 0});
void setWorldOffset(WorldCoordinates offset);
void setScreenOffset(IsometricCoordinates offset);
private:
WorldCoordinates worldCoordinates;
const float worldToGridFactor = INITIAL_WORLD_TO_GRID_FACTOR;
const std::shared_ptr<CoordinateTransformer> coordTransformer = std::make_shared<CoordinateTransformer>();
std::shared_ptr<TranslatedCoordinates> parent = nullptr;
};

View file

@ -7,7 +7,8 @@ enum GameAction
CANCEL,
MENU,
JUMP
GROW,
SHRINK
};
#endif //HOLESOME_GAME_ACTION_HPP

View file

@ -0,0 +1,44 @@
#include "map_player.hpp"
void MapPlayer::updateSimulationPosition()
{
auto coordinates = player->coordinates->world();
b2Vec2 playerPosition = b2Vec2(coordinates.x, coordinates.y);
// Calculate velocity that theoretically needs to be applied to the body, to get to the same position
b2Vec2 delta = playerPosition - body->GetPosition();
b2Vec2 velocity = {delta.x * FRAME_RATE, delta.y * FRAME_RATE};
body->SetLinearVelocity(velocity);
if (player->getWorldRadius() != shapeRadius)
{
updateShape();
}
}
void MapPlayer::updatePlayerPosition() const
{
b2Vec2 playerPosition = body->GetPosition();
player->coordinates->set(sf::Vector2f(playerPosition.x, playerPosition.y));
}
void MapPlayer::updateShape()
{
shapeRadius = player->getWorldRadius();
b2Fixture *oldFixture = body->GetFixtureList();
if (oldFixture != nullptr) {
body->DestroyFixture(oldFixture);
}
b2CircleShape shape;
shape.m_radius = shapeRadius;
shape.m_p.Set(0, 0);
b2FixtureDef fixtureDef;
fixtureDef.shape = &shape;
fixtureDef.density = 1.0f;
body->CreateFixture(&fixtureDef);
}

View file

@ -6,31 +6,23 @@
#include "../player/player.hpp"
#include "../../config.h"
struct MapPlayer
class MapPlayer
{
public:
Player *player;
b2Body *body;
float shapeRadius = 0;
MapPlayer(Player *player, b2Body *body) : player(player), body(body)
{}
void updateSimulationPosition() const
{
auto coordinates = player->coordinates->world();
b2Vec2 playerPosition = b2Vec2(coordinates.x, coordinates.y);
// Calculate velocity that theoretically needs to be applied to the body, to get to the same position
b2Vec2 delta = playerPosition - body->GetPosition();
b2Vec2 velocity = {delta.x * FRAME_RATE, delta.y * FRAME_RATE};
body->SetLinearVelocity(velocity);
updateShape();
}
void updatePlayerPosition() const
{
b2Vec2 playerPosition = body->GetPosition();
player->coordinates->set(sf::Vector2f(playerPosition.x, playerPosition.y));
}
void updateSimulationPosition();
void updatePlayerPosition() const;
void updateShape();
};

View file

@ -68,15 +68,5 @@ void MapSimulation::addPlayer(Player *player)
bodyDef.type = b2_dynamicBody;
bodyDef.position.Set(player->coordinates->world().x, player->coordinates->world().y);
b2Body *body = world->CreateBody(&bodyDef);
b2CircleShape shape;
shape.m_radius = player->getWorldRadius();
shape.m_p.Set(0, 0);
b2FixtureDef fixtureDef;
fixtureDef.shape = &shape;
fixtureDef.density = 1.0f;
body->CreateFixture(&fixtureDef);
mapPlayersById[player->getPlayerId()] = std::make_shared<MapPlayer>(player, body);
}

View file

@ -12,8 +12,8 @@ Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &
input = std::move(assignedInput);
auto sprite = std::make_shared<VersatileSprite>(skinRessourceName, getIsoSize());
addChildScreenOffset(sprite, IsometricCoordinates(-getIsoSize() / 2.f));
skinSprite = std::make_shared<VersatileSprite>(skinRessourceName, getIsoSize());
addChildScreenOffset(skinSprite, IsometricCoordinates(-getIsoSize() / 2.f));
}
sf::Vector2f Player::getTrackablePosition() const
@ -38,9 +38,17 @@ void Player::update()
auto moveDelta = moveDirection * speed * FRAME_TIME.asSeconds();
coordinates->move(moveDelta);
if (input->isPerformingAction(GameAction::JUMP))
if (input->isPerformingAction(GameAction::GROW))
{
coordinates->move({0, 0, 10});
setWorldRadius(radiusInWorld * (1 + PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED * FRAME_TIME.asSeconds()));
} else if (input->isPerformingAction(GameAction::SHRINK))
{
auto newRadius = radiusInWorld * (1 - PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED * FRAME_TIME.asSeconds());
if (newRadius <= DEFAULT_PLAYER_RADIUS)
{
newRadius = DEFAULT_PLAYER_RADIUS;
}
setWorldRadius(newRadius);
}
GameObject::update();
@ -74,3 +82,13 @@ sf::Vector2f Player::getIsoSize() const
float width = radiusInWorld * 2.f * WORLD_TO_ISO_SCALE * fixFactor;
return {width, width * ISOMETRIC_SKEW};
}
void Player::setWorldRadius(float newWorldRadius)
{
radiusInWorld = newWorldRadius;
// Update skin
auto newSize = getIsoSize();
skinSprite->setSize(newSize);
skinSprite->coordinates->setScreenOffset(IsometricCoordinates(-newSize / 2.f));
}

View file

@ -34,11 +34,14 @@ public:
private:
std::shared_ptr<InputIdentity> input;
float radiusInWorld = DEFAULT_PLAYER_RADIUS;
std::shared_ptr<VersatileSprite> skinSprite;
sf::Vector2f spawnPosition;
int playerId;
static inline int playerCreationCounter = 0;
void setWorldRadius(float newWorldRadius);
};

View file

@ -17,31 +17,36 @@ const std::map<sf::Keyboard::Key, ButtonConfig> KEY_CONFIGS = {
{sf::Keyboard::Down, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::DOWN)},
{sf::Keyboard::Left, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::LEFT)},
{sf::Keyboard::Right, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::RIGHT)},
{sf::Keyboard::RControl, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::JUMP})},
{sf::Keyboard::RControl, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::GROW})},
{sf::Keyboard::Numpad0, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::SHRINK})},
{sf::Keyboard::W, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::UP)},
{sf::Keyboard::S, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::DOWN)},
{sf::Keyboard::A, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::LEFT)},
{sf::Keyboard::D, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::RIGHT)},
{sf::Keyboard::Space, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::JUMP})},
{sf::Keyboard::Space, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::GROW})},
{sf::Keyboard::Q, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::SHRINK})},
{sf::Keyboard::I, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::UP)},
{sf::Keyboard::K, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::DOWN)},
{sf::Keyboard::J, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::LEFT)},
{sf::Keyboard::L, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::RIGHT)},
{sf::Keyboard::B, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::JUMP})}
{sf::Keyboard::U, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::GROW})},
{sf::Keyboard::O, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::SHRINK})}
};
// Gamepad buttons
const std::map<int, ButtonConfig> GAMEPAD_BUTTON_CONFIGS = {
{GamepadButton::SOUTH, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::JUMP})}
{GamepadButton::EAST, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::GROW})},
{GamepadButton::SOUTH, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::SHRINK})}
};
// Actions
const std::map<GameAction, GameActionConfig> GAME_ACTION_CONFIGS = {
{GameAction::JUMP, GameActionConfig(InteractionMode::PRESS)}
{GameAction::GROW, GameActionConfig(InteractionMode::HOLD)},
{GameAction::SHRINK, GameActionConfig(InteractionMode::HOLD)}
};
#endif //HOLESOME_INPUT_CONFIG_H