nin101's picture
NONE OF THE buttons work
c839f4f verified
class GameCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}
static get observedAttributes() {
return ['title', 'icon', 'color', 'href'];
}
connectedCallback() {
this.render();
this.addEventListeners();
}
render() {
const title = this.getAttribute('title') || 'Game Mode';
const icon = this.getAttribute('icon') || 'play';
const color = this.getAttribute('color') || 'green';
const href = this.getAttribute('href') || '#';
const colorClasses = {
green: 'bg-green-600 hover:bg-green-700',
yellow: 'bg-yellow-600 hover:bg-yellow-700',
blue: 'bg-blue-600 hover:bg-blue-700',
purple: 'bg-purple-600 hover:bg-purple-700'
};
this.shadowRoot.innerHTML = `
<style>
.card {
background: #1f2937;
border-radius: 0.75rem;
padding: 1.5rem;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
border: 2px solid transparent;
position: relative;
overflow: hidden;
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, #10b981, #3b82f6);
opacity: 0;
transition: opacity 0.3s ease;
}
.card:hover::before {
opacity: 1;
}
.card:hover {
transform: translateY(-4px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3);
border-color: rgba(16, 185, 129, 0.3);
}
.icon-container {
width: 60px;
height: 60px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem auto;
}
.title {
font-size: 1.125rem;
font-weight: 600;
margin-bottom: 0.5rem;
}
.play-button {
background: #10b981;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
.play-button:hover {
background: #059669;
transform: scale(1.05);
}
.card.green .icon-container { background: rgba(16, 185, 129, 0.2); }
.card.yellow .icon-container { background: rgba(245, 158, 11, 0.2); }
.card.blue { background: rgba(59, 130, 246, 0.2); }
.card.purple .icon-container { background: rgba(139, 92, 246, 0.2); }
.card.green .play-button { background: #10b981; }
.card.yellow .play-button { background: #f59e0b; }
.card.blue .play-button { background: #3b82f6; }
.card.purple .play-button { background: #8b5cf6; }
.card.green:hover::before { background: linear-gradient(90deg, #10b981, #059669); }
.card.yellow:hover::before { background: linear-gradient(90deg, #f59e0b, #d97706); }
.card.blue:hover::before { background: linear-gradient(90deg, #3b82f6, #1d4ed8); }
.card.purple:hover::before { background: linear-gradient(90deg, #8b5cf6, #7c3aed); }
</style>
<div class="card ${color}">
<div class="icon-container">
<i data-feather="${icon}" class="w-6 h-6"></i>
</div>
<div class="title">${title}</div>
<button class="play-button w-full py-2 rounded-lg font-bold transition-all">
Play Now
</button>
</div>
</div>
`;
// Replace feather icons after rendering
setTimeout(() => {
if (this.shadowRoot.querySelector('[data-feather]')) {
feather.replace({
root: this.shadowRoot
});
}
}, 100);
}
addEventListeners() {
this.shadowRoot.querySelector('.play-button').addEventListener('click', (e) => {
e.stopPropagation();
const title = this.getAttribute('title');
const color = this.getAttribute('color');
// Create interactive game overlay
this.showGameOverlay(title, color);
});
}
showGameOverlay(title, color) {
const overlay = document.createElement('div');
overlay.className = 'fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50';
overlay.innerHTML = `
<div class="bg-gray-800 rounded-xl p-8 max-w-md w-full mx-4 border-4 ${this.getBorderColor(color)}">
<div class="text-center">
<h3 class="text-2xl font-bold mb-4">${title}</h3>
<div class="mb-6">
<div class="text-4xl font-bold mb-2">⚽</div>
<p class="text-gray-300 mb-6">Get ready for the penalty shootout!</p>
<div class="grid grid-cols-3 gap-4 mb-6">
<button class="bg-green-600 hover:bg-green-700 py-3 rounded-lg font-bold transition-all" data-action="shoot">
SHOOT
</button>
<button class="bg-blue-600 hover:bg-blue-700 py-3 rounded-lg font-bold transition-all" data-action="aim">
AIM
</button>
<button class="bg-red-600 hover:bg-red-700 py-3 rounded-lg font-bold transition-all" data-action="power">
POWER
</button>
</div>
<div class="space-y-3">
<div class="flex items-center justify-between bg-gray-700 p-3 rounded-lg">
<span>Target:</span>
<span class="text-yellow-400">GOAL!</span>
</div>
<div class="mt-6 flex gap-4">
<button class="flex-1 bg-gray-600 hover:bg-gray-700 py-2 rounded-lg transition-all">
Top Left
</button>
<button class="flex-1 bg-gray-600 hover:bg-gray-700 py-2 rounded-lg transition-all" data-action="close">
Close
</button>
<button class="flex-1 bg-green-600 hover:bg-green-700 py-2 rounded-lg transition-all">
Start Game
</button>
</div>
</div>
</div>
`;
// Add event listeners to overlay buttons
overlay.querySelector('[data-action="shoot"]').addEventListener('click', () => {
this.simulatePenaltyShot(title);
});
overlay.querySelector('[data-action="aim"]').addEventListener('click', () => {
this.showAimInterface();
});
overlay.querySelector('[data-action="power"]').addEventListener('click', () => {
this.showPowerInterface();
});
overlay.querySelector('[data-action="close"]').addEventListener('click', () => {
overlay.remove();
});
document.body.appendChild(overlay);
// Animate the overlay in
gsap.from(overlay.querySelector('div'), {
duration: 0.5,
scale: 0.8,
opacity: 0,
ease: "back.out(1.7)"
});
}
getBorderColor(color) {
const colors = {
green: 'border-green-500',
yellow: 'border-yellow-500',
blue: 'border-blue-500',
purple: 'border-purple-500'
};
return colors[color] || 'border-green-500';
}
simulatePenaltyShot(gameMode) {
const isGoal = Math.random() > 0.3;
const power = Math.floor(Math.random() * 30) + 70;
const speed = Math.floor(Math.random() * 20) + 80;
// Show shot result
const resultOverlay = document.createElement('div');
resultOverlay.className = 'fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50';
resultOverlay.innerHTML = `
<div class="bg-gray-800 rounded-xl p-8 max-w-md w-full mx-4 text-center';
resultOverlay.innerHTML = `
<div class="text-6xl mb-4">${isGoal ? '⚽🎉' : '❌'}</div>
<h3 class="text-3xl font-bold mb-4 ${isGoal ? 'text-green-400' : 'text-red-400'}">
${isGoal ? 'GOAL!' : 'MISSED!'}
</h3>
<p class="text-xl mb-6">${isGoal ? 'Perfect shot! The ball is in the net!' : 'The goalkeeper saved it! Better luck next time.'}</p>
<div class="space-y-2 mb-6">
<div class="flex justify-between">
<span>Shot Power:</span>
<span class="text-yellow-400">${power}%</span>
</div>
<div class="flex justify-between">
<span>Ball Speed:</span>
<span class="text-blue-400">${speed} km/h</span>
</div>
<button class="bg-green-600 hover:bg-green-700 px-6 py-3 rounded-lg font-bold transition-all">
Continue
</button>
`;
resultOverlay.querySelector('button').addEventListener('click', () => {
resultOverlay.remove();
// Add rewards based on game mode
if (isGoal) {
const rewards = {
'Quick Match': { coins: 15, xp: 50 },
'Daily Challenge': { coins: 50, xp: 150 },
'Training Mode': { coins: 0, xp: 25 },
'Change Player': { coins: 10, xp: 30 }
};
const reward = rewards[gameMode] || { coins: 10, xp: 25 };
// Dispatch custom event to update game state
document.dispatchEvent(new CustomEvent('gameAction', {
detail: {
type: gameMode,
success: true,
...reward
}
});
}
});
document.body.appendChild(resultOverlay);
// Animate result
gsap.from(resultOverlay.querySelector('div'), {
duration: 0.5,
scale: 0.8,
opacity: 0,
ease: "back.out(1.7)"
});
}
showAimInterface() {
const aimOverlay = document.createElement('div');
aimOverlay.className = 'fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50';
aimOverlay.innerHTML = `
<div class="bg-gray-800 rounded-xl p-8 max-w-md w-full mx-4 text-center';
aimOverlay.innerHTML = `
<h3 class="text-2xl font-bold mb-6">Aim Selection</h3>
<div class="grid grid-cols-3 gap-2 mb-6">
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="top-left">
↖️
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="top-center">
⬆️
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="top-right">
↗️
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="middle-left">
⬅️
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="center">
🎯
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="middle-right">
➡️
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="bottom-left">
↙️
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="bottom-center">
⬇️
</button>
<button class="bg-gray-700 hover:bg-green-600 p-4 rounded-lg transition-all" data-target="bottom-right">
↘️
</button>
</div>
<button class="bg-red-600 hover:bg-red-700 px-6 py-3 rounded-lg font-bold transition-all">
Back
</button>
`;
aimOverlay.querySelectorAll('[data-target]').forEach(button => {
button.addEventListener('click', (e) => {
const target = e.target.getAttribute('data-target');
this.showAimConfirmation(target);
});
});
aimOverlay.querySelector('button:last-child').addEventListener('click', () => {
aimOverlay.remove();
});
document.body.appendChild(aimOverlay);
}
showAimConfirmation(target) {
const confirmation = document.createElement('div');
confirmation.className = 'fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50';
confirmation.innerHTML = `
<div class="bg-gray-800 rounded-xl p-8 max-w-md w-full mx-4 text-center';
confirmation.innerHTML = `
<h3 class="text-xl font-bold mb-4">Aim Set: ${target.replace('-', ' ').toUpperCase()}</h3>
<p class="text-gray-300 mb-6">Ready to shoot at ${target.replace('-', ' ')}</p>
<div class="flex gap-4">
<button class="flex-1 bg-gray-600 hover:bg-gray-700 py-2 rounded-lg transition-all">
Confirm
</button>
`;
confirmation.querySelector('button').addEventListener('click', () => {
confirmation.remove();
this.simulatePenaltyShot(this.getAttribute('title'));
});
document.body.appendChild(confirmation);
}
showPowerInterface() {
const powerOverlay = document.createElement('div');
powerOverlay.className = 'fixed inset-0 bg-black bg-opacity-80 flex items-center justify-center z-50';
confirmation.innerHTML = `
<div class="bg-gray-800 rounded-xl p-8 max-w-md w-full mx-4 text-center';
confirmation.innerHTML = `
<h3 class="text-xl font-bold mb-4">Power Selection</h3>
<div class="mb-6">
<div class="flex justify-between mb-2">
<span>Shot Power</span>
<span class="text-yellow-400">85%</span>
</div>
<div class="w-full bg-gray-700 rounded-full h-4">
<div class="bg-red-500 h-4 rounded-full" style="width: 85%"></div>
</div>
<input type="range" min="50" max="100" value="85" class="w-full h-2 bg-gray-600 rounded-lg appearance-none cursor-pointer" min="50" max="100" value="85" class="w-full h-2 bg-gray-600 rounded-lg appearance-none cursor-pointer">
<div class="mt-4 flex gap-4">
<button class="flex-1 bg-green-600 hover:bg-green-700 py-2 rounded-lg transition-all">
Set Power
</button>
`;
const slider = powerOverlay.querySelector('input[type="range"]');
const powerDisplay = powerOverlay.querySelector('.text-yellow-400');
slider.addEventListener('input', (e) => {
const power = e.target.value;
powerDisplay.textContent = `${power}%`;
powerOverlay.querySelector('.bg-red-500').style.width = `${power}%`;
});
powerOverlay.querySelector('button').addEventListener('click', () => {
const power = slider.value;
powerOverlay.remove();
this.simulatePenaltyShot(this.getAttribute('title'));
});
document.body.appendChild(powerOverlay);
}
}
customElements.define('game-card', GameCard);