Mushroom Collisions
Damaging and Bouncing
// -----
#include "engine/rectangle_collider.h" // Add: Include RectangleCollider.
class Mushroom {
public:
// -----
bool GetIsDead() const;
void TakeDamage();
// -----
private:
// -----
// --- Add: Store the collider so that it's possible to check for collisions and death state. ---
const ng::RectangleCollider* collider_ = nullptr;
bool is_dead_ = false;
// --- End ---
};// -----
// --- Add: Includes. ---
#include <vector>
#include "engine/collider.h"
#include "engine/rectangle_collider.h"
#include "player.h"
// --- End ---
Mushroom::Mushroom(ng::App* app, const ng::Tilemap* tilemap) {
// -----
// --- Add: Add collider as child of the mushroom. ---
auto& collider = MakeChild<ng::RectangleCollider>(sf::Vector2f(32, 32));
collider.SetLocalPosition({0, 16});
collider_ = &collider;
// --- End ---
}
// -----
// --- Add: Death getter and TakeDamage. ---
bool Mushroom::GetIsDead() const {
return is_dead_;
}
void Mushroom::TakeDamage() {
if (is_dead_) {
return;
}
is_dead_ = true;
Destroy();
}
// --- End ---
// -----
void Mushroom::Update() {
// --- Add: Stop if mushroom is dead. ---
if (is_dead_) {
return;
}
// --- End ---
// -----
sf::Vector2f old_pos = collider_->GetGlobalTransform().getPosition(); // Change: Use collider position.
sf::Vector2f new_pos = old_pos + velocity_;
sf::Vector2f col_half_size = collider_->GetSize() / 2.F; // Change: Use collider size instead of hard-coded size.
sf::Vector2f tilemap_size = sf::Vector2f(tilemap_->GetTileSize());
// -----
SetLocalPosition(new_pos - collider_->GetLocalTransform().getPosition()); // Change: Remove collider's local position offset.
// -----
if (!tilemap_->IsWithinWorldBounds(top_left) ||
!tilemap_->IsWithinWorldBounds(bottom_left)) {
TakeDamage(); // Add: TakeDamage when outside of bounds.
return;
}
// -----
if (!tilemap_->IsWithinWorldBounds(top_right) ||
!tilemap_->IsWithinWorldBounds(bottom_right)) {
TakeDamage(); // Add: TakeDamage when outside of bounds.
return;
}
// -----
if (!tilemap_->IsWithinWorldBounds(top_left) ||
!tilemap_->IsWithinWorldBounds(top_right)) {
TakeDamage(); // Add: TakeDamage when outside of bounds.
return;
}
// -----
if (!tilemap_->IsWithinWorldBounds(bottom_left) ||
!tilemap_->IsWithinWorldBounds(bottom_right)) {
TakeDamage(); // Add: TakeDamage when outside of bounds.
return;
}
// -----
// --- Add: Check collisions with the Player and other Mushrooms. ---
std::vector<const ng::Collider*> others =
GetScene()->GetPhysics().Overlap(*collider_);
for (const auto* other : others) {
if (other->GetParent()->GetName() == "Player") {
auto* player = dynamic_cast<Player*>(other->GetParent());
if (player->GetVelocity().y <= 0) {
player->TakeDamage();
}
} else if (other->GetParent()->GetName() == "Mushroom") {
auto* mushroom = dynamic_cast<Mushroom*>(other->GetParent());
if (!mushroom->GetIsDead()) {
mushroom->direction_.x = -mushroom->direction_.x;
direction_.x = -direction_.x;
}
}
}
// --- End ---
}Last updated