// 游戏统计和成就系统
class GameStats {
constructor() {
this.achievements = [
{
id: 'first_game',
name: '初次体验',
description: '完成第一次游戏',
condition: (stats) => true
},
{
id: 'score_1000',
name: '小试牛刀',
description: '单局得分达到1000分',
condition: (stats) => stats.score >= 1000
},
{
id: 'score_5000',
name: '游戏达人',
description: '单局得分达到5000分',
condition: (stats) => stats.score >= 5000
},
{
id: 'score_10000',
name: '方块大师',
description: '单局得分达到10000分',
condition: (stats) => stats.score >= 10000
},
{
id: 'level_5',
name: '步步高升',
description: '达到第5级',
condition: (stats) => stats.level >= 5
},
{
id: 'level_10',
name: '速度之王',
description: '达到第10级',
condition: (stats) => stats.level >= 10
},
{
id: 'lines_50',
name: '消除专家',
description: '累计消除50行',
condition: (stats) => stats.lines >= 50
},
{
id: 'lines_100',
name: '清理大师',
description: '累计消除100行',
condition: (stats) => stats.lines >= 100
},
{
id: 'tetris',
name: 'Tetris!',
description: '一次消除4行',
condition: (stats) => stats.maxCombo >= 4
},
{
id: 'time_10min',
name: '持久战士',
description: '单局游戏时间超过10分钟',
condition: (stats) => stats.playTime >= 600000
},
{
id: 'efficiency',
name: '效率专家',
description: '平均每分钟得分超过500',
condition: (stats) => stats.avgScore >= 500
}
];
this.init();
}
init() {
this.setupEventListeners();
}
setupEventListeners() {
const playAgainBtn = document.getElementById('playAgainBtn');
playAgainBtn.addEventListener('click', () => {
this.hideStats();
game.restart();
});
}
showStats(gameData) {
const playTimeMinutes = gameData.playTime / 60000;
const avgScore = playTimeMinutes > 0 ? Math.round(gameData.score / playTimeMinutes) : 0;
const stats = {
...gameData,
avgScore: avgScore
};
// 更新统计显示
document.getElementById('finalScore').textContent = stats.score.toLocaleString();
document.getElementById('finalLevel').textContent = stats.level;
document.getElementById('finalLines').textContent = stats.lines;
document.getElementById('playTime').textContent = this.formatTime(stats.playTime);
document.getElementById('maxCombo').textContent = stats.maxCombo;
document.getElementById('avgScore').textContent = stats.avgScore;
// 检查成就
const achievement = this.checkAchievements(stats);
this.displayAchievement(achievement);
// 显示统计界面
document.getElementById('gameStats').style.display = 'flex';
document.getElementById('gameStats').classList.add('fade-in');
}
hideStats() {
document.getElementById('gameStats').style.display = 'none';
document.getElementById('gameStats').classList.remove('fade-in');
}
formatTime(milliseconds) {
const seconds = Math.floor(milliseconds / 1000);
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
return `${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
}
checkAchievements(stats) {
// 获取已获得的成就
const earnedAchievements = this.getEarnedAchievements();
// 检查新成就
for (let achievement of this.achievements) {
if (!earnedAchievements.includes(achievement.id) &&
achievement.condition(stats)) {
// 保存新成就
this.saveAchievement(achievement.id);
return achievement;
}
}
return null;
}
displayAchievement(achievement) {
const achievementEl = document.getElementById('achievement');
if (achievement) {
achievementEl.innerHTML = `
🏆 成就解锁!
${achievement.name}
${achievement.description}
`;
achievementEl.classList.add('pulse');
} else {
// 显示随机鼓励话语
const encouragements = [
'继续努力,你会变得更强!',
'每一次游戏都是进步的机会!',
'方块世界需要你的智慧!',
'熟能生巧,加油!',
'下一局一定会更好!',
'坚持就是胜利!',
'你的反应速度在提升!',
'策略思维正在增强!'
];
const randomEncouragement = encouragements[Math.floor(Math.random() * encouragements.length)];
achievementEl.innerHTML = `💪 ${randomEncouragement}`;
achievementEl.classList.remove('pulse');
}
}
getEarnedAchievements() {
const saved = localStorage.getItem('tetris_achievements');
return saved ? JSON.parse(saved) : [];
}
saveAchievement(achievementId) {
const earned = this.getEarnedAchievements();
if (!earned.includes(achievementId)) {
earned.push(achievementId);
localStorage.setItem('tetris_achievements', JSON.stringify(earned));
}
}
// 获取历史最佳记录
getBestStats() {
const saved = localStorage.getItem('tetris_best_stats');
return saved ? JSON.parse(saved) : {
score: 0,
level: 0,
lines: 0,
maxCombo: 0
};
}
// 保存最佳记录
saveBestStats(stats) {
const best = this.getBestStats();
let updated = false;
if (stats.score > best.score) {
best.score = stats.score;
updated = true;
}
if (stats.level > best.level) {
best.level = stats.level;
updated = true;
}
if (stats.lines > best.lines) {
best.lines = stats.lines;
updated = true;
}
if (stats.maxCombo > best.maxCombo) {
best.maxCombo = stats.maxCombo;
updated = true;
}
if (updated) {
localStorage.setItem('tetris_best_stats', JSON.stringify(best));
}
return updated;
}
// 显示排行榜
showLeaderboard() {
const best = this.getBestStats();
const earned = this.getEarnedAchievements();
console.log('最佳记录:', best);
console.log('已获得成就:', earned.length + '/' + this.achievements.length);
}
}
// 高级特效系统
class GameEffects {
constructor(game) {
this.game = game;
this.particles = [];
this.effects = [];
this.init();
}
init() {
// 创建特效canvas
this.effectsCanvas = document.createElement('canvas');
this.effectsCanvas.width = this.game.canvas.width;
this.effectsCanvas.height = this.game.canvas.height;
this.effectsCanvas.style.position = 'absolute';
this.effectsCanvas.style.top = '0';
this.effectsCanvas.style.left = '0';
this.effectsCanvas.style.pointerEvents = 'none';
this.effectsCanvas.style.zIndex = '10';
this.effectsCtx = this.effectsCanvas.getContext('2d');
// 将特效canvas添加到游戏板容器中
this.game.canvas.parentElement.style.position = 'relative';
this.game.canvas.parentElement.appendChild(this.effectsCanvas);
}
// 行消除特效
lineCleared(row) {
for (let i = 0; i < 20; i++) {
this.particles.push({
x: Math.random() * this.game.canvas.width,
y: row * this.game.CELL_SIZE + this.game.CELL_SIZE / 2,
vx: (Math.random() - 0.5) * 10,
vy: (Math.random() - 0.5) * 10,
life: 1,
decay: 0.02,
color: `hsl(${Math.random() * 360}, 100%, 50%)`
});
}
}
// 方块锁定特效
pieceLocked(piece) {
const centerX = (piece.x + piece.matrix[0].length / 2) * this.game.CELL_SIZE;
const centerY = (piece.y + piece.matrix.length / 2) * this.game.CELL_SIZE;
for (let i = 0; i < 10; i++) {
this.particles.push({
x: centerX,
y: centerY,
vx: (Math.random() - 0.5) * 8,
vy: (Math.random() - 0.5) * 8,
life: 0.8,
decay: 0.03,
color: piece.color
});
}
}
// 更新特效
update() {
// 更新粒子
for (let i = this.particles.length - 1; i >= 0; i--) {
const particle = this.particles[i];
particle.x += particle.vx;
particle.y += particle.vy;
particle.life -= particle.decay;
if (particle.life <= 0) {
this.particles.splice(i, 1);
}
}
}
// 绘制特效
draw() {
this.effectsCtx.clearRect(0, 0, this.effectsCanvas.width, this.effectsCanvas.height);
// 绘制粒子
for (let particle of this.particles) {
this.effectsCtx.save();
this.effectsCtx.globalAlpha = particle.life;
this.effectsCtx.fillStyle = particle.color;
this.effectsCtx.beginPath();
this.effectsCtx.arc(particle.x, particle.y, 3, 0, Math.PI * 2);
this.effectsCtx.fill();
this.effectsCtx.restore();
}
}
}
// 创建统计系统实例
const gameStats = new GameStats();
// 在适当的地方创建特效系统
// const gameEffects = new GameEffects(game);