From 7b2adac92226251015c5b6e1c25ff2b41a9b580b Mon Sep 17 00:00:00 2001 From: zvon Date: Sat, 7 Aug 2021 21:41:15 +0200 Subject: [PATCH] Mario: add mushroom block --- mario/CMakeLists.txt | 2 ++ mario/blocks/mushroomblock.cpp | 51 ++++++++++++++++++++++++++ mario/blocks/mushroomblock.hpp | 17 +++++++++ mario/maploader.cpp | 7 ++++ mario/objectids.hpp | 1 + mario/sprites.cpp | 1 + mario/sprites.hpp | 1 + mario/visitors/mushroom_visitor.cpp | 52 +++++++++++++++++++++++++++ mario/visitors/mushroom_visitor.hpp | 56 +++++++++++++++++++++++++++++ 9 files changed, 188 insertions(+) create mode 100644 mario/blocks/mushroomblock.cpp create mode 100644 mario/blocks/mushroomblock.hpp create mode 100644 mario/visitors/mushroom_visitor.cpp create mode 100644 mario/visitors/mushroom_visitor.hpp diff --git a/mario/CMakeLists.txt b/mario/CMakeLists.txt index 03731b7..9a72d6d 100644 --- a/mario/CMakeLists.txt +++ b/mario/CMakeLists.txt @@ -67,9 +67,11 @@ target_sources(mario PRIVATE ${CommonFiles} PRIVATE main.cpp PRIVATE visitors/mario_visitor.cpp + PRIVATE visitors/mushroom_visitor.cpp PRIVATE visitors/bounce_visitor.cpp PRIVATE visitors/visitor_generator.cpp PRIVATE blocks/coinblock.cpp + PRIVATE blocks/mushroomblock.cpp ) target_sources(editor diff --git a/mario/blocks/mushroomblock.cpp b/mario/blocks/mushroomblock.cpp new file mode 100644 index 0000000..d7d8348 --- /dev/null +++ b/mario/blocks/mushroomblock.cpp @@ -0,0 +1,51 @@ +#include "mushroomblock.hpp" +#include "../sprites.hpp" +#include "../global_vars.hpp" +#include "../objectids.hpp" +#include "../visitors/mushroom_visitor.hpp" + +MushroomBlock::MushroomBlock( int x, int y, std::shared_ptr< SDLPP::Renderer > &renderer ) : MarioBlock(x, y, renderer, g_terrain_texture, MUSHROOM_SRC, true, true) { + setHidden(true); + ensureCollision(); + setId(MUSHROOM_ID); + auto bottom_detect = SDLPP::RectColider( 0.2, 1, 0.6, 0, MARIO_FLOOR_DETECT ); + bottom_detect.setColor("#FF0000"); + bottom_detect.setOutlineColor("#FF0000"); + bottom_detect.setMinHeight(1); + addCollision(bottom_detect); + addCollision( + SDLPP::RectColider( 0, 0.25, 0.1, 0.6, MARIO_LEFT_SIDE_DETECT ) ); + addCollision( + SDLPP::RectColider( 0.9, 0.25, 0.1, 0.6, MARIO_RIGHT_SIDE_DETECT ) ); +} + +void MushroomBlock::custom_move(int ticks) { + if(_parent != nullptr && !_parent->isBouncing() && !isTraveling()) { + setHidden(false); + travelToPos(_parent->getPos() - SDLPP::Vec2D(0, BLOCK_SIZE)); + _parent = nullptr; + } else if(_parent == nullptr && !isTraveling() && !_started_movement) { + _started_movement = true; + setMovement(movementSpeed/2, 0); + } + gravity(ticks); + MarioBlock::custom_move(ticks); +} + +void MushroomBlock::setParent(MarioBlock *parent) { + _parent = parent; +} + +void MushroomBlock::handleVisitor(SDLPP::Visitor &visitor) { + if(!_started_movement) { + return; + } + auto &m_visitor = dynamic_cast(visitor); + setOnGround(m_visitor.isOnGround()); + if(!m_visitor.canGoLeft() || !m_visitor.canGoRight()) { + setMovement(-getMovement().getX(), getMovement().getY()); + } + if(m_visitor.getDeath()) { + destroy(); + } +} diff --git a/mario/blocks/mushroomblock.hpp b/mario/blocks/mushroomblock.hpp new file mode 100644 index 0000000..90054fd --- /dev/null +++ b/mario/blocks/mushroomblock.hpp @@ -0,0 +1,17 @@ +#ifndef MUSHROOM_BLOCK_HPP +#define MUSHROOM_BLOCK_HPP + +#include "../blocks.hpp" + +class MushroomBlock : public MarioBlock { +public: + MushroomBlock( int x, int y, std::shared_ptr< SDLPP::Renderer > &renderer ); + void custom_move(int ticks) override; + void setParent(MarioBlock *parent); + void handleVisitor(SDLPP::Visitor &visitor) override; +private: + MarioBlock *_parent = nullptr; + bool _started_movement = false; +}; + +#endif diff --git a/mario/maploader.cpp b/mario/maploader.cpp index 5a39dc6..e7215e4 100644 --- a/mario/maploader.cpp +++ b/mario/maploader.cpp @@ -113,6 +113,7 @@ void loadMap( std::shared_ptr< SDLPP::Scene > &scene, bool destructible = false; bool removeCollisions = false; int coinCount = 0; + bool mushroom = false; if ( !editor && block.getModifierId() == DESTRUCTIBLE_MODIFIER_ID ) { destructible = true; @@ -126,6 +127,9 @@ void loadMap( std::shared_ptr< SDLPP::Scene > &scene, block.getModifierId() == COIN_MODIFIER_ID ) { coinCount = block.getModifierData(); } + if ( !editor && block.getModifierId() == MUSHROOM_MODIFIER_ID ) { + mushroom = true; + } // TODO add modifiers to createTerrainBlock if(block.getTerrainId() != 0) { auto obj = createTerrainBlock( @@ -133,6 +137,9 @@ void loadMap( std::shared_ptr< SDLPP::Scene > &scene, renderer, i, j, destructible, editor ); if(obj != nullptr) { obj->setCoinCount(coinCount); + if(mushroom) { + obj->addMushroom(); + } if(removeCollisions) { obj->removeCollisions(); } diff --git a/mario/objectids.hpp b/mario/objectids.hpp index 91c0f4b..3b5ef73 100644 --- a/mario/objectids.hpp +++ b/mario/objectids.hpp @@ -62,6 +62,7 @@ #define CANNON_PEDESTAL_ID 0x7039 #define CANNON_ID 0x703A #define COIN_ID 0x703B +#define MUSHROOM_ID 0x703C // modifiers #define DESTRUCTIBLE_MODIFIER_ID 0x01 diff --git a/mario/sprites.cpp b/mario/sprites.cpp index fbf2d72..7a671a1 100644 --- a/mario/sprites.cpp +++ b/mario/sprites.cpp @@ -79,6 +79,7 @@ const SDL_Rect CANNON_TOWER_SRC = {256, 46, 16, 16}; const SDL_Rect CANNON_PEDESTAL_SRC = {256, 29, 16, 16}; const SDL_Rect CANNON_SRC = {256, 12, 16, 16}; const SDL_Rect COIN_SRC = {549, 202, 16, 16}; +const SDL_Rect MUSHROOM_SRC = {69, 12, 16, 16}; extern const SDL_Rect MOD_DESTRUCTIBLE_SRC = {0, 0, 16, 16}; extern const SDL_Rect MOD_BACKGROUND_SRC = {16, 0, 16, 16}; diff --git a/mario/sprites.hpp b/mario/sprites.hpp index a75890e..d757efc 100644 --- a/mario/sprites.hpp +++ b/mario/sprites.hpp @@ -87,6 +87,7 @@ extern const SDL_Rect CANNON_TOWER_SRC; extern const SDL_Rect CANNON_PEDESTAL_SRC; extern const SDL_Rect CANNON_SRC; extern const SDL_Rect COIN_SRC; +extern const SDL_Rect MUSHROOM_SRC; //------------------ MODIFIERS ---------------------- extern const SDL_Rect MOD_DESTRUCTIBLE_SRC; extern const SDL_Rect MOD_BACKGROUND_SRC; diff --git a/mario/visitors/mushroom_visitor.cpp b/mario/visitors/mushroom_visitor.cpp new file mode 100644 index 0000000..6bd4cc8 --- /dev/null +++ b/mario/visitors/mushroom_visitor.cpp @@ -0,0 +1,52 @@ +#include "mushroom_visitor.hpp" +#include "../../sdlpp/sdlpp_renderobject.hpp" +#include "../objectids.hpp" +#include "../sprites.hpp" + +void MushroomVisitor::visit( const SDLPP::RenderObject &obj ) { + auto id = obj.getId(); + switch ( id ) { + case FLOOR_ID: + case BRICK_ID: + case BRICK_TOP_ID: + case PIPE_LEFT_BOTTOM_ID: + case PIPE_RIGHT_BOTTOM_ID: + case PIPE_LEFT_TOP_ID: + case PIPE_RIGHT_TOP_ID: + case STEP_ID: + case SIDEWAY_PIPE_END_TOP_ID: + case SIDEWAY_PIPE_END_BOTTOM_ID: + case SIDEWAY_PIPE_MIDDLE_BOTTOM_ID: + case SIDEWAY_PIPE_MIDDLE_TOP_ID: + case SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID: + case SIDEWAY_PIPE_CONNECTOR_TOP_ID: + case TREE_PLATFORM_TOP_LEFT_ID: + case TREE_PLATFORM_TOP_RIGHT_ID: + case MUSHROOM_PLATFORM_TOP_MIDDLE_ID: + case MUSHROOM_PLATFORM_TOP_LEFT_ID: + case MUSHROOM_PLATFORM_TOP_RIGHT_ID: + case CANNON_TOWER_ID: + case CANNON_PEDESTAL_ID: + case CANNON_ID: + if ( from == MARIO_FLOOR_DETECT ) { + onGround = true; + groundY = obj.getPos().getY(); + } else if ( from == MARIO_LEFT_SIDE_DETECT ) { + if(!left && !right) { + movement_blockage = obj.getPos(); + } + left = true; + } else if (from == MARIO_RIGHT_SIDE_DETECT ) { + if(!left && !right) { + movement_blockage = obj.getPos(); + } + right = true; + } + break; + case MARIO_ID: + std::cout << "MARIO" << std::endl; + death = true; + default: + break; + } +} diff --git a/mario/visitors/mushroom_visitor.hpp b/mario/visitors/mushroom_visitor.hpp new file mode 100644 index 0000000..12bb600 --- /dev/null +++ b/mario/visitors/mushroom_visitor.hpp @@ -0,0 +1,56 @@ +#ifndef MUSHROOM_VISITOR_H +#define MUSHROOM_VISITOR_H + +#include "../../sdlpp/sdlpp_visitor.hpp" +#include "../../sdlpp/sdlpp_geometry.hpp" +#include "../../sdlpp/sdlpp_scene.hpp" +#include "../blocks.hpp" + +class MushroomVisitor : public SDLPP::Visitor { +public: + MushroomVisitor() = default; + void visit( const SDLPP::RenderObject &obj ) override; + bool isOnGround() const { + return onGround; + } + void setFromId( uint64_t id ) override { + from = id; + } + uint64_t getFromId() const override { + return from; + } + void setVisitorType( uint64_t type ) override { + _type = type; + } + uint64_t getVisitorType() const override { + return _type; + } + bool canGoLeft() const { + return !left; + } + bool canGoRight() const { + return !right; + } + double getGroundY() const { + return groundY; + } + const SDLPP::Vec2D &getMovementBlockage() { + return movement_blockage; + } + bool getDeath() { + return death; + } + +private: + bool onGround = false; + double groundY = 0; + bool stop = false; + bool left = false; + bool right = false; + SDLPP::Vec2D movement_blockage; + uint64_t from{}; + uint64_t _type{}; + bool death = false; +}; + +#endif