Mario: end of level logic
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
zv0n 2022-09-23 16:46:50 +02:00
parent 6211e8c756
commit 3437aa6b47
8 changed files with 88 additions and 23 deletions

View File

@ -47,7 +47,7 @@ void MarioBlock::visit(SDLPP::Visitor &visitor) {
// TODO if big mario and _can_be_destroyed // TODO if big mario and _can_be_destroyed
if (_destructible && !hasCoin()) { if (_destructible && !hasCoin()) {
destroy(); destroy();
} else { } else if (_bouncable) {
BounceVisitor bv; BounceVisitor bv;
bv.setVisitorType(VisitorType::Terrain); bv.setVisitorType(VisitorType::Terrain);

View File

@ -64,6 +64,14 @@ protected:
virtual void setWorldTypeSrc(LandType::Value world); virtual void setWorldTypeSrc(LandType::Value world);
bool isBouncable() {
return _bouncable;
}
void setBouncable(bool bouncable = true) {
_bouncable = bouncable;
}
private: private:
bool _tool = false; bool _tool = false;
bool _terrain = true; bool _terrain = true;
@ -85,6 +93,7 @@ private:
int _ticks_till_gravity = 0; int _ticks_till_gravity = 0;
double _gravity_acceleration = 1.0 / (64.0 / 7.0); double _gravity_acceleration = 1.0 / (64.0 / 7.0);
bool _was_visible = false; bool _was_visible = false;
bool _bouncable = true;
}; };
extern const std::vector<uint64_t> possibleBlocks; extern const std::vector<uint64_t> possibleBlocks;

View File

@ -204,6 +204,7 @@ PoleTopBlock::PoleTopBlock(int x, int y,
: MarioBlock(x, y, renderer, g_terrain_texture, POLE_TOP_SRC, false) { : MarioBlock(x, y, renderer, g_terrain_texture, POLE_TOP_SRC, false) {
ensureCollision(); ensureCollision();
setId(POLE_TOP_ID); setId(POLE_TOP_ID);
setBouncable(false);
} }
PoleBottomBlock::PoleBottomBlock(int x, int y, PoleBottomBlock::PoleBottomBlock(int x, int y,
@ -212,11 +213,13 @@ PoleBottomBlock::PoleBottomBlock(int x, int y,
false) { false) {
ensureCollision(); ensureCollision();
setId(POLE_BOTTOM_ID); setId(POLE_BOTTOM_ID);
setBouncable(false);
} }
FlagBlock::FlagBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer) FlagBlock::FlagBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_terrain_texture, FLAG_SRC, false) { : MarioBlock(x, y, renderer, g_terrain_texture, FLAG_SRC, false) {
setId(FLAG_ID); setId(FLAG_ID);
setBouncable(false);
} }
StepBlock::StepBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer) StepBlock::StepBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> &renderer)

View File

@ -70,12 +70,11 @@ void handleKeyDown(SDL_Keycode key, SDLPP::Scene &scene) {
void handleKeyUp(SDL_Keycode key) { void handleKeyUp(SDL_Keycode key) {
switch (key) { switch (key) {
case SDLK_ESCAPE: case SDLK_ESCAPE: {
{ std::lock_guard<std::mutex> lock(render_mutex);
std::lock_guard<std::mutex> lock(render_mutex); game_scenes.push_back(
game_scenes.push_back(createGameMainMenuScene(renderer, false, true, true)); createGameMainMenuScene(renderer, false, true, true));
} } break;
break;
case SDLK_a: case SDLK_a:
mario->walkRight(); mario->walkRight();
break; break;
@ -147,7 +146,7 @@ void pollEvents(SDLPP::Scene &scene) {
} }
void doInputMainGame(std::shared_ptr<SDLPP::Scene> scene) { void doInputMainGame(std::shared_ptr<SDLPP::Scene> scene) {
if(newLoaded) { if (newLoaded) {
auto prev_mario_pos = mario->getAbsolutePos(); auto prev_mario_pos = mario->getAbsolutePos();
scene->updateSizeAndPosition(); scene->updateSizeAndPosition();
moveToMarioPosition(*scene, prev_mario_pos); moveToMarioPosition(*scene, prev_mario_pos);
@ -155,8 +154,9 @@ void doInputMainGame(std::shared_ptr<SDLPP::Scene> scene) {
update_count = 2; update_count = 2;
newLoaded = false; newLoaded = false;
} }
if(g_death) { if (g_death) {
game_scenes.push_back(createGameMainMenuScene(renderer, true, false, true)); game_scenes.push_back(
createGameMainMenuScene(renderer, true, false, true));
g_death = false; g_death = false;
} }
pollEvents(*scene); pollEvents(*scene);
@ -170,12 +170,11 @@ void doInputMainGame(std::shared_ptr<SDLPP::Scene> scene) {
continue; continue;
} }
auto visitor = getVisitor(*moving_objects[i], *scene, g_death, auto visitor = getVisitor(*moving_objects[i], *scene, g_death,
coin_count, moving_objects); coin_count, moving_objects);
scene->visitCollisions(*moving_objects[i], *visitor); scene->visitCollisions(*moving_objects[i], *visitor);
moving_objects[i]->handleVisitor(*visitor); moving_objects[i]->handleVisitor(*visitor);
auto rightmost_pos = auto rightmost_pos = moving_objects[i]->getAbsolutePos().getX() +
moving_objects[i]->getAbsolutePos().getX() + moving_objects[i]->getDoubleRect().second.getX();
moving_objects[i]->getDoubleRect().second.getX();
if (rightmost_pos < 0 && moving_objects[i] != mario) { if (rightmost_pos < 0 && moving_objects[i] != mario) {
moving_objects[i]->destroy(); moving_objects[i]->destroy();
} }
@ -203,10 +202,13 @@ void doInputMainGame(std::shared_ptr<SDLPP::Scene> scene) {
auto rightmostX = auto rightmostX =
scene->rightmost()->getRect().x + scene->rightmost()->getRect().w; scene->rightmost()->getRect().x + scene->rightmost()->getRect().w;
scene->moveEverything((playerX > rightBarrier && rightmostX > width) * scene->moveEverything((playerX > rightBarrier && rightmostX > width) *
(rightBarrier - playerX) / width, (rightBarrier - playerX) / width,
0); 0);
update = update || (playerX > rightBarrier && rightmostX > width); update = update || (playerX > rightBarrier && rightmostX > width);
global_frames++; global_frames++;
if (mario->isDead()) {
g_death = true;
}
} }
void doInput() { void doInput() {
@ -221,7 +223,7 @@ void doInput() {
} }
} }
void mainGameAdditional(std::shared_ptr<SDLPP::Scene> &/*UNUSED*/) { void mainGameAdditional(std::shared_ptr<SDLPP::Scene> & /*UNUSED*/) {
static auto base = SDL_GetTicks(); static auto base = SDL_GetTicks();
static int frames = 0; static int frames = 0;
mario->setStanding(); mario->setStanding();
@ -326,10 +328,10 @@ SceneStruct mainGameScene(const std::string &level_path) {
} }
void loadLevel(const std::string &level) { void loadLevel(const std::string &level) {
//std::lock_guard<std::mutex> lock(render_mutex); // std::lock_guard<std::mutex> lock(render_mutex);
coin_count = 0; coin_count = 0;
std::lock_guard<std::mutex> lock(gamescene_mutex); std::lock_guard<std::mutex> lock(gamescene_mutex);
for(auto &scene : game_scenes) { for (auto &scene : game_scenes) {
scene.scene->resetScene(); scene.scene->resetScene();
} }
game_scenes.clear(); game_scenes.clear();
@ -343,7 +345,7 @@ void loadLevel(const std::string &level) {
} }
void loadLastLevel() { void loadLastLevel() {
if(last_load_level != "") { if (last_load_level != "") {
loadLevel(last_load_level); loadLevel(last_load_level);
} }
} }
@ -380,7 +382,8 @@ int main() {
auto font = std::make_shared<SDLPP::Font>("testfont.ttf", 36); auto font = std::make_shared<SDLPP::Font>("testfont.ttf", 36);
g_text_config = std::make_shared<SDLPP::FontConfiguration>(font, "#FFFFFF", g_text_config = std::make_shared<SDLPP::FontConfiguration>(font, "#FFFFFF",
"#000000", 0.15); "#000000", 0.15);
game_scenes.push_back(createGameMainMenuScene(renderer, false, false, false)); game_scenes.push_back(
createGameMainMenuScene(renderer, false, false, false));
std::thread inputThread(doInput); std::thread inputThread(doInput);
SDL_PumpEvents(); SDL_PumpEvents();
@ -394,10 +397,10 @@ int main() {
SDL_PumpEvents(); SDL_PumpEvents();
std::lock_guard<std::mutex> lock(render_mutex); std::lock_guard<std::mutex> lock(render_mutex);
if (update) { if (update) {
for(auto &scene : game_scenes) { for (auto &scene : game_scenes) {
scene.scene->updateSizeAndPosition(); scene.scene->updateSizeAndPosition();
} }
if(update_count > 0) { if (update_count > 0) {
update_count--; update_count--;
} else { } else {
update = false; update = false;

View File

@ -1,4 +1,5 @@
#include "mario.hpp" #include "mario.hpp"
#include "blocks.hpp"
#include "global_vars.hpp" #include "global_vars.hpp"
#include "objectids.hpp" #include "objectids.hpp"
#include "sprites.hpp" #include "sprites.hpp"
@ -34,6 +35,9 @@ Mario::Mario(int x, int y, const std::shared_ptr<SDLPP::Renderer> &renderer)
Mario::Mario(const std::shared_ptr<SDLPP::Renderer> &renderer) Mario::Mario(const std::shared_ptr<SDLPP::Renderer> &renderer)
: Mario(0, 0, renderer) {} : Mario(0, 0, renderer) {}
void Mario::walkLeft() { void Mario::walkLeft() {
if (!controllable) {
return;
}
if (on_ground) if (on_ground)
resumeAnimation(); resumeAnimation();
addMovement(-side_movement, 0); addMovement(-side_movement, 0);
@ -46,6 +50,9 @@ void Mario::walkLeft() {
} }
void Mario::walkRight() { void Mario::walkRight() {
if (!controllable) {
return;
}
if (on_ground) if (on_ground)
resumeAnimation(); resumeAnimation();
addMovement(side_movement, 0); addMovement(side_movement, 0);
@ -73,6 +80,9 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) {
if (!jumping && on_ground) { if (!jumping && on_ground) {
resetMovementY(); resetMovementY();
setBaseRect(MARIO_STANDING_SRC); setBaseRect(MARIO_STANDING_SRC);
if (!controllable) {
setDeath();
}
if (getMovement().getX() != 0) if (getMovement().getX() != 0)
resumeAnimation(); resumeAnimation();
// for some reason falling of the edge causes on_ground to be true, but // for some reason falling of the edge causes on_ground to be true, but
@ -120,10 +130,20 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) {
if (m_visitor.hasMushroom()) { if (m_visitor.hasMushroom()) {
setType(LandType::UNDERWORLD); setType(LandType::UNDERWORLD);
} }
if (m_visitor.levelEnd() && controllable) {
if (std::abs(getPos().getX() - m_visitor.getEndPos().getX()) <
BLOCK_SIZE / 8) {
setPos(m_visitor.getEndPos().getX(), getPos().getY());
stopMovement();
}
}
#endif #endif
} }
void Mario::jump() { void Mario::jump() {
if (!controllable) {
return;
}
if (!on_ground) if (!on_ground)
return; return;
jumping = true; jumping = true;
@ -172,3 +192,8 @@ void Mario::setWorldTypeSrc(LandType::Value /*UNUSED*/) {
MarioBlock::setWorldTypeSrc(LandType::OVERWORLD); MarioBlock::setWorldTypeSrc(LandType::OVERWORLD);
// TODO // TODO
} }
void Mario::stopMovement() {
controllable = false;
setMovement(0, getMovement().getY());
}

View File

@ -17,8 +17,16 @@ public:
void stopJump(); void stopJump();
void custom_move(int ticks) override; void custom_move(int ticks) override;
void visit(SDLPP::Visitor &visitor) override; void visit(SDLPP::Visitor &visitor) override;
bool isDead() {
return _death;
}
private: private:
void setDeath(bool dead = true) {
_death = dead;
}
bool _death = false;
bool controllable = true;
bool faces_right = true; bool faces_right = true;
double side_movement = 0.3; double side_movement = 0.3;
double jump_movement = 1.0; double jump_movement = 1.0;
@ -35,6 +43,7 @@ private:
const double gravity_add_falling = jump_movement / (64.0 / 7.0); const double gravity_add_falling = jump_movement / (64.0 / 7.0);
std::shared_ptr<SDLPP::RectColider> top_collision = nullptr; std::shared_ptr<SDLPP::RectColider> top_collision = nullptr;
void setWorldTypeSrc(LandType::Value world) override; void setWorldTypeSrc(LandType::Value world) override;
void stopMovement();
}; };
#endif #endif

View File

@ -67,6 +67,12 @@ void MarioVisitor::visit(const SDLPP::RenderObject &obj) {
case MUSHROOM_ID: case MUSHROOM_ID:
mushroom = true; mushroom = true;
break; break;
case POLE_BOTTOM_ID:
case POLE_TOP_ID:
case FLAG_ID:
_end = true;
endPos = obj.getPos();
break;
default: default:
break; break;
} }

View File

@ -108,6 +108,14 @@ public:
return _bounce; return _bounce;
} }
bool levelEnd() {
return _end;
}
const SDLPP::Vec2D<double> &getEndPos() {
return endPos;
}
private: private:
bool onGround = false; bool onGround = false;
double groundY = 0; double groundY = 0;
@ -130,6 +138,8 @@ private:
bool mushroom = false; bool mushroom = false;
std::vector<std::shared_ptr<MarioBlock>> &_moving_objects; std::vector<std::shared_ptr<MarioBlock>> &_moving_objects;
bool _bounce = false; bool _bounce = false;
bool _end = false;
SDLPP::Vec2D<double> endPos;
}; };
#endif #endif