#include "PocketDungeon.h" #include namespace PocketDungeon { static constexpr uint32_t TICK_MS = 200; static constexpr const char* PREF_BEST_FLOOR = "bestFloor"; static constexpr const char* PREF_BEST_GOLD = "bestGold"; void PocketDungeon::onShow(AppHandle app, lv_obj_t* parent) { lv_obj_remove_flag(parent, LV_OBJ_FLAG_SCROLLABLE); lv_obj_set_style_pad_all(parent, 0, LV_PART_MAIN); root = parent; (void) tt_lvgl_toolbar_create_for_app(parent, app); model.setBests(static_cast(prefs.getInt(PREF_BEST_FLOOR, 1)), static_cast(prefs.getInt(PREF_BEST_GOLD, 0))); model.reset(lv_tick_get()); if (sfx == nullptr) { sfx = new SfxEngine(); if (sfx->start()) sfx->applyVolumePreset(SfxEngine::VolumePreset::Quiet); } onEnter(parent); loop.start(TICK_MS, this); } void PocketDungeon::onHide(AppHandle app) { (void) app; loop.stop(); onExit(); saveBests(); if (sfx != nullptr) { sfx->stop(); delete sfx; sfx = nullptr; } root = nullptr; } void PocketDungeon::onEnter(lv_obj_t* sceneRoot) { renderer.create(sceneRoot); GameKit::attachInput(sceneRoot, this); lastResult = MoveResult::None; render(); } void PocketDungeon::onExit() {} void PocketDungeon::onInput(const GameKit::InputEvent& input) { int dx = 0; int dy = 0; switch (input.kind) { case GameKit::InputKind::Up: dy = -1; break; case GameKit::InputKind::Down: dy = 1; break; case GameKit::InputKind::Left: dx = -1; break; case GameKit::InputKind::Right: dx = 1; break; default: break; } if (model.getState().gameOver) { model.reset(lv_tick_get()); lastResult = MoveResult::None; render(); return; } if (dx != 0 || dy != 0) { lastResult = model.movePlayer(dx, dy); playResultSound(lastResult); if (lastResult == MoveResult::Dead) saveBests(); render(); } } void PocketDungeon::onTick(const GameKit::Tick& tick) { (void) tick; } void PocketDungeon::render() { renderer.render(model, lastResult); } void PocketDungeon::saveBests() { prefs.putInt(PREF_BEST_FLOOR, model.getBestFloor()); prefs.putInt(PREF_BEST_GOLD, model.getBestGold()); } void PocketDungeon::playResultSound(MoveResult result) { if (sfx == nullptr) return; switch (result) { case MoveResult::Attacked: sfx->play(SfxId::Hurt); break; case MoveResult::Treasure: sfx->play(SfxId::Coin); break; case MoveResult::Stairs: sfx->play(SfxId::Warp); break; case MoveResult::Dead: sfx->play(SfxId::GameOver); break; case MoveResult::Moved: sfx->play(SfxId::Blip); break; case MoveResult::Blocked: sfx->play(SfxId::Error); break; default: break; } } } // namespace PocketDungeon