hanli/src/Core/Game.php
2025-12-04 18:11:28 +08:00

208 lines
7.5 KiB
PHP

<?php
namespace Game\Core;
use Game\Entities\Player;
use Game\Entities\Partner;
use Game\Modules\InventoryPanel;
use Game\Modules\Menu;
use Game\Modules\Battle;
use Game\Modules\StatsPanel;
use Game\Modules\NpcPanel;
use Game\Modules\TalentPanel;
use Game\Modules\DungeonSelectPanel;
use Game\Modules\EquipmentEnhancePanel;
use Game\Modules\SpellPanel;
class Game
{
const MENU = 1;
const BATTLE = 2;
const STATS = 3;
const INVENTORY = 4;
const NPC = 5;
const TALENT = 6;
const EQUIPMENT_ENHANCE = 7;
const DUNGEON_SELECT = 8;
const EXIT = 0;
public Player $player;
public int $state = self::MENU;
public int $dungeonId = 1;
private string $saveFile;
private string $savesDir;
private ?string $userId = null;
public function __construct(public $input, public $output, ?string $userId = null)
{
$this->player = new Player();
$this->savesDir = __DIR__ . '/../../saves';
// 确保存档目录存在
if (!is_dir($this->savesDir)) {
mkdir($this->savesDir, 0755, true);
}
// 设置用户ID和存档路径
if ($userId) {
$this->userId = $userId;
$this->saveFile = $this->savesDir . '/' . $userId . '.json';
} else {
// 向后兼容:单机模式使用默认存档
$this->saveFile = __DIR__ . '/../../save.json';
}
$this->loadState();
}
/**
* 获取当前用户ID
*/
public function getUserId(): ?string
{
return $this->userId;
}
private function loadState(): void
{
if (file_exists($this->saveFile)) {
$data = json_decode(file_get_contents($this->saveFile), true);
if (is_array($data)) {
$p = $data['player'] ?? [];
$this->player->hp = $p['hp'] ?? $this->player->hp;
$this->player->maxHp = $p['maxHp'] ?? $this->player->maxHp;
// 新属性系统,向后兼容旧存档
$this->player->patk = $p['patk'] ?? $p['atk'] ?? $this->player->patk;
$this->player->matk = $p['matk'] ?? $this->player->matk;
$this->player->pdef = $p['pdef'] ?? $p['def'] ?? $this->player->pdef;
$this->player->mdef = $p['mdef'] ?? $this->player->mdef;
$this->player->crit = $p['crit'] ?? $this->player->crit;
$this->player->critdmg = $p['critdmg'] ?? $this->player->critdmg;
$this->player->level = $p['level'] ?? $this->player->level;
$this->player->exp = $p['exp'] ?? $this->player->exp;
$this->player->maxExp = $p['maxExp'] ?? $this->player->maxExp;
$this->player->inventory = $p['inventory'] ?? $this->player->inventory;
$this->player->equip = $p['equip'] ?? $this->player->equip;
$this->player->spiritStones = $p['spiritStones'] ?? $this->player->spiritStones;
$this->player->npcFlags = $p['npcFlags'] ?? $this->player->npcFlags;
// 加载天赋数据
$this->player->talentPoints = $p['talentPoints'] ?? $this->player->talentPoints;
$this->player->talents = $p['talents'] ?? $this->player->talents;
// 加载同伴数据
if (isset($p['partners']) && is_array($p['partners'])) {
foreach ($p['partners'] as $partnerData) {
$partner = new Partner($partnerData);
$this->player->partners[$partner->id] = $partner;
}
}
// 加载技能槽位数据 (新法术系统)
$this->player->mana = $p['mana'] ?? $this->player->mana;
$this->player->maxMana = $p['maxMana'] ?? $this->player->maxMana;
$this->player->skillSlots = $p['skillSlots'] ?? $this->player->skillSlots;
$this->dungeonId = $data['dungeonId'] ?? $this->dungeonId;
$this->state = self::MENU;
}
}
}
public function saveState(): void
{
// 序列化同伴数据
$partnersData = [];
foreach ($this->player->partners as $partner) {
$partnersData[] = [
'id' => $partner->id,
'name' => $partner->name,
'level' => $partner->level,
'exp' => $partner->exp,
'maxExp' => $partner->maxExp,
'equip' => $partner->equip,
'talents' => $partner->talents,
'talentWeights' => $partner->talentWeights,
'mana' => $partner->mana,
'maxMana' => $partner->maxMana,
'skillSlots' => $partner->skillSlots,
'hp' => $partner->hp,
'maxHp' => $partner->maxHp,
'patk' => $partner->patk,
'matk' => $partner->matk,
'pdef' => $partner->pdef,
'mdef' => $partner->mdef,
'crit' => $partner->crit,
'critdmg' => $partner->critdmg,
];
}
$data = [
'player' => [
'hp' => $this->player->hp,
'maxHp' => $this->player->maxHp,
'patk' => $this->player->patk,
'matk' => $this->player->matk,
'pdef' => $this->player->pdef,
'mdef' => $this->player->mdef,
'crit' => $this->player->crit,
'critdmg' => $this->player->critdmg,
'level' => $this->player->level,
'exp' => $this->player->exp,
'maxExp' => $this->player->maxExp,
'inventory' => $this->player->inventory,
'equip' => $this->player->equip,
'spiritStones' => $this->player->spiritStones,
'npcFlags' => $this->player->npcFlags,
'talentPoints' => $this->player->talentPoints,
'talents' => $this->player->talents,
'mana' => $this->player->mana,
'maxMana' => $this->player->maxMana,
'skillSlots' => $this->player->skillSlots,
'partners' => $partnersData,
],
'dungeonId' => $this->dungeonId,
'state' => $this->state,
];
file_put_contents($this->saveFile, json_encode($data, JSON_UNESCAPED_UNICODE));
}
public function run()
{
while (true) {
switch ($this->state) {
case self::MENU:
(new Menu($this))->show();
break;
case self::DUNGEON_SELECT:
(new DungeonSelectPanel($this))->show();
break;
case self::BATTLE:
(new Battle($this))->start();
break;
case self::STATS:
(new StatsPanel($this))->show();
break;
case self::INVENTORY:
(new InventoryPanel($this))->show();
break;
case self::NPC:
(new NpcPanel($this))->show();
break;
case self::TALENT:
(new TalentPanel($this))->show();
break;
case self::EQUIPMENT_ENHANCE:
(new EquipmentEnhancePanel($this))->show();
break;
case self::EXIT:
$this->output->writeln("再见!");
$this->saveState();
return;
}
}
}
}