User prompt
Add the opening screen asset as the background without affecting the opening screen elements
User prompt
Remove the background of opening screen first, without affecting game title, language selector and play button
User prompt
Move up the opening screen to the middle
User prompt
The asset still found to be at the corner,make sure it's full fit the screen covering game title, language and play button without affect the visibility of the elements
User prompt
The asset opening screen is found at the corner of the game screen, adjust the asset to be fully fit to the screen
User prompt
Move down the game title within the visible area without affecting the language selector, as the game title is too upside
User prompt
The opening screen is found at the corner of the screen
User prompt
All of the elements are found at the corner of the screen, adjust this error
User prompt
Add opening screen asset, and make sure the game title, language selector and play button are within the opening screen
User prompt
The game title is outside from the game screen
User prompt
What is the size of the screen? Adjust xy of the title, language selector and start button according to the size of the screen
User prompt
Still cannot see all of the setup
User prompt
The game title, language selector and play button suddenly disappear
User prompt
Move the game title, language selector and play button to the middle of the screen
User prompt
All of the screen is empty, fix this problems, make sure including four main screens such as opening screen, homepage, storyline and gameplay mode, and all of the elements are within the mobile screen
User prompt
All of the things out from the screen
User prompt
Make it fits the mobile screen
User prompt
Add opening screen asset with the title Kaleidoscope of Music Rhythm, language selector and start button, instead of empty screen
User prompt
Replace Japanese selector with Chinese selector (中文)
Code edit (1 edits merged)
Please save this source code
User prompt
Kaleidoscope of Music Rhythm
Initial prompt
The music rhythm game has four main screens, that is opening screen, homepage for song selector, story of song introduction and gameplay mode, the music rhythm game title is Kaleidoscope of Music Rhythm. For the opening screen, including language selector and start button, then homepage is appeared as song selection, the songs are Sky Journey, Night Pulse and Sunrise Waltz, other songs can be added from time to time, then appearing story of song introduction after a song is selected, and there is difficulty selection like easy, medium and hard for storybox, then appearing gameplay mode that consists of tap note, hold note and swipe note
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { language: "en" }); /**** * Classes ****/ // Note types: 'tap', 'hold', 'swipe' var Note = Container.expand(function () { var self = Container.call(this); self.type = 'tap'; // tap, hold, swipe self.lane = 0; // 0-3 self.time = 0; // ms, when the note should be hit self.duration = 0; // for hold notes, ms self.hit = false; self.active = true; self.swipeDir = null; // 'left', 'right', 'up', 'down' for swipe notes // Visuals self.noteAsset = null; self.trailAsset = null; self.init = function (type, lane, time, duration, swipeDir) { self.type = type; self.lane = lane; self.time = time; self.duration = duration || 0; self.swipeDir = swipeDir || null; self.hit = false; self.active = true; if (self.noteAsset) self.removeChild(self.noteAsset); if (self.trailAsset) self.removeChild(self.trailAsset); if (type === 'tap') { self.noteAsset = self.attachAsset('tapNote', { anchorX: 0.5, anchorY: 0.5 }); } else if (type === 'hold') { self.trailAsset = self.attachAsset('noteTrail', { anchorX: 0.5, anchorY: 1 }); self.noteAsset = self.attachAsset('holdNote', { anchorX: 0.5, anchorY: 0.5 }); } else if (type === 'swipe') { self.noteAsset = self.attachAsset('swipeNote', { anchorX: 0.5, anchorY: 0.5 }); } }; self.setTrailLength = function (len) { if (self.trailAsset) { self.trailAsset.height = len; } }; self.flash = function () { if (self.noteAsset) { tween(self.noteAsset, { alpha: 0.2 }, { duration: 80, onFinish: function onFinish() { tween(self.noteAsset, { alpha: 1 }, { duration: 80 }); } }); } }; self.update = function () { // Position is handled by main game loop }; return self; }); // Song selection card var SongCard = Container.expand(function () { var self = Container.call(this); self.songId = ''; self.title = ''; self.cover = null; self.text = null; self.init = function (songId, title, colorAsset) { self.songId = songId; self.title = title; if (self.cover) self.removeChild(self.cover); if (self.text) self.removeChild(self.text); self.cover = self.attachAsset(colorAsset, { anchorX: 0.5, anchorY: 0.5 }); self.text = new Text2(title, { size: 60, fill: "#fff" }); self.text.anchor.set(0.5, 0); self.text.y = 220; self.addChild(self.text); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c20 }); /**** * Game Code ****/ // --- GLOBALS --- // Note: Assets are auto-initialized by LK based on usage below. // We'll use shapes for notes, and images for backgrounds and song covers as needed. // Example note assets: // Sounds and music (placeholders, actual music not implemented here) var GAME_STATE = 'LANGUAGE'; // LANGUAGE, HOME, STORY, DIFFICULTY, PLAY, RESULT var selectedLanguage = storage.language || 'en'; var selectedSong = null; var selectedDifficulty = null; var currentSongData = null; var currentNotes = []; var noteIndex = 0; var startTime = 0; var score = 0; var combo = 0; var maxCombo = 0; var accuracy = 0; var totalNotes = 0; var hitNotes = 0; var missNotes = 0; var holdActive = null; var swipeStart = null; var swipeNote = null; var isPlaying = false; var resultTimeout = null; // Lanes: 4 lanes, evenly spaced var LANE_COUNT = 4; var LANE_WIDTH = 400; var LANE_MARGIN = 40; var LANE_START_X = (2048 - (LANE_COUNT * LANE_WIDTH + (LANE_COUNT - 1) * LANE_MARGIN)) / 2; var HIT_LINE_Y = 2200; // Where notes should be hit // --- SONG DATA (MVP: 3 songs, 3 difficulties, simple patterns) --- var SONGS = [{ id: 'sky_journey', title: 'Sky Journey', cover: 'songCover1', story: { en: "You soar above the clouds, chasing the horizon. The sky is endless, and your journey has just begun.", zh: "你在云端翱翔,追逐地平线。天空无垠,你的旅程才刚刚开始。" }, difficulties: ['Easy', 'Medium', 'Hard'], notes: { Easy: [ // [type, lane, time(ms), duration(ms), swipeDir] ['tap', 0, 1000], ['tap', 1, 1800], ['tap', 2, 2600], ['tap', 3, 3400], ['hold', 1, 4200, 1200], ['tap', 0, 6000], ['swipe', 2, 7000, 0, 'right'], ['tap', 3, 8000]], Medium: [['tap', 0, 800], ['tap', 1, 1400], ['tap', 2, 2000], ['tap', 3, 2600], ['hold', 0, 3200, 1000], ['tap', 1, 4400], ['swipe', 2, 5200, 0, 'left'], ['tap', 3, 6000], ['tap', 2, 6600], ['hold', 1, 7200, 1200], ['tap', 0, 9000]], Hard: [['tap', 0, 600], ['tap', 1, 1000], ['tap', 2, 1400], ['tap', 3, 1800], ['hold', 0, 2200, 1000], ['tap', 1, 3400], ['swipe', 2, 3800, 0, 'up'], ['tap', 3, 4200], ['tap', 2, 4600], ['hold', 1, 5000, 1200], ['tap', 0, 6400], ['swipe', 3, 7000, 0, 'down'], ['tap', 1, 7600], ['tap', 2, 8200], ['tap', 3, 8800]] } }, { id: 'night_pulse', title: 'Night Pulse', cover: 'songCover2', story: { en: "The city lights flicker in rhythm with your heartbeat. Tonight, the music guides your every move.", zh: "城市的灯光随着你的心跳闪烁。今夜,音乐引领你的每一步。" }, difficulties: ['Easy', 'Medium', 'Hard'], notes: { Easy: [['tap', 2, 1000], ['tap', 1, 1800], ['hold', 0, 2600, 1000], ['tap', 3, 4000], ['swipe', 2, 5000, 0, 'left'], ['tap', 1, 6000]], Medium: [['tap', 2, 800], ['tap', 1, 1400], ['hold', 0, 2000, 1000], ['tap', 3, 3200], ['swipe', 2, 4000, 0, 'right'], ['tap', 1, 4800], ['tap', 0, 5400], ['hold', 3, 6000, 1200]], Hard: [['tap', 2, 600], ['tap', 1, 1000], ['hold', 0, 1400, 1000], ['tap', 3, 2600], ['swipe', 2, 3200, 0, 'up'], ['tap', 1, 3800], ['tap', 0, 4200], ['hold', 3, 4600, 1200], ['tap', 2, 6000], ['swipe', 1, 6600, 0, 'down']] } }, { id: 'sunrise_waltz', title: 'Sunrise Waltz', cover: 'songCover3', story: { en: "As dawn breaks, melodies dance in the golden light. Every note is a step in your waltz with the sun.", zh: "黎明破晓,旋律在金色的光芒中舞动。每一个音符都是你与太阳华尔兹的步伐。" }, difficulties: ['Easy', 'Medium', 'Hard'], notes: { Easy: [['tap', 1, 1000], ['tap', 2, 1800], ['hold', 3, 2600, 1000], ['tap', 0, 4000], ['swipe', 1, 5000, 0, 'up'], ['tap', 2, 6000]], Medium: [['tap', 1, 800], ['tap', 2, 1400], ['hold', 3, 2000, 1000], ['tap', 0, 3200], ['swipe', 1, 4000, 0, 'down'], ['tap', 2, 4800], ['tap', 3, 5400], ['hold', 0, 6000, 1200]], Hard: [['tap', 1, 600], ['tap', 2, 1000], ['hold', 3, 1400, 1000], ['tap', 0, 2600], ['swipe', 1, 3200, 0, 'left'], ['tap', 2, 3800], ['tap', 3, 4200], ['hold', 0, 4600, 1200], ['tap', 1, 6000], ['swipe', 2, 6600, 0, 'right']] } }]; // --- GUI ELEMENTS --- var gui = LK.gui; var languageButtons = []; var startButton = null; var songCards = []; var storyText = null; var continueButton = null; var difficultyButtons = []; var scoreText = null; var comboText = null; var accuracyText = null; var resultText = null; var homeButton = null; // --- GAME ELEMENTS --- var lanes = []; var laneDividers = []; var hitLine = null; // --- UTILS --- function clearGUI() { // Remove all children from gui overlays gui.top.removeChildren(); gui.topRight.removeChildren(); gui.topLeft.removeChildren(); gui.left.removeChildren(); gui.right.removeChildren(); gui.bottom.removeChildren(); gui.bottomLeft.removeChildren(); gui.bottomRight.removeChildren(); gui.center.removeChildren(); } function clearGameObjects() { // Remove all notes, lanes, etc. for (var i = 0; i < lanes.length; ++i) { if (lanes[i].parent) lanes[i].parent.removeChild(lanes[i]); } for (var i = 0; i < laneDividers.length; ++i) { if (laneDividers[i].parent) laneDividers[i].parent.removeChild(laneDividers[i]); } if (hitLine && hitLine.parent) hitLine.parent.removeChild(hitLine); for (var i = 0; i < currentNotes.length; ++i) { if (currentNotes[i].parent) currentNotes[i].parent.removeChild(currentNotes[i]); } currentNotes = []; } function setGameState(state) { GAME_STATE = state; clearGUI(); clearGameObjects(); if (state === 'LANGUAGE') { showLanguageSelector(); } else if (state === 'HOME') { showHome(); } else if (state === 'STORY') { showStory(); } else if (state === 'DIFFICULTY') { showDifficulty(); } else if (state === 'PLAY') { startGameplay(); } else if (state === 'RESULT') { showResult(); } } // --- LANGUAGE SELECTOR --- function showLanguageSelector() { languageButtons = []; // Title var titleText = new Text2("Kaleidoscope of Music Rhythm", { size: 80, // smaller for mobile fill: "#fff" }); titleText.anchor.set(0.5, 0.5); titleText.x = 2048 / 2; titleText.y = 2732 / 2 - 300; gui.center.addChild(titleText); // Language selector var langs = [{ code: 'en', label: 'English' }, { code: 'zh', label: '中文' }]; var langBtnYStart = 2732 / 2 - 80; var langBtnSpacing = 160; for (var i = 0; i < langs.length; ++i) { (function (idx) { var btn = new Text2(langs[idx].label, { size: 64, // smaller for mobile fill: "#fff" }); btn.anchor.set(0.5, 0.5); btn.x = 2048 / 2; btn.y = langBtnYStart + idx * langBtnSpacing; btn.interactive = true; btn.down = function (x, y, obj) { selectedLanguage = langs[idx].code; storage.language = selectedLanguage; // Do not advance to HOME yet, just set language clearGUI(); showLanguageSelector(); }; gui.center.addChild(btn); languageButtons.push(btn); })(i); } // Start button startButton = new Text2(selectedLanguage === 'zh' ? "开始" : "Start", { size: 90, // smaller for mobile fill: "#fff" }); startButton.anchor.set(0.5, 0.5); startButton.x = 2048 / 2; startButton.y = 2732 / 2 + 300; startButton.interactive = true; startButton.down = function (x, y, obj) { setGameState('HOME'); }; gui.center.addChild(startButton); } // --- HOME / SONG SELECTION --- function showHome() { songCards = []; var title = new Text2(selectedLanguage === 'zh' ? "选择歌曲" : "Select a Song", { size: 100, fill: "#fff" }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = 100; gui.top.addChild(title); for (var i = 0; i < SONGS.length; ++i) { (function (idx) { var card = new SongCard(); card.init(SONGS[idx].id, SONGS[idx].title, SONGS[idx].cover); card.x = 600 + idx * 450; card.y = 800; card.interactive = true; card.down = function (x, y, obj) { selectedSong = SONGS[idx]; setGameState('STORY'); }; gui.center.addChild(card); songCards.push(card); })(i); } } // --- STORY INTRO --- function showStory() { var story = selectedSong.story[selectedLanguage] || selectedSong.story['en']; storyText = new Text2(story, { size: 70, fill: "#fff", wordWrap: true, wordWrapWidth: 1600 }); storyText.anchor.set(0.5, 0.5); storyText.x = 2048 / 2; storyText.y = 1000; gui.center.addChild(storyText); continueButton = new Text2(selectedLanguage === 'zh' ? "继续" : "Continue", { size: 100, fill: "#fff" }); continueButton.anchor.set(0.5, 0.5); continueButton.x = 2048 / 2; continueButton.y = 1800; continueButton.interactive = true; continueButton.down = function (x, y, obj) { setGameState('DIFFICULTY'); }; gui.center.addChild(continueButton); } // --- DIFFICULTY SELECT --- function showDifficulty() { difficultyButtons = []; var title = new Text2(selectedLanguage === 'zh' ? "选择难度" : "Select Difficulty", { size: 100, fill: "#fff" }); title.anchor.set(0.5, 0); title.x = 2048 / 2; title.y = 100; gui.top.addChild(title); for (var i = 0; i < selectedSong.difficulties.length; ++i) { (function (idx) { var label = selectedSong.difficulties[idx]; var btn = new Text2(label, { size: 90, fill: "#fff" }); btn.anchor.set(0.5, 0.5); btn.x = 2048 / 2; btn.y = 900 + idx * 200; btn.interactive = true; btn.down = function (x, y, obj) { selectedDifficulty = label; setGameState('PLAY'); }; gui.center.addChild(btn); difficultyButtons.push(btn); })(i); } } // --- GAMEPLAY --- function startGameplay() { // Setup lanes lanes = []; laneDividers = []; for (var i = 0; i < LANE_COUNT; ++i) { var lane = LK.getAsset('lane', { anchorX: 0, anchorY: 0 }); lane.x = LANE_START_X + i * (LANE_WIDTH + LANE_MARGIN); lane.y = 0; lanes.push(lane); game.addChild(lane); if (i > 0) { var divider = LK.getAsset('laneDivider', { anchorX: 0, anchorY: 0 }); divider.x = LANE_START_X + i * (LANE_WIDTH + LANE_MARGIN) - LANE_MARGIN / 2 - 10; divider.y = 0; laneDividers.push(divider); game.addChild(divider); } } // Hit line hitLine = LK.getAsset('laneDivider', { anchorX: 0, anchorY: 0 }); hitLine.width = 2048; hitLine.height = 16; hitLine.x = 0; hitLine.y = HIT_LINE_Y; game.addChild(hitLine); // Load notes currentSongData = selectedSong.notes[selectedDifficulty]; currentNotes = []; noteIndex = 0; score = 0; combo = 0; maxCombo = 0; accuracy = 0; totalNotes = currentSongData.length; hitNotes = 0; missNotes = 0; holdActive = null; swipeStart = null; swipeNote = null; isPlaying = true; for (var i = 0; i < currentSongData.length; ++i) { var n = currentSongData[i]; var note = new Note(); note.init(n[0], n[1], n[2], n[3], n[4]); // Initial position: y far above screen, will be updated in update loop note.x = LANE_START_X + n[1] * (LANE_WIDTH + LANE_MARGIN) + LANE_WIDTH / 2; note.y = -200; currentNotes.push(note); game.addChild(note); } // Score/Combo/Accuracy GUI scoreText = new Text2("Score: 0", { size: 80, fill: "#fff" }); scoreText.anchor.set(0, 0); gui.topRight.addChild(scoreText); comboText = new Text2("Combo: 0", { size: 80, fill: "#fff" }); comboText.anchor.set(0, 0); gui.topRight.addChild(comboText); accuracyText = new Text2("Accuracy: 100%", { size: 80, fill: "#fff" }); accuracyText.anchor.set(0, 0); gui.topRight.addChild(accuracyText); // Start music LK.playMusic(selectedSong.id); // Start timer startTime = Date.now(); } // --- GAMEPLAY LOGIC --- function getCurrentTime() { return Date.now() - startTime; } function getNoteY(noteTime) { // Notes fall from y = -200 to HIT_LINE_Y at the time they should be hit // We'll use a fixed speed so that notes reach HIT_LINE_Y at noteTime var speed = (HIT_LINE_Y + 200) / 2000; // 2 seconds to fall var t = getCurrentTime(); var dt = noteTime - t; return HIT_LINE_Y - dt * speed; } function getHoldTrailLength(note, t) { // For hold notes, trail from note head to end time var endTime = note.time + note.duration; var y1 = getNoteY(note.time); var y2 = getNoteY(endTime); return Math.max(0, y2 - y1); } function judgeNote(note, lane, y, eventType, swipeDir) { if (!note.active || note.hit) return false; var noteY = getNoteY(note.time); var hitWindow = 120; // ms var t = getCurrentTime(); var dt = Math.abs(note.time - t); if (note.type === 'tap') { if (lane === note.lane && Math.abs(y - HIT_LINE_Y) < 180 && dt < hitWindow) { note.hit = true; note.active = false; note.flash(); LK.getSound('tap').play(); score += 100; combo += 1; hitNotes += 1; maxCombo = Math.max(combo, maxCombo); return true; } } else if (note.type === 'hold') { if (eventType === 'down' && lane === note.lane && Math.abs(y - HIT_LINE_Y) < 180 && dt < hitWindow) { holdActive = { note: note, start: t }; note.flash(); LK.getSound('hold').play(); return true; } } else if (note.type === 'swipe') { if (eventType === 'swipe' && lane === note.lane && Math.abs(y - HIT_LINE_Y) < 180 && dt < hitWindow && swipeDir === note.swipeDir) { note.hit = true; note.active = false; note.flash(); LK.getSound('swipe').play(); score += 150; combo += 1; hitNotes += 1; maxCombo = Math.max(combo, maxCombo); return true; } } return false; } function endHold() { if (holdActive && holdActive.note && !holdActive.note.hit) { var t = getCurrentTime(); var note = holdActive.note; var holdEnd = note.time + note.duration; if (t >= holdEnd - 150) { note.hit = true; note.active = false; score += 200; combo += 1; hitNotes += 1; maxCombo = Math.max(combo, maxCombo); } else { combo = 0; missNotes += 1; } holdActive = null; } } // --- INPUT HANDLING --- var dragLane = null; var dragY = null; var dragNote = null; var dragStartX = null; var dragStartY = null; var dragStartTime = null; function getLaneFromX(x) { for (var i = 0; i < LANE_COUNT; ++i) { var lx = LANE_START_X + i * (LANE_WIDTH + LANE_MARGIN); if (x >= lx && x < lx + LANE_WIDTH) return i; } return -1; } function handleGameDown(x, y, obj) { if (GAME_STATE !== 'PLAY' || !isPlaying) return; var lane = getLaneFromX(x); if (lane === -1) return; dragLane = lane; dragY = y; dragStartX = x; dragStartY = y; dragStartTime = Date.now(); // Check for tap/hold notes for (var i = 0; i < currentNotes.length; ++i) { var note = currentNotes[i]; if (!note.active || note.hit) continue; if (note.type === 'tap' || note.type === 'hold') { if (judgeNote(note, lane, y, 'down')) { if (note.type === 'tap') { note.hit = true; note.active = false; } if (note.type === 'hold') { dragNote = note; } break; } } } } function handleGameUp(x, y, obj) { if (GAME_STATE !== 'PLAY' || !isPlaying) return; if (holdActive) { endHold(); } dragLane = null; dragNote = null; dragStartX = null; dragStartY = null; dragStartTime = null; } function handleGameMove(x, y, obj) { if (GAME_STATE !== 'PLAY' || !isPlaying) return; // For hold notes, check if finger is still on lane if (holdActive && dragNote) { var lane = getLaneFromX(x); if (lane !== dragNote.lane || Math.abs(y - HIT_LINE_Y) > 300) { // Released too early combo = 0; missNotes += 1; holdActive = null; dragNote = null; } } } function handleGameSwipe(x, y, obj) { if (GAME_STATE !== 'PLAY' || !isPlaying) return; if (dragStartX === null || dragStartY === null) return; var dx = x - dragStartX; var dy = y - dragStartY; var absDx = Math.abs(dx); var absDy = Math.abs(dy); if (absDx < 80 && absDy < 80) return; // Not enough movement var dir = null; if (absDx > absDy) { dir = dx > 0 ? 'right' : 'left'; } else { dir = dy > 0 ? 'down' : 'up'; } var lane = getLaneFromX(dragStartX); for (var i = 0; i < currentNotes.length; ++i) { var note = currentNotes[i]; if (!note.active || note.hit) continue; if (note.type === 'swipe') { if (judgeNote(note, lane, dragStartY, 'swipe', dir)) { break; } } } dragStartX = null; dragStartY = null; } // Attach input handlers game.down = function (x, y, obj) { handleGameDown(x, y, obj); }; game.up = function (x, y, obj) { handleGameUp(x, y, obj); }; game.move = function (x, y, obj) { handleGameMove(x, y, obj); // Detect swipe if (dragStartX !== null && dragStartY !== null) { var dx = x - dragStartX; var dy = y - dragStartY; if (Math.abs(dx) > 120 || Math.abs(dy) > 120) { handleGameSwipe(x, y, obj); } } }; // --- GAME UPDATE LOOP --- game.update = function () { if (GAME_STATE !== 'PLAY' || !isPlaying) return; var t = getCurrentTime(); // Update notes for (var i = 0; i < currentNotes.length; ++i) { var note = currentNotes[i]; if (!note.active) continue; // Update position note.x = LANE_START_X + note.lane * (LANE_WIDTH + LANE_MARGIN) + LANE_WIDTH / 2; note.y = getNoteY(note.time); // For hold notes, update trail if (note.type === 'hold' && note.trailAsset) { var len = getHoldTrailLength(note, t); note.setTrailLength(len); note.trailAsset.x = 0; note.trailAsset.y = 0; } // Missed note if (!note.hit && t - note.time > 200 && note.type !== 'hold') { note.active = false; combo = 0; missNotes += 1; } // For hold notes, if not held until end if (note.type === 'hold' && !note.hit && t - (note.time + note.duration) > 200) { note.active = false; combo = 0; missNotes += 1; } } // Remove notes that are far below screen for (var i = currentNotes.length - 1; i >= 0; --i) { var note = currentNotes[i]; if (note.y > 3000 || !note.active && note.y > HIT_LINE_Y + 400) { if (note.parent) note.parent.removeChild(note); currentNotes.splice(i, 1); } } // Update GUI scoreText.setText("Score: " + score); comboText.setText("Combo: " + combo); var acc = totalNotes > 0 ? Math.floor(100 * hitNotes / totalNotes) : 100; accuracyText.setText("Accuracy: " + acc + "%"); // End of song if (t > getSongEndTime() + 1000 && isPlaying) { isPlaying = false; LK.stopMusic(); resultTimeout = LK.setTimeout(function () { setGameState('RESULT'); }, 1200); } }; function getSongEndTime() { var last = currentSongData[currentSongData.length - 1]; if (!last) return 0; if (last[0] === 'hold') { return last[2] + last[3]; } return last[2] + 1000; } // --- RESULT SCREEN --- function showResult() { clearGameObjects(); var acc = totalNotes > 0 ? Math.floor(100 * hitNotes / totalNotes) : 100; var resultStr = (selectedLanguage === 'zh' ? "结果" : "Result") + "\n"; resultStr += (selectedLanguage === 'zh' ? "分数: " : "Score: ") + score + "\n"; resultStr += (selectedLanguage === 'zh' ? "最大连击: " : "Max Combo: ") + maxCombo + "\n"; resultStr += (selectedLanguage === 'zh' ? "准确率: " : "Accuracy: ") + acc + "%\n"; resultStr += (selectedLanguage === 'zh' ? "命中: " : "Hit: ") + hitNotes + "/" + totalNotes + "\n"; resultStr += (selectedLanguage === 'zh' ? "未命中: " : "Miss: ") + missNotes; resultText = new Text2(resultStr, { size: 90, fill: "#fff", align: "center" }); resultText.anchor.set(0.5, 0.5); resultText.x = 2048 / 2; resultText.y = 1000; gui.center.addChild(resultText); homeButton = new Text2(selectedLanguage === 'zh' ? "返回首页" : "Home", { size: 100, fill: "#fff" }); homeButton.anchor.set(0.5, 0.5); homeButton.x = 2048 / 2; homeButton.y = 1800; homeButton.interactive = true; homeButton.down = function (x, y, obj) { setGameState('HOME'); }; gui.center.addChild(homeButton); } // --- START GAME --- // Start at language selector (opening screen) setGameState('LANGUAGE');
===================================================================
--- original.js
+++ change.js
@@ -115,13 +115,13 @@
/****
* Game Code
****/
-// Sounds and music (placeholders, actual music not implemented here)
-// Example note assets:
-// We'll use shapes for notes, and images for backgrounds and song covers as needed.
-// Note: Assets are auto-initialized by LK based on usage below.
// --- GLOBALS ---
+// Note: Assets are auto-initialized by LK based on usage below.
+// We'll use shapes for notes, and images for backgrounds and song covers as needed.
+// Example note assets:
+// Sounds and music (placeholders, actual music not implemented here)
var GAME_STATE = 'LANGUAGE'; // LANGUAGE, HOME, STORY, DIFFICULTY, PLAY, RESULT
var selectedLanguage = storage.language || 'en';
var selectedSong = null;
var selectedDifficulty = null;
@@ -263,11 +263,11 @@
size: 80,
// smaller for mobile
fill: "#fff"
});
- titleText.anchor.set(0.5, 0);
+ titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
- titleText.y = 120; // closer to top for mobile
+ titleText.y = 2732 / 2 - 300;
gui.center.addChild(titleText);
// Language selector
var langs = [{
code: 'en',
@@ -275,9 +275,9 @@
}, {
code: 'zh',
label: '中文'
}];
- var langBtnYStart = 400;
+ var langBtnYStart = 2732 / 2 - 80;
var langBtnSpacing = 160;
for (var i = 0; i < langs.length; ++i) {
(function (idx) {
var btn = new Text2(langs[idx].label, {
@@ -307,9 +307,9 @@
fill: "#fff"
});
startButton.anchor.set(0.5, 0.5);
startButton.x = 2048 / 2;
- startButton.y = 900; // lower for mobile, but not too low
+ startButton.y = 2732 / 2 + 300;
startButton.interactive = true;
startButton.down = function (x, y, obj) {
setGameState('HOME');
};
Game design for Kaleidoscope of Music Rhythm without game title, just the design for opening screen background. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style design empty selector UI. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style hold note for music rhythm game. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style swipe note for music rhythm game. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style tap note for music rhythm game. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style kaleidoscope pattern design for homepage. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style lane divider for music rhythm game that is horizontal and used for judging the touching of rhythm In-Game asset. 2d. High contrast. No shadows
Empty cyberpunk style storybox design in which it's size enable song cover, difficulty level and song description to be added in the storybox. In-Game asset. 2d. High contrast. No shadows
Round shape of song cover of anime style with Sky Journey theme. In-Game asset. 2d. High contrast. No shadows
Round shape song cover of cyberpunk anime style with the themed “Night Pulse”. In-Game asset. 2d. High contrast. No shadows
Round shape of anime style song cover with the themed Sunrise Waltz. In-Game asset. 2d. High contrast. No shadows
Anime style design for the round shape song cover of New Era Malay Style
Round shape, Replace Chinese word from “不知途”to“莫问前程”,others remaining the same
Empty cyberpunk style menu design. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style pause symbol. In-Game asset. 2d. High contrast. No shadows
Cyberpunk style return symbol. In-Game asset. 2d. High contrast. No shadows