Skip to content

Commit

Permalink
Merge pull request #534 from lethal-guitar/more-bugfixes
Browse files Browse the repository at this point in the history
More bug fixes
  • Loading branch information
lethal-guitar authored Jun 1, 2020
2 parents 5f7300f + c9e0c65 commit d4cc375
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 83 deletions.
44 changes: 35 additions & 9 deletions src/game_logic/camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ constexpr auto DEAD_ZONE_END_X = 21;
constexpr auto DEFAULT_VERTICAL_DEAD_ZONE = VerticalDeadZone{2, 19};
constexpr auto TIGHT_VERTICAL_DEAD_ZONE = VerticalDeadZone{7, 13};

constexpr auto INITIAL_CAMERA_OFFSET = base::Vector{15, 19};

constexpr auto MANUAL_SROLL_COOLDOWN_AFTER_SHOOTING = 4;


Expand Down Expand Up @@ -85,23 +87,42 @@ base::Rect<int> deadZoneRect(const Player& player) {
}


base::Vector offsetToDeadZone(
/** Calculate 'normalized' player bounds
*
* Returns player collision box in world space, adjusted to always be in the
* center of the screen with regards to the original game's horizontal screen
* size.
*
* This makes the camera code work correctly when in widescreen mode. The
* dead zone is tailored towards normal (i.e. not widescreen) mode, which
* would cause the player to be constrained to move inside the left half of
* the screen when in widescreen mode. By shifting the player position, we
* effectively move the dead zone to the center of the screen instead.
*
* When the view port is not wide, the result is identical with the player's
* world space collision box.
*/
base::Rect<int> normalizedPlayerBounds(
const Player& player,
const base::Vector& cameraPosition,
const base::Extents& viewPortSize
) {
const auto extraTiles =
viewPortSize.width - data::GameTraits::mapViewPortSize.width;
const auto offsetToCenter = extraTiles / 2;
auto playerBounds = player.worldSpaceCollisionBox();

// This makes the camera code work correctly when in widescreen mode. The
// dead zone is tailored towards normal (i.e. not widescreen) mode, which
// would cause the player to be constrained to move inside the left half of
// the screen when in widescreen mode. By shifting the player position, we
// effectively move the dead zone to the center of the screen instead.
auto playerBounds = player.worldSpaceCollisionBox();
playerBounds.topLeft.x -= offsetToCenter;

return playerBounds;
}


base::Vector offsetToDeadZone(
const Player& player,
const base::Vector& cameraPosition,
const base::Extents& viewPortSize
) {
const auto playerBounds = normalizedPlayerBounds(player, viewPortSize);
auto worldSpaceDeadZone = deadZoneRect(player);
worldSpaceDeadZone.topLeft += cameraPosition;

Expand Down Expand Up @@ -202,7 +223,12 @@ void Camera::setPosition(const base::Vector position) {


void Camera::centerViewOnPlayer() {
setPosition(offsetToDeadZone(*mpPlayer, {}, mViewPortSize));
auto playerPos = normalizedPlayerBounds(*mpPlayer, mViewPortSize).bottomLeft();
if (mpPlayer->orientation() == Orientation::Left) {
playerPos.x -= 1;
}

setPosition(playerPos - INITIAL_CAMERA_OFFSET);
}


Expand Down
92 changes: 51 additions & 41 deletions src/game_logic/enemies/red_bird.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,23 @@

using namespace rigel::engine::components;

namespace {

const int FLY_ANIMATION_L[] = {0, 1, 2, 1};
const int FLY_ANIMATION_R[] = {3, 4, 5, 4};
const int HOVER_ANIMATION[] = {6, 7};
namespace {

constexpr int FLY_ANIMATION[] = {0, 1, 2, 1};
constexpr int HOVER_ANIMATION[] = {6, 7};

void fly(entityx::Entity entity, const bool left) {
rigel::engine::startAnimationSequence(
entity,
left ? FLY_ANIMATION_L : FLY_ANIMATION_R,
0,
true);
entity.component<MovingBody>()->mVelocity.x = left ? -1.0f : 1.0f;
}
constexpr int FLY_ANIMATION_ORIENTATION_OFFSET = 3;

}


void rigel::game_logic::configureRedBird(entityx::Entity entity) {
using namespace engine::components::parameter_aliases;
entity.assign<MovingBody>(Velocity{-1.0f, 0.0f}, GravityAffected{false});
entity.assign<MovingBody>(Velocity{}, GravityAffected{false});
entity.assign<ActivationSettings>(
ActivationSettings::Policy::AlwaysAfterFirstActivation);
entity.assign<components::BehaviorController>(behaviors::RedBird{});

engine::startAnimationSequence(entity, FLY_ANIMATION_L, 0, true);
}


Expand All @@ -65,48 +55,71 @@ void RedBird::update(
const bool isOnScreen,
entityx::Entity entity
) {
using namespace red_bird;

auto& position = *entity.component<WorldPosition>();
auto& body = *entity.component<MovingBody>();
auto& sprite = *entity.component<Sprite>();

const auto& playerPosition = s.mpPlayer->orientedPosition();
base::match(mState,
[&, this](const Flying&) {
[&, this](Flying& state) {
const auto wantsToAttack =
position.y + 2 < playerPosition.y &&
position.x > playerPosition.x &&
position.x < playerPosition.x + 2;
if (wantsToAttack) {
sprite.mFramesToRender[0] =
HOVER_ANIMATION[int(s.mpPerFrameState->mIsOddFrame)];
mState = Hovering{};
body.mVelocity = {};
engine::startAnimationSequence(entity, HOVER_ANIMATION, 0, true);
} else {
const auto result = engine::moveHorizontally(
*d.mpCollisionChecker,
entity,
engine::orientation::toMovement(state.mOrientation));
if (result != engine::MovementResult::Completed) {
state.mOrientation =
engine::orientation::opposite(state.mOrientation);
} else {
// Animate flying
++state.mAnimStep;
sprite.mFramesToRender[0] =
FLY_ANIMATION[state.mAnimStep % 4] +
(state.mOrientation == Orientation::Right
? FLY_ANIMATION_ORIENTATION_OFFSET : 0);
}
}
},

[&, this](Hovering& state) {
sprite.mFramesToRender[0] =
HOVER_ANIMATION[int(s.mpPerFrameState->mIsOddFrame)];

++state.mFramesElapsed;
if (state.mFramesElapsed >= 6) {
if (state.mFramesElapsed >= 7) {
mState = PlungingDown{position.y};
body.mGravityAffected = true;
entity.remove<AnimationSequence>();
sprite.mFramesToRender[0] = 6;
}
},

[&](const PlungingDown&) {
// no-op, state transition handled by collision event handler
[&](const PlungingDown& state) {
const auto bbox = *entity.component<BoundingBox>();
if (d.mpCollisionChecker->isOnSolidGround(position, bbox)) {
startRisingUp(state.mInitialHeight, entity);
}
},

[&, this](RisingUp& state) {
if (state.mBackAtOriginalHeight) {
mState = Flying{};
const auto flyingLeft = !s.mpPerFrameState->mIsOddFrame;
fly(entity, flyingLeft);
const auto newOrientation =
flyingLeft ? Orientation::Left : Orientation::Right;
mState = Flying{newOrientation};
return;
}

sprite.mFramesToRender[0] =
HOVER_ANIMATION[int(s.mpPerFrameState->mIsOddFrame)];

if (position.y > state.mInitialHeight) {
--position.y;
} else {
Expand All @@ -117,6 +130,8 @@ void RedBird::update(
state.mBackAtOriginalHeight = true;
}
});

engine::synchronizeBoundingBoxToSprite(entity);
}


Expand All @@ -126,27 +141,22 @@ void RedBird::onCollision(
const engine::events::CollidedWithWorld& event,
entityx::Entity entity
) {
using namespace red_bird;

auto& body = *entity.component<MovingBody>();

base::match(mState,
[&](const Flying&) {
if (event.mCollidedLeft || event.mCollidedRight) {
fly(entity, !event.mCollidedLeft);
}
},

[&, this](const PlungingDown& state) {
if (event.mCollidedBottom) {
mState = RisingUp{state.mInitialHeight};
body.mGravityAffected = false;
engine::startAnimationSequence(entity, HOVER_ANIMATION, 0, true);
startRisingUp(state.mInitialHeight, entity);
}
},

[](const Hovering&) {},
[](const RisingUp&) {});
[](const auto&) {});
}


void RedBird::startRisingUp(const int initialHeight, entityx::Entity entity) {
auto& body = *entity.component<MovingBody>();

mState = RisingUp{initialHeight};
body.mGravityAffected = false;
}

}
68 changes: 36 additions & 32 deletions src/game_logic/enemies/red_bird.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#pragma once

#include "engine/base_components.hpp"
#include "game_logic/global_dependencies.hpp"

#include <variant>
Expand All @@ -32,37 +33,6 @@ void configureRedBird(entityx::Entity entity);

namespace rigel::game_logic::behaviors {

namespace red_bird {

struct Flying {};


struct Hovering {
int mFramesElapsed = 0;
};


struct PlungingDown {
int mInitialHeight;
};


struct RisingUp {
explicit RisingUp(const int initialHeight)
: mInitialHeight(initialHeight)
{
}

int mInitialHeight;
bool mBackAtOriginalHeight = false;
};


using State = std::variant<Flying, Hovering, PlungingDown, RisingUp>;

}


struct RedBird {
void update(
GlobalDependencies&,
Expand All @@ -76,7 +46,41 @@ struct RedBird {
const engine::events::CollidedWithWorld& event,
entityx::Entity entity);

red_bird::State mState;
void startRisingUp(int initialHeight, entityx::Entity entity);


struct Flying {
Flying() noexcept = default;
explicit Flying(const engine::components::Orientation orientation)
: mOrientation(orientation)
{
}

engine::components::Orientation mOrientation =
engine::components::Orientation::Left;
unsigned int mAnimStep = 0;
};

struct Hovering {
int mFramesElapsed = 0;
};

struct PlungingDown {
int mInitialHeight;
};

struct RisingUp {
explicit RisingUp(const int initialHeight)
: mInitialHeight(initialHeight)
{
}

int mInitialHeight;
bool mBackAtOriginalHeight = false;
};

using State = std::variant<Flying, Hovering, PlungingDown, RisingUp>;
State mState;
};

}
1 change: 1 addition & 0 deletions src/game_logic/game_world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ void GameWorld::handleTeleporter() {
}

mpSystems->centerViewOnPlayer();
updateGameLogic({});
render();
mpServiceProvider->fadeInScreen();
}
Expand Down
8 changes: 7 additions & 1 deletion src/game_logic/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,13 @@ void Player::die() {
}

mpPlayerModel->takeFatalDamage();
mEntity.component<c::Sprite>()->mShow = true;
mpPlayerModel->removeItem(data::InventoryItemType::CloakingDevice);
mpEvents->emit(rigel::events::CloakExpired{});

auto& sprite = *mEntity.component<c::Sprite>();
sprite.mTranslucent = false;
sprite.mShow = true;

mState = Dieing{};
setVisualState(VisualState::Dieing);
mpServiceProvider->playSound(data::SoundId::DukeDeath);
Expand Down

0 comments on commit d4cc375

Please sign in to comment.