Mario: add basic big mario logic
Some checks reported errors
continuous-integration/drone/push Build encountered an error

This commit is contained in:
zv0n 2022-09-25 19:44:28 +02:00
parent 09cb13195c
commit 4109cfe1af
12 changed files with 156 additions and 57 deletions

View File

@ -42,10 +42,10 @@ void MarioBlock::visit(SDLPP::Visitor &visitor) {
destroy(); destroy();
} }
#else #else
if (visitor.getFromId() == MARIO_TOP_DETECT && if (visitor.getFromId() == MARIO_TOP_DETECT) {
dynamic_cast<MarioVisitor &>(visitor).canDestroy()) { auto &mario_visitor = dynamic_cast<MarioVisitor &>(visitor);
// TODO if big mario and _can_be_destroyed if (mario_visitor.canDestroy()) {
if (_destructible && !hasCoin()) { if ((_destructible && !hasCoin()) || (_can_be_destroyed && mario_visitor.isBig() && !hasCoin())) {
destroy(); destroy();
} else if (_bouncable) { } else if (_bouncable) {
BounceVisitor bv; BounceVisitor bv;
@ -80,6 +80,7 @@ void MarioBlock::visit(SDLPP::Visitor &visitor) {
dynamic_cast<MarioVisitor &>(visitor).setMushroomBlock(mushroom); dynamic_cast<MarioVisitor &>(visitor).setMushroomBlock(mushroom);
} }
} }
}
#endif #endif
visitor.visit(*this); visitor.visit(*this);
} }

View File

@ -7,7 +7,7 @@
GoombaBlock::GoombaBlock(int x, int y, GoombaBlock::GoombaBlock(int x, int y,
std::shared_ptr<SDLPP::Renderer> &renderer) std::shared_ptr<SDLPP::Renderer> &renderer)
: MarioBlock(x, y, renderer, g_enemies_texture, GOOMBA_WALK_ANIM[0], : MarioBlock(x, y, renderer, g_enemies_texture, GOOMBA_WALK_ANIM[0],
true, true) { false, false) {
#ifndef EDITOR #ifndef EDITOR
setAnimationFrames(GOOMBA_WALK_ANIM); setAnimationFrames(GOOMBA_WALK_ANIM);
setAnimationSpeed(12.5); setAnimationSpeed(12.5);
@ -22,6 +22,7 @@ GoombaBlock::GoombaBlock(int x, int y,
SDLPP::RectColider(0.9, 0.25, 0.1, 0.6, NPC_RIGHT_SIDE_DETECT)); SDLPP::RectColider(0.9, 0.25, 0.1, 0.6, NPC_RIGHT_SIDE_DETECT));
addCollision(std::make_shared<SDLPP::RectColider>(0.35, 0, 0.3, 0.15, addCollision(std::make_shared<SDLPP::RectColider>(0.35, 0, 0.3, 0.15,
NPC_TOP_DETECT)); NPC_TOP_DETECT));
setBouncable(false);
#ifndef EDITOR #ifndef EDITOR
setMovement(-0.19, 0); setMovement(-0.19, 0);
#endif #endif
@ -58,7 +59,7 @@ void GoombaBlock::handleVisitor(SDLPP::Visitor &visitor) {
if (isOnGround()) { if (isOnGround()) {
setPos(getPos().getX(), g_visitor.getGroundY() - BLOCK_SIZE); setPos(getPos().getX(), g_visitor.getGroundY() - BLOCK_SIZE);
} }
if((!g_visitor.canGoLeft() && getMovement().getX() < 0) || if ((!g_visitor.canGoLeft() && getMovement().getX() < 0) ||
(!g_visitor.canGoRight() && getMovement().getX() > 0)) { (!g_visitor.canGoRight() && getMovement().getX() > 0)) {
setPos(g_visitor.getValidXPos(), getPos().getY()); setPos(g_visitor.getValidXPos(), getPos().getY());
setMovement(-getMovement().getX(), getMovement().getY()); setMovement(-getMovement().getX(), getMovement().getY());

View File

@ -28,7 +28,7 @@ void MushroomBlock::custom_move(int ticks) {
_parent = nullptr; _parent = nullptr;
} else if (_parent == nullptr && !isTraveling() && !_started_movement) { } else if (_parent == nullptr && !isTraveling() && !_started_movement) {
_started_movement = true; _started_movement = true;
setMovement(movementSpeed / 2, 0); setMovement(movementSpeed / 4, 0);
} }
gravity(ticks); gravity(ticks);
MarioBlock::custom_move(ticks); MarioBlock::custom_move(ticks);

View File

@ -191,7 +191,7 @@ void doInputMainGame(std::shared_ptr<SDLPP::Scene> scene) {
if (!moving_objects[i]->wasVisible()) { if (!moving_objects[i]->wasVisible()) {
continue; continue;
} }
auto visitor = getVisitor(*moving_objects[i], *scene, g_death, auto visitor = getVisitor(*moving_objects[i], *scene,
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);

View File

@ -99,7 +99,7 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) {
resetMovementY(); resetMovementY();
stop_jump = true; stop_jump = true;
} }
if (m_visitor.shouldBounce()) { if (m_visitor.shouldBounce() && getMovement().getY() > 0) {
addMovement(0, -bounce_speed); addMovement(0, -bounce_speed);
} }
// make sure Mario isn't stuck inside a wall // make sure Mario isn't stuck inside a wall
@ -128,7 +128,7 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) {
} }
} }
if (m_visitor.hasMushroom()) { if (m_visitor.hasMushroom()) {
setType(LandType::UNDERWORLD); setBig();
} }
if (m_visitor.levelEnd() && controllable) { if (m_visitor.levelEnd() && controllable) {
if (std::abs(getPos().getX() - m_visitor.getEndPos().getX()) < if (std::abs(getPos().getX() - m_visitor.getEndPos().getX()) <
@ -137,8 +137,19 @@ void Mario::handleVisitor(SDLPP::Visitor &visitor) {
stopMovement(); stopMovement();
} }
} }
if (m_visitor.isDead()) {
handleDeath();
}
#endif #endif
} }
void Mario::handleDeath() {
if (isBig() && ticks_till_vulnurable <= 0) {
unsetBig();
ticks_till_vulnurable = base_vulnurable_ticks;
} else if (ticks_till_vulnurable <= 0) {
setDeath();
}
}
void Mario::jump() { void Mario::jump() {
if (!controllable) { if (!controllable) {
@ -162,6 +173,9 @@ void Mario::stopJump() {
} }
void Mario::custom_move(int ticks) { void Mario::custom_move(int ticks) {
if (ticks_till_vulnurable > 0) {
ticks_till_vulnurable -= ticks;
}
MarioBlock::custom_move(ticks); MarioBlock::custom_move(ticks);
if (!jumping && on_ground) if (!jumping && on_ground)
return; return;

View File

@ -4,6 +4,11 @@
#include "../sdlpp/sdlpp_rectrenderer.hpp" #include "../sdlpp/sdlpp_rectrenderer.hpp"
#include "sprites.hpp" #include "sprites.hpp"
#include "blocks.hpp" #include "blocks.hpp"
#include <_types/_uint8_t.h>
#define BIG_FLAG 0x0001
#define FIRE_FLAG 0x0002
#define STAR_FLAG 0x0004
class Mario : public MarioBlock { class Mario : public MarioBlock {
public: public:
@ -20,6 +25,40 @@ public:
bool isDead() { bool isDead() {
return _death; return _death;
} }
void handleDeath();
void setBig() {
if (isBig()) {
setFireFlag();
} else {
setBigFlag();
}
}
void unsetBig() {
if (hasFire()) {
unsetFireFlag();
} else {
unsetBigFlag();
}
}
void setStar() {
setStarFlag();
}
void unsetStar() {
unsetStarFlag();
}
bool isBig() const {
return special_flags & BIG_FLAG;
}
bool hasFire() const {
return special_flags & FIRE_FLAG;
}
bool hasStar() const {
return special_flags & STAR_FLAG;
}
bool isJumping() const {
return jumping;
}
private: private:
void setDeath(bool dead = true) { void setDeath(bool dead = true) {
@ -37,13 +76,35 @@ private:
double slow_jump = 0; double slow_jump = 0;
bool on_ground = true; bool on_ground = true;
int ticks_till_gravity = 0; int ticks_till_gravity = 0;
int ticks_till_vulnurable = 0;
// gravity should be added every frame in 60fps game // gravity should be added every frame in 60fps game
const int base_gravity_ticks = 1000 / 60; const int base_gravity_ticks = 1000 / 60;
const int base_vulnurable_ticks = 1000;
const double gravity_add_jumping = jump_movement / 32.0; const double gravity_add_jumping = jump_movement / 32.0;
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(); void stopMovement();
uint8_t special_flags = 0;
void setBigFlag() {
special_flags = special_flags | BIG_FLAG;
}
void setFireFlag() {
special_flags = special_flags | FIRE_FLAG;
}
void setStarFlag() {
special_flags = special_flags | STAR_FLAG;
}
void unsetBigFlag() {
special_flags = special_flags & ~BIG_FLAG;
}
void unsetFireFlag() {
special_flags = special_flags & ~FIRE_FLAG;
}
void unsetStarFlag() {
special_flags = special_flags & ~STAR_FLAG;
}
}; };
#endif #endif

View File

@ -2,6 +2,7 @@
#include "../../sdlpp/sdlpp_renderobject.hpp" #include "../../sdlpp/sdlpp_renderobject.hpp"
#include "../objectids.hpp" #include "../objectids.hpp"
#include "../sprites.hpp" #include "../sprites.hpp"
#include "../mario.hpp"
void GoombaVisitor::visit(const SDLPP::RenderObject &obj) { void GoombaVisitor::visit(const SDLPP::RenderObject &obj) {
auto id = obj.getId(); auto id = obj.getId();
@ -49,9 +50,12 @@ void GoombaVisitor::visit(const SDLPP::RenderObject &obj) {
death = true; death = true;
break; break;
case MARIO_ID: case MARIO_ID:
if (from == NPC_TOP_DETECT) { {
auto &mario = dynamic_cast<const Mario &>(obj);
if (from == NPC_TOP_DETECT && obj.getPos().getY() <= goomba_pos.getY() - BLOCK_SIZE && !mario.isJumping()) {
death = true; death = true;
} }
}
break; break;
default: default:
break; break;

View File

@ -8,7 +8,8 @@
class GoombaVisitor : public SDLPP::Visitor { class GoombaVisitor : public SDLPP::Visitor {
public: public:
GoombaVisitor() = default; GoombaVisitor() = delete;
GoombaVisitor(const SDLPP::Vec2D<double> &pos) : goomba_pos(pos) {}
void visit(const SDLPP::RenderObject &obj) override; void visit(const SDLPP::RenderObject &obj) override;
bool isOnGround() const { bool isOnGround() const {
return onGround; return onGround;
@ -59,6 +60,7 @@ private:
bool top_hit = false; bool top_hit = false;
SDLPP::Vec2D<double> movement_blockage; SDLPP::Vec2D<double> movement_blockage;
double validXPos = 0; double validXPos = 0;
const SDLPP::Vec2D<double> goomba_pos;
}; };
#endif #endif

View File

@ -55,7 +55,7 @@ void MarioVisitor::visit(const SDLPP::RenderObject &obj) {
case GOOMBA_ID: case GOOMBA_ID:
if (from != MARIO_FLOOR_DETECT && from != MARIO_ENEMY_DETECT) { if (from != MARIO_FLOOR_DETECT && from != MARIO_ENEMY_DETECT) {
_death = true; _death = true;
} else { } else if (from == MARIO_FLOOR_DETECT || from == MARIO_ENEMY_DETECT) {
_bounce = true; _bounce = true;
} }
break; break;

View File

@ -8,11 +8,13 @@
class MarioVisitor : public SDLPP::Visitor { class MarioVisitor : public SDLPP::Visitor {
public: public:
MarioVisitor(bool is_jumping, SDLPP::Scene &scene, bool &death, MarioVisitor(bool is_jumping, SDLPP::Scene &scene,
int &coin_count, int &coin_count,
std::vector<std::shared_ptr<MarioBlock>> &moving_objects) std::vector<std::shared_ptr<MarioBlock>> &moving_objects,
: jumping(is_jumping), _scene(scene), _death(death), bool is_big, bool has_star)
_coin_count(coin_count), _moving_objects(moving_objects) {} : jumping(is_jumping), _scene(scene),
_coin_count(coin_count), _moving_objects(moving_objects),
_is_big(is_big), _has_star(has_star) {}
void visit(const SDLPP::RenderObject &obj) override; void visit(const SDLPP::RenderObject &obj) override;
bool isOnGround() const { bool isOnGround() const {
return onGround; return onGround;
@ -116,6 +118,14 @@ public:
return endPos; return endPos;
} }
bool isBig() const {
return _is_big;
}
bool hasStar() const {
return _has_star;
}
private: private:
bool onGround = false; bool onGround = false;
double groundY = 0; double groundY = 0;
@ -133,13 +143,15 @@ private:
SDLPP::Vec2D<double> movement_blockage; SDLPP::Vec2D<double> movement_blockage;
std::shared_ptr<MarioBlock> coin_block = nullptr; std::shared_ptr<MarioBlock> coin_block = nullptr;
SDLPP::Scene &_scene; SDLPP::Scene &_scene;
bool &_death;
int &_coin_count; int &_coin_count;
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; bool _end = false;
SDLPP::Vec2D<double> endPos; SDLPP::Vec2D<double> endPos;
bool _is_big = false;
bool _has_star = false;
bool _death = false;
}; };
#endif #endif

View File

@ -3,18 +3,22 @@
#include "mario_visitor.hpp" #include "mario_visitor.hpp"
#include "mushroom_visitor.hpp" #include "mushroom_visitor.hpp"
#include "goomba_visitor.hpp" #include "goomba_visitor.hpp"
#include "../mario.hpp"
std::shared_ptr<SDLPP::Visitor> std::shared_ptr<SDLPP::Visitor>
getVisitor(const MarioBlock &block, SDLPP::Scene &scene, bool &death, getVisitor(const MarioBlock &block, SDLPP::Scene &scene,
int &coin_count, int &coin_count,
std::vector<std::shared_ptr<MarioBlock>> &moving_objects) { std::vector<std::shared_ptr<MarioBlock>> &moving_objects) {
std::shared_ptr<SDLPP::Visitor> result{}; std::shared_ptr<SDLPP::Visitor> result{};
switch (block.getId()) { switch (block.getId()) {
case MARIO_ID: case MARIO_ID:
{
auto &mario = dynamic_cast<const Mario &>(block);
result = std::static_pointer_cast<SDLPP::Visitor>( result = std::static_pointer_cast<SDLPP::Visitor>(
std::make_shared<MarioVisitor>(block.getMovement().getY() < 0, std::make_shared<MarioVisitor>(block.getMovement().getY() < 0,
scene, death, coin_count, scene, coin_count,
moving_objects)); moving_objects, mario.isBig(), mario.hasStar()));
}
break; break;
case MUSHROOM_ID: case MUSHROOM_ID:
result = std::static_pointer_cast<SDLPP::Visitor>( result = std::static_pointer_cast<SDLPP::Visitor>(
@ -22,7 +26,7 @@ getVisitor(const MarioBlock &block, SDLPP::Scene &scene, bool &death,
break; break;
case GOOMBA_ID: case GOOMBA_ID:
result = std::static_pointer_cast<SDLPP::Visitor>( result = std::static_pointer_cast<SDLPP::Visitor>(
std::make_shared<GoombaVisitor>()); std::make_shared<GoombaVisitor>(block.getPos()));
break; break;
default: default:
break; break;

View File

@ -4,7 +4,7 @@
#include "../blocks.hpp" #include "../blocks.hpp"
std::shared_ptr<SDLPP::Visitor> std::shared_ptr<SDLPP::Visitor>
getVisitor(const MarioBlock &block, SDLPP::Scene &scene, bool &quit, getVisitor(const MarioBlock &block, SDLPP::Scene &scene,
int &coin_count, int &coin_count,
std::vector<std::shared_ptr<MarioBlock>> &moving_objects); std::vector<std::shared_ptr<MarioBlock>> &moving_objects);