0% found this document useful (0 votes)
3 views

popn.html

The document is an HTML code for a game called 'Pop'n Music Clone', featuring a canvas for gameplay, buttons for user interaction, and audio elements for background music and sound effects. It includes styles for the game interface, character animations, and note mechanics, allowing players to hit notes by clicking buttons or using keyboard controls. The game tracks scores, combos, and difficulty levels, providing a dynamic music rhythm experience.

Uploaded by

artema210908
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

popn.html

The document is an HTML code for a game called 'Pop'n Music Clone', featuring a canvas for gameplay, buttons for user interaction, and audio elements for background music and sound effects. It includes styles for the game interface, character animations, and note mechanics, allowing players to hit notes by clicking buttons or using keyboard controls. The game tracks scores, combos, and difficulty levels, providing a dynamic music rhythm experience.

Uploaded by

artema210908
Copyright
© © All Rights Reserved
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 6

<!

DOCTYPE html>
<html>
<head>
<title>Pop'n Music Clone</title>
<style>
canvas {
border: 2px solid #fff;
display: block;
margin: 20px auto;
}
.game-container {
text-align: center;
font-family: Arial, sans-serif;
background: #1a1a1a;
color: white;
position: relative;
}
.buttons {
margin: 20px;
}
.game-button {
width: 80px;
height: 80px;
margin: 0 15px;
font-size: 24px;
cursor: pointer;
border: 3px solid #fff;
border-radius: 50%;
color: white;
text-shadow: 1px 1px 2px #000;
transition: transform 0.1s;
}
.game-button:active { transform: scale(0.9); }
#btn1 { background: #ff4d4d; }
#btn2 { background: #4dff4d; }
#btn3 { background: #4d4dff; }
#btn4 { background: #ffff4d; }
#btn5 { background: #ff4dff; }
#startScreen, #difficultyScreen {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 20px;
border-radius: 10px;
z-index: 10;
}
.menu-button {
padding: 10px 20px;
font-size: 18px;
margin: 5px;
cursor: pointer;
background: #666;
border: none;
color: white;
border-radius: 5px;
}
.menu-button:hover { background: #888; }
#character {
position: absolute;
top: 50px;
left: 50px;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div class="game-container">
<canvas id="gameCanvas" width="600" height="400"></canvas>
<div class="buttons">
<button class="game-button" id="btn1">1</button>
<button class="game-button" id="btn2">2</button>
<button class="game-button" id="btn3">3</button>
<button class="game-button" id="btn4">4</button>
<button class="game-button" id="btn5">5</button>
</div>
<div>Score: <span id="score">0</span> | Combo: <span id="combo">0</span> |
Max Combo: <span id="maxCombo">0</span></div>
<img id="character" src="https://via.placeholder.com/100/00FF00/FFFFFF?
text=Char" alt="Character">
<audio id="bgm" loop>
<!-- Host locally: <source src="music/bgm.mp3" type="audio/mpeg"> -->
<source src="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-
1.mp3" type="audio/mpeg">
</audio>
<audio id="hitSound">
<!-- Host locally: <source src="sfx/hit.mp3" type="audio/mpeg"> -->
<source src="https://www.myinstants.com/media/sounds/popn_hit.mp3"
type="audio/mpeg">
</audio>
<audio id="missSound">
<!-- Host locally: <source src="sfx/miss.mp3" type="audio/mpeg"> -->
<source src="https://www.myinstants.com/media/sounds/popn_miss.mp3"
type="audio/mpeg">
</audio>
<div id="startScreen">
<h1>Pop'n Music Clone</h1>
<button class="menu-button" id="startButton">Start Game</button>
</div>
<div id="difficultyScreen" style="display: none;">
<h2>Select Difficulty</h2>
<button class="menu-button" onclick="startGame(1)">Easy</button>
<button class="menu-button" onclick="startGame(2)">Normal</button>
<button class="menu-button" onclick="startGame(3)">Hard</button>
</div>
</div>

<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const comboDisplay = document.getElementById('combo');
const maxComboDisplay = document.getElementById('maxCombo');
const bgm = document.getElementById('bgm');
const hitSound = document.getElementById('hitSound');
const missSound = document.getElementById('missSound');
const startScreen = document.getElementById('startScreen');
const difficultyScreen = document.getElementById('difficultyScreen');
const character = document.getElementById('character');

let score = 0;
let combo = 0;
let maxCombo = 0;
let notes = [];
let hitEffects = [];
const laneWidth = canvas.width / 5;
const noteSize = 50;
const hitZone = canvas.height - 100;
let gameStarted = false;
let difficulty = 1;
let bgOffset = 0;

// Load assets
const noteImage = new Image();
noteImage.src = 'https://via.placeholder.com/50/FF6666/FFFFFF?text=♪'; //
Replace with note.png
const bgImage = new Image();
bgImage.src = 'https://via.placeholder.com/600x400/333333/666666?
text=Stage'; // Replace with bg.png
const charIdle = new Image();
charIdle.src = 'https://via.placeholder.com/100/00FF00/FFFFFF?
text=Idle'; // Replace with idle.png
const charDance = new Image();
charDance.src = 'https://via.placeholder.com/100/00FFFF/FFFFFF?text=Dance';
// Replace with dance.png

class Note {
constructor(lane) {
this.x = lane * laneWidth + laneWidth/2 - noteSize/2;
this.y = -noteSize;
this.lane = lane;
}

update() {
this.y += 3 + difficulty;
}

draw() {
ctx.drawImage(noteImage, this.x, this.y, noteSize, noteSize);
}
}

class HitEffect {
constructor(x, y) {
this.x = x;
this.y = y;
this.life = 20; // Frames of animation
}

update() {
this.life--;
}

draw() {
ctx.fillStyle = `rgba(255, 255, 0, ${this.life / 20})`;
ctx.beginPath();
ctx.arc(this.x + noteSize/2, this.y + noteSize/2, noteSize, 0,
Math.PI * 2);
ctx.fill();
}
}

function spawnNote() {
if (!gameStarted) return;
const lane = Math.floor(Math.random() * 5);
notes.push(new Note(lane));
}

function drawBackground() {
bgOffset += 1.5;
if (bgOffset >= bgImage.height) bgOffset = 0;
ctx.drawImage(bgImage, 0, bgOffset - bgImage.height, canvas.width,
bgImage.height);
ctx.drawImage(bgImage, 0, bgOffset, canvas.width, bgImage.height);
}

function drawLanes() {
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
for (let i = 1; i < 5; i++) {
ctx.beginPath();
ctx.moveTo(i * laneWidth, 0);
ctx.lineTo(i * laneWidth, canvas.height);
ctx.stroke();
}
const gradient = ctx.createLinearGradient(0, hitZone, 0, hitZone +
100);
gradient.addColorStop(0, 'rgba(255, 105, 180, 0.4)');
gradient.addColorStop(1, 'rgba(255, 105, 180, 0.1)');
ctx.fillStyle = gradient;
ctx.fillRect(0, hitZone, canvas.width, 100);
}

function checkHit(lane) {
for (let i = notes.length - 1; i >= 0; i--) {
const note = notes[i];
if (note.lane === lane &&
note.y > hitZone - 50 &&
note.y < hitZone + 100) {
score += 10 + combo * difficulty;
combo++;
maxCombo = Math.max(maxCombo, combo);
scoreDisplay.textContent = score;
comboDisplay.textContent = combo;
maxComboDisplay.textContent = maxCombo;
hitSound.currentTime = 0;
hitSound.play();
hitEffects.push(new HitEffect(note.x, note.y));
notes.splice(i, 1);
character.src = charDance.src; // Dance on hit
setTimeout(() => { if (combo > 0) character.src =
charDance.src; else character.src = charIdle.src; }, 200);
return;
}
}
score -= 5;
combo = 0;
missSound.currentTime = 0;
missSound.play();
character.src = charIdle.src; // Idle on miss
scoreDisplay.textContent = score;
comboDisplay.textContent = combo;
}

// Button event listeners


document.getElementById('btn1').addEventListener('click', () =>
checkHit(0));
document.getElementById('btn2').addEventListener('click', () =>
checkHit(1));
document.getElementById('btn3').addEventListener('click', () =>
checkHit(2));
document.getElementById('btn4').addEventListener('click', () =>
checkHit(3));
document.getElementById('btn5').addEventListener('click', () =>
checkHit(4));

// Keyboard controls
document.addEventListener('keydown', (e) => {
if (!gameStarted) return;
const key = parseInt(e.key);
if (key >= 1 && key <= 5) {
checkHit(key - 1);
}
});

function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBackground();
drawLanes();

if (gameStarted) {
for (let i = notes.length - 1; i >= 0; i--) {
notes[i].update();
notes[i].draw();
if (notes[i].y > canvas.height) {
notes.splice(i, 1);
score -= 5;
combo = 0;
missSound.currentTime = 0;
missSound.play();
character.src = charIdle.src;
scoreDisplay.textContent = score;
comboDisplay.textContent = combo;
}
}
for (let i = hitEffects.length - 1; i >= 0; i--) {
hitEffects[i].update();
hitEffects[i].draw();
if (hitEffects[i].life <= 0) hitEffects.splice(i, 1);
}
}

requestAnimationFrame(gameLoop);
}

// Start game setup


document.getElementById('startButton').addEventListener('click', () => {
startScreen.style.display = 'none';
difficultyScreen.style.display = 'block';
});

function startGame(diff) {
difficulty = diff;
gameStarted = true;
difficultyScreen.style.display = 'none';
bgm.play();
const bpm = 120;
const spawnInterval = (60 / bpm) * 1000 / (difficulty * 0.5 + 0.5);
setInterval(spawnNote, spawnInterval);
}

gameLoop();
</script>
</body>
</html>

You might also like