Skip to content

Commit

Permalink
Add platforming physics
Browse files Browse the repository at this point in the history
- Add tilemap collision resolution
- Add gravity & movement to player
- Add player animations
  • Loading branch information
copyrat90 committed Jun 14, 2021
1 parent c769b91 commit 2980ebf
Show file tree
Hide file tree
Showing 27 changed files with 986 additions and 240 deletions.
Binary file modified graphics/bg_w0_s0_0.bmp
Binary file not shown.
78 changes: 39 additions & 39 deletions graphics_source/bg_w0_s0_0.tmx

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions include/game_entity_IEntity.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ class IEntity
void SetX(bn::fixed x);
void SetY(bn::fixed y);

void SetHorizontalFlip(bool flip);
bool GetHorizontalFlip() const;
void SetVerticalFlip(bool flip);
bool GetVerticalFlip() const;

protected:
bn::fixed_point position_;
bn::fixed_rect relativeInteractRange_;
Expand Down
48 changes: 0 additions & 48 deletions include/game_entity_IGravityEntity.h

This file was deleted.

88 changes: 88 additions & 0 deletions include/game_entity_IPhysicsEntity.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#pragma once

#include "game_entity_IEntity.h"

namespace sym::game::entity
{

class IPhysicsEntity : public IEntity
{
public:
virtual ~IPhysicsEntity() = 0;

IPhysicsEntity(bn::fixed_point position, bn::fixed_rect relativeInteractRange,
bn::fixed_rect relativePhysicsCollider, bool isGravityEnabledByDefault, bn::fixed gravityScale,
const bn::sprite_item* spriteItem);

IPhysicsEntity(IPhysicsEntity&& other);
IPhysicsEntity& operator=(IPhysicsEntity&& other);

IPhysicsEntity(const IPhysicsEntity& other) = delete;
IPhysicsEntity& operator=(const IPhysicsEntity& other) = delete;

/**
* @brief Get the physics collider.
* Absolute Coordinate.
*
* @return `bn::fixed_rect` collider
*/
[[nodiscard]] bn::fixed_rect GetPhysicsCollider() const;

[[nodiscard]] bool GetGravityEnabled() const;
void SetGravityEnabled(bool isGravityEnabled);

[[nodiscard]] bn::fixed GetGravityScale() const;
void SetGravityScale(bn::fixed gravityScale);
[[maybe_unused]] bool ToggleGravityEnabled();

[[nodiscard]] bn::fixed_point GetVelocity() const;
void SetVelocity(bn::fixed_point velocity);
void SetXVelocity(bn::fixed xVel);
void SetYVelocity(bn::fixed yVel);

[[nodiscard]] bool GetGrounded() const;
void SetGrounded(bool);

enum class MoveDirections
{
UP = 1,
DOWN = 2,
LEFT = 4,
RIGHT = 8
};
MoveDirections GetMoveDirections() const;

static constexpr bn::fixed EPSILON_VEL = 0.01;

protected:
/**
* @brief saves collider relative to the position_.
*
*/
bn::fixed_rect relativePhysicsCollider_;
bool isGravityEnabled_;
bn::fixed gravityScale_;

bn::fixed_point velocity_ = {0, 0};
bool isGrounded_ = false;
};

inline IPhysicsEntity::MoveDirections operator|(IPhysicsEntity::MoveDirections d1, IPhysicsEntity::MoveDirections d2)
{
using MoveDirections = IPhysicsEntity::MoveDirections;
return static_cast<MoveDirections>(static_cast<int>(d1) | static_cast<int>(d2));
}

inline IPhysicsEntity::MoveDirections operator&(IPhysicsEntity::MoveDirections d1, IPhysicsEntity::MoveDirections d2)
{
using MoveDirections = IPhysicsEntity::MoveDirections;
return static_cast<MoveDirections>(static_cast<int>(d1) & static_cast<int>(d2));
}

inline bool operator!(IPhysicsEntity::MoveDirections dir)
{
using MoveDirections = IPhysicsEntity::MoveDirections;
return dir == static_cast<MoveDirections>(0);
}

} // namespace sym::game::entity
17 changes: 15 additions & 2 deletions include/game_entity_Player.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#pragma once

#include "game_entity_IGravityEntity.h"
#include "game_entity_IPhysicsEntity.h"

#include <bn_sprite_animate_actions.h>

namespace sym::game::entity
{

class Player final : public IGravityEntity
class Player final : public IPhysicsEntity
{
public:
Player(bn::fixed_point position);
Expand Down Expand Up @@ -37,9 +37,22 @@ class Player final : public IGravityEntity
[[nodiscard]] bn::fixed_point GetRightSymbolPosition() const;
[[nodiscard]] bn::fixed_point GetMergeSymbolPosition() const;

enum class ActionState
{
IDLE,
JUMP,
FALL,
LAND,
MERGE_START,
MERGE_END
};

ActionState GetActionState() const;

private:
bn::optional<bn::sprite_animate_action<2>> action2_;
bn::optional<bn::sprite_animate_action<3>> action3_;
ActionState actionState_ = ActionState::IDLE;
/**
* @brief Additional wait update before the InitIdleAction() is called.
* If it is `-1`, InitIdleAction() is not called.
Expand Down
4 changes: 2 additions & 2 deletions include/game_entity_Symbol.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#pragma once

#include "game_entity_IGravityEntity.h"
#include "game_entity_IPhysicsEntity.h"

namespace sym::game::entity
{

class Symbol final : public IGravityEntity
class Symbol final : public IPhysicsEntity
{
public:
static constexpr int COMPLEX_SYMBOL_START_NUM = 100;
Expand Down
8 changes: 2 additions & 6 deletions include/game_system_ButtonInteraction.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,12 @@ class ButtonInteraction final : public ISystem
void Update() final;

private:
static constexpr int KEYPRESS_LASTING_UPDATE_COUNT = 5;
int lKeyLastingCount = -1;
int rKeyLastingCount = -1;

void HoverButtonPlayerInteract_();
void HoverButtonThrownSymbolInteract_();

void UpdateKeyLastingCount_();
bool IsLKeyPressLasts_() const;
bool IsRKeyPressLasts_() const;
[[nodiscard]] bool IsLKeyPressLasts_() const;
[[nodiscard]] bool IsRKeyPressLasts_() const;
void ResetLKeyPress_();
void ResetRKeyPress_();
void ToggleOpenedHoverButtonAssociatedOpenables_(int hoverButtonIdx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
namespace sym::game::system
{

class PlayerMovement final : public ISystem
class KeyPress final : public ISystem
{
public:
PlayerMovement(scene::GameState& state);
KeyPress(scene::GameState& state);

void Update() final;

private:
void UpdateLRKeyLastingCount_();
};

} // namespace sym::game::system
32 changes: 32 additions & 0 deletions include/game_system_PhysicsMovement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include "game_system_ISystem.h"

namespace sym::game::system
{

class PhysicsMovement final : public ISystem
{
public:
PhysicsMovement(scene::GameState& state);

void Update() final;

private:
void UpdatePlayer_();
void PlayerKeyboardHandle_();
void PlayerGravity_();
void PlayerClampVelocity_();
void PlayerCollision_();
void PlayerAnimation_();

void UpdateSymbols_();
void UpdateSymbolsInHands_();
void UpdateSymbolsOnFloor_();
void UpdateSymbolsThrown_();

static constexpr int MAX_PLAYER_JUMP_COUNT = 1;
int playerJumpCount = MAX_PLAYER_JUMP_COUNT;
};

} // namespace sym::game::system
18 changes: 18 additions & 0 deletions include/helper_math.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "bn_log.h"
#include <bn_assert.h>
#include <bn_fixed.h>

namespace sym::helper::math
{

[[nodiscard]] inline bn::fixed operator%(bn::fixed a, int b)
{
bn::fixed result = a - (a / b).floor_integer() * b;
BN_LOG("operator% : ", result);
BN_ASSERT(0 <= result && result < b, "operator% is giving wrong result");
return result;
}

} // namespace sym::helper::math
64 changes: 64 additions & 0 deletions include/helper_tilemap.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#pragma once

#include <bn_affine_bg_ptr.h>
#include <bn_assert.h>
#include <bn_camera_ptr.h>
#include <bn_fixed_rect.h>
#include <bn_point.h>
#include <bn_size.h>
#include <bn_vector.h>

#include "helper_rect.h"

Expand Down Expand Up @@ -110,4 +112,66 @@ struct IndexRect
*/
void SnapCameraToZoneBoundary(bn::camera_ptr& cam, const bn::fixed_rect& zoneBoundary);

class TileInfo
{
public:
TileInfo(const bn::affine_bg_ptr& bg);
void Reset(const bn::affine_bg_ptr& bg);

TileInfo(const TileInfo&) = delete;
TileInfo& operator=(const TileInfo&) = delete;

TileInfo(TileInfo&& other) : bg_(other.bg_), tileFlags_(bn::move(other.tileFlags_))
{
}
TileInfo& operator=(TileInfo&& other)
{
bg_ = other.bg_;
tileFlags_ = bn::move(other.tileFlags_);
return *this;
}

enum class Flags
{
EMPTY = 0,
CEILING = 0x01,
FLOOR = 0x02,
LEFT_BLOCKING_WALL = 0x04,
RIGHT_BLOCKING_WALL = 0x08,
SPIKE = 0x10,
};

Flags GetTileFlagsByPosition(bn::fixed_point position) const;

private:
static constexpr int TILE_VARIATION_COUNT = 32;
static constexpr int TILE_GROUP_COUNT = 9;

const bn::affine_bg_ptr* bg_;
bn::vector<Flags, TILE_VARIATION_COUNT> tileFlags_;

Flags At_(int tileVariationId) const;

/**
* @brief Get map index which can be used to index bg.map().cells_ref().value()
*
*/
int MapIndex_(bn::fixed_point point) const;
};

inline TileInfo::Flags operator|(TileInfo::Flags f1, TileInfo::Flags f2)
{
return static_cast<TileInfo::Flags>(static_cast<int>(f1) | static_cast<int>(f2));
}

inline TileInfo::Flags operator&(TileInfo::Flags f1, TileInfo::Flags f2)
{
return static_cast<TileInfo::Flags>(static_cast<int>(f1) & static_cast<int>(f2));
}

inline bool operator!(TileInfo::Flags flags)
{
return flags == TileInfo::Flags::EMPTY;
}

} // namespace sym::helper::tilemap
7 changes: 5 additions & 2 deletions include/scene_Game.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
#include "scene_IScene.h"

#include "game_system_ButtonInteraction.h"
#include "game_system_PlayerMovement.h"
#include "game_system_KeyPress.h"
#include "game_system_PhysicsMovement.h"
#include "scene_GameState.h"

namespace sym::scene
Expand All @@ -29,8 +30,10 @@ class Game final : public IScene
*/
GameState state_;

system::PlayerMovement playerMovement_;
system::KeyPress keyPress_;
system::ButtonInteraction buttonInteraction_;
// system::SymbolInteraction symbolInteraction_;
system::PhysicsMovement physicsMovement_;

void SetCurrentZone_(int zoneIdx);
};
Expand Down
Loading

0 comments on commit 2980ebf

Please sign in to comment.