CollectionTab.tsx
Обзор
Файл CollectionTab.tsx реализует React-компонент CollectionTab, который является ключевым элементом пользовательского интерфейса для управления коллекцией элементалей игрока в игре. Компонент отвечает за отображение всех элементалей игрока, предоставляет удобный интерфейс фильтрации по стихиям и редкостям, а также обеспечивает механизмы прокачки выбранных элементалей с подтверждением через модальное окно.
Основная задача компонента — предоставить игроку функциональность для просмотра и сортировки своих элементалей, а также безопасно и наглядно выполнять повышение уровня или редкости с учётом доступных ресурсов (маны).
Описание компонента и его функциональности
Компонент: CollectionTab
const CollectionTab: React.FC<CollectionTabProps> = ({ player, onLevelUpElemental }) => { ... }
Назначение: Основной компонент для отображения коллекции элементалей, фильтрации и управления прокачкой.
Параметры:
player: PlayerStats— объект с текущими данными игрока, включая коллекцию элементалей и количество маны.onLevelUpElemental: (elementalId: string) => void— callback-функция, вызываемая при подтверждении прокачки элементаля. Передаёт идентификатор элементаля для обновления в родительском компоненте.
Локальное состояние:
selectedElement— выбранный фильтр по стихиям ('earth' | 'water' | 'fire' | 'all').selectedRarity— выбранный фильтр по редкости ('common' | 'rare' | 'epic' | 'immortal' | 'all').showConfirmModal— флаг отображения модального окна подтверждения прокачки.selectedElemental— выбранный для прокачки элементаль (типCollectedElementalилиnull).selectedDisplayData— данные отображения для выбранного элементаля, включая стоимость и возможность повышения редкости (ElementalDisplayDataилиnull).forceUpdate— вспомогательный стейт для принудительного обновления компонента каждую секунду (обновление таймеров кулдауна).
Подробное описание ключевых частей и методов
1. Фильтрация и сортировка коллекции
const ownedElementals = Object.values(player.elementalCollection.elementals).filter(e => e.isOwned);
Получаем все элементали, которыми владеет игрок (
isOwned === true).
const sortByRarity = (a: CollectedElemental, b: CollectedElemental) => { ... }
Функция сортировки элементалей с приоритетом по редкости (от самой редкой —
immortal— к самой распространённой —common).При равенстве редкости сортирует по стихии (порядок: fire, water, earth).
const filteredElementals = ownedElementals
.filter(elemental => {
if (selectedElement !== 'all' && elemental.element !== selectedElement)
return false;
if (selectedRarity !== 'all' && elemental.rarity !== selectedRarity)
return false;
return true;
})
.sort(sortByRarity);
Фильтрация по выбранным стихиям и редкости.
Сортировка отфильтрованных элементалей по редкости и стихии.
2. Обновление состояния и таймер кулдаунов
useEffect(() => {
const interval = setInterval(() => {
forceUpdate(prev => prev + 1);
}, 1000);
return () => clearInterval(interval);
}, [forceUpdate]);
Каждую секунду вызывается обновление компонента для актуализации отображения оставшегося времени кулдауна элементалей.
3. Управление модальным окном подтверждения прокачки
Управление классом
modal-openу<body>при открытии/закрытии модального окна:
useEffect(() => {
if (showConfirmModal) {
document.body.classList.add('modal-open');
} else {
document.body.classList.remove('modal-open');
}
return () => {
document.body.classList.remove('modal-open');
};
}, [showConfirmModal]);
Обработка нажатия клавиши Escape для отмены прокачки и закрытия модального окна:
useEffect(() => {
const handleEscape = (e: KeyboardEvent) => {
if (e.key === 'Escape' && showConfirmModal) {
handleCancelLevelUp();
}
};
if (showConfirmModal) {
document.addEventListener('keydown', handleEscape);
}
return () => {
document.removeEventListener('keydown', handleEscape);
};
}, [showConfirmModal]);
4. Обработка выбора прокачки элементаля
const handleLevelUpClick = (
elemental: CollectedElemental,
displayData: ElementalDisplayData
) => {
setSelectedElemental(elemental);
setSelectedDisplayData(displayData);
setShowConfirmModal(true);
};
Вызывается при клике на кнопку "Level Up" в карточке элементаля.
Устанавливает выбранного элементаля и его данные отображения, открывает модальное подтверждение.
5. Подтверждение прокачки
const handleConfirmLevelUp = () => {
if (selectedElemental && selectedDisplayData) {
onLevelUpElemental(selectedElemental.id);
setShowConfirmModal(false);
setSelectedElemental(null);
setSelectedDisplayData(null);
// Запуск вибрации с небольшой задержкой после закрытия модального окна
setTimeout(() => {
const windowWithVibration = window as Window & {
triggerCardVibration?: Record<string, (isUpgrade?: boolean) => void>;
};
if (windowWithVibration.triggerCardVibration && selectedElemental) {
const cardVibrationFunction =
windowWithVibration.triggerCardVibration[selectedElemental.id];
if (cardVibrationFunction) {
cardVibrationFunction(selectedDisplayData.canUpgradeRarity);
}
}
}, 100);
}
};
Вызывает функцию прокачки из родительского компонента.
Закрывает модальное окно.
Запускает вибрацию карточки элементаля для тактильной обратной связи.
Вибрация усиливается, если происходит повышение редкости (обозначено параметром
canUpgradeRarity).
6. Отмена прокачки
const handleCancelLevelUp = () => {
setShowConfirmModal(false);
setSelectedElemental(null);
setSelectedDisplayData(null);
};
Закрывает модальное окно без изменений.
7. Рендеринг интерфейса
Фильтры по стихиям и редкости: Кнопки с визуальной индикацией выбранных фильтров.
Сетка карточек элементалей: Отрисовка отфильтрованных элементалей с помощью компонента
CollectibleCard.Пустое состояние: При отсутствии элементалей после фильтрации отображается подсказка с кнопками сброса фильтров.
Модальное окно подтверждения прокачки: Создаётся через React Portal, содержит информацию:
Текущий и будущий уровень элементаля.
Информация о повышении редкости (если применимо).
Стоимость прокачки в мане.
Баланс игрока и остаток после списания.
Кнопки подтверждения и отмены.
Взаимодействие с другими частями системы
Родительский компонент: Передаёт объект
playerс состоянием игрока и функциюonLevelUpElementalдля обработки прокачки.Компонент
CollectibleCard: Отвечает за отображение каждой карточки элементаля, включая кнопку прокачки, которая вызываетhandleLevelUpClick.Глобальный объект
window.triggerCardVibration: Используется для вызова вибрации карточек после успешной прокачки. Поддерживается как Telegram WebApp API, так и Web Vibration API.Типы
CollectedElemental,ElementalDisplayData,PlayerStats: Определяют структуру данных элементалей, их отображаемых свойств и состояния игрока.Модальные окна через React Portal: Обеспечивают отображение поверх основного интерфейса без нарушения текущей структуры DOM.
Пример использования
<CollectionTab
player={currentPlayerStats}
onLevelUpElemental={(elementalId) => {
// Обработать повышение уровня элементаля с id = elementalId
// Обновить состояние игрока и коллекции
}}
/>
Важные детали реализации
Использование
useEffectс интервалом в 1000 мс для обновления компонента и актуализации таймеров кулдауна.Управление классом
modal-openв<body>, чтобы предотвратить скроллинг при открытом модальном окне.Обработка нажатия клавиши Escape для удобного закрытия модального окна.
Сортировка элементалей сначала по редкости (от редких к обычным), затем по стихии, для удобства пользователя.
Вибрация карточки запускается с небольшой задержкой (100 мс) после закрытия модального окна, чтобы избежать конфликтов UI.
Кнопка подтверждения прокачки отключается, если у игрока недостаточно маны (менее 100 маны после списания).
Диаграмма структуры компонента CollectionTab
componentDiagram
direction TB
CollectionTab <|-- CollectibleCard : использует
CollectionTab o-- "PlayerStats" : получает данные игрока
CollectionTab o-- "CollectedElemental[]" : обрабатывает коллекцию
CollectionTab o-- "ElementalDisplayData" : отображает данные
CollectionTab --> ReactDOM.createPortal : рендерит модальное окно
class CollectionTab {
+player: PlayerStats
+onLevelUpElemental(elementalId: string): void
-selectedElement: 'earth'|'water'|'fire'|'all'
-selectedRarity: 'common'|'rare'|'epic'|'immortal'|'all'
-showConfirmModal: boolean
-selectedElemental: CollectedElemental|null
-selectedDisplayData: ElementalDisplayData|null
-handleLevelUpClick()
-handleConfirmLevelUp()
-handleCancelLevelUp()
}
class CollectibleCard {
+elemental: CollectedElemental
+onLevelUpClick()
+playerMana: number
}
Заключение
CollectionTab.tsx — это ключевой UI-компонент для управления коллекцией элементалей в игре, обеспечивающий:
Гибкую фильтрацию и сортировку коллекции.
Отображение карточек элементалей с актуальной информацией.
Безопасную и информативную прокачку с подтверждением.
Интерактивную обратную связь (модальные окна, вибрация).
Интеграцию с бизнес-логикой и данными игрока.
Такой подход обеспечивает удобство, прозрачность и погружение пользователя в игровой процесс развития персонажей.
Дополнительная информация
Для полного понимания работы прокачки стоит ознакомиться с бизнес-логикой в gameLogic.ts и компонентом карточек CollectibleCard.tsx, так как именно там реализованы алгоритмы определения стоимости, проверки возможности прокачки и визуализация каждого элементаля.
Если нужна более подробная документация по связанным компонентам или бизнес-логике, пожалуйста, дайте знать.