User prompt
Can we make it infinite and have different speeds so 0.5x 1x and 2x
User prompt
Get rid of the color thing make it so you don’t need to change color
User prompt
Can we make it so we tap on one of the rectangles where the circles come down and you move to that one
User prompt
I don’t see any buttons so plz fix
Code edit (1 edits merged)
Please save this source code
User prompt
Cat Rhythm Color Dash
Initial prompt
A 2D rhythm game with cats featuring color matching. Also add 4 buttons for forward backward left right with arrows as an icon and you use those for movement. Also make sure that the buttons are visible.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Arrow Button class var ArrowButton = Container.expand(function () { var self = Container.call(this); self.direction = 'left'; // 'left', 'right', 'up', 'down' self.arrowAsset = null; self.setDirection = function (dir) { self.direction = dir; if (self.arrowAsset) { self.removeChild(self.arrowAsset); } var assetId = 'arrow_' + dir; self.arrowAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Add a simple arrow "icon" using Text2 var arrowChar = { 'left': '←', 'right': '→', 'up': '↑', 'down': '↓' }[dir]; if (self.arrowText) { self.removeChild(self.arrowText); } self.arrowText = new Text2(arrowChar, { size: 120, fill: 0x222222 }); self.arrowText.anchor.set(0.5, 0.5); self.addChild(self.arrowText); }; return self; }); // Cat class var Cat = Container.expand(function () { var self = Container.call(this); self.lane = 1; // start in lane 1 (from 0-3) self.color = 'yellow'; self.catAsset = self.attachAsset('cat', { anchorX: 0.5, anchorY: 0.5 }); self.setLane = function (lane) { self.lane = lane; self.x = laneCenters[lane]; }; self.setColor = function (color) { self.color = color; // Tint the cat to match color var tintMap = { 'red': 0xff4b4b, 'blue': 0x4b7bff, 'green': 0x4bff7b, 'yellow': 0xffe066 }; self.catAsset.tint = tintMap[color]; }; return self; }); // Note class var Note = Container.expand(function () { var self = Container.call(this); self.color = 'red'; // default, will be set on spawn self.lane = 0; // 0-3 self.hit = false; self.setColor = function (color) { self.color = color; if (self.noteAsset) { self.removeChild(self.noteAsset); } var assetId = 'note_' + color; self.noteAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; self.update = function () { self.y += noteSpeed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // Lane setup // Cat character: cute box, default color yellow // Note shapes: four colors // Lane backgrounds (for visual feedback) // Arrow buttons // Sound effects // Music (looping, for rhythm) var laneCount = 4; var laneWidth = 400; var laneSpacing = 32; var laneColors = ['red', 'blue', 'green', 'yellow']; var laneCenters = []; var laneLeft = (2048 - (laneCount * laneWidth + (laneCount - 1) * laneSpacing)) / 2; for (var i = 0; i < laneCount; i++) { laneCenters[i] = laneLeft + i * (laneWidth + laneSpacing) + laneWidth / 2; } // Lane backgrounds var laneBGs = []; for (var i = 0; i < laneCount; i++) { var assetId = 'lane_' + laneColors[i]; var laneBG = LK.getAsset(assetId, { anchorX: 0.5, anchorY: 0, x: laneCenters[i], y: 0, width: laneWidth, height: 2732 }); laneBG.interactive = true; laneBG.buttonMode = true; laneBG.laneIndex = i; laneBG.down = function (x, y, obj) { // Move cat to this lane if not already there if (cat.lane !== this.laneIndex) { cat.setLane(this.laneIndex); } }; game.addChild(laneBG); laneBGs.push(laneBG); } // Cat setup var cat = new Cat(); cat.setLane(1); cat.setColor('yellow'); cat.y = 2732 - 350; game.addChild(cat); // Arrow buttons (bottom of screen, left/right/up/down) var arrowButtons = []; var arrowButtonSize = 180; var arrowButtonY = 2732 - 120; var arrowButtonSpacing = 220; var arrowButtonXStart = 2048 / 2 - arrowButtonSpacing * 1.5; var arrowDirs = ['left', 'right', 'up', 'down']; for (var i = 0; i < 4; i++) { var btn = new ArrowButton(); btn.setDirection(arrowDirs[i]); btn.x = arrowButtonXStart + i * arrowButtonSpacing; btn.y = arrowButtonY; btn.direction = arrowDirs[i]; btn.interactive = true; btn.buttonMode = true; game.addChild(btn); // Place arrow buttons in the main game area so they are always visible arrowButtons.push(btn); } // Color change buttons (above arrow buttons) var colorButtons = []; var colorNames = ['red', 'blue', 'green', 'yellow']; var colorButtonY = arrowButtonY - 220; var colorButtonSpacing = 220; var colorButtonXStart = 2048 / 2 - colorButtonSpacing * 1.5; for (var i = 0; i < 4; i++) { var colorBtn = LK.getAsset('note_' + colorNames[i], { anchorX: 0.5, anchorY: 0.5, x: colorButtonXStart + i * colorButtonSpacing, y: colorButtonY, width: 140, height: 140 }); colorBtn.interactive = true; colorBtn.buttonMode = true; colorBtn.color = colorNames[i]; game.addChild(colorBtn); // Place color buttons in the main game area so they are always visible colorButtons.push(colorBtn); } // Score display var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Combo display var comboTxt = new Text2('', { size: 80, fill: 0xFFE066 }); comboTxt.anchor.set(0.5, 0); comboTxt.y = 130; LK.gui.top.addChild(comboTxt); // Notes array var notes = []; var noteSpeed = 18; // px per frame var noteSpawnInterval = 36; // frames between notes (60fps ~ 0.6s) var noteTimer = 0; var noteColors = ['red', 'blue', 'green', 'yellow']; // Rhythm pattern (random for now, can be improved) function spawnNote() { var lane = Math.floor(Math.random() * 4); var color = noteColors[Math.floor(Math.random() * 4)]; var note = new Note(); note.setColor(color); note.lane = lane; note.x = laneCenters[lane]; note.y = -100; notes.push(note); game.addChild(note); } // Hit window (distance from cat.y to note.y for a "hit") var hitWindow = 120; // Score/combo var score = 0; var combo = 0; var maxCombo = 0; // Input handling function handleArrowButton(dir) { var newLane = cat.lane; if (dir === 'left') { newLane = Math.max(0, cat.lane - 1); } else if (dir === 'right') { newLane = Math.min(laneCount - 1, cat.lane + 1); } else if (dir === 'up') { // No vertical movement, but can add jump effect tween(cat, { y: cat.y - 60 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(cat, { y: 2732 - 350 }, { duration: 120, easing: tween.easeIn }); } }); return; } else if (dir === 'down') { // No vertical movement, but can add crouch effect tween(cat, { y: cat.y + 40 }, { duration: 80, easing: tween.easeOut, onFinish: function onFinish() { tween(cat, { y: 2732 - 350 }, { duration: 120, easing: tween.easeIn }); } }); return; } if (newLane !== cat.lane) { cat.setLane(newLane); } } function handleColorButton(color) { cat.setColor(color); } // Attach input events to arrow buttons for (var i = 0; i < arrowButtons.length; i++) { (function (btn) { btn.down = function (x, y, obj) { handleArrowButton(btn.direction); }; })(arrowButtons[i]); } // Attach input events to color buttons for (var i = 0; i < colorButtons.length; i++) { (function (btn) { btn.down = function (x, y, obj) { handleColorButton(btn.color); }; })(colorButtons[i]); } // Touch input: allow swipe left/right to move cat, tap on color buttons to change color var touchStartX = null; var touchStartY = null; game.down = function (x, y, obj) { touchStartX = x; touchStartY = y; }; game.up = function (x, y, obj) { if (touchStartX !== null && Math.abs(x - touchStartX) > 80 && Math.abs(x - touchStartX) > Math.abs(y - touchStartY)) { // Horizontal swipe if (x < touchStartX) { handleArrowButton('left'); } else { handleArrowButton('right'); } } touchStartX = null; touchStartY = null; }; // Main update loop game.update = function () { // Spawn notes if (LK.ticks % noteSpawnInterval === 0) { spawnNote(); } // Update notes for (var i = notes.length - 1; i >= 0; i--) { var note = notes[i]; note.update(); // Check for hit if (!note.hit && Math.abs(note.y - cat.y) < hitWindow && note.lane === cat.lane) { if (note.color === cat.color) { // Hit! note.hit = true; score += 1; combo += 1; if (combo > maxCombo) maxCombo = combo; scoreTxt.setText(score); comboTxt.setText(combo > 1 ? combo + ' combo!' : ''); LK.getSound('note_hit').play(); LK.effects.flashObject(cat, 0xffffff, 120); // Animate note tween(note, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 180, onFinish: function onFinish() { note.destroy(); } }); notes.splice(i, 1); continue; } } // Missed note (passed cat) if (!note.hit && note.y > cat.y + hitWindow) { note.hit = true; combo = 0; comboTxt.setText(''); LK.getSound('note_miss').play(); LK.effects.flashScreen(0xff4b4b, 200); // Animate note tween(note, { alpha: 0 }, { duration: 120, onFinish: function onFinish() { note.destroy(); } }); notes.splice(i, 1); continue; } // Remove notes off screen if (note.y > 2732 + 200) { note.destroy(); notes.splice(i, 1); } } // Win condition: score 30 if (score >= 30) { LK.showYouWin(); } }; // Start music LK.playMusic('bgmusic', { fade: { start: 0, end: 0.7, duration: 1200 } });
===================================================================
--- original.js
+++ change.js
@@ -126,8 +126,17 @@
y: 0,
width: laneWidth,
height: 2732
});
+ laneBG.interactive = true;
+ laneBG.buttonMode = true;
+ laneBG.laneIndex = i;
+ laneBG.down = function (x, y, obj) {
+ // Move cat to this lane if not already there
+ if (cat.lane !== this.laneIndex) {
+ cat.setLane(this.laneIndex);
+ }
+ };
game.addChild(laneBG);
laneBGs.push(laneBG);
}
// Cat setup