Ping-Pong
HTML
<div id="gameContainer">
<div id="scoreDisplay">
<div>Score: <span id="scoreValue">0</span></div>
<div id="comboText">Combo: <span id="comboCount">0</span></div>
</div>
<div class="canvas-wrapper">
<div class="border-animate" id="borderAnimate"></div>
<canvas id="gameCanvas" width="800" height="400"></canvas>
</div>
</div>
<div class="instructions">
<strong>W/S:</strong> Move paddle | <strong>Space:</strong> Start/Pause<br>
<em>Perfect rallies unlock musical evolution!</em>
</div>
<div id="comboDisplay"></div>
<div id="stageTransition"></div>
CSS
body {
margin: 0; padding: 0;
font-family: 'Courier New', monospace;
color: #00ff88;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background: linear-gradient(135deg, #0f0f23, #1a1a2e, #16213e);
transition: background 2s ease;
}
#gameContainer {
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
position: relative;
}
#gameCanvas {
background: #0a0a0a;
position: relative;
transition: all 0.3s ease;
}
.canvas-wrapper {
position: relative;
padding: 20px;
border-radius: 12px;
}
.border-animate {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
border-radius: 12px;
pointer-events: none;
z-index: -1;
}
.border-wave {
position: absolute;
top: -10px; left: -10px; right: -10px; bottom: -10px;
border-radius: 18px;
opacity: 0;
pointer-events: none;
z-index: -2;
animation: borderWave 0.8s ease-out forwards;
}
@keyframes borderWave {
0% {
transform: scale(0.95);
opacity: 0.8;
box-shadow: 0 0 0 2px currentColor;
}
60% {
transform: scale(1.02);
opacity: 0.6;
box-shadow: 0 0 0 4px currentColor;
}
100% {
transform: scale(1.05);
opacity: 0;
box-shadow: 0 0 40px 12px currentColor;
}
}
#scoreDisplay {
...
JavaScript
const canvas = document.getElementById('gameCanvas'), ctx = canvas.getContext('2d');
let gameRunning = false, audioContext, isAudioReady = false;
const BALL_SPEED = 4.5;
const paddle1 = {x: 10, y: 160, width: 12, height: 80, speed: 5.5};
const paddle2 = {x: 778, y: 160, width: 12, height: 80, speed: 5.0};
const ball = {x: 400, y: 200, dx: BALL_SPEED, dy: 0, size: 10};
let score1 = 0, score2 = 0, totalScore = 0, comboCount = 0, currentStage = 1, stageProgress = 0;
let keys = {}, fieldPulseIntensity = 0, fieldPulseTarget = 0;
// Music system variables
let musicStep = 0, currentChord = 0, melodyNote = 0, gameStartTime = 0;
const BEAT_DURATION = 600; // milliseconds
const stageColors = {
1: '#00ff88', 2: '#ff4466', 3: '#ffaa00', 4: '#6644ff', 5: '#ff0088'
};
const stageBackgrounds = {
1: 'linear-gradient(135deg, #0f0f23, #1a1a2e, #16213e)',
2: 'linear-gradient(135deg, #23110f, #2e1a1a, #3e1616)',
3: 'linear-gradient(135deg, #23180f, #2e251a, #3e2c16)',
4: 'linear-gradient(135deg, #140f23, #1c1a2e, #1e163e)',
5: 'linear-gradient(135deg, #230f1a, #2e1a25, #3e162c)'
};
const stages = {
1: {name: 'Foundation Beat', target: 6},
2: {name: 'Bass Groove', target: 10},
3: {name: 'Melodic Voice', target: 15},
4: {name: 'Lyrical Flow', target: 22},
5: {name: 'Full Orchestra', target: 30}
};
// Music system with V1 progression + V2 effects
const musicSystem = {
masterGain: null,
compressor: null,
reverb: null,
scales: {
bass: [65.41, 73.42, 82.41, 98.00, 110.00, 123.47],
melody: [261.63, 293.66, 329.63, 392.00, 440.00, 493.88]
},
chordProgression: [0, 3, 4, 0] // I-IV-V-I from V1
};
// Initialize audio with V2's professional effects but reduced volume
async function initAudio() {
try {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
await audioContext.resume();
...