CollectibleCard.tsx
Обзор
CollectibleCard.tsx — это React-компонент, отвечающий за визуальное отображение и управление отдельной карточкой элементаля в коллекции игрока. Компонент отображает информацию об элементале (стихия, редкость, уровень, защита), визуальные элементы (изображение, эмодзи, индикаторы редкости и кулдауна), а также кнопку для прокачки уровня или повышения редкости персонажа.
Кроме визуализации, компонент содержит логику управления интерактивностью:
проверяет возможность прокачки элементаля с учётом ресурсов игрока,
обрабатывает клики по кнопке повышения уровня,
реализует вибрацию карточки с использованием Telegram Web App API и Web Vibration API для тактильной обратной связи,
динамически генерирует уникальное стабильное имя персонажа на основе его ID, стихии и редкости.
Компонент тесно интегрирован с бизнес-логикой игры (gameLogic.ts) через импорт вспомогательных функций и типов.
Детальное описание
Интерфейс CollectibleCardProps
Определяет свойства, передаваемые в компонент:
Свойство | Тип | Описание |
|---|---|---|
|
| Объект элементаля с его текущими характеристиками |
| (elemental: CollectedElemental, displayData: ElementalDisplayData) => void | Коллбек при клике на кнопку прокачки/улучшения |
|
| Текущий запас маны игрока |
Компонент CollectibleCard
React функциональный компонент:
const CollectibleCard: React.FC<CollectibleCardProps> = ({ elemental, onLevelUpClick, playerMana }) => { ... }
Локальное состояние
isVibrating: boolean— флаг, указывающий, активна ли вибрация карточки в данный момент.
Основные методы и функции
handleLevelUpClick()
Обработчик клика по кнопке прокачки.
Проверяет, можно ли прокачать элементаля (через
displayData.canLevelUp).Если да, вызывает
onLevelUpClickс текущим элементалем и данными для отображения.
Эффект вибрации (React.useEffect)
Создаёт и регистрирует функцию вибрации для этой карточки в глобальном объекте
window.triggerCardVibrationс ключомelemental.id.Вибрация реализована через:
Telegram Web App API — предпочтительный метод для Telegram Mini Apps, с разной интенсивностью для обычного повышения уровня и повышения редкости (апгрейда).
Web Vibration API — fallback для браузеров.
Несколько уровней fallback с обработкой ошибок для максимальной совместимости.
После 800 мс сбрасывает состояние
isVibratingвfalse.При размонтировании компонента удаляет функцию вибрации из глобального объекта.
getRarityColor(rarity: ElementalRarity): string
Возвращает цвет, соответствующий редкости элементаля.
Редкость | Цвет |
|---|---|
common | #9ca3af |
rare | #3b82f6 |
epic | #8b5cf6 |
immortal | #f59e0b |
default | #9ca3af |
getElementColor(element: Element): string
Возвращает цвет, соответствующий стихии элементаля.
Стихия | Цвет |
|---|---|
earth | #059669 |
water | #0ea5e9 |
fire | #dc2626 |
default | #6b7280 |
getRarityClass(rarity: ElementalRarity): string
Возвращает CSS-класс для стилизации редкости.
Редкость | CSS класс |
|---|---|
common | rarity-common |
rare | rarity-rare |
epic | rarity-epic |
immortal | rarity-immortal |
default | rarity-common |
getStableCharacterName(element: string, rarity: string, elementalId: string): string
Генерирует стабильное уникальное имя персонажа на основе ID, стихии и редкости.
Алгоритм:
Хэширует
elementalId, используя битовые операции.Для каждой стихии определён набор прилагательных и существительных (тематика элемента).
Выбирает прилагательное и существительное по индексу, зависящему от хэша и длины редкости.
Возвращает строку
<прилагательное> <существительное>.
Пример использования:
const name = getStableCharacterName('earth', 'rare', 'abc123');
// => "Mighty Guardian" (пример)
getElementalDisplayData(elemental: CollectedElemental): ElementalDisplayData
Формирует объект с данными для отображения элементаля, включая:
Текущее имя и эмодзи (из
ELEMENTAL_TYPESпо стихии и редкости).Защиту (процент) — через
getElementalProtection.Максимальный уровень для редкости (
getMaxLevelForRarity).Проверка возможности повышения редкости (если уровень достиг максимума).
Стоимость прокачки (уровня или редкости).
Флаги:
canLevelUp,canUpgradeRarity,isImmortal.
JSX-разметка
Структура карточки:
Внешний
div.collectible-cardс классами по редкости, стихии и состоянию вибрации.Область изображения (
card-artwork):Контейнер изображения с классом
on-cooldown, если элементаль на кулдауне.Изображение элементаля с fallback’ом на эмодзи при ошибке загрузки.
Фон и эмодзи.
Индикатор редкости (нижний левый угол).
Индикатор кулдауна (таймер с часами, минутами, секундами) — видим только если элементаль на кулдауне.
Кнопка прокачки с динамическими классами и подсказками:
Показывает
MAXесли достигнут максимальный уровень дляimmortal.Показывает
Upgradeесли доступно повышение редкости.Иначе
LVL UP.Активна только если можно прокачать (
canLevelUp).
Блок с именем и описанием персонажа (
character-name-block):Имя персонажа, сгенерированное функцией
getStableCharacterName.Краткое описание с процентом защиты, зависящее от стихии.
Текущий уровень.
Важные детали реализации и алгоритмы
Вибрация: реализована с учётом специфики Telegram Mini Apps (использование Telegram WebApp API) и браузерных API с несколькими уровнями fallback. Вибрация усиливается при повышении редкости.
Детерминированные имена: позволяет создавать атмосферные и уникальные имена без необходимости хранить отдельную базу имён.
Управление состоянием вибрации: локальное состояние
isVibratingотвечает за добавление CSS-класса, обеспечивающего визуальный эффект вибрации.Обработка ошибок загрузки изображений: переключается на эмодзи, если картинка не загрузилась.
Динамическое формирование стилей: через CSS-переменные (
--rarity-color,--rarity-glow,--element-color) для удобства темы и кастомизации.
Взаимодействие с другими частями системы
Импортирует функции из
gameLogic.tsдля получения данных о элементалях: стоимости прокачки, проверке возможности уровня, кулдауне и защите.Использует типы из
types.ts, обеспечивая строгую типизацию.При клике вызывает коллбек
onLevelUpClick, переданный из родительского компонента (например,CollectionTab.tsx), который управляет отображением модального окна подтверждения и обновлением состояния коллекции.Использует глобальный объект
window.triggerCardVibrationдля внешнего вызова вибрации карточки (например, после подтверждения прокачки).Отвечает за локальное визуальное состояние, включая отображение кулдауна и вибрационных эффектов.
Зависит от переменной окружения
process.env.PUBLIC_URLдля загрузки изображений персонажей.
Пример использования
import CollectibleCard from './CollectibleCard';
const onLevelUp = (elemental, displayData) => {
if (displayData.canLevelUp) {
// логика прокачки, например, вызвать API или обновить состояние
console.log(`Прокачка ${elemental.id}`);
}
};
const playerMana = 500;
const elemental = {
id: 'abc123',
element: 'fire',
rarity: 'rare',
level: 2,
// ...другие поля
};
<CollectibleCard
elemental={elemental}
onLevelUpClick={onLevelUp}
playerMana={playerMana}
/>;
Mermaid диаграмма структуры компонента
classDiagram
class CollectibleCard {
-isVibrating: boolean
+handleLevelUpClick(): void
+getRarityColor(rarity: ElementalRarity): string
+getElementColor(element: Element): string
+getRarityClass(rarity: ElementalRarity): string
+getStableCharacterName(element: string, rarity: string, elementalId: string): string
+getElementalDisplayData(elemental: CollectedElemental): ElementalDisplayData
+render(): JSX.Element
}
CollectibleCard ..> CollectedElemental : uses
CollectibleCard ..> ElementalDisplayData : uses
CollectibleCard ..> gameLogic : imports functions
Заключение
CollectibleCard.tsx — ключевой компонент UI для отображения и управления отдельным элементалем в коллекции игрока. Он сочетает в себе визуализацию, бизнес-логику по отображению состояния элементаля и интерактивность (прокачка, вибрация). Его дизайн ориентирован на удобство пользователя, поддержку мобильных устройств (вибрация), а также тесную интеграцию с остальной системой, включая бизнес-логику и обработку коллекции.
Данный компонент идеально вписывается в архитектуру проекта, обеспечивая модульность, расширяемость и высокий уровень пользовательского опыта.