User prompt
Add return button to main menu
User prompt
set the screen aspect ratio to 9:16
User prompt
change background
User prompt
Ad music
User prompt
Please fix the bug: 'TypeError: LK.isPaused is not a function' in or related to this line: 'var isPaused = LK.isPaused();' Line Number: 369
User prompt
When we pause the game, there should be an option to return to the main menu.
User prompt
When we press the start button, the difficulties will appear, easy, normal and difficult, the notes will fall fast in easy, normal and difficult.
User prompt
add main menu and have a start button there
User prompt
get the score and combo at the top right
User prompt
take the score and combo to the left
User prompt
Enlarge the green area downwards by 2.5 times
Code edit (1 edits merged)
Please save this source code
User prompt
Rhythm Tap Challenge
Initial prompt
when game starts: set score to 0 set combo to 0 play music "ritim.mp3" repeat forever: create note at random position (sol, orta, sagĢ) move note down slowly wait 0.75 beat #when note touches pad and tapped: if y pozisyonu dogĢruysa: destroy note increase score by 10 increase combo by 1 if combo >= 3: increase score by 5 # bonus show effect "combo" play sound "click.wav" else: decrease score by 5 reset combo to 0 shake screenwhen note touches bottom of screen: destroy note decrease score by 5 reset combo to 0 play sound "fail.wav"
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Game starts in menu state var MenuButton = Container.expand(function (text, onClickCallback) { var self = Container.call(this); // Create button background var buttonBg = self.attachAsset('notePad', { anchorX: 0.5, anchorY: 0.5, scaleX: 3.0, scaleY: 2.4 }); buttonBg.tint = 0xffffff; // Create button text var buttonText = new Text2(text, { size: 120, fill: 0x000000 }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.onClickCallback = onClickCallback; self.down = function (x, y, obj) { buttonBg.tint = 0xcccccc; if (self.onClickCallback) { self.onClickCallback(); } }; self.up = function (x, y, obj) { buttonBg.tint = 0xffffff; }; return self; }); var Note = Container.expand(function (lane, isRedMode) { var self = Container.call(this); var noteGraphics = self.attachAsset('note', { anchorX: 0.5, anchorY: 0.5 }); self.lane = lane; // 0 = left, 1 = center, 2 = right self.speed = Note.prototype.speed || 8; self.hasBeenHit = false; self.isRedMode = isRedMode || false; self.startX = 0; // Track starting X position for swipe detection self.hasStartedDrag = false; // Make red notes visually distinct if (self.isRedMode) { noteGraphics.tint = 0xff0000; // Red color } self.update = function () { self.y += self.speed; }; self.down = function (x, y, obj) { if (!self.hasBeenHit) { if (self.isRedMode) { // For red notes, track starting position for swipe detection self.startX = x; self.hasStartedDrag = true; } else { // Normal note behavior self.hasBeenHit = true; gameScore += 5; gameCombo += 1; // Combo system logic combo += 1; if (combo >= 10 && !feverMode) { feverMode = true; LK.effects.flashScreen(0xFFD700, 200); game.setBackgroundColor(0xFFD700); // Gold LK.setTimeout(function () { feverMode = false; game.setBackgroundColor(0x1a1a2e); combo = 0; }, 5000); } comboDisplayText.setText("Perfect!"); comboDisplayText.visible = true; LK.setTimeout(function () { comboDisplayText.visible = false; }, 500); // Create explosion effect createExplosionEffect(self.x, self.y); // Change background color effect var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff]; var randomColor = colors[Math.floor(Math.random() * colors.length)]; game.setBackgroundColor(randomColor); // Visual effect tween(self, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 200, onFinish: function onFinish() { removeNote(self); } }); LK.getSound('success').play(); updateUI(); } } }; self.up = function (x, y, obj) { if (self.isRedMode && self.hasStartedDrag && !self.hasBeenHit) { // Check if user swiped left (moved at least 100 pixels to the left) var swipeDistance = self.startX - x; if (swipeDistance > 100) { // Successful left swipe on red note self.hasBeenHit = true; gameScore += 10; // Red notes give 10 points gameCombo += 1; // Combo system logic combo += 1; if (combo >= 10 && !feverMode) { feverMode = true; LK.effects.flashScreen(0xFFD700, 200); game.setBackgroundColor(0xFFD700); // Gold LK.setTimeout(function () { feverMode = false; game.setBackgroundColor(0x1a1a2e); combo = 0; }, 5000); } comboDisplayText.setText("Perfect!"); comboDisplayText.visible = true; LK.setTimeout(function () { comboDisplayText.visible = false; }, 500); // Create explosion effect createExplosionEffect(self.x, self.y); // Change background color effect var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff]; var randomColor = colors[Math.floor(Math.random() * colors.length)]; game.setBackgroundColor(randomColor); // Visual effect tween(self, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 200, onFinish: function onFinish() { removeNote(self); } }); LK.getSound('success').play(); updateUI(); } } self.hasStartedDrag = false; }; return self; }); var NotePad = Container.expand(function (lane) { var self = Container.call(this); var padGraphics = self.attachAsset('notePad', { anchorX: 0.5, anchorY: 0.5 }); var perfectZone = self.attachAsset('perfectZone', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); self.lane = lane; self.isPressed = false; self.down = function (x, y, obj) { self.isPressed = true; checkNoteHit(self.lane); }; self.up = function (x, y, obj) { self.isPressed = false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Create background var background = LK.getAsset('Background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(background); var notes = []; var gameScore = 0; var gameCombo = 0; var spawnTimer = 0; var spawnInterval = 45; // 0.75 seconds at 60fps var perfectZoneY = 2400; var perfectTolerance = 100; var noteCounter = 0; // Track total notes spawned for red mode var combo = 0; var feverMode = false; var comboDisplayText; var scoreDisplayText; // Game state var gameState = 'menu'; // 'menu', 'difficulty', or 'playing' var selectedDifficulty = 'normal'; var mainMenu = new Container(); var difficultyMenu = new Container(); var howToPlayMenu = new Container(); var gameContainer = new Container(); // Main Menu Elements var titleText = new Text2('Rhythm Tap Challenge', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0.5); titleText.x = 1024; titleText.y = 800; mainMenu.addChild(titleText); var startButton = new MenuButton('START', function () { showDifficultyMenu(); }); startButton.x = 1024; startButton.y = 1200; mainMenu.addChild(startButton); var howToPlayButton = new MenuButton('HOW TO PLAY', function () { showHowToPlayMenu(); }); // Enlarge the green area behind the How To Play button howToPlayButton.children[0].scaleX = 5.0; howToPlayButton.children[0].scaleY = 4.0; howToPlayButton.x = 1024; howToPlayButton.y = 1500; mainMenu.addChild(howToPlayButton); // Difficulty Menu Elements var difficultyTitle = new Text2('Select Difficulty', { size: 70, fill: 0xFFFFFF }); difficultyTitle.anchor.set(0.5, 0.5); difficultyTitle.x = 1024; difficultyTitle.y = 800; difficultyMenu.addChild(difficultyTitle); var easyButton = new MenuButton('EASY', function () { selectedDifficulty = 'easy'; startGame(); }); easyButton.x = 1024; easyButton.y = 1000; difficultyMenu.addChild(easyButton); var normalButton = new MenuButton('NORMAL', function () { selectedDifficulty = 'normal'; startGame(); }); normalButton.x = 1024; normalButton.y = 1150; difficultyMenu.addChild(normalButton); var hardButton = new MenuButton('HARD', function () { selectedDifficulty = 'hard'; startGame(); }); hardButton.x = 1024; hardButton.y = 1300; difficultyMenu.addChild(hardButton); var backButton = new MenuButton('BACK', function () { showMainMenu(); }); backButton.x = 1024; backButton.y = 1500; difficultyMenu.addChild(backButton); // How To Play Menu Elements var howToPlayTitle = new Text2('How To Play', { size: 70, fill: 0xFFFFFF }); howToPlayTitle.anchor.set(0.5, 0.5); howToPlayTitle.x = 1024; howToPlayTitle.y = 600; howToPlayMenu.addChild(howToPlayTitle); var instructionsText1 = new Text2('Notes fall from 3 different points', { size: 50, fill: 0xFFFFFF }); instructionsText1.anchor.set(0.5, 0.5); instructionsText1.x = 1024; instructionsText1.y = 900; howToPlayMenu.addChild(instructionsText1); var instructionsText2 = new Text2('from top to bottom.', { size: 50, fill: 0xFFFFFF }); instructionsText2.anchor.set(0.5, 0.5); instructionsText2.x = 1024; instructionsText2.y = 970; howToPlayMenu.addChild(instructionsText2); var instructionsText3 = new Text2('Touch the notes before they disappear', { size: 50, fill: 0xFFFFFF }); instructionsText3.anchor.set(0.5, 0.5); instructionsText3.x = 1024; instructionsText3.y = 1040; howToPlayMenu.addChild(instructionsText3); var instructionsText4 = new Text2('and earn 5 points.', { size: 50, fill: 0xFFFFFF }); instructionsText4.anchor.set(0.5, 0.5); instructionsText4.x = 1024; instructionsText4.y = 1110; howToPlayMenu.addChild(instructionsText4); var instructionsText5 = new Text2('If you cannot touch them in time,', { size: 50, fill: 0xFFFFFF }); instructionsText5.anchor.set(0.5, 0.5); instructionsText5.x = 1024; instructionsText5.y = 1180; howToPlayMenu.addChild(instructionsText5); var instructionsText6 = new Text2('your 5 points will decrease and', { size: 50, fill: 0xFFFFFF }); instructionsText6.anchor.set(0.5, 0.5); instructionsText6.x = 1024; instructionsText6.y = 1250; howToPlayMenu.addChild(instructionsText6); var instructionsText7 = new Text2('the game will end at -50 points', { size: 50, fill: 0xFFFFFF }); instructionsText7.anchor.set(0.5, 0.5); instructionsText7.x = 1024; instructionsText7.y = 1320; howToPlayMenu.addChild(instructionsText7); var instructionsText8 = new Text2('We must move the red note that comes every 25 notes', { size: 50, fill: 0xFFFFFF }); instructionsText8.anchor.set(0.5, 0.5); instructionsText8.x = 1024; instructionsText8.y = 1390; howToPlayMenu.addChild(instructionsText8); var instructionsText9 = new Text2('to the left. If we move it, we gain 20 points.', { size: 50, fill: 0xFFFFFF }); instructionsText9.anchor.set(0.5, 0.5); instructionsText9.x = 1024; instructionsText9.y = 1460; howToPlayMenu.addChild(instructionsText9); var instructionsText10 = new Text2('If we cannot, our 20 points will be deducted', { size: 50, fill: 0xFFFFFF }); instructionsText10.anchor.set(0.5, 0.5); instructionsText10.x = 1024; instructionsText10.y = 1530; howToPlayMenu.addChild(instructionsText10); var backFromHowToPlayButton = new MenuButton('BACK', function () { showMainMenu(); }); backFromHowToPlayButton.x = 1024; backFromHowToPlayButton.y = 1650; howToPlayMenu.addChild(backFromHowToPlayButton); game.addChild(mainMenu); game.addChild(difficultyMenu); game.addChild(howToPlayMenu); difficultyMenu.visible = false; howToPlayMenu.visible = false; // UI Elements var scoreText = new Text2('0', { size: 60, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); scoreText.x = 0; scoreText.y = 50; LK.gui.top.addChild(scoreText); var comboText = new Text2('Combo: 0', { size: 50, fill: 0xFFFF00 }); comboText.anchor.set(1, 0); comboText.x = -50; comboText.y = 130; LK.gui.topRight.addChild(comboText); var highScoreText = new Text2('High Score: ' + (storage.highScore || 0), { size: 40, fill: 0xFFFFFF }); highScoreText.anchor.set(1, 0); highScoreText.x = -50; highScoreText.y = 200; LK.gui.topRight.addChild(highScoreText); // Hide UI initially scoreText.visible = false; comboText.visible = false; highScoreText.visible = false; // Create restart button for game screen var restartButton = new MenuButton('āŗ', function () { // Reset game state gameScore = 0; gameCombo = 0; spawnTimer = 0; noteCounter = 0; // Reset note counter for red mode // Clear all notes for (var i = notes.length - 1; i >= 0; i--) { removeNote(notes[i]); } updateUI(); }); restartButton.x = 924; restartButton.y = 50; restartButton.scaleX = 0.42; restartButton.scaleY = 0.42; gameContainer.addChild(restartButton); // Create return to main menu button for game screen var returnMenuButton = new MenuButton('š ', function () { // Stop game music and start menu music LK.stopMusic(); LK.playMusic('menumusic', { loop: true }); gameState = 'menu'; gameContainer.visible = false; scoreText.visible = false; comboText.visible = false; highScoreText.visible = false; // Clear all notes for (var i = notes.length - 1; i >= 0; i--) { removeNote(notes[i]); } // Reset game variables gameScore = 0; gameCombo = 0; spawnTimer = 0; noteCounter = 0; // Reset note counter for red mode updateUI(); // Show main menu showMainMenu(); }); returnMenuButton.x = 1124; returnMenuButton.y = 50; returnMenuButton.scaleX = 0.42; returnMenuButton.scaleY = 0.42; gameContainer.addChild(returnMenuButton); // Create note pads var padPositions = [512, 1024, 1536]; // Left, center, right positions game.addChild(gameContainer); gameContainer.visible = false; // Create intro text var introText = new Text2('lighten the darkness with music', { size: 80, fill: 0xFFFFFF }); introText.anchor.set(0.5, 0.5); introText.x = 1024; introText.y = 1366; introText.alpha = 1; game.addChild(introText); // Create black overlay for screen blackout effect var blackOverlay = LK.getAsset('notePad', { anchorX: 0, anchorY: 0, scaleX: 10, scaleY: 35, x: 0, y: 0 }); blackOverlay.tint = 0x000000; blackOverlay.alpha = 0.8; game.addChild(blackOverlay); // Initialize combo and score display text comboDisplayText = new Text2("", { size: 64, fill: 0xFFFFFF }); comboDisplayText.anchor.set(0.5, 0.5); comboDisplayText.x = 360; comboDisplayText.y = 300; comboDisplayText.visible = false; game.addChild(comboDisplayText); scoreDisplayText = new Text2("", { size: 24, fill: 0xFFFFFF }); scoreDisplayText.anchor.set(0.5, 0.5); scoreDisplayText.x = 360; scoreDisplayText.y = 50; game.addChild(scoreDisplayText); // Show intro text with fade in effect and black screen - starting 4.5 seconds earlier LK.setTimeout(function () { // Hold for 2 seconds then fade out LK.setTimeout(function () { tween(introText, { alpha: 0 }, { duration: 1500, onFinish: function onFinish() { game.removeChild(introText); } }); // Fade black overlay out tween(blackOverlay, { alpha: 0 }, { duration: 1500, onFinish: function onFinish() { game.removeChild(blackOverlay); } }); }, 2000); }, 0); // Start 4.5 seconds earlier (reduced from 500ms to 0ms) // Start menu music LK.playMusic('menumusic', { loop: true }); function showDifficultyMenu() { gameState = 'difficulty'; mainMenu.visible = false; difficultyMenu.visible = true; } function showHowToPlayMenu() { gameState = 'howtoplay'; mainMenu.visible = false; howToPlayMenu.visible = true; } function showMainMenu() { gameState = 'menu'; mainMenu.visible = true; difficultyMenu.visible = false; howToPlayMenu.visible = false; } function startGame() { gameState = 'playing'; mainMenu.visible = false; difficultyMenu.visible = false; gameContainer.visible = true; scoreText.visible = true; comboText.visible = true; highScoreText.visible = true; // Reset game state gameScore = 0; gameCombo = 0; spawnTimer = 0; noteCounter = 0; // Reset note counter for red mode // Set note speed based on difficulty var noteSpeed = 8; // normal speed if (selectedDifficulty === 'easy') { noteSpeed = 12; // 1.5 times faster than normal (8 * 1.5) } else if (selectedDifficulty === 'normal') { noteSpeed = 28; // 3.5 times faster than normal (8 * 3.5) } else if (selectedDifficulty === 'hard') { noteSpeed = 32; // 4 times faster than normal (8 * 4) } // Update all note pads with new speed Note.prototype.speed = noteSpeed; // Clear any existing notes for (var i = notes.length - 1; i >= 0; i--) { removeNote(notes[i]); } // Stop menu music and start game music LK.stopMusic(); LK.playMusic('bgmusic', { loop: true }); updateUI(); // Update high score display for selected difficulty var highScoreKey = 'highScore_' + selectedDifficulty; highScoreText.setText('Best (' + selectedDifficulty.toUpperCase() + '): ' + (storage[highScoreKey] || 0)); } function spawnNote() { var randomLane = Math.floor(Math.random() * 3); noteCounter++; // Create red note every 25 notes var isRedMode = noteCounter % 25 === 0; var note = new Note(randomLane, isRedMode); note.x = padPositions[randomLane]; note.y = -50; notes.push(note); gameContainer.addChild(note); } function checkNoteHit(lane) { var hitNote = null; var bestDistance = Infinity; // Find the closest note in the perfect zone for this lane for (var i = 0; i < notes.length; i++) { var note = notes[i]; if (note.lane === lane && !note.hasBeenHit) { var distance = Math.abs(note.y - perfectZoneY); if (distance < perfectTolerance && distance < bestDistance) { hitNote = note; bestDistance = distance; } } } if (hitNote) { // Perfect hit hitNote.hasBeenHit = true; gameScore += 5; gameCombo += 1; // Create explosion effect createExplosionEffect(hitNote.x, hitNote.y); // Change background color effect var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff]; var randomColor = colors[Math.floor(Math.random() * colors.length)]; game.setBackgroundColor(randomColor); // Visual effect tween(hitNote, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 200, onFinish: function onFinish() { removeNote(hitNote); } }); LK.getSound('success').play(); updateUI(); } else { // Wrong timing gameScore -= 5; gameCombo = 0; LK.effects.flashScreen(0xff0000, 200); updateUI(); } } function createExplosionEffect(x, y) { // Create multiple explosion particles for (var i = 0; i < 8; i++) { var particle = LK.getAsset('note', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); particle.x = x; particle.y = y; particle.tint = 0xFFFF00; // Yellow explosion color gameContainer.addChild(particle); // Random direction for each particle var angle = i / 8 * Math.PI * 2; var speed = 100 + Math.random() * 50; var targetX = x + Math.cos(angle) * speed; var targetY = y + Math.sin(angle) * speed; // Animate particle outward and fade tween(particle, { x: targetX, y: targetY, alpha: 0, scaleX: 0.1, scaleY: 0.1 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { gameContainer.removeChild(particle); } }); } } function showComboEffect(x, y) { var comboEffect = new Text2('COMBO!', { size: 80, fill: 0xFFFF00 }); comboEffect.anchor.set(0.5, 0.5); comboEffect.x = x; comboEffect.y = y; gameContainer.addChild(comboEffect); tween(comboEffect, { y: y - 100, alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { gameContainer.removeChild(comboEffect); } }); } function removeNote(note) { var index = notes.indexOf(note); if (index > -1) { notes.splice(index, 1); gameContainer.removeChild(note); } } function updateUI() { scoreText.setText(gameScore); comboText.setText('Combo: ' + gameCombo); LK.setScore(gameScore); // Update high score if current score is higher var highScoreKey = 'highScore_' + selectedDifficulty; var currentHighScore = storage[highScoreKey] || 0; if (gameScore > currentHighScore) { storage[highScoreKey] = gameScore; } highScoreText.setText('Best (' + selectedDifficulty.toUpperCase() + '): ' + (storage[highScoreKey] || 0)); // Check for game over at -50 points if (gameScore <= -50) { LK.showGameOver(); } } // Add pause menu functionality var pauseMenu = new Container(); var pauseTitle = new Text2('Game Paused', { size: 70, fill: 0xFFFFFF }); pauseTitle.anchor.set(0.5, 0.5); pauseTitle.x = 1024; pauseTitle.y = 1000; pauseMenu.addChild(pauseTitle); var resumeButton = new MenuButton('RESUME', function () { pauseMenu.visible = false; }); resumeButton.x = 1024; resumeButton.y = 1200; pauseMenu.addChild(resumeButton); var mainMenuButton = new MenuButton('MAIN MENU', function () { // Stop game music and start menu music LK.stopMusic(); LK.playMusic('menumusic', { loop: true }); gameState = 'menu'; pauseMenu.visible = false; gameContainer.visible = false; scoreText.visible = false; comboText.visible = false; highScoreText.visible = false; // Clear all notes for (var i = notes.length - 1; i >= 0; i--) { removeNote(notes[i]); } // Reset game variables gameScore = 0; gameCombo = 0; spawnTimer = 0; noteCounter = 0; // Reset note counter for red mode updateUI(); // Show main menu showMainMenu(); }); mainMenuButton.x = 1024; mainMenuButton.y = 1350; pauseMenu.addChild(mainMenuButton); game.addChild(pauseMenu); pauseMenu.visible = false; game.update = function () { if (gameState !== 'playing') { return; } // Spawn notes spawnTimer++; if (spawnTimer >= spawnInterval) { spawnNote(); spawnTimer = 0; } // Update and check notes for (var i = notes.length - 1; i >= 0; i--) { var note = notes[i]; // Check if note reached bottom (missed) if (note.y > 2800 && !note.hasBeenHit) { if (note.isRedMode) { gameScore -= 20; // Red notes penalty is -20 points } else { gameScore -= 5; // Normal notes penalty is -5 points } gameCombo = 0; // Combo system reset on miss combo = 0; comboDisplayText.setText("Miss!"); comboDisplayText.visible = true; LK.setTimeout(function () { comboDisplayText.visible = false; }, 500); LK.getSound('fail').play(); updateUI(); removeNote(note); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Game starts in menu state
var MenuButton = Container.expand(function (text, onClickCallback) {
var self = Container.call(this);
// Create button background
var buttonBg = self.attachAsset('notePad', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3.0,
scaleY: 2.4
});
buttonBg.tint = 0xffffff;
// Create button text
var buttonText = new Text2(text, {
size: 120,
fill: 0x000000
});
buttonText.anchor.set(0.5, 0.5);
self.addChild(buttonText);
self.onClickCallback = onClickCallback;
self.down = function (x, y, obj) {
buttonBg.tint = 0xcccccc;
if (self.onClickCallback) {
self.onClickCallback();
}
};
self.up = function (x, y, obj) {
buttonBg.tint = 0xffffff;
};
return self;
});
var Note = Container.expand(function (lane, isRedMode) {
var self = Container.call(this);
var noteGraphics = self.attachAsset('note', {
anchorX: 0.5,
anchorY: 0.5
});
self.lane = lane; // 0 = left, 1 = center, 2 = right
self.speed = Note.prototype.speed || 8;
self.hasBeenHit = false;
self.isRedMode = isRedMode || false;
self.startX = 0; // Track starting X position for swipe detection
self.hasStartedDrag = false;
// Make red notes visually distinct
if (self.isRedMode) {
noteGraphics.tint = 0xff0000; // Red color
}
self.update = function () {
self.y += self.speed;
};
self.down = function (x, y, obj) {
if (!self.hasBeenHit) {
if (self.isRedMode) {
// For red notes, track starting position for swipe detection
self.startX = x;
self.hasStartedDrag = true;
} else {
// Normal note behavior
self.hasBeenHit = true;
gameScore += 5;
gameCombo += 1;
// Combo system logic
combo += 1;
if (combo >= 10 && !feverMode) {
feverMode = true;
LK.effects.flashScreen(0xFFD700, 200);
game.setBackgroundColor(0xFFD700); // Gold
LK.setTimeout(function () {
feverMode = false;
game.setBackgroundColor(0x1a1a2e);
combo = 0;
}, 5000);
}
comboDisplayText.setText("Perfect!");
comboDisplayText.visible = true;
LK.setTimeout(function () {
comboDisplayText.visible = false;
}, 500);
// Create explosion effect
createExplosionEffect(self.x, self.y);
// Change background color effect
var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff];
var randomColor = colors[Math.floor(Math.random() * colors.length)];
game.setBackgroundColor(randomColor);
// Visual effect
tween(self, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 200,
onFinish: function onFinish() {
removeNote(self);
}
});
LK.getSound('success').play();
updateUI();
}
}
};
self.up = function (x, y, obj) {
if (self.isRedMode && self.hasStartedDrag && !self.hasBeenHit) {
// Check if user swiped left (moved at least 100 pixels to the left)
var swipeDistance = self.startX - x;
if (swipeDistance > 100) {
// Successful left swipe on red note
self.hasBeenHit = true;
gameScore += 10; // Red notes give 10 points
gameCombo += 1;
// Combo system logic
combo += 1;
if (combo >= 10 && !feverMode) {
feverMode = true;
LK.effects.flashScreen(0xFFD700, 200);
game.setBackgroundColor(0xFFD700); // Gold
LK.setTimeout(function () {
feverMode = false;
game.setBackgroundColor(0x1a1a2e);
combo = 0;
}, 5000);
}
comboDisplayText.setText("Perfect!");
comboDisplayText.visible = true;
LK.setTimeout(function () {
comboDisplayText.visible = false;
}, 500);
// Create explosion effect
createExplosionEffect(self.x, self.y);
// Change background color effect
var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff];
var randomColor = colors[Math.floor(Math.random() * colors.length)];
game.setBackgroundColor(randomColor);
// Visual effect
tween(self, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 200,
onFinish: function onFinish() {
removeNote(self);
}
});
LK.getSound('success').play();
updateUI();
}
}
self.hasStartedDrag = false;
};
return self;
});
var NotePad = Container.expand(function (lane) {
var self = Container.call(this);
var padGraphics = self.attachAsset('notePad', {
anchorX: 0.5,
anchorY: 0.5
});
var perfectZone = self.attachAsset('perfectZone', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
self.lane = lane;
self.isPressed = false;
self.down = function (x, y, obj) {
self.isPressed = true;
checkNoteHit(self.lane);
};
self.up = function (x, y, obj) {
self.isPressed = false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Create background
var background = LK.getAsset('Background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
game.addChild(background);
var notes = [];
var gameScore = 0;
var gameCombo = 0;
var spawnTimer = 0;
var spawnInterval = 45; // 0.75 seconds at 60fps
var perfectZoneY = 2400;
var perfectTolerance = 100;
var noteCounter = 0; // Track total notes spawned for red mode
var combo = 0;
var feverMode = false;
var comboDisplayText;
var scoreDisplayText;
// Game state
var gameState = 'menu'; // 'menu', 'difficulty', or 'playing'
var selectedDifficulty = 'normal';
var mainMenu = new Container();
var difficultyMenu = new Container();
var howToPlayMenu = new Container();
var gameContainer = new Container();
// Main Menu Elements
var titleText = new Text2('Rhythm Tap Challenge', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 1024;
titleText.y = 800;
mainMenu.addChild(titleText);
var startButton = new MenuButton('START', function () {
showDifficultyMenu();
});
startButton.x = 1024;
startButton.y = 1200;
mainMenu.addChild(startButton);
var howToPlayButton = new MenuButton('HOW TO PLAY', function () {
showHowToPlayMenu();
});
// Enlarge the green area behind the How To Play button
howToPlayButton.children[0].scaleX = 5.0;
howToPlayButton.children[0].scaleY = 4.0;
howToPlayButton.x = 1024;
howToPlayButton.y = 1500;
mainMenu.addChild(howToPlayButton);
// Difficulty Menu Elements
var difficultyTitle = new Text2('Select Difficulty', {
size: 70,
fill: 0xFFFFFF
});
difficultyTitle.anchor.set(0.5, 0.5);
difficultyTitle.x = 1024;
difficultyTitle.y = 800;
difficultyMenu.addChild(difficultyTitle);
var easyButton = new MenuButton('EASY', function () {
selectedDifficulty = 'easy';
startGame();
});
easyButton.x = 1024;
easyButton.y = 1000;
difficultyMenu.addChild(easyButton);
var normalButton = new MenuButton('NORMAL', function () {
selectedDifficulty = 'normal';
startGame();
});
normalButton.x = 1024;
normalButton.y = 1150;
difficultyMenu.addChild(normalButton);
var hardButton = new MenuButton('HARD', function () {
selectedDifficulty = 'hard';
startGame();
});
hardButton.x = 1024;
hardButton.y = 1300;
difficultyMenu.addChild(hardButton);
var backButton = new MenuButton('BACK', function () {
showMainMenu();
});
backButton.x = 1024;
backButton.y = 1500;
difficultyMenu.addChild(backButton);
// How To Play Menu Elements
var howToPlayTitle = new Text2('How To Play', {
size: 70,
fill: 0xFFFFFF
});
howToPlayTitle.anchor.set(0.5, 0.5);
howToPlayTitle.x = 1024;
howToPlayTitle.y = 600;
howToPlayMenu.addChild(howToPlayTitle);
var instructionsText1 = new Text2('Notes fall from 3 different points', {
size: 50,
fill: 0xFFFFFF
});
instructionsText1.anchor.set(0.5, 0.5);
instructionsText1.x = 1024;
instructionsText1.y = 900;
howToPlayMenu.addChild(instructionsText1);
var instructionsText2 = new Text2('from top to bottom.', {
size: 50,
fill: 0xFFFFFF
});
instructionsText2.anchor.set(0.5, 0.5);
instructionsText2.x = 1024;
instructionsText2.y = 970;
howToPlayMenu.addChild(instructionsText2);
var instructionsText3 = new Text2('Touch the notes before they disappear', {
size: 50,
fill: 0xFFFFFF
});
instructionsText3.anchor.set(0.5, 0.5);
instructionsText3.x = 1024;
instructionsText3.y = 1040;
howToPlayMenu.addChild(instructionsText3);
var instructionsText4 = new Text2('and earn 5 points.', {
size: 50,
fill: 0xFFFFFF
});
instructionsText4.anchor.set(0.5, 0.5);
instructionsText4.x = 1024;
instructionsText4.y = 1110;
howToPlayMenu.addChild(instructionsText4);
var instructionsText5 = new Text2('If you cannot touch them in time,', {
size: 50,
fill: 0xFFFFFF
});
instructionsText5.anchor.set(0.5, 0.5);
instructionsText5.x = 1024;
instructionsText5.y = 1180;
howToPlayMenu.addChild(instructionsText5);
var instructionsText6 = new Text2('your 5 points will decrease and', {
size: 50,
fill: 0xFFFFFF
});
instructionsText6.anchor.set(0.5, 0.5);
instructionsText6.x = 1024;
instructionsText6.y = 1250;
howToPlayMenu.addChild(instructionsText6);
var instructionsText7 = new Text2('the game will end at -50 points', {
size: 50,
fill: 0xFFFFFF
});
instructionsText7.anchor.set(0.5, 0.5);
instructionsText7.x = 1024;
instructionsText7.y = 1320;
howToPlayMenu.addChild(instructionsText7);
var instructionsText8 = new Text2('We must move the red note that comes every 25 notes', {
size: 50,
fill: 0xFFFFFF
});
instructionsText8.anchor.set(0.5, 0.5);
instructionsText8.x = 1024;
instructionsText8.y = 1390;
howToPlayMenu.addChild(instructionsText8);
var instructionsText9 = new Text2('to the left. If we move it, we gain 20 points.', {
size: 50,
fill: 0xFFFFFF
});
instructionsText9.anchor.set(0.5, 0.5);
instructionsText9.x = 1024;
instructionsText9.y = 1460;
howToPlayMenu.addChild(instructionsText9);
var instructionsText10 = new Text2('If we cannot, our 20 points will be deducted', {
size: 50,
fill: 0xFFFFFF
});
instructionsText10.anchor.set(0.5, 0.5);
instructionsText10.x = 1024;
instructionsText10.y = 1530;
howToPlayMenu.addChild(instructionsText10);
var backFromHowToPlayButton = new MenuButton('BACK', function () {
showMainMenu();
});
backFromHowToPlayButton.x = 1024;
backFromHowToPlayButton.y = 1650;
howToPlayMenu.addChild(backFromHowToPlayButton);
game.addChild(mainMenu);
game.addChild(difficultyMenu);
game.addChild(howToPlayMenu);
difficultyMenu.visible = false;
howToPlayMenu.visible = false;
// UI Elements
var scoreText = new Text2('0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.x = 0;
scoreText.y = 50;
LK.gui.top.addChild(scoreText);
var comboText = new Text2('Combo: 0', {
size: 50,
fill: 0xFFFF00
});
comboText.anchor.set(1, 0);
comboText.x = -50;
comboText.y = 130;
LK.gui.topRight.addChild(comboText);
var highScoreText = new Text2('High Score: ' + (storage.highScore || 0), {
size: 40,
fill: 0xFFFFFF
});
highScoreText.anchor.set(1, 0);
highScoreText.x = -50;
highScoreText.y = 200;
LK.gui.topRight.addChild(highScoreText);
// Hide UI initially
scoreText.visible = false;
comboText.visible = false;
highScoreText.visible = false;
// Create restart button for game screen
var restartButton = new MenuButton('āŗ', function () {
// Reset game state
gameScore = 0;
gameCombo = 0;
spawnTimer = 0;
noteCounter = 0; // Reset note counter for red mode
// Clear all notes
for (var i = notes.length - 1; i >= 0; i--) {
removeNote(notes[i]);
}
updateUI();
});
restartButton.x = 924;
restartButton.y = 50;
restartButton.scaleX = 0.42;
restartButton.scaleY = 0.42;
gameContainer.addChild(restartButton);
// Create return to main menu button for game screen
var returnMenuButton = new MenuButton('š ', function () {
// Stop game music and start menu music
LK.stopMusic();
LK.playMusic('menumusic', {
loop: true
});
gameState = 'menu';
gameContainer.visible = false;
scoreText.visible = false;
comboText.visible = false;
highScoreText.visible = false;
// Clear all notes
for (var i = notes.length - 1; i >= 0; i--) {
removeNote(notes[i]);
}
// Reset game variables
gameScore = 0;
gameCombo = 0;
spawnTimer = 0;
noteCounter = 0; // Reset note counter for red mode
updateUI();
// Show main menu
showMainMenu();
});
returnMenuButton.x = 1124;
returnMenuButton.y = 50;
returnMenuButton.scaleX = 0.42;
returnMenuButton.scaleY = 0.42;
gameContainer.addChild(returnMenuButton);
// Create note pads
var padPositions = [512, 1024, 1536]; // Left, center, right positions
game.addChild(gameContainer);
gameContainer.visible = false;
// Create intro text
var introText = new Text2('lighten the darkness with music', {
size: 80,
fill: 0xFFFFFF
});
introText.anchor.set(0.5, 0.5);
introText.x = 1024;
introText.y = 1366;
introText.alpha = 1;
game.addChild(introText);
// Create black overlay for screen blackout effect
var blackOverlay = LK.getAsset('notePad', {
anchorX: 0,
anchorY: 0,
scaleX: 10,
scaleY: 35,
x: 0,
y: 0
});
blackOverlay.tint = 0x000000;
blackOverlay.alpha = 0.8;
game.addChild(blackOverlay);
// Initialize combo and score display text
comboDisplayText = new Text2("", {
size: 64,
fill: 0xFFFFFF
});
comboDisplayText.anchor.set(0.5, 0.5);
comboDisplayText.x = 360;
comboDisplayText.y = 300;
comboDisplayText.visible = false;
game.addChild(comboDisplayText);
scoreDisplayText = new Text2("", {
size: 24,
fill: 0xFFFFFF
});
scoreDisplayText.anchor.set(0.5, 0.5);
scoreDisplayText.x = 360;
scoreDisplayText.y = 50;
game.addChild(scoreDisplayText);
// Show intro text with fade in effect and black screen - starting 4.5 seconds earlier
LK.setTimeout(function () {
// Hold for 2 seconds then fade out
LK.setTimeout(function () {
tween(introText, {
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
game.removeChild(introText);
}
});
// Fade black overlay out
tween(blackOverlay, {
alpha: 0
}, {
duration: 1500,
onFinish: function onFinish() {
game.removeChild(blackOverlay);
}
});
}, 2000);
}, 0); // Start 4.5 seconds earlier (reduced from 500ms to 0ms)
// Start menu music
LK.playMusic('menumusic', {
loop: true
});
function showDifficultyMenu() {
gameState = 'difficulty';
mainMenu.visible = false;
difficultyMenu.visible = true;
}
function showHowToPlayMenu() {
gameState = 'howtoplay';
mainMenu.visible = false;
howToPlayMenu.visible = true;
}
function showMainMenu() {
gameState = 'menu';
mainMenu.visible = true;
difficultyMenu.visible = false;
howToPlayMenu.visible = false;
}
function startGame() {
gameState = 'playing';
mainMenu.visible = false;
difficultyMenu.visible = false;
gameContainer.visible = true;
scoreText.visible = true;
comboText.visible = true;
highScoreText.visible = true;
// Reset game state
gameScore = 0;
gameCombo = 0;
spawnTimer = 0;
noteCounter = 0; // Reset note counter for red mode
// Set note speed based on difficulty
var noteSpeed = 8; // normal speed
if (selectedDifficulty === 'easy') {
noteSpeed = 12; // 1.5 times faster than normal (8 * 1.5)
} else if (selectedDifficulty === 'normal') {
noteSpeed = 28; // 3.5 times faster than normal (8 * 3.5)
} else if (selectedDifficulty === 'hard') {
noteSpeed = 32; // 4 times faster than normal (8 * 4)
}
// Update all note pads with new speed
Note.prototype.speed = noteSpeed;
// Clear any existing notes
for (var i = notes.length - 1; i >= 0; i--) {
removeNote(notes[i]);
}
// Stop menu music and start game music
LK.stopMusic();
LK.playMusic('bgmusic', {
loop: true
});
updateUI();
// Update high score display for selected difficulty
var highScoreKey = 'highScore_' + selectedDifficulty;
highScoreText.setText('Best (' + selectedDifficulty.toUpperCase() + '): ' + (storage[highScoreKey] || 0));
}
function spawnNote() {
var randomLane = Math.floor(Math.random() * 3);
noteCounter++;
// Create red note every 25 notes
var isRedMode = noteCounter % 25 === 0;
var note = new Note(randomLane, isRedMode);
note.x = padPositions[randomLane];
note.y = -50;
notes.push(note);
gameContainer.addChild(note);
}
function checkNoteHit(lane) {
var hitNote = null;
var bestDistance = Infinity;
// Find the closest note in the perfect zone for this lane
for (var i = 0; i < notes.length; i++) {
var note = notes[i];
if (note.lane === lane && !note.hasBeenHit) {
var distance = Math.abs(note.y - perfectZoneY);
if (distance < perfectTolerance && distance < bestDistance) {
hitNote = note;
bestDistance = distance;
}
}
}
if (hitNote) {
// Perfect hit
hitNote.hasBeenHit = true;
gameScore += 5;
gameCombo += 1;
// Create explosion effect
createExplosionEffect(hitNote.x, hitNote.y);
// Change background color effect
var colors = [0xff6b6b, 0x4ecdc4, 0x45b7d1, 0x96ceb4, 0xfeca57, 0xff9ff3, 0x54a0ff];
var randomColor = colors[Math.floor(Math.random() * colors.length)];
game.setBackgroundColor(randomColor);
// Visual effect
tween(hitNote, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 200,
onFinish: function onFinish() {
removeNote(hitNote);
}
});
LK.getSound('success').play();
updateUI();
} else {
// Wrong timing
gameScore -= 5;
gameCombo = 0;
LK.effects.flashScreen(0xff0000, 200);
updateUI();
}
}
function createExplosionEffect(x, y) {
// Create multiple explosion particles
for (var i = 0; i < 8; i++) {
var particle = LK.getAsset('note', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3
});
particle.x = x;
particle.y = y;
particle.tint = 0xFFFF00; // Yellow explosion color
gameContainer.addChild(particle);
// Random direction for each particle
var angle = i / 8 * Math.PI * 2;
var speed = 100 + Math.random() * 50;
var targetX = x + Math.cos(angle) * speed;
var targetY = y + Math.sin(angle) * speed;
// Animate particle outward and fade
tween(particle, {
x: targetX,
y: targetY,
alpha: 0,
scaleX: 0.1,
scaleY: 0.1
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
gameContainer.removeChild(particle);
}
});
}
}
function showComboEffect(x, y) {
var comboEffect = new Text2('COMBO!', {
size: 80,
fill: 0xFFFF00
});
comboEffect.anchor.set(0.5, 0.5);
comboEffect.x = x;
comboEffect.y = y;
gameContainer.addChild(comboEffect);
tween(comboEffect, {
y: y - 100,
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
gameContainer.removeChild(comboEffect);
}
});
}
function removeNote(note) {
var index = notes.indexOf(note);
if (index > -1) {
notes.splice(index, 1);
gameContainer.removeChild(note);
}
}
function updateUI() {
scoreText.setText(gameScore);
comboText.setText('Combo: ' + gameCombo);
LK.setScore(gameScore);
// Update high score if current score is higher
var highScoreKey = 'highScore_' + selectedDifficulty;
var currentHighScore = storage[highScoreKey] || 0;
if (gameScore > currentHighScore) {
storage[highScoreKey] = gameScore;
}
highScoreText.setText('Best (' + selectedDifficulty.toUpperCase() + '): ' + (storage[highScoreKey] || 0));
// Check for game over at -50 points
if (gameScore <= -50) {
LK.showGameOver();
}
}
// Add pause menu functionality
var pauseMenu = new Container();
var pauseTitle = new Text2('Game Paused', {
size: 70,
fill: 0xFFFFFF
});
pauseTitle.anchor.set(0.5, 0.5);
pauseTitle.x = 1024;
pauseTitle.y = 1000;
pauseMenu.addChild(pauseTitle);
var resumeButton = new MenuButton('RESUME', function () {
pauseMenu.visible = false;
});
resumeButton.x = 1024;
resumeButton.y = 1200;
pauseMenu.addChild(resumeButton);
var mainMenuButton = new MenuButton('MAIN MENU', function () {
// Stop game music and start menu music
LK.stopMusic();
LK.playMusic('menumusic', {
loop: true
});
gameState = 'menu';
pauseMenu.visible = false;
gameContainer.visible = false;
scoreText.visible = false;
comboText.visible = false;
highScoreText.visible = false;
// Clear all notes
for (var i = notes.length - 1; i >= 0; i--) {
removeNote(notes[i]);
}
// Reset game variables
gameScore = 0;
gameCombo = 0;
spawnTimer = 0;
noteCounter = 0; // Reset note counter for red mode
updateUI();
// Show main menu
showMainMenu();
});
mainMenuButton.x = 1024;
mainMenuButton.y = 1350;
pauseMenu.addChild(mainMenuButton);
game.addChild(pauseMenu);
pauseMenu.visible = false;
game.update = function () {
if (gameState !== 'playing') {
return;
}
// Spawn notes
spawnTimer++;
if (spawnTimer >= spawnInterval) {
spawnNote();
spawnTimer = 0;
}
// Update and check notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
// Check if note reached bottom (missed)
if (note.y > 2800 && !note.hasBeenHit) {
if (note.isRedMode) {
gameScore -= 20; // Red notes penalty is -20 points
} else {
gameScore -= 5; // Normal notes penalty is -5 points
}
gameCombo = 0;
// Combo system reset on miss
combo = 0;
comboDisplayText.setText("Miss!");
comboDisplayText.visible = true;
LK.setTimeout(function () {
comboDisplayText.visible = false;
}, 500);
LK.getSound('fail').play();
updateUI();
removeNote(note);
}
}
};