Fix digging

This commit is contained in:
Bram Verhulst
2024-04-20 20:20:54 +02:00
parent ebda39f690
commit 5477b8a7f2
11 changed files with 258 additions and 126 deletions

View File

@@ -21,6 +21,7 @@ Player::Player(const Vector2f& Position, TextureManager* manager) : m_Position(P
8, 0.1f, Rectf { 0, 0, 70, 70 });
m_currentAnimation = m_walkAnimation;
}
Collision::CollisionRect Player::GetCollisionRect() const {
Collision::CollisionRect rect = { m_Position, m_Size, m_Vel };
return rect;
@@ -36,15 +37,17 @@ void Player::Draw() const {
const int frameWidth = 70; //TODO: fix this
int halfFrameWidth = frameWidth / 2;
float bobOffset = m_BobUp ? 1 : 0;
Vector2f drawPos = Vector2f { center.x - halfFrameWidth, center.y - halfFrameWidth + 9 + bobOffset} ;
Vector2f drawPos = Vector2f { center.x - halfFrameWidth, center.y - halfFrameWidth + 9 + bobOffset };
m_walkAnimation->Draw(drawPos, Rectf { drawPos.x, drawPos.y , frameWidth, frameWidth });
m_walkAnimation->Draw(drawPos, Rectf { drawPos.x, drawPos.y, frameWidth, frameWidth });
utils::DrawEllipse(m_DigDestination, 5, 5);
utils::DrawEllipse(m_DigStart, 5, 5);
}
void Player::ProcessImGui() {
ImGui::Begin("Collision Info", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
ImGui::Text("is Grounded: %s", m_Grounded ? "true" : "false");
ImGui::Checkbox("Draw Collision Rect", &m_DrawCollisionRect);
std::string currentState{};
std::string currentState {};
switch (m_State) {
case PlayerState::Idle:
currentState = "Idle";
@@ -59,8 +62,8 @@ void Player::ProcessImGui() {
ImGui::Text("Player State %s", currentState.c_str());
ImGui::Text("Bob counter: %f", m_BobTimer);
ImGui::Text("Bob up: %s", m_BobUp ? "true" : "false");
//ContactMap
ImGui::Text("ContactMap:");
ImGui::Text("Top: %s", m_ContactMap[Collision::CollisionDirection::Top] != nullptr ? "true" : "false");
@@ -69,53 +72,88 @@ void Player::ProcessImGui() {
ImGui::Text("Right: %s", m_ContactMap[Collision::CollisionDirection::Right] != nullptr ? "true" : "false");
ImGui::End();
}
void Player::Dig(Collision::CollisionDirection dir, WorldLevel& level) {
m_State = PlayerState::Digging;
m_DigProgress = 0;
m_DigTile = m_ContactMap[dir];
//Set the digging location in the center of the destination tile;
const WorldTile* tile = m_ContactMap[dir];
//Add case for bottom because otherwise i clip through the floor
m_DigDestination = tile->GetPosition();
if (dir == Collision::Bottom) {
m_DigDestination += Vector2f { 0, 2 };
//Center
m_DigDestination.x += tile->GetSize().x / 2 - m_Size.x / 2;
}
if(dir == Collision::Left) {
m_DigDestination += Vector2f{ 2, 0};
}
m_ContactMap[dir] = nullptr;
}
bool Player::CanDig(Collision::CollisionDirection dir, WorldLevel& level) {
WorldTile* tile = m_ContactMap[dir];
if (tile == nullptr) {
return false;
}
GroundTileType type = *tile->GetTileType();
//TODO: Add a list of non diggable tiles
if (type == Tiles::Special::HARD_LEFT || type == Tiles::Special::HARD_MIDDLE || type == Tiles::Special::HARD_RIGHT) {
return false;
}
return true;
}
void Player::Update(float elapsedTime, WorldLevel& level) {
m_BobTimer += elapsedTime;
if(m_BobTimer >= m_BobTime) {
if (m_BobTimer >= m_BobTime) {
m_BobUp = !m_BobUp;
m_BobTimer = 0.0f;
}
//check for keys
if(m_State != PlayerState::Digging) {
if (m_State != PlayerState::Digging) {
m_Vel = Vector2f { 0, -100 };
if (utils::isKeyDown(SDL_SCANCODE_W)) {
m_Vel.y = 100;
m_Grounded = false;
}
if (utils::isKeyPressed(SDL_SCANCODE_S)) {
m_Vel.y = -100;
if (m_Grounded) {
if (m_ContactMap[Collision::CollisionDirection::Bottom] != nullptr) {
//Do the digging
m_State = PlayerState::Digging;
m_DigProgress = 0;
m_DigTile = m_ContactMap[Collision::CollisionDirection::Bottom];
//Set the digging location in the center of the destination tile;
const WorldTile* tile = m_ContactMap[Collision::CollisionDirection::Bottom];
m_DigDestination = tile->GetPosition() + Vector2f{0, 0};
m_ContactMap[Collision::CollisionDirection::Bottom] = nullptr;
if (this->CanDig(Collision::Bottom, level)) {
this->Dig(Collision::CollisionDirection::Bottom, level);
}
}
else {
m_Vel.y = -100;
}
}
if (utils::isKeyDown(SDL_SCANCODE_A)) {
m_walkAnimation->SetFlipped(false);
m_Vel.x = -100;
if (m_Grounded && !m_DidJustDigLeft) {
//Check if the player doesnt come from digging a tile
if (this->CanDig(Collision::CollisionDirection::Left, level)) {
this->Dig(Collision::CollisionDirection::Left, level);
m_DidJustDigLeft = true;
}
}
}
if (m_DidJustDigLeft) {
if (!utils::isKeyDown(SDL_SCANCODE_A)) {
m_DidJustDigLeft = false;
}
}
if (utils::isKeyDown(SDL_SCANCODE_D)) {
m_Vel.x = 100;
m_walkAnimation->SetFlipped(true);
if (m_Grounded && !m_DidJustDigRight) {
//Check if the player doesnt come from digging a tile
if (m_ContactMap[Collision::CollisionDirection::Right] != nullptr) {
m_ContactMap[Collision::CollisionDirection::Right]->SetTileType(Tiles::AIR);
WorldTile* tile = m_ContactMap[Collision::CollisionDirection::Right];
//center of tile
const Vector2f tileCenter = tile->GetCollisionRect().getCollisionRect().pos + tile->GetCollisionRect().getCollisionRect().size / 2;
m_Position = Vector2f { tileCenter.x - m_Size.x / 2, tileCenter.y - m_Size.y / 2 + 5 };
m_ContactMap[Collision::CollisionDirection::Right] = nullptr;
if (this->CanDig(Collision::CollisionDirection::Right, level)) {
this->Dig(Collision::CollisionDirection::Right, level);
m_DidJustDigRight = true;
}
}
@@ -126,6 +164,7 @@ void Player::Update(float elapsedTime, WorldLevel& level) {
}
}
m_walkAnimation->Update(elapsedTime);
@@ -155,8 +194,7 @@ void Player::Update(float elapsedTime, WorldLevel& level) {
}
}
std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair<int, float>& a, const std::pair<int, float>& b)
{
std::sort(contactTimes.begin(), contactTimes.end(), [](const std::pair<int, float>& a, const std::pair<int, float>& b) {
return a.second < b.second;
});
@@ -198,7 +236,7 @@ void Player::Update(float elapsedTime, WorldLevel& level) {
Collision::CollisionRect rect = world_tile->GetCollisionRect().getCollisionRect(); //TODO: fix this mess
Collision::ResolvePlayerVsRect(*this, elapsedTime, &rect);
}
if(m_State != PlayerState::Digging) { //Fix for when the state is JUST set to digging
if (m_State != PlayerState::Digging) { //Fix for when the state is JUST set to digging
if (m_Vel.x != 0.0f) {
m_State = PlayerState::Walking;
}
@@ -207,7 +245,6 @@ void Player::Update(float elapsedTime, WorldLevel& level) {
}
}
}
switch (m_State) {
case PlayerState::Idle:
m_walkAnimation->SetPlaying(false);
@@ -218,11 +255,17 @@ void Player::Update(float elapsedTime, WorldLevel& level) {
case PlayerState::Digging: {
m_walkAnimation->SetPlaying(false);
//Diganimation
if (!m_Digging) { //TODO: fix for setting the start position
m_Digging = true;
m_DigStart = m_Position;
}
m_DigProgress += elapsedTime;
//lerp to the destination
float progress = utils::map(m_DigProgress, 0.0f, m_DigTime, 0.0f, 1.0f);
std::cout << progress << '\n';
m_Position = utils::lerp(m_Position, m_DigDestination, progress);
m_Position = utils::lerp(m_DigStart, m_DigDestination, progress);
if (progress >= 0.5f && !m_HasDeletedTile) {
m_DigTile->SetTileType(Tiles::AIR);
m_DigTile = nullptr;
@@ -231,15 +274,15 @@ void Player::Update(float elapsedTime, WorldLevel& level) {
if (progress >= 1.0f) {
m_State = PlayerState::Idle;
m_HasDeletedTile = false;
m_Digging = false;
}
break;
}
default:
break;
}
if(m_State != PlayerState::Digging) {
if (m_State != PlayerState::Digging) {
m_Position = m_Position + m_Vel * elapsedTime;
}
}