User prompt
a little bit more
User prompt
move it to the right
User prompt
a little little bit right
User prompt
a little bit more
User prompt
move it more
User prompt
move backgrond to the left
User prompt
make the backgorund an assetr
User prompt
make the note hitbox bigger
User prompt
when a note is played on: guitarString1, play E sound guitarString2, play A sound guitarString3, play D sound guitarString4, play G sound guitarString5, play B sound guitarString6, play E2 sound
User prompt
play the notes of a popular rock song when a note is pressed
User prompt
make the columns infinite
User prompt
add one more line to ball fall
Code edit (1 edits merged)
Please save this source code
User prompt
Strum Hero: Guitar Rhythm Challenge
Initial prompt
guitar playing game
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // GuitarString class: visual representation of a string var GuitarString = Container.expand(function () { var self = Container.call(this); self.stringIndex = 0; // 0-5 self.init = function (stringIndex) { self.stringIndex = stringIndex; var stringAssetId = 'guitarString' + (stringIndex + 1); var string = self.attachAsset(stringAssetId, { anchorX: 0.5, anchorY: 0 }); self.width = string.width; self.height = string.height; }; return self; }); // Note class: represents a falling note on a string var Note = Container.expand(function () { var self = Container.call(this); self.stringIndex = 0; // 0-5 self.hit = false; self.missed = false; self.init = function (stringIndex) { self.stringIndex = stringIndex; var noteAssetId = 'note' + (stringIndex + 1); var note = self.attachAsset(noteAssetId, { anchorX: 0.5, anchorY: 0.5 }); self.width = note.width; self.height = note.height; }; self.update = function () { if (!self.hit && !self.missed) { self.y += noteSpeed; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // --- Game Constants --- // Guitar string shapes (5 strings) // Note shapes (one per string, colored) // Hit zone // Sound for hit/miss // Music (background track) var NUM_STRINGS = 6; var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var STRING_SPACING = 260; var STRING_TOP = 200; var STRING_BOTTOM = 2000; var NOTE_START_Y = -100; var HIT_ZONE_Y = 2000; var HIT_ZONE_HEIGHT = 40; var NOTE_HIT_WINDOW = 180; // px (was 100) var NOTE_MISS_WINDOW = 200; // px (was 120) var MAX_MISSES = 10; var BASE_NOTE_SPEED = 16; // px per frame var NOTE_SPAWN_OFFSET = 60; // frames between notes (song tempo) var MULTIPLIER_THRESHOLDS = [10, 20, 40, 60]; // streaks for multipliers // --- Game State --- var strings = []; var notes = []; var noteSpeed = BASE_NOTE_SPEED; var score = 0; var streak = 0; var multiplier = 1; var misses = 0; var songTime = 0; var songEnded = false; var lastNoteSpawnTick = 0; var songNotes = []; // Array of {tick, stringIndex} var nextSongNoteIndex = 0; // --- UI Elements --- var scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var streakTxt = new Text2('', { size: 60, fill: "#fff" }); streakTxt.anchor.set(0.5, 0); LK.gui.top.addChild(streakTxt); var missesTxt = new Text2('', { size: 60, fill: 0xFF4444 }); missesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(missesTxt); // --- Background --- var background = LK.getAsset('background', { anchorX: 0, anchorY: 0, x: -1600, // Move background even further to the left y: 0 }); game.addChild(background); // --- Hit Zone --- var hitZone = LK.getAsset('hitZone', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: HIT_ZONE_Y }); game.addChild(hitZone); hitZone.alpha = 0.15; // --- Place Guitar Strings --- var stringStartX = (GAME_WIDTH - (NUM_STRINGS - 1) * STRING_SPACING) / 2; for (var i = 0; i < NUM_STRINGS; i++) { var gs = new GuitarString(); gs.init(i); gs.x = stringStartX + i * STRING_SPACING; gs.y = STRING_TOP; game.addChild(gs); strings.push(gs); } // --- Song Data (simple hardcoded song for MVP) --- // Each entry: {tick: frame to spawn, stringIndex: 0-4} songNotes = [{ tick: 30, stringIndex: 2 }, { tick: 60, stringIndex: 1 }, { tick: 90, stringIndex: 3 }, { tick: 120, stringIndex: 0 }, { tick: 150, stringIndex: 4 }, { tick: 165, stringIndex: 5 }, { tick: 180, stringIndex: 2 }, { tick: 210, stringIndex: 1 }, { tick: 225, stringIndex: 5 }, { tick: 240, stringIndex: 3 }, { tick: 270, stringIndex: 0 }, { tick: 285, stringIndex: 5 }, { tick: 300, stringIndex: 4 }, { tick: 315, stringIndex: 5 }, { tick: 330, stringIndex: 2 }, { tick: 345, stringIndex: 5 }, { tick: 360, stringIndex: 1 }, { tick: 375, stringIndex: 5 }, { tick: 390, stringIndex: 3 }, { tick: 405, stringIndex: 5 }, { tick: 420, stringIndex: 0 }, { tick: 435, stringIndex: 5 }, { tick: 450, stringIndex: 4 }, { tick: 465, stringIndex: 5 }, { tick: 480, stringIndex: 2 }, { tick: 495, stringIndex: 5 }, { tick: 510, stringIndex: 1 }, { tick: 525, stringIndex: 5 }, { tick: 540, stringIndex: 3 }, { tick: 555, stringIndex: 5 }, { tick: 570, stringIndex: 0 }, { tick: 585, stringIndex: 5 }, { tick: 600, stringIndex: 4 }]; // Song ends after last note + 3 seconds var songEndTick = songNotes[songNotes.length - 1].tick + 180; // --- Helper Functions --- function updateScoreUI() { scoreTxt.setText(score); streakTxt.setText(streak > 0 ? "Streak: " + streak + " x" + multiplier : ""); missesTxt.setText(misses > 0 ? "Misses: " + misses + "/" + MAX_MISSES : ""); } function getStringIndexFromX(x) { // Find which string x is closest to var minDist = 99999; var idx = 0; for (var i = 0; i < strings.length; i++) { var dist = Math.abs(x - strings[i].x); if (dist < minDist) { minDist = dist; idx = i; } } return idx; } function tryHitNote(stringIndex) { // Find the first note on this string within the hit window for (var i = 0; i < notes.length; i++) { var n = notes[i]; if (n.stringIndex === stringIndex && !n.hit && !n.missed) { var dy = Math.abs(n.y - HIT_ZONE_Y); if (dy <= NOTE_HIT_WINDOW) { n.hit = true; // Play the correct guitar note sound for each string if (stringIndex === 0) { LK.getSound('E').play(); } else if (stringIndex === 1) { LK.getSound('A').play(); } else if (stringIndex === 2) { LK.getSound('D').play(); } else if (stringIndex === 3) { LK.getSound('G').play(); } else if (stringIndex === 4) { LK.getSound('B').play(); } else if (stringIndex === 5) { LK.getSound('E2').play(); } score += 100 * multiplier; streak += 1; // Multiplier logic if (streak >= MULTIPLIER_THRESHOLDS[3]) { multiplier = 5; } else if (streak >= MULTIPLIER_THRESHOLDS[2]) { multiplier = 4; } else if (streak >= MULTIPLIER_THRESHOLDS[1]) { multiplier = 3; } else if (streak >= MULTIPLIER_THRESHOLDS[0]) { multiplier = 2; } else { multiplier = 1; } updateScoreUI(); // Animate note tween(n, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { n.destroy(); } }); return true; } } } // Missed (no note in window) LK.getSound('noteMiss').play(); streak = 0; multiplier = 1; misses += 1; updateScoreUI(); LK.effects.flashObject(strings[stringIndex], 0xff0000, 200); if (misses >= MAX_MISSES) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } return false; } // --- Input Handling --- game.down = function (x, y, obj) { // Only allow input in lower 2/3 of screen (where strings are) if (y < STRING_TOP) return; var stringIdx = getStringIndexFromX(x); tryHitNote(stringIdx); }; // --- Game Update Loop --- game.update = function () { // Spawn notes according to songNotes if (!songEnded && nextSongNoteIndex < songNotes.length) { while (nextSongNoteIndex < songNotes.length && LK.ticks >= songNotes[nextSongNoteIndex].tick) { var noteData = songNotes[nextSongNoteIndex]; var n = new Note(); n.init(noteData.stringIndex); n.x = strings[noteData.stringIndex].x; n.y = NOTE_START_Y; n.alpha = 1; n.scaleX = 1; n.scaleY = 1; notes.push(n); game.addChild(n); nextSongNoteIndex += 1; } } // Update notes for (var i = notes.length - 1; i >= 0; i--) { var n = notes[i]; n.update(); // Missed note? if (!n.hit && !n.missed && n.y > HIT_ZONE_Y + NOTE_MISS_WINDOW) { n.missed = true; streak = 0; multiplier = 1; misses += 1; updateScoreUI(); LK.getSound('noteMiss').play(); LK.effects.flashObject(strings[n.stringIndex], 0xff0000, 200); tween(n, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { n.destroy(); } }); if (misses >= MAX_MISSES) { LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); } } // Remove notes that are hit and faded out if ((n.hit || n.missed) && n.alpha <= 0.01) { notes.splice(i, 1); continue; } // Make columns infinite: if note goes off bottom, respawn at top (unless hit/missed) if (!n.hit && !n.missed && n.y > GAME_HEIGHT + n.height) { n.y = NOTE_START_Y; n.hit = false; n.missed = false; n.alpha = 1; n.scaleX = 1; n.scaleY = 1; } } // End of song if (!songEnded && LK.ticks > songEndTick) { songEnded = true; LK.showYouWin(); } }; // --- UI Placement --- scoreTxt.position.set(GAME_WIDTH / 2, 20); streakTxt.position.set(GAME_WIDTH / 2, 160); missesTxt.position.set(GAME_WIDTH / 2, 240); // --- Start Music --- LK.playMusic('song1', { fade: { start: 0, end: 1, duration: 1000 } }); // --- Initialize UI --- updateScoreUI();
===================================================================
--- original.js
+++ change.js
@@ -112,10 +112,10 @@
// --- Background ---
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
- x: -1200,
- // Move background further to the left
+ x: -1600,
+ // Move background even further to the left
y: 0
});
game.addChild(background);
// --- Hit Zone ---