208 lines
7.5 KiB
PHP
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|