Refactor: UIManager modularization and Devlog update
This commit is contained in:
110
src/view/ui/SpellbookUI.js
Normal file
110
src/view/ui/SpellbookUI.js
Normal file
@@ -0,0 +1,110 @@
|
||||
import { SPELLS } from '../../engine/data/Spells.js';
|
||||
|
||||
export class SpellbookUI {
|
||||
constructor(game) {
|
||||
this.game = game;
|
||||
this.spellBookContainer = null;
|
||||
}
|
||||
|
||||
toggle(hero) {
|
||||
if (this.spellBookContainer) {
|
||||
document.body.removeChild(this.spellBookContainer);
|
||||
this.spellBookContainer = null;
|
||||
return;
|
||||
}
|
||||
|
||||
const container = document.createElement('div');
|
||||
Object.assign(container.style, {
|
||||
position: 'absolute',
|
||||
bottom: '140px',
|
||||
left: '50%',
|
||||
transform: 'translateX(-50%)',
|
||||
display: 'flex',
|
||||
gap: '15px',
|
||||
backgroundColor: 'rgba(20, 10, 30, 0.9)',
|
||||
padding: '20px',
|
||||
borderRadius: '10px',
|
||||
border: '2px solid #9933ff',
|
||||
zIndex: '1500',
|
||||
boxShadow: '0 0 20px rgba(100, 0, 255, 0.5)'
|
||||
});
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.textContent = "LIBRO DE HECHIZOS";
|
||||
Object.assign(title.style, {
|
||||
position: 'absolute', top: '-30px', left: '0', width: '100%', textAlign: 'center',
|
||||
color: '#d8bfff', fontFamily: '"Cinzel", serif', fontSize: '18px', textShadow: '0 0 5px #8a2be2'
|
||||
});
|
||||
container.appendChild(title);
|
||||
|
||||
SPELLS.forEach(spell => {
|
||||
const canCast = this.game.canCastSpell(spell);
|
||||
|
||||
const card = document.createElement('div');
|
||||
Object.assign(card.style, {
|
||||
width: '180px', height: '260px', position: 'relative', cursor: canCast ? 'pointer' : 'not-allowed',
|
||||
transition: 'transform 0.2s', filter: canCast ? 'none' : 'grayscale(100%) brightness(50%)',
|
||||
backgroundImage: this.getSpellTemplate(spell.type), backgroundSize: 'cover'
|
||||
});
|
||||
|
||||
if (canCast) {
|
||||
card.onmouseenter = () => { card.style.transform = 'scale(1.1) translateY(-10px)'; card.style.zIndex = '10'; };
|
||||
card.onmouseleave = () => { card.style.transform = 'scale(1)'; card.style.zIndex = '1'; };
|
||||
|
||||
card.onclick = (e) => {
|
||||
e.stopPropagation();
|
||||
document.body.removeChild(this.spellBookContainer);
|
||||
this.spellBookContainer = null;
|
||||
|
||||
if (spell.type === 'attack' || spell.type === 'defense') {
|
||||
this.game.startSpellTargeting(spell);
|
||||
} else {
|
||||
// Global/Instant
|
||||
this.game.executeSpell(spell);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Cost Badge
|
||||
const costBadge = document.createElement('div');
|
||||
costBadge.textContent = spell.cost;
|
||||
Object.assign(costBadge.style, {
|
||||
position: 'absolute', top: '12px', left: '12px', width: '30px', height: '30px', borderRadius: '50%',
|
||||
backgroundColor: '#fff', color: '#000', fontWeight: 'bold', display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
border: '2px solid #000', fontSize: '18px', fontFamily: 'serif'
|
||||
});
|
||||
card.appendChild(costBadge);
|
||||
|
||||
// Name
|
||||
const nameEl = document.createElement('div');
|
||||
nameEl.textContent = spell.name.toUpperCase();
|
||||
Object.assign(nameEl.style, {
|
||||
position: 'absolute', top: '45px', width: '100%', textAlign: 'center', fontSize: '14px',
|
||||
color: '#000', fontWeight: 'bold', fontFamily: '"Cinzel", serif', padding: '0 10px', boxSizing: 'border-box'
|
||||
});
|
||||
card.appendChild(nameEl);
|
||||
|
||||
// Description
|
||||
const descEl = document.createElement('div');
|
||||
descEl.textContent = spell.description;
|
||||
Object.assign(descEl.style, {
|
||||
position: 'absolute', bottom: '30px', left: '10px', width: '160px', height: '80px',
|
||||
fontSize: '11px', color: '#000', textAlign: 'center', display: 'flex', alignItems: 'center',
|
||||
justifyContent: 'center', fontFamily: 'serif', lineHeight: '1.2'
|
||||
});
|
||||
card.appendChild(descEl);
|
||||
|
||||
container.appendChild(card);
|
||||
});
|
||||
|
||||
document.body.appendChild(container);
|
||||
this.spellBookContainer = container;
|
||||
}
|
||||
|
||||
getSpellTemplate(type) {
|
||||
let filename = 'attack_template.png';
|
||||
if (type === 'heal') filename = 'healing_template.png';
|
||||
if (type === 'defense') filename = 'defense_template.png';
|
||||
return `url('/assets/images/dungeon1/spells/${filename}')`;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user