// Shared game logic and utilities
class PenaltyProGame {
constructor() {
this.playerStats = {
name: "Marco Rodriguez",
level: 1,
xp: 60,
xpToNextLevel: 1000,
coins: 90,
wins: 2,
losses: 4,
goals: 0,
streak: 0,
power: 82,
speed: 78,
acceleration: 74
};
}
addCoins(amount) {
this.playerStats.coins += amount;
this.updateUI();
this.showRewardNotification(`+${amount} coins`);
}
addXP(amount) {
this.playerStats.xp += amount;
if (this.playerStats.xp >= this.playerStats.xpToNextLevel) {
this.levelUp();
}
this.updateUI();
this.showRewardNotification(`+${amount} XP`);
}
levelUp() {
this.playerStats.level += 1;
this.playerStats.xp -= this.playerStats.xpToNextLevel;
this.playerStats.xpToNextLevel = Math.floor(this.playerStats.xpToNextLevel * 1.2);
this.showLevelUpNotification();
}
showRewardNotification(message) {
const notification = document.createElement('div');
notification.className = 'fixed bottom-4 right-4 bg-green-600 text-white px-4 py-2 rounded-lg shadow-lg flex items-center';
notification.innerHTML = `
${message}
`;
document.body.appendChild(notification);
feather.replace();
setTimeout(() => {
notification.classList.add('fade-out');
setTimeout(() => notification.remove(), 500);
}, 3000);
}
showLevelUpNotification() {
const notification = document.createElement('div');
notification.className = 'fixed inset-0 flex items-center justify-center bg-black bg-opacity-70 z-50';
notification.innerHTML = `
LEVEL UP!
You are now level ${this.playerStats.level}
Unlock new abilities and rewards
`;
document.body.appendChild(notification);
feather.replace();
notification.querySelector('button').addEventListener('click', () => {
notification.remove();
});
}
updateUI() {
// Update all UI elements with current player stats
const elements = {
'.player-name': this.playerStats.name,
'.player-level': this.playerStats.level,
'.player-xp': `${this.playerStats.xp}/${this.playerStats.xpToNextLevel}`,
'.player-coins': this.playerStats.coins,
'.player-wins': this.playerStats.wins,
'.player-losses': this.playerStats.losses,
'.player-goals': this.playerStats.goals,
'.player-streak': this.playerStats.streak,
'.pwr-stat': this.playerStats.power,
'.spd-stat': this.playerStats.speed,
'.acc-stat': this.playerStats.acceleration,
'.xp-bar': `${(this.playerStats.xp / this.playerStats.xpToNextLevel) * 100}%`,
'.pwr-bar': `${this.playerStats.power}%`,
'.spd-bar': `${this.playerStats.speed}%`,
'.acc-bar': `${this.playerStats.acceleration}%`
};
for (const [selector, value] of Object.entries(elements)) {
document.querySelectorAll(selector).forEach(el => {
if (selector.includes('-bar')) {
el.style.width = value;
} else {
el.textContent = value;
}
});
}
}
}
// Initialize game
const game = new PenaltyProGame();
// Add event listeners for game actions
document.addEventListener('DOMContentLoaded', () => {
// Update all UI elements
game.updateUI();
// Listen for game action events from components
document.addEventListener('gameAction', (e) => {
const { type, success, coins, xp } = e.detail;
if (success) {
game.addCoins(coins);
game.addXP(xp);
}
});
// Add click event listeners to game mode cards
document.querySelectorAll('[data-game-mode]').forEach(card => {
card.addEventListener('click', (e) => {
const gameMode = card.getAttribute('data-game-mode');
const difficulty = card.getAttribute('data-difficulty');
switch(gameMode) {
case 'quick-match':
startQuickMatch(difficulty);
break;
case 'daily-challenge':
startDailyChallenge();
break;
case 'training':
startTraining();
break;
}
});
});
});
function startQuickMatch(difficulty) {
// Simulate match and rewards based on difficulty
let coins = 0;
let xp = 0;
switch(difficulty) {
case 'easy':
coins = 15;
xp = 50;
break;
case 'medium':
coins = 20;
xp = 75;
break;
case 'hard':
coins = 25;
xp = 100;
break;
}
// Random outcome for demo
const isWin = Math.random() > 0.4;
if (isWin) {
game.playerStats.wins += 1;
game.playerStats.streak += 1;
game.playerStats.goals += Math.floor(Math.random() * 5) + 1;
} else {
game.playerStats.losses += 1;
game.playerStats.streak = 0;
}
game.addCoins(coins);
game.addXP(xp);
// Show match result
showMatchResult(isWin, coins, xp);
}
function startDailyChallenge() {
// Simulate daily challenge with better rewards
const coins = 50;
const xp = 150;
const isWin = Math.random() > 0.3;
if (isWin) {
game.playerStats.wins += 1;
game.playerStats.streak += 1;
game.playerStats.goals += Math.floor(Math.random() * 7) + 1;
} else {
game.playerStats.losses += 1;
game.playerStats.streak = 0;
}
game.addCoins(coins);
game.addXP(xp);
showMatchResult(isWin, coins, xp);
}
function startTraining() {
// Training doesn't give rewards but updates goals
game.playerStats.goals += Math.floor(Math.random() * 10);
game.updateUI();
// Show training completed message
const notification = document.createElement('div');
notification.className = 'fixed bottom-4 right-4 bg-blue-600 text-white px-4 py-2 rounded-lg shadow-lg';
notification.textContent = 'Training completed! Your accuracy improved.';
document.body.appendChild(notification);
setTimeout(() => {
notification.classList.add('fade-out');
setTimeout(() => notification.remove(), 500);
}, 3000);
}
function showMatchResult(isWin, coins, xp) {
const resultEl = document.createElement('div');
resultEl.className = 'fixed inset-0 flex items-center justify-center bg-black bg-opacity-70 z-50';
resultEl.innerHTML = `
${isWin ? 'VICTORY!' : 'DEFEAT'}
${isWin ? 'You scored!' : 'Better luck next time'}
Current streak: ${game.playerStats.streak}
`;
document.body.appendChild(resultEl);
resultEl.querySelector('button').addEventListener('click', () => {
resultEl.remove();
});
}