User prompt
Oyun notaları her seferinde rastgele yerlerde oluşsun ve sonsuza kadar notalar rastgele gelsin.
User prompt
Oyun 1000 puandan sonrada devam etsin
User prompt
Oyun sonsuza kadar devam etsin
User prompt
Miss çalma süresini 1 yap
User prompt
Her nota geçtiğinde misses bir sayılsın
User prompt
Miss çalma süresini 2 saniye yap
User prompt
Kaybedince miss sesi çıksın
User prompt
Oyun başladığında müzikte başlasın
User prompt
Nota tıklama yerlerini büyüt
User prompt
Notalar daha yavaş ve teker teker gelsin
Code edit (1 edits merged)
Please save this source code
User prompt
Beat Tapper
Initial prompt
Bana bir müzik oyunu tasarla
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Note class for falling notes var Note = Container.expand(function () { var self = Container.call(this); // Lane index (0-3) self.lane = 0; self.hit = false; self.missed = false; self.speed = 0; // pixels per tick self.time = 0; // time (in ticks) when note should reach the target self.spawned = false; // Attach correct note asset based on lane self.setLane = function (laneIdx) { self.lane = laneIdx; var assetId = 'note' + (laneIdx + 1); var noteAsset = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; // Called every tick self.update = function () { if (!self.spawned) return; self.y += self.speed; }; // Called when note is hit self.onHit = function () { if (self.hit || self.missed) return; self.hit = true; // Animate note tween(self, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); }; // Called when note is missed self.onMiss = function () { if (self.hit || self.missed) return; self.missed = true; LK.getSound('miss').play({ fade: { start: 1, end: 0, duration: 1000 } }); tween(self, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { self.destroy(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // 4 note lanes, each with a different color for clarity // --- Game Constants --- var NUM_LANES = 4; var LANE_WIDTH = 200; var LANE_SPACING = 40; var NOTE_WIDTH = 180; var NOTE_HEIGHT = 80; var TARGET_HEIGHT = 120; // Increased from 40 to 120 for larger tap area var LANE_HEIGHT = 2200; var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var LANE_TOTAL_WIDTH = NUM_LANES * LANE_WIDTH + (NUM_LANES - 1) * LANE_SPACING; var LANE_START_X = (GAME_WIDTH - LANE_TOTAL_WIDTH) / 2 + LANE_WIDTH / 2; var TARGET_Y = GAME_HEIGHT - 220; // Target zone Y position // --- Game State --- var notes = []; // All active notes var noteIndex = 0; // Index of next note to spawn var songTicks = 0; // Ticks since song start var score = 0; var combo = 0; var maxCombo = 0; var misses = 0; var maxMisses = 10; var songEnded = false; var songStarted = false; var lastTick = 0; // --- UI Elements --- var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var comboTxt = new Text2('', { size: 70, fill: 0xFFE066 }); comboTxt.anchor.set(0.5, 0); LK.gui.top.addChild(comboTxt); comboTxt.y = 130; var missTxt = new Text2('', { size: 70, fill: 0xFF6666 }); missTxt.anchor.set(0.5, 0); LK.gui.top.addChild(missTxt); missTxt.y = 210; // --- Lanes and Targets --- var lanes = []; var targets = []; for (var i = 0; i < NUM_LANES; i++) { // Lane background var laneX = LANE_START_X + i * (LANE_WIDTH + LANE_SPACING); var lane = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0, x: laneX, y: 0, width: LANE_WIDTH, height: LANE_HEIGHT }); game.addChild(lane); lanes.push(lane); // Target zone var target = LK.getAsset('target', { anchorX: 0.5, anchorY: 0.5, x: laneX, y: TARGET_Y, width: LANE_WIDTH, height: TARGET_HEIGHT // Now uses the updated, larger TARGET_HEIGHT }); game.addChild(target); targets.push(target); } // --- Song Data (Random Infinite Notes) --- // Each note: {lane: 0-3, time: tick when note should reach target} // We'll generate notes on the fly, at random lanes and random intervals var bpm = 60; var ticksPerBeat = 60 * 60 / bpm; // 60fps var NOTE_TRAVEL_TICKS = 180; // 3 seconds at 60fps // Infinite random note generator state var nextNoteTick = 60; // When the next note should appear (in songTicks) function getRandomLane() { return Math.floor(Math.random() * NUM_LANES); } function getRandomInterval() { // Random interval between notes: 0.5x to 1.5x of ticksPerBeat return Math.floor(ticksPerBeat * (0.5 + Math.random())); } // --- Helper Functions --- function getLaneX(laneIdx) { return LANE_START_X + laneIdx * (LANE_WIDTH + LANE_SPACING); } // --- Game Logic --- // Start song/music function startSong() { if (songStarted) return; songStarted = true; LK.playMusic('song1'); songTicks = 0; noteIndex = 0; score = 0; combo = 0; maxCombo = 0; misses = 0; songEnded = false; scoreTxt.setText('0'); comboTxt.setText(''); missTxt.setText(''); notes.length = 0; } // End song/game function endSong(win) { if (songEnded) return; songEnded = true; LK.stopMusic(); // No win or game over, just stop music and mark as ended } // --- Input Handling --- game.down = function (x, y, obj) { // Only allow input if song is running if (!songStarted || songEnded) return; // Find which lane was tapped for (var i = 0; i < NUM_LANES; i++) { var laneX = getLaneX(i); var minX = laneX - LANE_WIDTH / 2; var maxX = laneX + LANE_WIDTH / 2; if (x >= minX && x <= maxX) { // Check for a hittable note in this lane var hit = false; for (var j = 0; j < notes.length; j++) { var note = notes[j]; if (note.lane !== i || note.hit || note.missed) continue; // If note is within hit window (±TARGET_HEIGHT/2) var dy = Math.abs(note.y - TARGET_Y); // Make the hit window slightly more generous to match the larger target if (dy <= TARGET_HEIGHT / 2 + NOTE_HEIGHT / 2) { // Hit! note.onHit(); hit = true; score += 100; combo += 1; if (combo > maxCombo) maxCombo = combo; scoreTxt.setText(score + ''); comboTxt.setText(combo > 1 ? combo + ' Combo!' : ''); LK.getSound('tap').play(); break; } } if (!hit) { // Missed tap (no note in window) combo = 0; misses += 1; comboTxt.setText(''); missTxt.setText('Misses: ' + misses); LK.getSound('miss').play({ fade: { start: 1, end: 0, duration: 1000 } }); // Flash lane red LK.effects.flashObject(targets[i], 0xff0000, 200); if (misses >= maxMisses) { endSong(false); } } break; } } }; // --- Main Game Loop --- game.update = function () { if (!songStarted || songEnded) return; songTicks += 1; // Spawn notes as needed (random, infinite) while (songTicks >= nextNoteTick - NOTE_TRAVEL_TICKS) { var lane = getRandomLane(); var noteTime = nextNoteTick; var note = new Note(); note.setLane(lane); note.x = getLaneX(lane); note.y = -NOTE_HEIGHT / 2; note.speed = (TARGET_Y + NOTE_HEIGHT / 2) / NOTE_TRAVEL_TICKS; note.time = noteTime; note.spawned = true; notes.push(note); game.addChild(note); // Schedule next note nextNoteTick += getRandomInterval(); } // Update notes for (var i = notes.length - 1; i >= 0; i--) { var note = notes[i]; note.update(); // If note reached target zone and not hit, mark as missed if (!note.hit && !note.missed && note.y >= TARGET_Y + TARGET_HEIGHT / 2) { note.onMiss(); combo = 0; misses += 1; comboTxt.setText(''); missTxt.setText('Misses: ' + misses); LK.getSound('miss').play({ fade: { start: 1, end: 0, duration: 1000 } }); LK.effects.flashObject(targets[note.lane], 0xff0000, 200); if (misses >= maxMisses) { // No game over, just keep going } } // Remove destroyed notes if (note.destroyed) { notes.splice(i, 1); } } // No win condition, keep game running }; // --- Start the game --- startSong();
===================================================================
--- original.js
+++ change.js
@@ -154,54 +154,23 @@
});
game.addChild(target);
targets.push(target);
}
-// --- Song Data (Slower, Single Note Demo Song) ---
+// --- Song Data (Random Infinite Notes) ---
// Each note: {lane: 0-3, time: tick when note should reach target}
-// Lower BPM for slower note frequency
+// We'll generate notes on the fly, at random lanes and random intervals
var bpm = 60;
var ticksPerBeat = 60 * 60 / bpm; // 60fps
-// Notes come one by one, spaced far apart, alternating lanes
-var songNotes = [{
- lane: 0,
- time: 60
-}, {
- lane: 1,
- time: 180
-}, {
- lane: 2,
- time: 300
-}, {
- lane: 3,
- time: 420
-}, {
- lane: 0,
- time: 540
-}, {
- lane: 1,
- time: 660
-}, {
- lane: 2,
- time: 780
-}, {
- lane: 3,
- time: 900
-}, {
- lane: 0,
- time: 1020
-}, {
- lane: 1,
- time: 1140
-}, {
- lane: 2,
- time: 1260
-}, {
- lane: 3,
- time: 1380
-}];
-// How many ticks before target to spawn note (so it falls from top to target in time)
-// Increase travel time for slower falling notes
var NOTE_TRAVEL_TICKS = 180; // 3 seconds at 60fps
+// Infinite random note generator state
+var nextNoteTick = 60; // When the next note should appear (in songTicks)
+function getRandomLane() {
+ return Math.floor(Math.random() * NUM_LANES);
+}
+function getRandomInterval() {
+ // Random interval between notes: 0.5x to 1.5x of ticksPerBeat
+ return Math.floor(ticksPerBeat * (0.5 + Math.random()));
+}
// --- Helper Functions ---
function getLaneX(laneIdx) {
return LANE_START_X + laneIdx * (LANE_WIDTH + LANE_SPACING);
}
@@ -287,26 +256,23 @@
// --- Main Game Loop ---
game.update = function () {
if (!songStarted || songEnded) return;
songTicks += 1;
- // Spawn notes as needed
- while (noteIndex < songNotes.length) {
- var noteData = songNotes[noteIndex];
- if (noteData.time - NOTE_TRAVEL_TICKS <= songTicks) {
- // Spawn note
- var note = new Note();
- note.setLane(noteData.lane);
- note.x = getLaneX(noteData.lane);
- note.y = -NOTE_HEIGHT / 2;
- note.speed = (TARGET_Y + NOTE_HEIGHT / 2) / NOTE_TRAVEL_TICKS;
- note.time = noteData.time;
- note.spawned = true;
- notes.push(note);
- game.addChild(note);
- noteIndex += 1;
- } else {
- break;
- }
+ // Spawn notes as needed (random, infinite)
+ while (songTicks >= nextNoteTick - NOTE_TRAVEL_TICKS) {
+ var lane = getRandomLane();
+ var noteTime = nextNoteTick;
+ var note = new Note();
+ note.setLane(lane);
+ note.x = getLaneX(lane);
+ note.y = -NOTE_HEIGHT / 2;
+ note.speed = (TARGET_Y + NOTE_HEIGHT / 2) / NOTE_TRAVEL_TICKS;
+ note.time = noteTime;
+ note.spawned = true;
+ notes.push(note);
+ game.addChild(note);
+ // Schedule next note
+ nextNoteTick += getRandomInterval();
}
// Update notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];