User prompt
Make actual music
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'comboText.style.fill = comboColors[colorIndex];' Line Number: 750
User prompt
Make the bottom circles (hitnotes) higher
User prompt
Make it so if the accuracy is less than 40% game over and the background purple
User prompt
Or notes are circles with 12345678§∆×÷π√✓><
User prompt
Try making the notes to <>∆✓
User prompt
Make so i can choose
User prompt
The notes too
User prompt
Make bigger
User prompt
Make 4 squares in the bottom for me to click
User prompt
Exactly:
Click anywhere when the glowing notes reach the bottom area!
User prompt
Make it exactly:
Click anywhere when the glowing notes reach the bottom area!
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Note = Container.expand(function (type, lane) { var self = Container.call(this); self.type = type || 'regular'; // 'regular' or 'hold' self.lane = lane || 0; self.speed = 8; self.hit = false; self.missed = false; self.holdPressed = false; self.holdDuration = 0; self.maxHoldDuration = 0; self.colorIndex = Math.floor(Math.random() * 5) + 1; // 1-5 for different colors self.lastY = self.y; // Musical note symbols var symbols = ['♪', '♫', '♩', '♬', '♭']; self.symbol = symbols[self.colorIndex - 1]; // Create note graphics based on type if (self.type === 'hold') { self.noteGraphics = self.attachAsset('noteHold' + self.colorIndex, { anchorX: 0.5, anchorY: 0.5 }); self.maxHoldDuration = 60; // 1 second at 60fps } else { self.noteGraphics = self.attachAsset('noteRegular' + self.colorIndex, { anchorX: 0.5, anchorY: 0.5 }); } // Add text symbol self.symbolText = new Text2(self.symbol, { size: 60, fill: 0xffffff }); self.symbolText.anchor.set(0.5, 0.5); self.addChild(self.symbolText); // Position based on lane self.x = 256 + self.lane * 384; // 4 lanes across screen self.y = -100; self.lastY = self.y; self.update = function () { self.lastY = self.y; self.y += self.speed; // Add pulsing glow effect var pulse = Math.sin(LK.ticks * 0.2) * 0.2 + 0.8; self.noteGraphics.alpha = pulse; self.alpha = pulse; // Check if note is in hit zone var hitZoneY = 2732 - 150; var distanceFromHitZone = Math.abs(self.y - hitZoneY); // Miss detection - transition from inside to outside hit zone if (self.lastY <= hitZoneY + 100 && self.y > hitZoneY + 100 && !self.hit && !self.missed) { self.missed = true; combo = 0; accuracy.total++; accuracy.missed++; LK.getSound('miss').play(); } // Handle hold notes if (self.type === 'hold' && self.hit && self.holdPressed) { self.holdDuration++; // Change opacity while holding self.noteGraphics.alpha = 0.5; } }; return self; }); var ParticleEffect = Container.expand(function (x, y, color) { var self = Container.call(this); self.x = x; self.y = y; self.lifetime = 30; self.age = 0; self.particle = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); // Tint with passed color or random neon color if (color) { self.particle.tint = color; } else { var colors = [0x7d4dff, 0xb366ff, 0xff65d7, 0xff8fe6, 0x65b3ff]; self.particle.tint = colors[Math.floor(Math.random() * colors.length)]; } self.velocityX = (Math.random() - 0.5) * 15; self.velocityY = (Math.random() - 0.5) * 15 - 8; self.update = function () { self.age++; self.x += self.velocityX; self.y += self.velocityY; self.velocityY += 0.3; // Gravity effect var alpha = 1 - self.age / self.lifetime; self.particle.alpha = alpha; var scale = 0.8 + (1 - alpha) * 0.5; self.particle.scaleX = scale; self.particle.scaleY = scale; if (self.age >= self.lifetime) { self.destroy(); for (var i = particles.length - 1; i >= 0; i--) { if (particles[i] === self) { particles.splice(i, 1); break; } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x0a0a1a }); /**** * Game Code ****/ // Neon-style note shapes with various colors // Game variables var notes = []; var particles = []; var combo = 0; var score = 0; var accuracy = { perfect: 0, good: 0, missed: 0, total: 0 }; var gameStarted = false; var noteSpawnTimer = 0; var activeTouches = {}; var hitZoneLastAlpha = 0.2; var selectedSong = 'random'; var gameMode = 'menu'; // 'menu', 'playing' // Song data var songs = { random: { name: "Random Notes", bpm: 120, spawnRate: 40, difficulty: "Easy" }, neonBeats: { name: "Neon Beats", bpm: 140, spawnRate: 30, difficulty: "Medium", notes: [{ time: 1000, lane: 0, type: 'regular' }, { time: 1200, lane: 1, type: 'regular' }, { time: 1400, lane: 2, type: 'hold', duration: 60 }, { time: 1600, lane: 3, type: 'regular' }, { time: 1800, lane: 0, type: 'regular' }, { time: 2000, lane: 1, type: 'regular' }, { time: 2200, lane: 2, type: 'regular' }, { time: 2400, lane: 3, type: 'hold', duration: 80 }, { time: 2600, lane: 0, type: 'regular' }, { time: 2800, lane: 1, type: 'regular' }] }, synthWave: { name: "Synth Wave", bpm: 160, spawnRate: 25, difficulty: "Hard", notes: [{ time: 500, lane: 0, type: 'regular' }, { time: 700, lane: 1, type: 'regular' }, { time: 900, lane: 2, type: 'regular' }, { time: 1100, lane: 3, type: 'regular' }, { time: 1300, lane: 0, type: 'hold', duration: 40 }, { time: 1300, lane: 2, type: 'hold', duration: 40 }, { time: 1500, lane: 1, type: 'regular' }, { time: 1700, lane: 3, type: 'regular' }, { time: 1900, lane: 0, type: 'regular' }, { time: 2100, lane: 1, type: 'regular' }, { time: 2300, lane: 2, type: 'regular' }, { time: 2500, lane: 3, type: 'regular' }] }, cyberpunk: { name: "Cyberpunk City", bpm: 180, spawnRate: 20, difficulty: "Expert", notes: [{ time: 400, lane: 0, type: 'regular' }, { time: 600, lane: 1, type: 'regular' }, { time: 800, lane: 2, type: 'regular' }, { time: 1000, lane: 3, type: 'regular' }, { time: 1200, lane: 0, type: 'hold', duration: 30 }, { time: 1200, lane: 1, type: 'hold', duration: 30 }, { time: 1400, lane: 2, type: 'regular' }, { time: 1600, lane: 3, type: 'regular' }, { time: 1800, lane: 0, type: 'regular' }, { time: 2000, lane: 1, type: 'regular' }, { time: 2200, lane: 2, type: 'hold', duration: 60 }, { time: 2400, lane: 3, type: 'regular' }] } }; var songStartTime = 0; var songNoteIndex = 0; var menuVisible = true; // Create hit zone with neon glow effect var hitZone = game.addChild(LK.getAsset('hitZone', { anchorX: 0.5, anchorY: 0.5 })); hitZone.x = 2048 / 2; hitZone.y = 2732 - 150; hitZone.alpha = 0.2; // Create lane markers with neon styling for (var i = 0; i < 4; i++) { var laneMarker = game.addChild(LK.getAsset('trail', { anchorX: 0.5, anchorY: 0.5, scaleY: 30 })); laneMarker.x = 256 + i * 384; laneMarker.y = 2732 / 2; laneMarker.alpha = 0.15; } // Create 4 clickable squares at the bottom for each lane var laneButtons = []; for (var i = 0; i < 4; i++) { var laneButton = game.addChild(LK.getAsset('noteRegular' + (i + 1), { anchorX: 0.5, anchorY: 0.5, scaleX: 2.0, scaleY: 2.0 })); laneButton.x = 256 + i * 384; laneButton.y = 2732 - 75; // Position at bottom hit zone laneButton.alpha = 0.6; laneButton.lane = i; laneButtons.push(laneButton); } // UI Elements with neon colors var scoreText = new Text2('Score: 0', { size: 60, fill: 0x9D65FF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); var comboText = new Text2('Combo: 0', { size: 50, fill: 0xFF65D7 }); comboText.anchor.set(1, 0); LK.gui.topRight.addChild(comboText); var accuracyText = new Text2('Accuracy: 100%', { size: 40, fill: 0x65B3FF }); accuracyText.anchor.set(0, 0); LK.gui.topLeft.addChild(accuracyText); accuracyText.x = 120; // Offset from menu button // Create song selection menu var menuContainer = new Container(); game.addChild(menuContainer); // Menu background var menuBg = LK.getAsset('hitZone', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.0, scaleY: 8.0 }); menuBg.x = 2048 / 2; menuBg.y = 2732 / 2; menuBg.alpha = 0.8; menuContainer.addChild(menuBg); // Menu title var menuTitle = new Text2('Choose Your Song', { size: 80, fill: 0xFF65D7 }); menuTitle.anchor.set(0.5, 0.5); menuTitle.x = 2048 / 2; menuTitle.y = 800; menuContainer.addChild(menuTitle); // Song selection buttons var songButtons = []; var songNames = Object.keys(songs); var buttonSpacing = 300; var startY = 1200; for (var i = 0; i < songNames.length; i++) { var songKey = songNames[i]; var song = songs[songKey]; // Button background var buttonBg = LK.getAsset('noteRegular' + (i % 4 + 1), { anchorX: 0.5, anchorY: 0.5, scaleX: 4.0, scaleY: 1.5 }); buttonBg.x = 2048 / 2; buttonBg.y = startY + i * buttonSpacing; buttonBg.alpha = 0.7; buttonBg.songKey = songKey; menuContainer.addChild(buttonBg); // Button text var buttonText = new Text2(song.name, { size: 50, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = buttonBg.x; buttonText.y = buttonBg.y - 20; menuContainer.addChild(buttonText); // Difficulty and BPM text var infoText = new Text2(song.difficulty + ' • ' + song.bpm + ' BPM', { size: 30, fill: 0x65B3FF }); infoText.anchor.set(0.5, 0.5); infoText.x = buttonBg.x; infoText.y = buttonBg.y + 30; menuContainer.addChild(infoText); songButtons.push({ bg: buttonBg, text: buttonText, info: infoText, songKey: songKey }); } function spawnNote(forcedLane, forcedType, forcedDuration) { var lane = forcedLane !== undefined ? forcedLane : Math.floor(Math.random() * 4); var noteType = forcedType || (Math.random() < 0.2 ? 'hold' : 'regular'); var note = new Note(noteType, lane); if (forcedDuration && noteType === 'hold') { note.maxHoldDuration = forcedDuration; } notes.push(note); game.addChild(note); } function updateScore(hitType) { var basePoints = 100; var multiplier = Math.max(1, Math.floor(combo / 10) + 1); if (hitType === 'perfect') { score += basePoints * 2 * multiplier; accuracy.perfect++; } else if (hitType === 'good') { score += basePoints * multiplier; accuracy.good++; } accuracy.total++; LK.setScore(score); scoreText.setText('Score: ' + score); comboText.setText('Combo: ' + combo); var accuracyPercent = Math.round((accuracy.perfect + accuracy.good) / accuracy.total * 100); accuracyText.setText('Accuracy: ' + accuracyPercent + '%'); } function createParticleEffect(x, y, color) { for (var i = 0; i < 8; i++) { var particle = new ParticleEffect(x, y, color); particles.push(particle); game.addChild(particle); } } function getLaneFromX(x) { if (x < 448) { return 0; } if (x < 832) { return 1; } if (x < 1216) { return 2; } return 3; } function startSelectedSong() { menuVisible = false; menuContainer.visible = false; gameMode = 'playing'; songStartTime = LK.ticks; songNoteIndex = 0; // Reset game state score = 0; combo = 0; accuracy = { perfect: 0, good: 0, missed: 0, total: 0 }; // Clear existing notes for (var i = notes.length - 1; i >= 0; i--) { notes[i].destroy(); notes.splice(i, 1); } updateScore('good'); // Updates displays LK.setScore(0); scoreText.setText('Score: 0'); comboText.setText('Combo: 0'); accuracyText.setText('Accuracy: 100%'); } function showMenu() { menuVisible = true; menuContainer.visible = true; gameMode = 'menu'; gameStarted = false; } game.down = function (x, y, obj) { // Handle menu interactions if (menuVisible) { for (var i = 0; i < songButtons.length; i++) { var button = songButtons[i]; var buttonBounds = { left: button.bg.x - button.bg.width * button.bg.scaleX / 2, right: button.bg.x + button.bg.width * button.bg.scaleX / 2, top: button.bg.y - button.bg.height * button.bg.scaleY / 2, bottom: button.bg.y + button.bg.height * button.bg.scaleY / 2 }; if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) { // Button clicked selectedSong = button.songKey; startSelectedSong(); return; } } return; } var lane = getLaneFromX(x); var hitZoneY = 2732 - 150; var hitFound = false; // Add visual feedback to lane button if (laneButtons[lane]) { laneButtons[lane].alpha = 1.0; tween(laneButtons[lane], { scaleX: 2.4, scaleY: 2.4 }, { duration: 100 }); } // Find the closest note in this lane var closestNote = null; var closestDistance = Infinity; for (var i = 0; i < notes.length; i++) { var note = notes[i]; if (note.lane === lane && !note.hit && !note.missed) { var distance = Math.abs(note.y - hitZoneY); if (distance < closestDistance) { closestDistance = distance; closestNote = note; } } } if (closestNote && closestDistance < 100) { closestNote.hit = true; hitFound = true; if (closestNote.type === 'hold') { closestNote.holdPressed = true; activeTouches[lane] = true; } // Determine hit accuracy var hitType = 'good'; var noteColor = [0x7d4dff, 0xb366ff, 0xff65d7, 0xff8fe6, 0x65b3ff][closestNote.colorIndex - 1]; if (closestDistance < 40) { hitType = 'perfect'; combo++; LK.getSound('hitPerfect').play(); createParticleEffect(closestNote.x, closestNote.y, noteColor); // Flash screen effect for perfect hits LK.effects.flashScreen(noteColor, 200); } else { combo++; LK.getSound('hitGood').play(); createParticleEffect(closestNote.x, closestNote.y, noteColor); } updateScore(hitType); // Flash hit zone with note color tween(hitZone, { alpha: 0.6 }, { duration: 100, onFinish: function onFinish() { tween(hitZone, { alpha: 0.2 }, { duration: 300 }); } }); } if (!hitFound) { combo = 0; comboText.setText('Combo: 0'); } }; game.up = function (x, y, obj) { var lane = getLaneFromX(x); activeTouches[lane] = false; // Reset visual feedback for lane button if (laneButtons[lane]) { laneButtons[lane].alpha = 0.6; tween(laneButtons[lane], { scaleX: 2.0, scaleY: 2.0 }, { duration: 150 }); } // Release hold notes in this lane for (var i = 0; i < notes.length; i++) { var note = notes[i]; if (note.lane === lane && note.type === 'hold' && note.holdPressed) { note.holdPressed = false; // Score based on hold duration if (note.holdDuration >= note.maxHoldDuration * 0.8) { combo++; updateScore('perfect'); } else if (note.holdDuration >= note.maxHoldDuration * 0.5) { updateScore('good'); } else { combo = 0; } } } }; game.update = function () { // Handle menu mode if (menuVisible) { // Add pulsing effect to menu buttons for (var i = 0; i < songButtons.length; i++) { var button = songButtons[i]; var pulse = Math.sin(LK.ticks * 0.1 + i * 0.3) * 0.1 + 0.7; button.bg.alpha = pulse; } return; } // Start background music if (!gameStarted) { LK.playMusic('bgmusic'); gameStarted = true; } // Add pulsing glow effect to hit zone var hitZonePulse = Math.sin(LK.ticks * 0.15) * 0.1 + 0.2; hitZone.alpha = hitZonePulse; // Add subtle pulsing effect to lane buttons for (var i = 0; i < laneButtons.length; i++) { if (!activeTouches[i]) { var buttonPulse = Math.sin(LK.ticks * 0.1 + i * 0.5) * 0.1 + 0.6; laneButtons[i].alpha = buttonPulse; } } // Handle song-specific note spawning if (selectedSong === 'random') { // Spawn notes randomly noteSpawnTimer++; if (noteSpawnTimer >= 40) { spawnNote(); noteSpawnTimer = 0; } } else { // Spawn notes based on song pattern var currentSong = songs[selectedSong]; if (currentSong.notes && songNoteIndex < currentSong.notes.length) { var currentTime = (LK.ticks - songStartTime) * (1000 / 60); // Convert ticks to milliseconds var nextNote = currentSong.notes[songNoteIndex]; if (currentTime >= nextNote.time) { spawnNote(nextNote.lane, nextNote.type, nextNote.duration); songNoteIndex++; } } // End song when all notes are played and cleared if (songNoteIndex >= currentSong.notes.length && notes.length === 0) { LK.setTimeout(function () { showMenu(); }, 2000); } } // Clean up off-screen notes for (var i = notes.length - 1; i >= 0; i--) { var note = notes[i]; // Remove notes that are off screen or completed if (note.y > 2800 || note.hit && note.type === 'regular' || note.hit && note.type === 'hold' && !note.holdPressed && note.holdDuration > 0) { note.destroy(); notes.splice(i, 1); } } // Update hold note states for (var lane = 0; lane < 4; lane++) { if (!activeTouches[lane]) { for (var j = 0; j < notes.length; j++) { var note = notes[j]; if (note.lane === lane && note.type === 'hold' && note.holdPressed) { note.holdPressed = false; } } } } // Add combo glow effect if (combo > 10) { var comboColors = ["#ff65d7", "#9d65ff", "#65b3ff", "#ff8fe6"]; var colorIndex = Math.floor(LK.ticks / 10 % comboColors.length); comboText.style.fill = comboColors[colorIndex]; } // End game condition (for demo purposes, end after reaching high score) if (score >= 50000) { LK.showYouWin(); } };
===================================================================
--- original.js
+++ change.js
@@ -141,8 +141,186 @@
var gameStarted = false;
var noteSpawnTimer = 0;
var activeTouches = {};
var hitZoneLastAlpha = 0.2;
+var selectedSong = 'random';
+var gameMode = 'menu'; // 'menu', 'playing'
+// Song data
+var songs = {
+ random: {
+ name: "Random Notes",
+ bpm: 120,
+ spawnRate: 40,
+ difficulty: "Easy"
+ },
+ neonBeats: {
+ name: "Neon Beats",
+ bpm: 140,
+ spawnRate: 30,
+ difficulty: "Medium",
+ notes: [{
+ time: 1000,
+ lane: 0,
+ type: 'regular'
+ }, {
+ time: 1200,
+ lane: 1,
+ type: 'regular'
+ }, {
+ time: 1400,
+ lane: 2,
+ type: 'hold',
+ duration: 60
+ }, {
+ time: 1600,
+ lane: 3,
+ type: 'regular'
+ }, {
+ time: 1800,
+ lane: 0,
+ type: 'regular'
+ }, {
+ time: 2000,
+ lane: 1,
+ type: 'regular'
+ }, {
+ time: 2200,
+ lane: 2,
+ type: 'regular'
+ }, {
+ time: 2400,
+ lane: 3,
+ type: 'hold',
+ duration: 80
+ }, {
+ time: 2600,
+ lane: 0,
+ type: 'regular'
+ }, {
+ time: 2800,
+ lane: 1,
+ type: 'regular'
+ }]
+ },
+ synthWave: {
+ name: "Synth Wave",
+ bpm: 160,
+ spawnRate: 25,
+ difficulty: "Hard",
+ notes: [{
+ time: 500,
+ lane: 0,
+ type: 'regular'
+ }, {
+ time: 700,
+ lane: 1,
+ type: 'regular'
+ }, {
+ time: 900,
+ lane: 2,
+ type: 'regular'
+ }, {
+ time: 1100,
+ lane: 3,
+ type: 'regular'
+ }, {
+ time: 1300,
+ lane: 0,
+ type: 'hold',
+ duration: 40
+ }, {
+ time: 1300,
+ lane: 2,
+ type: 'hold',
+ duration: 40
+ }, {
+ time: 1500,
+ lane: 1,
+ type: 'regular'
+ }, {
+ time: 1700,
+ lane: 3,
+ type: 'regular'
+ }, {
+ time: 1900,
+ lane: 0,
+ type: 'regular'
+ }, {
+ time: 2100,
+ lane: 1,
+ type: 'regular'
+ }, {
+ time: 2300,
+ lane: 2,
+ type: 'regular'
+ }, {
+ time: 2500,
+ lane: 3,
+ type: 'regular'
+ }]
+ },
+ cyberpunk: {
+ name: "Cyberpunk City",
+ bpm: 180,
+ spawnRate: 20,
+ difficulty: "Expert",
+ notes: [{
+ time: 400,
+ lane: 0,
+ type: 'regular'
+ }, {
+ time: 600,
+ lane: 1,
+ type: 'regular'
+ }, {
+ time: 800,
+ lane: 2,
+ type: 'regular'
+ }, {
+ time: 1000,
+ lane: 3,
+ type: 'regular'
+ }, {
+ time: 1200,
+ lane: 0,
+ type: 'hold',
+ duration: 30
+ }, {
+ time: 1200,
+ lane: 1,
+ type: 'hold',
+ duration: 30
+ }, {
+ time: 1400,
+ lane: 2,
+ type: 'regular'
+ }, {
+ time: 1600,
+ lane: 3,
+ type: 'regular'
+ }, {
+ time: 1800,
+ lane: 0,
+ type: 'regular'
+ }, {
+ time: 2000,
+ lane: 1,
+ type: 'regular'
+ }, {
+ time: 2200,
+ lane: 2,
+ type: 'hold',
+ duration: 60
+ }, {
+ time: 2400,
+ lane: 3,
+ type: 'regular'
+ }]
+ }
+};
+var songStartTime = 0;
+var songNoteIndex = 0;
+var menuVisible = true;
// Create hit zone with neon glow effect
var hitZone = game.addChild(LK.getAsset('hitZone', {
anchorX: 0.5,
anchorY: 0.5
@@ -195,12 +373,83 @@
});
accuracyText.anchor.set(0, 0);
LK.gui.topLeft.addChild(accuracyText);
accuracyText.x = 120; // Offset from menu button
-function spawnNote() {
- var lane = Math.floor(Math.random() * 4);
- var noteType = Math.random() < 0.2 ? 'hold' : 'regular';
+// Create song selection menu
+var menuContainer = new Container();
+game.addChild(menuContainer);
+// Menu background
+var menuBg = LK.getAsset('hitZone', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 1.0,
+ scaleY: 8.0
+});
+menuBg.x = 2048 / 2;
+menuBg.y = 2732 / 2;
+menuBg.alpha = 0.8;
+menuContainer.addChild(menuBg);
+// Menu title
+var menuTitle = new Text2('Choose Your Song', {
+ size: 80,
+ fill: 0xFF65D7
+});
+menuTitle.anchor.set(0.5, 0.5);
+menuTitle.x = 2048 / 2;
+menuTitle.y = 800;
+menuContainer.addChild(menuTitle);
+// Song selection buttons
+var songButtons = [];
+var songNames = Object.keys(songs);
+var buttonSpacing = 300;
+var startY = 1200;
+for (var i = 0; i < songNames.length; i++) {
+ var songKey = songNames[i];
+ var song = songs[songKey];
+ // Button background
+ var buttonBg = LK.getAsset('noteRegular' + (i % 4 + 1), {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ scaleX: 4.0,
+ scaleY: 1.5
+ });
+ buttonBg.x = 2048 / 2;
+ buttonBg.y = startY + i * buttonSpacing;
+ buttonBg.alpha = 0.7;
+ buttonBg.songKey = songKey;
+ menuContainer.addChild(buttonBg);
+ // Button text
+ var buttonText = new Text2(song.name, {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ buttonText.anchor.set(0.5, 0.5);
+ buttonText.x = buttonBg.x;
+ buttonText.y = buttonBg.y - 20;
+ menuContainer.addChild(buttonText);
+ // Difficulty and BPM text
+ var infoText = new Text2(song.difficulty + ' • ' + song.bpm + ' BPM', {
+ size: 30,
+ fill: 0x65B3FF
+ });
+ infoText.anchor.set(0.5, 0.5);
+ infoText.x = buttonBg.x;
+ infoText.y = buttonBg.y + 30;
+ menuContainer.addChild(infoText);
+ songButtons.push({
+ bg: buttonBg,
+ text: buttonText,
+ info: infoText,
+ songKey: songKey
+ });
+}
+function spawnNote(forcedLane, forcedType, forcedDuration) {
+ var lane = forcedLane !== undefined ? forcedLane : Math.floor(Math.random() * 4);
+ var noteType = forcedType || (Math.random() < 0.2 ? 'hold' : 'regular');
var note = new Note(noteType, lane);
+ if (forcedDuration && noteType === 'hold') {
+ note.maxHoldDuration = forcedDuration;
+ }
notes.push(note);
game.addChild(note);
}
function updateScore(hitType) {
@@ -238,9 +487,60 @@
return 2;
}
return 3;
}
+function startSelectedSong() {
+ menuVisible = false;
+ menuContainer.visible = false;
+ gameMode = 'playing';
+ songStartTime = LK.ticks;
+ songNoteIndex = 0;
+ // Reset game state
+ score = 0;
+ combo = 0;
+ accuracy = {
+ perfect: 0,
+ good: 0,
+ missed: 0,
+ total: 0
+ };
+ // Clear existing notes
+ for (var i = notes.length - 1; i >= 0; i--) {
+ notes[i].destroy();
+ notes.splice(i, 1);
+ }
+ updateScore('good'); // Updates displays
+ LK.setScore(0);
+ scoreText.setText('Score: 0');
+ comboText.setText('Combo: 0');
+ accuracyText.setText('Accuracy: 100%');
+}
+function showMenu() {
+ menuVisible = true;
+ menuContainer.visible = true;
+ gameMode = 'menu';
+ gameStarted = false;
+}
game.down = function (x, y, obj) {
+ // Handle menu interactions
+ if (menuVisible) {
+ for (var i = 0; i < songButtons.length; i++) {
+ var button = songButtons[i];
+ var buttonBounds = {
+ left: button.bg.x - button.bg.width * button.bg.scaleX / 2,
+ right: button.bg.x + button.bg.width * button.bg.scaleX / 2,
+ top: button.bg.y - button.bg.height * button.bg.scaleY / 2,
+ bottom: button.bg.y + button.bg.height * button.bg.scaleY / 2
+ };
+ if (x >= buttonBounds.left && x <= buttonBounds.right && y >= buttonBounds.top && y <= buttonBounds.bottom) {
+ // Button clicked
+ selectedSong = button.songKey;
+ startSelectedSong();
+ return;
+ }
+ }
+ return;
+ }
var lane = getLaneFromX(x);
var hitZoneY = 2732 - 150;
var hitFound = false;
// Add visual feedback to lane button
@@ -338,8 +638,18 @@
}
}
};
game.update = function () {
+ // Handle menu mode
+ if (menuVisible) {
+ // Add pulsing effect to menu buttons
+ for (var i = 0; i < songButtons.length; i++) {
+ var button = songButtons[i];
+ var pulse = Math.sin(LK.ticks * 0.1 + i * 0.3) * 0.1 + 0.7;
+ button.bg.alpha = pulse;
+ }
+ return;
+ }
// Start background music
if (!gameStarted) {
LK.playMusic('bgmusic');
gameStarted = true;
@@ -353,14 +663,33 @@
var buttonPulse = Math.sin(LK.ticks * 0.1 + i * 0.5) * 0.1 + 0.6;
laneButtons[i].alpha = buttonPulse;
}
}
- // Spawn notes
- noteSpawnTimer++;
- if (noteSpawnTimer >= 40) {
- // Slightly faster spawn rate
- spawnNote();
- noteSpawnTimer = 0;
+ // Handle song-specific note spawning
+ if (selectedSong === 'random') {
+ // Spawn notes randomly
+ noteSpawnTimer++;
+ if (noteSpawnTimer >= 40) {
+ spawnNote();
+ noteSpawnTimer = 0;
+ }
+ } else {
+ // Spawn notes based on song pattern
+ var currentSong = songs[selectedSong];
+ if (currentSong.notes && songNoteIndex < currentSong.notes.length) {
+ var currentTime = (LK.ticks - songStartTime) * (1000 / 60); // Convert ticks to milliseconds
+ var nextNote = currentSong.notes[songNoteIndex];
+ if (currentTime >= nextNote.time) {
+ spawnNote(nextNote.lane, nextNote.type, nextNote.duration);
+ songNoteIndex++;
+ }
+ }
+ // End song when all notes are played and cleared
+ if (songNoteIndex >= currentSong.notes.length && notes.length === 0) {
+ LK.setTimeout(function () {
+ showMenu();
+ }, 2000);
+ }
}
// Clean up off-screen notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];