Skip to content

Commit

Permalink
すくう動作の大幅改良
Browse files Browse the repository at this point in the history
  • Loading branch information
sashi0034 committed Nov 23, 2023
1 parent 5de6b10 commit 315749f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 47 deletions.
1 change: 1 addition & 0 deletions Sukuu/App/asset/parameters.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ constant_floor = true

[play.scene]
hitstopping_timescale = 0.1
slow_timescale = 0.3

[play.player]
move_duration = 0.3
Expand Down
6 changes: 5 additions & 1 deletion Sukuu/Play/PlayScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,11 @@ class Play::PlayScene::Impl
m_measuredSeconds[m_floorIndex] += GetDeltaTime();

// ヒットストッピング管理
SetTimeScale(m_hitStoppingRequested > 0 ? getToml<double>(U"hitstopping_timescale") : 1.0);
SetTimeScale(m_hitStoppingRequested > 0
? getToml<double>(U"hitstopping_timescale")
: (m_player.IsSlowMotion()
? getToml<double>(U"slow_timescale")
: 1.0));
}

private:
Expand Down
103 changes: 57 additions & 46 deletions Sukuu/Play/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ struct Play::Player::Impl
bool m_terminated{};
PlayerImmortality m_immortal{};
bool m_guardHelmet{};
std::function<void()> m_subDrawing = {};
std::function<void()> m_subUpdating = {};
bool m_scoopRequested{};
bool m_slowMotion{};
int m_scoopContinuous{};
PlayerVisionState m_vision{};
double m_faintStealthTime{};
Expand All @@ -66,10 +68,10 @@ struct Play::Player::Impl

m_faintStealthTime = std::max(m_faintStealthTime - GetDeltaTime(), 0.0);

if (m_subDrawing)
if (m_subUpdating)
{
// すくうなどの描画
m_subDrawing();
m_subUpdating();
}
else
{
Expand Down Expand Up @@ -105,7 +107,7 @@ struct Play::Player::Impl
m_isGameOver = true;
m_flowchart.Kill();
m_distField.Clear();
m_subDrawing = {};
m_subUpdating = {};
m_immortal.immortalStock++;
AnimateEasing<EaseOutCirc>(self, &m_cameraScale, 8.0, 0.5);
StartCoro(self, [this](YieldExtended yield)
Expand Down Expand Up @@ -354,7 +356,9 @@ struct Play::Player::Impl
m_cameraOffsetDestination = {0, 0};
m_flowchart.Kill();
m_distField.Clear();
m_subDrawing = {};
m_subUpdating = {};
m_scoopRequested = false;
m_slowMotion = false;
}

void flowchartLoop(YieldExtended& yield, ActorView self)
Expand Down Expand Up @@ -461,15 +465,16 @@ struct Play::Player::Impl
yield();
if (not MouseR.pressed())
{
m_subDrawing = {};
m_subUpdating = {};
return;
}

const auto center = m_pos.actualPos.movedBy(CellPx_24 / 2, CellPx_24 / 2);
const auto deltaCursor = Cursor::PosF() - center;
m_direction = Dir4::FromXY(deltaCursor);
m_subDrawing = [center, d = m_direction, t = m_animTimer.Time()]()
m_subUpdating = [center, d = m_direction, t = m_animTimer.Time()]()
{
// 矢印描画
constexpr auto c = ColorF(U"#ffc22b");
(void)Shape2D::Arrow(Line{center, center + d.ToXY() * (32 - 4 * Periodic::Jump0_1(0.5s, t))}, 20,
Vec2{16, 16})
Expand All @@ -481,7 +486,8 @@ struct Play::Player::Impl

void checkScoopFromMouse(YieldExtended& yield, ActorView self)
{
if (RectF(m_pos.actualPos, {CellPx_24, CellPx_24}).intersects(Cursor::PosF()) == false)
if (not m_scoopRequested &&
RectF(m_pos.actualPos, {CellPx_24, CellPx_24}).intersects(Cursor::PosF()) == false)
return;

if (const auto tutorial = PlayScene::Instance().Tutorial())
Expand All @@ -493,73 +499,73 @@ struct Play::Player::Impl

// マウスクリックまで待機
focusCameraFor(self, getToml<double>(U"focus_scale_large"));
m_subDrawing = [this, self]() mutable
m_subUpdating = [this, self]() mutable
{
if (RectF(m_pos.actualPos, {CellPx_24, CellPx_24}).intersects(Cursor::PosF()) == false)
{
// 解除
m_subDrawing = {};
m_subUpdating = {};
focusCameraFor(self, 1.0);
return;
}
RectF(m_pos.actualPos.MapPoint() * CellPx_24, {CellPx_24, CellPx_24})
.draw(getToml<ColorF>(U"scoop_rect_color_1"));
.draw(m_scoopRequested
? getToml<ColorF>(U"scoop_rect_color_2")
: getToml<ColorF>(U"scoop_rect_color_1"));
if (MouseL.down()) m_scoopRequested = true;
};
while (true)
{
if (checkMoveInput() != Dir4::Invalid && MouseL.pressed() == false) return;
if (RectF(m_pos.actualPos, {CellPx_24, CellPx_24}).intersects(Cursor::PosF()) == false)
return;

yield();
if (MouseL.pressed()) break;
}
// すくうが要求されるまで処理を進めない
if (not m_scoopRequested) return;
AudioAsset(AssetSes::scoop_start).playOneShot();

// ドラッグ解除まで待機
m_subDrawing = [this]()
// すくう方向を決定
m_subUpdating = [this]()
{
for (int i = 0; i < 4; ++i)
{
auto r = RectF(m_pos.actualPos.movedBy(Dir4Type(i).ToXY() * CellPx_24), {CellPx_24, CellPx_24});
r.draw(getToml<ColorF>(U"scoop_rect_color_2"));
}
};
m_slowMotion = true;
while (true)
{
yield();
if (MouseL.pressed() == false)
if (MouseL.down())
{
m_subDrawing = {};
// すくう解除
m_subUpdating = {};
m_scoopRequested = false;
m_slowMotion = false;
break;
}

// 目標が決まったかチェック
for (int i = 0; i < 4; ++i)
const auto centerRect = RectF(m_pos.actualPos, Vec2{CellPx_24, CellPx_24});

// もともとのマスからカーソルが離れたら処理スタート
if (centerRect.intersects(Cursor::PosF())) continue;

const auto centerPoint = m_pos.actualPos.movedBy(Point::One() * CellPx_24 / 2);

// カーソルをもとに目標の方向を決める
auto dir = Dir4::FromXY(Cursor::PosF() - centerPoint);

const auto checkingPos = m_pos.actualPos.movedBy(Dir4Type(dir).ToXY() * CellPx_24);
if (const auto tutorial = PlayScene::Instance().Tutorial())
{
const auto checkingPos = m_pos.actualPos.movedBy(Dir4Type(i).ToXY() * CellPx_24);
auto r = RectF(checkingPos, {CellPx_24, CellPx_24});
if (r.intersects(Cursor::PosF()) == false) continue;
if (const auto tutorial = PlayScene::Instance().Tutorial())
{
if (not tutorial->PlayerService().canScoopTo(checkingPos)) continue;
}

// 以下、移動させる処理を実行
// m_distField.Clear();
m_subDrawing = {};
succeedScoop(yield, self, checkingPos);

goto dropped;
if (not tutorial->PlayerService().canScoopTo(checkingPos)) continue;
}
}

dropped:;
focusCameraFor(self, 1.0);
yield.WaitForTrue([]()
{
return MouseL.pressed() == false;
});
// 以下、移動させる処理を実行
// m_distField.Clear();
m_scoopRequested = false;
m_subUpdating = {};
m_slowMotion = false;
succeedScoop(yield, self, checkingPos);
focusCameraFor(self, 1.0);
break;
}
}

void succeedScoop(YieldExtended& yield, ActorView self, const Vector2D<double> checkingPos)
Expand Down Expand Up @@ -800,6 +806,11 @@ namespace Play
return p_impl->m_distField.Field();
}

bool Player::IsSlowMotion() const
{
return p_impl->m_slowMotion;
}

bool Player::IsImmortal() const
{
return p_impl->m_immortal.IsImmortal();
Expand Down
2 changes: 2 additions & 0 deletions Sukuu/Play/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Play
double OrderPriority() const override;

void SendEnemyCollide(const RectF& rect, EnemyKind enemy);

bool CanUseItem(int itemIndex) const;
void RequestUseItem(int itemIndex);

Expand All @@ -26,6 +27,7 @@ namespace Play
const CharaPosition& CurrentPos() const;
Point CurrentPoint() const;
const PlayerDistField& DistField() const;
bool IsSlowMotion() const;
bool IsImmortal() const;
bool IsTerminated() const;
const PlayerVisionState& Vision() const;
Expand Down

0 comments on commit 315749f

Please sign in to comment.