Mario: add travelToPos function to blocks

This commit is contained in:
zvon 2021-08-07 21:39:15 +02:00
parent 7cb3f95e44
commit 4742f3dd02
2 changed files with 123 additions and 15 deletions

View File

@ -10,6 +10,7 @@
#include "blocks/simpleblocks.hpp" #include "blocks/simpleblocks.hpp"
#include "blocks/coineditorblock.hpp" #include "blocks/coineditorblock.hpp"
#include "blocks/coinblock.hpp" #include "blocks/coinblock.hpp"
#include "blocks/mushroomblock.hpp"
#include "mario.hpp" #include "mario.hpp"
#define CAN_BE_DESTROYED_FLAG 0x0000000000000001 #define CAN_BE_DESTROYED_FLAG 0x0000000000000001
@ -66,6 +67,13 @@ void MarioBlock::visit( SDLPP::Visitor &visitor ) {
dynamic_cast< MarioVisitor & >( visitor ).setCoin(); dynamic_cast< MarioVisitor & >( visitor ).setCoin();
dynamic_cast< MarioVisitor & >( visitor ).setCoinBlock(coin); dynamic_cast< MarioVisitor & >( visitor ).setCoinBlock(coin);
} }
if ( hasMushroom() ) {
removeMushroom();
auto mushroom = createTerrainBlock(MUSHROOM_ID, LandType::OVERWORLD, renderer);
mushroom->setPos(getPos());
std::dynamic_pointer_cast<MushroomBlock>(mushroom)->setParent(this);
dynamic_cast< MarioVisitor & >( visitor ).setMushroomBlock(mushroom);
}
} }
#endif #endif
visitor.visit( *this ); visitor.visit( *this );
@ -78,21 +86,61 @@ void MarioBlock::setTerrain( bool terrain ) {
} }
void MarioBlock::bounce() { void MarioBlock::bounce() {
if ( _bouncing ) if ( _bouncing ) {
return; return;
}
_bouncing = true; _bouncing = true;
og_pos = getPos(); og_pos = getPos();
ticks_to_bounce = bounce_ticks; ticks_to_bounce = bounce_ticks;
setMovement( 0, -bounce_speed ); setMovement( 0, -bounce_speed );
} }
bool MarioBlock::isBouncing() { void MarioBlock::travelToPos(const SDLPP::Vec2D<double> &target) {
if(_traveling) {
return;
}
_traveling = true;
_target = target;
auto movement = (_target - getPos());
auto abs_mov_x = movement.getX();
if(abs_mov_x < 0) {
abs_mov_x *= -1;
}
auto abs_mov_y = movement.getY();
if(abs_mov_y < 0) {
abs_mov_y *= -1;
}
movement = movement / (abs_mov_x > abs_mov_y ? abs_mov_x : abs_mov_y);
movement = movement * travel_speed;
setMovement(movement.getX(), movement.getY());
}
void MarioBlock::gravity(int ticks) {
if(_on_ground) {
return;
}
_ticks_till_gravity -= ticks;
if(_ticks_till_gravity < 0) {
addMovement(0, _gravity_acceleration);
_ticks_till_gravity = _base_gravity_ticks;
}
}
bool MarioBlock::isBouncing() const {
return _bouncing; return _bouncing;
} }
bool MarioBlock::isTraveling() const {
return _traveling;
}
void MarioBlock::custom_move( int ticks ) { void MarioBlock::custom_move( int ticks ) {
if ( !_bouncing ) if ( !_bouncing && !_traveling ) {
return; return;
}
if( _bouncing ) {
if ( getMovement().getY() < 0 ) { if ( getMovement().getY() < 0 ) {
ticks_to_bounce -= ticks; ticks_to_bounce -= ticks;
if ( ticks_to_bounce < 0 ) { if ( ticks_to_bounce < 0 ) {
@ -107,6 +155,28 @@ void MarioBlock::custom_move( int ticks ) {
} }
} }
} }
if(_traveling) {
bool overshot_x = (getMovement().getX() < 0 &&
getPos().getX() <= _target.getX()) ||
(getMovement().getX() > 0 &&
getPos().getX() >= _target.getX());
bool overshot_y = (getMovement().getY() < 0 &&
getPos().getY() <= _target.getY()) ||
(getMovement().getY() > 0 &&
getPos().getY() >= _target.getY());
if(overshot_x) {
setPos(_target.getX(), getPos().getY());
setMovement(0, getMovement().getY());
}
if(overshot_y) {
setPos(getPos().getX(), _target.getY());
setMovement(getMovement().getX(), 0);
}
if(getMovement() == SDLPP::Vec2D<double>(0,0)) {
_traveling = false;
}
}
}
void MarioBlock::setType( LandType::Value type ) { void MarioBlock::setType( LandType::Value type ) {
_type = type; _type = type;
@ -128,6 +198,9 @@ void MarioBlock::removeCoin() {
void MarioBlock::removeMushroom() { void MarioBlock::removeMushroom() {
_mushroom = false; _mushroom = false;
} }
void MarioBlock::addMushroom() {
_mushroom = true;
}
void MarioBlock::setCoinCount( int coins ) { void MarioBlock::setCoinCount( int coins ) {
_coins = coins; _coins = coins;
} }
@ -510,6 +583,10 @@ createBlockById( uint64_t id, int x, int y,
result = std::static_pointer_cast< MarioBlock >( result = std::static_pointer_cast< MarioBlock >(
std::make_shared< CoinBlock >( x, y, renderer ) ); std::make_shared< CoinBlock >( x, y, renderer ) );
break; break;
case MUSHROOM_ID:
result = std::static_pointer_cast< MarioBlock >(
std::make_shared< MushroomBlock >( x, y, renderer ) );
break;
#endif #endif
} }
return result; return result;
@ -574,3 +651,8 @@ enum BlockRole::Value getBlockRole( uint64_t id ) {
// TODO modifier/character // TODO modifier/character
return BlockRole::MODIFIER; return BlockRole::MODIFIER;
} }
void MarioBlock::setBaseRect(SDL_Rect rect) {
_base_src = rect;
setType(getType());
}

View File

@ -2,6 +2,7 @@
#define BLOCKS_H #define BLOCKS_H
#include "../sdlpp/sdlpp_rectrenderer.hpp" #include "../sdlpp/sdlpp_rectrenderer.hpp"
#include <SDL2/SDL_rect.h>
#include <memory> #include <memory>
struct LandType { struct LandType {
@ -18,6 +19,7 @@ public:
void setTool( bool tool = true ); void setTool( bool tool = true );
void setTerrain( bool terrain = true ); void setTerrain( bool terrain = true );
void bounce(); void bounce();
void travelToPos(const SDLPP::Vec2D<double> &target);
void custom_move( int ticks ) override; void custom_move( int ticks ) override;
void setType( LandType::Value type ); void setType( LandType::Value type );
LandType::Value getType() const; LandType::Value getType() const;
@ -33,14 +35,33 @@ public:
bool hasMushroom(); bool hasMushroom();
void removeCoin(); void removeCoin();
void removeMushroom(); void removeMushroom();
void addMushroom();
void setCoinCount( int coins ); void setCoinCount( int coins );
void setDestructible( bool destructible = true ); void setDestructible( bool destructible = true );
void ensureCollision(); void ensureCollision();
bool isBouncing(); bool isBouncing() const;
bool isTraveling() const;
void setBaseRect(SDL_Rect rect);
protected: protected:
double bounce_speed = 0.5; double bounce_speed = 0.5;
int bounce_ticks = 100; int bounce_ticks = 100;
double travel_speed = bounce_speed;
void gravity(int ticks);
void setOnGround(bool on_ground = true) {
_on_ground = on_ground;
if(on_ground) {
setMovement(getMovement().getX(), 0);
}
}
bool isOnGround() const {
return _on_ground;
}
void setGravityTicks(int ticks) {
_base_gravity_ticks = ticks;
}
virtual void setWorldTypeSrc( LandType::Value world );
private: private:
bool _tool = false; bool _tool = false;
@ -48,6 +69,7 @@ private:
bool _destructible = false; bool _destructible = false;
bool _can_be_destroyed = false; bool _can_be_destroyed = false;
bool _bouncing = false; bool _bouncing = false;
bool _traveling = false;
int _coins = 0; int _coins = 0;
bool _mushroom = false; bool _mushroom = false;
bool _release_coin = false; bool _release_coin = false;
@ -55,8 +77,12 @@ private:
SDLPP::Vec2D< double > og_pos = {}; SDLPP::Vec2D< double > og_pos = {};
LandType::Value _type; LandType::Value _type;
SDL_Rect _base_src; SDL_Rect _base_src;
SDLPP::Vec2D<double> _target = {0,0};
virtual void setWorldTypeSrc( LandType::Value world ); bool _on_ground = true;
int _base_gravity_ticks = 1000 / 60;
int _ticks_till_gravity = 0;
double _gravity_acceleration = 1.0/(64.0/7.0);
}; };
extern const std::vector< uint64_t > possibleBlocks; extern const std::vector< uint64_t > possibleBlocks;