逻辑优化

This commit is contained in:
hantao 2025-12-03 18:15:54 +08:00
parent 826f0e38a4
commit 05bff41e35
15 changed files with 436 additions and 153 deletions

View File

@ -1 +1 @@
{"player":{"hp":31,"maxHp":50,"patk":10,"matk":5,"pdef":5,"mdef":3,"crit":5,"critdmg":130,"level":3,"exp":70,"maxExp":225,"inventory":[],"equip":{"weapon":{"name":"青钢剑","type":"weapon","quality":"rare","level":1,"patk":14,"matk":3,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["暴击伤害 +6"],"desc":"Lv.1 rare品质的武器","id":"692ee8e0df082","quantity":1},"armor":{"name":"皮甲","type":"armor","quality":"common","level":3,"patk":0,"matk":0,"pdef":6,"mdef":1,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.3 common品质的防具","id":"692efecedbc7a","quantity":1}},"spiritStones":72,"npcFlags":[],"talentPoints":0,"talents":{"hp":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"mana":100,"maxMana":100,"spells":[],"spellBooks":{"3":1},"partners":[{"id":"li_feiyu","name":"厉飞雨","level":2,"exp":60,"maxExp":150,"baseStats":{"hp":100,"patk":15,"matk":5,"pdef":5,"mdef":3,"crit":10,"critdmg":130,"growth":1.2},"equip":{"weapon":{"name":"青钢剑","type":"weapon","quality":"common","level":1,"patk":6,"matk":2,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.1 common品质的武器","id":"692ee91453dd8","quantity":1}},"talents":{"hp":1,"patk":1,"matk":0,"pdef":0,"mdef":0,"crit":1,"critdmg":0},"talentWeights":{"hp":1,"patk":3,"matk":1,"pdef":1,"mdef":1,"crit":3,"critdmg":2},"mana":80,"maxMana":80,"spells":[],"spellBooks":[]}]},"dungeonId":1,"state":2} {"player":{"hp":110,"maxHp":50,"patk":10,"matk":5,"pdef":5,"mdef":3,"crit":5,"critdmg":130,"level":3,"exp":160,"maxExp":225,"inventory":[{"name":"雷霆锤","type":"weapon","quality":"common","level":1,"patk":8,"matk":3,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.1 common品质的武器","id":"692fa0f61aa45","quantity":1}],"equip":{"weapon":{"name":"青钢剑","type":"weapon","quality":"rare","level":1,"patk":14,"matk":3,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":["暴击伤害 +6"],"desc":"Lv.1 rare品质的武器","id":"692ee8e0df082","quantity":1},"armor":{"name":"皮甲","type":"armor","quality":"common","level":3,"patk":0,"matk":0,"pdef":6,"mdef":1,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.3 common品质的防具","id":"692efecedbc7a","quantity":1}},"spiritStones":91,"npcFlags":[],"talentPoints":0,"talents":{"hp":6,"patk":0,"matk":0,"pdef":0,"mdef":0,"crit":0,"critdmg":0},"mana":100,"maxMana":100,"spells":[],"spellBooks":{"3":1,"1":2,"10":2},"partners":[{"id":"li_feiyu","name":"厉飞雨","level":2,"exp":132,"maxExp":150,"baseStats":{"hp":100,"patk":15,"matk":5,"pdef":5,"mdef":3,"crit":10,"critdmg":130,"growth":1.2},"equip":{"weapon":{"name":"青钢剑","type":"weapon","quality":"common","level":1,"patk":6,"matk":2,"pdef":0,"mdef":0,"hp":0,"crit":0,"critdmg":0,"heal":0,"affixes":[],"desc":"Lv.1 common品质的武器","id":"692ee91453dd8","quantity":1}},"talents":{"hp":1,"patk":1,"matk":0,"pdef":0,"mdef":0,"crit":1,"critdmg":0},"talentWeights":{"hp":1,"patk":3,"matk":1,"pdef":1,"mdef":1,"crit":3,"critdmg":2},"mana":80,"maxMana":80,"spells":[],"spellBooks":[]}]},"dungeonId":1,"state":0}

24
src/Core/Colors.php Normal file
View File

@ -0,0 +1,24 @@
<?php
namespace Game\Core;
class Colors
{
public const RESET = "\033[0m";
public const BOLD = "\033[1m";
public const RED = "\033[31m";
public const GREEN = "\033[32m";
public const YELLOW = "\033[33m";
public const BLUE = "\033[34m";
public const MAGENTA = "\033[35m";
public const CYAN = "\033[36m";
public const WHITE = "\033[37m";
public const GRAY = "\033[90m";
// Semantic aliases
public const PROMPT = self::CYAN;
public const INFO = self::WHITE;
public const SUCCESS = self::GREEN;
public const WARNING = self::YELLOW;
public const ERROR = self::RED;
}

View File

@ -8,10 +8,10 @@ class ItemDisplay
{ {
// 品质颜色 // 品质颜色
private static array $qualityColors = [ private static array $qualityColors = [
'common' => "\033[37m", // 白色 'common' => Colors::WHITE,
'rare' => "\033[34m", // 蓝色 'rare' => Colors::BLUE,
'epic' => "\033[35m", // 紫色 'epic' => Colors::MAGENTA,
'legendary' => "\033[33m", // 黄色/金色 'legendary' => Colors::YELLOW,
]; ];
// 品质名称 // 品质名称
@ -45,12 +45,12 @@ class ItemDisplay
]; ];
// 颜色常量 // 颜色常量
private static string $reset = "\033[0m"; private static string $reset = Colors::RESET;
private static string $yellow = "\033[33m"; private static string $yellow = Colors::YELLOW;
private static string $green = "\033[32m"; private static string $green = Colors::GREEN;
private static string $cyan = "\033[36m"; private static string $cyan = Colors::CYAN;
private static string $white = "\033[37m"; private static string $white = Colors::WHITE;
private static string $gray = "\033[90m"; private static string $gray = Colors::GRAY;
/** /**
* 获取品质颜色 * 获取品质颜色

View File

@ -0,0 +1,14 @@
<?php
// Per-dungeon spell pools
return [
1 => [1, 10],
2 => [2, 3, 11],
3 => [20, 21],
4 => [12],
5 => [4],
6 => [5, 22],
7 => [13],
8 => [13, 22],
9 => [5, 13],
// others can be added later
];

179
src/Entities/Actor.php Normal file
View File

@ -0,0 +1,179 @@
<?php
namespace Game\Entities;
class Actor
{
// Common properties shared by Player, Partner, Monster
public string $name = '';
public int $level = 1;
public int $exp = 0;
public int $maxExp = 100;
public int $hp = 0;
public int $maxHp = 0;
public int $patk = 0;
public int $matk = 0;
public int $pdef = 0;
public int $mdef = 0;
public int $crit = 0;
public float $critdmg = 110.0;
public int $mana = 0;
public int $maxMana = 0;
public array $spells = [];
public array $spellBooks = [];
public array $equip = [];
public array $inventory = [];
public int $spiritStones = 0;
/**
* Heal by amount, not exceeding max HP. Returns actual healed amount.
*/
public function heal(int $amount): int
{
$maxHp = $this->maxHp ?? ($this->baseHp ?? ($this->hp ?? 0));
$old = $this->hp ?? 0;
$this->hp = min(($this->hp ?? 0) + $amount, $maxHp);
return $this->hp - $old;
}
public function fullHeal(): void
{
if (property_exists($this, 'maxHp')) {
$this->hp = $this->maxHp;
} elseif (property_exists($this, 'baseHp')) {
$this->hp = $this->baseHp;
}
}
public function recoverMana(int $amount): int
{
$old = $this->mana ?? 0;
$max = $this->maxMana ?? ($this->mana ?? 0);
$this->mana = min(($this->mana ?? 0) + $amount, $max);
return $this->mana - $old;
}
public function fullRecoverMana(): void
{
if (property_exists($this, 'maxMana')) {
$this->mana = $this->maxMana;
}
}
public function spendMana(int $amount): bool
{
if (($this->mana ?? 0) >= $amount) {
$this->mana -= $amount;
return true;
}
return false;
}
/**
* Unified getStats used by Player, Partner, Monster.
* Merges base stats, equipment bonuses, affixes, and optional talent modifiers provided by subclasses.
*/
public function getStats(): array
{
// Base stats
$base = [
'maxHp' => $this->maxHp ?? ($this->baseHp ?? ($this->hp ?? 0)),
'patk' => $this->patk ?? 0,
'matk' => $this->matk ?? 0,
'pdef' => $this->pdef ?? 0,
'mdef' => $this->mdef ?? 0,
'crit' => $this->crit ?? 0,
'critdmg' => $this->critdmg ?? 100,
];
$percentBonuses = array_fill_keys(array_keys($base), 0);
// 1. If subclass provides talent-like stats, merge them
if (method_exists($this, 'getTalentStats')) {
$talent = $this->getTalentStats();
foreach ($talent as $k => $v) {
if (isset($base[$k])) $base[$k] += $v;
}
}
// 2. Apply equipment base stats and collect affix percent bonuses
foreach ($this->equip as $item) {
if (empty($item)) continue;
$enhanceLevel = $item['enhanceLevel'] ?? 0;
$enhanceMultiplier = 1 + ($enhanceLevel * 0.05);
foreach (['hp','patk','matk','pdef','mdef','crit','critdmg'] as $statKey) {
if (isset($item[$statKey])) {
$k = $statKey === 'hp' ? 'maxHp' : $statKey;
$base[$k] += (int)(($item[$statKey] ?? 0) * $enhanceMultiplier);
}
}
if (!empty($item['affixes'])) {
foreach ($item['affixes'] as $affix) {
$this->parseAffix($affix, $base, $percentBonuses);
}
}
}
// 3. Apply percentage bonuses
foreach ($base as $k => $v) {
if (!empty($percentBonuses[$k])) {
$base[$k] = (int)($v * (1 + $percentBonuses[$k] / 100));
}
}
return $base;
}
private function parseAffix(string $affix, array &$flatStats, array &$percentStats)
{
// Example: "物攻 +5% (T1)" or "生命值 +20 (T1)"
if (preg_match('/(物攻|魔攻|物防|魔防|生命值|暴击率|暴击伤害)\s+\+(\d+)(%?)/', $affix, $matches)) {
$name = $matches[1];
$value = (int)$matches[2];
$isPercent = $matches[3] === '%';
$key = match ($name) {
'物攻' => 'patk',
'魔攻' => 'matk',
'物防' => 'pdef',
'魔防' => 'mdef',
'生命值' => 'maxHp',
'暴击率' => 'crit',
'暴击伤害' => 'critdmg',
default => null
};
if ($key) {
if ($isPercent && !in_array($key, ['crit','critdmg'])) {
$percentStats[$key] += $value;
} else {
$flatStats[$key] += $value;
}
}
}
}
/**
* Default factory to create an Actor (delegates to Monster by default).
*/
public static function create(int $dungeonId): Actor
{
return Monster::create($dungeonId);
}
/**
* Default factory to create a group of Actors (delegates to Monster::createGroup).
* @return Actor[]
*/
public static function createGroup(int $dungeonId): array
{
return Monster::createGroup($dungeonId);
}
}

View File

@ -1,25 +1,17 @@
<?php <?php
namespace Game\Entities; namespace Game\Entities;
class Monster class Monster extends Actor
{ {
public string $name = '普通怪物'; public string $name = '普通怪物';
public int $level = 1; public int $level = 1;
public int $hp = 20;
public int $baseHp = 20; // 基础HP不含装备加成 public int $baseHp = 20; // 基础HP不含装备加成
public int $patk = 4; // 物理攻击
public int $basePatk = 4; // 基础物理攻击(不含装备加成) public int $basePatk = 4; // 基础物理攻击(不含装备加成)
public int $matk = 2; // 魔法攻击
public int $baseMatk = 2; // 基础魔法攻击(不含装备加成) public int $baseMatk = 2; // 基础魔法攻击(不含装备加成)
public int $pdef = 0; // 物理防御
public int $basePdef = 0; // 基础物理防御(不含装备加成) public int $basePdef = 0; // 基础物理防御(不含装备加成)
public int $mdef = 0; // 魔法防御
public int $baseMdef = 0; // 基础魔法防御(不含装备加成) public int $baseMdef = 0; // 基础魔法防御(不含装备加成)
public int $crit = 5; // 暴击率
public int $critdmg = 150; // 暴击伤害
public int $expReward = 10; public int $expReward = 10;
public int $spiritStoneReward = 0; // 灵石奖励 public int $spiritStoneReward = 0; // 灵石奖励
public array $equip = []; // 怪物装备 ['weapon' => item, 'armor' => item, ...]
public array $dropTable = []; // 消耗品掉落表 ['item' => [...], 'rate' => 0.5] public array $dropTable = []; // 消耗品掉落表 ['item' => [...], 'rate' => 0.5]
public static function create(int $dungeonId): self public static function create(int $dungeonId): self
@ -72,7 +64,7 @@ class Monster
/** /**
* Create a group of monsters with random, diverse enemies (1-5 monsters) * Create a group of monsters with random, diverse enemies (1-5 monsters)
* Each monster is independently selected from the dungeon's monster pool using weighted random selection * Each monster is independently selected from the dungeon's monster pool using weighted random selection
* @return Monster[] * @return Actor[]
*/ */
public static function createGroup(int $dungeonId): array public static function createGroup(int $dungeonId): array
{ {
@ -164,6 +156,46 @@ class Monster
continue; continue;
} }
if ($type === 'spell') {
// Chance to include this spell tome in drop table
if (rand(1, 100) > $rate) continue;
// spell drop spec should include 'spell_id' (or 'id') to identify the spell
$spellId = $drop['spell_id'] ?? ($drop['id'] ?? null);
if ($spellId !== null) {
static $spellsData = null;
if ($spellsData === null) {
$spellsData = require __DIR__ . '/../../src/Data/spells.php';
}
$spellInfo = null;
foreach ($spellsData as $cat => $list) {
if (!is_array($list) || in_array($cat, ['quality_levels','upgrades'])) continue;
if (isset($list[$spellId])) { $spellInfo = $list[$spellId]; break; }
}
// Scale tome level by monster level (e.g., level tiers of 5)
$tomeLevel = max(1, min(10, (int)ceil($this->level / 5)));
$tome = [
'name' => ($spellInfo['name'] ?? ('法术#' . $spellId)) . '的法术书',
'type' => 'spell_tome',
'quality' => $spellInfo['quality'] ?? ($drop['quality'] ?? 'common'),
'level' => $tomeLevel,
'spell_id' => $spellId,
'spell_name' => $spellInfo['name'] ?? null,
'desc' => $drop['desc'] ?? ('能够学习或提升 ' . ($spellInfo['name'] ?? '未知法术')),
];
// Add to drop table with given rate
$this->dropTable[] = [
'item' => $tome,
'rate' => $rate,
];
}
continue;
}
if (in_array($type, ['weapon', 'armor', 'boots', 'ring', 'necklace'])) { if (in_array($type, ['weapon', 'armor', 'boots', 'ring', 'necklace'])) {
if (rand(1, 100) > $rate) continue; if (rand(1, 100) > $rate) continue;
$spec = $drop; $spec = $drop;
@ -179,19 +211,17 @@ class Monster
/** /**
* 应用装备属性加成到怪物属性 * 应用装备属性加成到怪物属性
*/ */
// Monster-specific application of equipment is handled by Actor::getStats; applyEquipmentStats remains for legacy callers
public function applyEquipmentStats(): void public function applyEquipmentStats(): void
{ {
// 重置为基础属性
$this->hp = $this->baseHp; $this->hp = $this->baseHp;
$this->patk = $this->basePatk; $this->patk = $this->basePatk;
$this->matk = $this->baseMatk; $this->matk = $this->baseMatk;
$this->pdef = $this->basePdef; $this->pdef = $this->basePdef;
$this->mdef = $this->baseMdef; $this->mdef = $this->baseMdef;
// 加上装备属性
foreach ($this->equip as $item) { foreach ($this->equip as $item) {
if (empty($item)) continue; if (empty($item)) continue;
$this->hp += $item['hp'] ?? 0; $this->hp += $item['hp'] ?? 0;
$this->patk += $item['patk'] ?? $item['atk'] ?? 0; $this->patk += $item['patk'] ?? $item['atk'] ?? 0;
$this->matk += $item['matk'] ?? 0; $this->matk += $item['matk'] ?? 0;
@ -201,7 +231,6 @@ class Monster
$this->critdmg += $item['critdmg'] ?? 0; $this->critdmg += $item['critdmg'] ?? 0;
} }
} }
/** /**
* 获取怪物装备的物品列表(用于战斗胜利时掉落) * 获取怪物装备的物品列表(用于战斗胜利时掉落)
* @return array * @return array

View File

@ -5,17 +5,10 @@ class Partner
{ {
public string $id; public string $id;
public string $name; public string $name;
public int $level = 1;
public int $exp = 0;
public int $maxExp = 100;
public int $hp = 100; // 当前血量
public array $baseStats = []; public array $baseStats = [];
public array $equip = []; // weapon, armor, ring, boots, necklace public array $equip = []; // weapon, armor, ring, boots, necklace
// 法术系统 // 法术系统
public int $mana = 80; // 当前魔法值(队友初始值低于玩家)
public int $maxMana = 80; // 最大魔法值
public array $spells = []; // 已学习的法术ID列表 public array $spells = []; // 已学习的法术ID列表
public array $spellBooks = []; // 拥有的法术资源书 public array $spellBooks = []; // 拥有的法术资源书

View File

@ -3,29 +3,8 @@ namespace Game\Entities;
use Game\Entities\Partner; use Game\Entities\Partner;
class Player class Player extends Actor
{ {
// 基础属性(初始值,不随等级变化)
public int $hp = 50; // 当前生命值
public int $maxHp = 50; // 基础生命值上限
public int $patk = 10; // 基础物理攻击
public int $matk = 5; // 基础魔法攻击
public int $pdef = 5; // 基础物理防御
public int $mdef = 3; // 基础魔法防御
public int $crit = 5; // 基础暴击率
public float $critdmg = 130; // 基础暴击伤害
public int $level = 1;
public int $exp = 0;
public int $maxExp = 100;
public int $spiritStones = 0; // 灵石
// 法术系统
public int $mana = 100; // 当前魔法值
public int $maxMana = 100; // 最大魔法值
public array $spells = []; // 已学习的法术ID列表 [1 => ['level' => 1], ...]
public array $spellBooks = []; // 拥有的法术资源书 [spell_id => 数量, ...]
// 天赋系统 // 天赋系统
public int $talentPoints = 0; // 可用天赋点 public int $talentPoints = 0; // 可用天赋点

View File

@ -5,14 +5,16 @@ use Game\Core\Game;
use Game\Core\Input; use Game\Core\Input;
use Game\Core\Screen; use Game\Core\Screen;
use Game\Core\ItemDisplay; use Game\Core\ItemDisplay;
use Game\Core\Colors;
use Game\Entities\Player; use Game\Entities\Player;
use Game\Entities\Actor;
use Game\Entities\Monster; use Game\Entities\Monster;
use Game\Entities\Partner; use Game\Entities\Partner;
class Battle class Battle
{ {
public Player $player; public Player $player;
/** @var Monster[] */ /** @var Actor[] */
public array $enemies = []; public array $enemies = [];
/** @var array<string, int> 同伴当前HP */ /** @var array<string, int> 同伴当前HP */
@ -21,22 +23,17 @@ class Battle
// 法术数据 // 法术数据
private array $spellsData = []; private array $spellsData = [];
private array $qualityColors = [ private array $qualityColors = [];
'common' => "\033[37m", // 白色
'rare' => "\033[34m", // 蓝色
'epic' => "\033[35m", // 紫色
'legendary' => "\033[33m", // 黄色
];
// 颜色定义 // 颜色定义 (use Colors constants)
private string $red = "\033[31m"; private string $red;
private string $green = "\033[32m"; private string $green;
private string $yellow = "\033[33m"; private string $yellow;
private string $cyan = "\033[36m"; private string $cyan;
private string $white = "\033[37m"; private string $white;
private string $magenta = "\033[35m"; private string $magenta;
private string $bold = "\033[1m"; private string $bold;
private string $reset = "\033[0m"; private string $reset;
private int $round = 0; private int $round = 0;
private int $totalMaxHp = 0; private int $totalMaxHp = 0;
@ -45,6 +42,23 @@ class Battle
{ {
$this->player = $game->player; $this->player = $game->player;
$this->spellsData = require __DIR__ . '/../../src/Data/spells.php'; $this->spellsData = require __DIR__ . '/../../src/Data/spells.php';
// Initialize color palette from centralized Colors
$this->red = Colors::RED;
$this->green = Colors::GREEN;
$this->yellow = Colors::YELLOW;
$this->cyan = Colors::CYAN;
$this->white = Colors::WHITE;
$this->magenta = Colors::MAGENTA;
$this->bold = Colors::BOLD;
$this->reset = Colors::RESET;
$this->qualityColors = [
'common' => Colors::WHITE,
'rare' => Colors::BLUE,
'epic' => Colors::MAGENTA,
'legendary' => Colors::YELLOW,
];
} }
/** /**
@ -85,7 +99,7 @@ class Battle
/** /**
* 获取存活的敌人 * 获取存活的敌人
* @return Monster[] * @return Actor[]
*/ */
private function getAliveEnemies(): array private function getAliveEnemies(): array
{ {
@ -612,29 +626,32 @@ class Battle
/** /**
* 生成法术资源书掉落 * 生成法术资源书掉落
*/ */
private function generateSpellTomeDrop(Monster $enemy): ?array private function generateSpellTomeDrop(Actor $enemy): ?array
{ {
// 获取当前地牢的法术掉落池 // 尝试从独立的副本法术映射文件获取(每个副本有自己的法术池)
$dungeonId = $this->game->dungeonId; $dungeonId = $this->game->dungeonId;
$dungeonSpellDrops = $this->spellsData['dungeon_spell_drops'] ?? []; $spellIds = null;
if (!isset($dungeonSpellDrops[$dungeonId])) { $dungeonSpellFile = __DIR__ . '/../../src/Data/dungeon_spells.php';
return null; // 该地牢没有配置法术掉落 if (file_exists($dungeonSpellFile)) {
$dungeonMap = require $dungeonSpellFile;
$spellIds = $dungeonMap[$dungeonId] ?? null;
} }
$spellIds = $dungeonSpellDrops[$dungeonId]; // 回退到全局配置里的 dungeon_spell_drops
if (empty($spellIds)) { if (empty($spellIds)) {
$dungeonSpellDrops = $this->spellsData['dungeon_spell_drops'] ?? [];
$spellIds = $dungeonSpellDrops[$dungeonId] ?? null;
}
if (empty($spellIds) || !is_array($spellIds)) {
return null; return null;
} }
// 从该地牢的掉落池中随机选择一个法术 // 从法术池中随机选择一个法术ID
$spellId = $spellIds[array_rand($spellIds)]; $spellId = $spellIds[array_rand($spellIds)];
$spellInfo = $this->getSpellInfo($spellId); $spellInfo = $this->getSpellInfo($spellId);
if (!$spellInfo) return null;
if (!$spellInfo) {
return null;
}
// 创建法术资源书物品 // 创建法术资源书物品
$tome = [ $tome = [
@ -931,7 +948,7 @@ class Battle
Screen::delay(1500000); Screen::delay(1500000);
} }
private function showDefeat($out, ?Monster $killer = null) private function showDefeat($out, ?Actor $killer = null)
{ {
Screen::clear($out); Screen::clear($out);
$killerName = $killer ? $killer->name : "敌人"; $killerName = $killer ? $killer->name : "敌人";

View File

@ -4,6 +4,7 @@ namespace Game\Modules;
use Game\Core\Game; use Game\Core\Game;
use Game\Core\ItemDisplay; use Game\Core\ItemDisplay;
use Game\Core\Screen; use Game\Core\Screen;
use Game\Core\Colors;
use Game\Services\EquipmentEnhancer; use Game\Services\EquipmentEnhancer;
/** /**
@ -12,15 +13,23 @@ use Game\Services\EquipmentEnhancer;
*/ */
class EquipmentEnhancePanel class EquipmentEnhancePanel
{ {
private string $cyan = "\033[36m"; private string $cyan;
private string $yellow = "\033[33m"; private string $yellow;
private string $green = "\033[32m"; private string $green;
private string $red = "\033[31m"; private string $red;
private string $white = "\033[37m"; private string $white;
private string $bold = "\033[1m"; private string $bold;
private string $reset = "\033[0m"; private string $reset;
public function __construct(public Game $game) {} public function __construct(public Game $game) {
$this->cyan = Colors::CYAN;
$this->yellow = Colors::YELLOW;
$this->green = Colors::GREEN;
$this->red = Colors::RED;
$this->white = Colors::WHITE;
$this->bold = Colors::BOLD;
$this->reset = Colors::RESET;
}
public function show() public function show()
{ {

View File

@ -4,18 +4,19 @@ namespace Game\Modules;
use Game\Core\Game; use Game\Core\Game;
use Game\Core\Screen; use Game\Core\Screen;
use Game\Core\ItemDisplay; use Game\Core\ItemDisplay;
use Game\Core\Colors;
class InventoryPanel class InventoryPanel
{ {
private array $rarityColors = [ private array $rarityColors = [
'common' => "\033[37m", 'common' => Colors::WHITE,
'uncommon' => "\033[32m", 'uncommon' => Colors::GREEN,
'rare' => "\033[34m", 'rare' => Colors::BLUE,
'epic' => "\033[35m", 'epic' => Colors::MAGENTA,
'legendary' => "\033[33m", 'legendary' => Colors::YELLOW,
]; ];
private string $reset = "\033[0m"; private string $reset = Colors::RESET;
private int $perPage = 8; private int $perPage = 8;
@ -728,11 +729,11 @@ class InventoryPanel
$stats = $player->getStats(); $stats = $player->getStats();
// Colors // Colors
$cyan = "\033[36m"; $cyan = Colors::CYAN;
$yellow = "\033[33m"; $yellow = Colors::YELLOW;
$green = "\033[32m"; $green = Colors::GREEN;
$red = "\033[31m"; $red = Colors::RED;
$reset = "\033[0m"; $reset = Colors::RESET;
$out->writeln("╔════════════════════════════════════════════════════════╗"); $out->writeln("╔════════════════════════════════════════════════════════╗");
$out->writeln("{$cyan}角色属性{$reset} Lv.{$player->level} | {$green}💰 {$player->spiritStones}{$reset} 灵石 ║"); $out->writeln("{$cyan}角色属性{$reset} Lv.{$player->level} | {$green}💰 {$player->spiritStones}{$reset} 灵石 ║");

View File

@ -1,6 +1,7 @@
<?php <?php
namespace Game\Modules; namespace Game\Modules;
use Game\Core\Colors;
use Game\Core\Game; use Game\Core\Game;
use Game\Core\Screen; use Game\Core\Screen;
use Game\Core\Input; use Game\Core\Input;
@ -9,16 +10,23 @@ use Game\Entities\Partner;
class PartnerPanel class PartnerPanel
{ {
private string $reset = "\033[0m"; private string $reset;
private string $cyan = "\033[36m"; private string $cyan;
private string $green = "\033[32m"; private string $green;
private string $yellow = "\033[33m"; private string $yellow;
private string $red = "\033[31m"; private string $red;
private string $magenta = "\033[35m"; private string $magenta;
private string $white = "\033[37m"; private string $white;
public function __construct(public Game $game) public function __construct(public Game $game)
{ {
$this->reset = Colors::RESET;
$this->cyan = Colors::CYAN;
$this->green = Colors::GREEN;
$this->yellow = Colors::YELLOW;
$this->red = Colors::RED;
$this->magenta = Colors::MAGENTA;
$this->white = Colors::WHITE;
} }
public function show() public function show()

View File

@ -1,23 +1,32 @@
<?php <?php
namespace Game\Modules; namespace Game\Modules;
use Game\Core\Colors;
use Game\Core\Game; use Game\Core\Game;
use Game\Core\Input; use Game\Core\Input;
use Game\Core\Screen; use Game\Core\Screen;
class SpellPanel class SpellPanel
{ {
private string $cyan = "\033[36m"; private string $cyan;
private string $white = "\033[37m"; private string $white;
private string $reset = "\033[0m"; private string $reset;
private string $bold = "\033[1m"; private string $bold;
private string $green = "\033[32m"; private string $green;
private string $yellow = "\033[33m"; private string $yellow;
private string $magenta = "\033[35m"; private string $magenta;
private string $red = "\033[31m"; private string $red;
public function __construct(public Game $game) public function __construct(public Game $game)
{ {
$this->cyan = Colors::CYAN;
$this->white = Colors::WHITE;
$this->reset = Colors::RESET;
$this->bold = Colors::BOLD;
$this->green = Colors::GREEN;
$this->yellow = Colors::YELLOW;
$this->magenta = Colors::MAGENTA;
$this->red = Colors::RED;
} }
public function show() public function show()
@ -368,7 +377,7 @@ class SpellPanel
} }
$out->writeln("[0] 返回"); $out->writeln("[0] 返回");
$choice = $in->prompt("请选择要升级的法术"); $choice = Input::ask($out,"请选择要升级的法术");
if ($choice == '0') { if ($choice == '0') {
return; return;
@ -421,13 +430,13 @@ class SpellPanel
*/ */
private function getQualityColor(string $quality): string private function getQualityColor(string $quality): string
{ {
return match($quality) { $map = [
'common' => "\033[37m", // 白色 'common' => Colors::WHITE,
'rare' => "\033[34m", // 蓝色 'rare' => Colors::BLUE,
'epic' => "\033[35m", // 紫色 'epic' => Colors::MAGENTA,
'legendary' => "\033[33m", // 黄色 'legendary' => Colors::YELLOW,
default => $this->white ];
}; return $map[$quality] ?? $this->white;
} }
/** /**
@ -435,13 +444,13 @@ class SpellPanel
*/ */
private function getQualityName(string $quality): string private function getQualityName(string $quality): string
{ {
return match($quality) { $map = [
'common' => '普通', 'common' => '普通',
'rare' => '稀有', 'rare' => '稀有',
'epic' => '史诗', 'epic' => '史诗',
'legendary' => '传奇', 'legendary' => '传奇',
default => '未知' ];
}; return $map[$quality] ?? '未知';
} }
/** /**

View File

@ -1,6 +1,7 @@
<?php <?php
namespace Game\Modules; namespace Game\Modules;
use Game\Core\Colors;
use Game\Core\Game; use Game\Core\Game;
use Game\Core\Screen; use Game\Core\Screen;
use Game\Core\ItemDisplay; use Game\Core\ItemDisplay;
@ -29,22 +30,17 @@ class StatsPanel
]; ];
// 颜色 // 颜色
private string $cyan = "\033[36m"; private string $cyan;
private string $yellow = "\033[33m"; private string $yellow;
private string $green = "\033[32m"; private string $green;
private string $magenta = "\033[35m"; private string $magenta;
private string $red = "\033[31m"; private string $red;
private string $white = "\033[37m"; private string $white;
private string $blue = "\033[34m"; private string $blue;
private string $reset = "\033[0m"; private string $reset;
// 品质颜色 // 品质颜色
private array $qualityColors = [ private array $qualityColors = [];
'common' => "\033[37m", // 白色
'rare' => "\033[34m", // 蓝色
'epic' => "\033[35m", // 紫色
'legendary' => "\033[33m", // 黄色/金色
];
// 品质名称 // 品质名称
private array $qualityNames = [ private array $qualityNames = [
@ -54,7 +50,23 @@ class StatsPanel
'legendary' => '传说', 'legendary' => '传说',
]; ];
public function __construct(public Game $game) {} public function __construct(public Game $game) {
$this->cyan = Colors::CYAN;
$this->yellow = Colors::YELLOW;
$this->green = Colors::GREEN;
$this->magenta = Colors::MAGENTA;
$this->red = Colors::RED;
$this->white = Colors::WHITE;
$this->blue = Colors::BLUE;
$this->reset = Colors::RESET;
$this->qualityColors = [
'common' => Colors::WHITE,
'rare' => Colors::BLUE,
'epic' => Colors::MAGENTA,
'legendary' => Colors::YELLOW,
];
}
public function show() public function show()
{ {
@ -122,7 +134,7 @@ class StatsPanel
} }
} else { } else {
$out->writeln("║ [{$slotIndex}] {$this->cyan}{$slotName}{$this->reset}: " . $out->writeln("║ [{$slotIndex}] {$this->cyan}{$slotName}{$this->reset}: " .
"\033[90m(空)\033[0m"); Colors::GRAY . '(空)' . Colors::RESET);
} }
$slotIndex++; $slotIndex++;
} }

View File

@ -4,21 +4,30 @@ namespace Game\Modules;
use Game\Core\Game; use Game\Core\Game;
use Game\Core\Screen; use Game\Core\Screen;
use Game\Core\Input; use Game\Core\Input;
use Game\Core\Colors;
use Game\Entities\Player; use Game\Entities\Player;
class TalentPanel class TalentPanel
{ {
private string $reset = "\033[0m"; private string $reset;
private string $cyan = "\033[36m"; private string $cyan;
private string $green = "\033[32m"; private string $green;
private string $yellow = "\033[33m"; private string $yellow;
private string $red = "\033[31m"; private string $red;
private string $magenta = "\033[35m"; private string $magenta;
private string $white = "\033[37m"; private string $white;
private string $gray = "\033[90m"; private string $gray;
public function __construct(public Game $game) public function __construct(public Game $game)
{ {
$this->reset = Colors::RESET;
$this->cyan = Colors::CYAN;
$this->green = Colors::GREEN;
$this->yellow = Colors::YELLOW;
$this->red = Colors::RED;
$this->magenta = Colors::MAGENTA;
$this->white = Colors::WHITE;
$this->gray = Colors::GRAY;
} }
public function show() public function show()