User prompt
Can sistemi ekle 10 can olsun.
User prompt
Işıklar dıştaki çemberlere temas etmeye başladıktan itibaren dokunulabilir olsun ta ki ortada merkezdeki çembere gelene kadar
User prompt
Çevredeki çemberler ile ışıklar ilk temas etmesinden ortadaki çembere ulaşana kadar basılabilsin. Orta çembere dokunursa game over olsun
User prompt
Işıklar arasında en az 2 sn olsun ard arda çok karışıyor.
User prompt
Bu kadar da fazla düzensiz oldu aralarında mutlaka 1 sn olsun
User prompt
5 ten sonra gene durdu. Şöyle yapalım sürekli düzensiz gelsin skor 20 olunca hızlansın
User prompt
Biraz daha hızlı ve düzensiz gelsin
User prompt
Bölüm mantığını sil. İlk 5 puana kadar yavaş ve tek tek gelsin ışıklar. 5 ten sonra geliş düzeni bozulsun yüzde 10 hızlansın. Skor 20 olunca daha da düzensiz ve hızlı olsun. Arka plan rengini sürekli basılan renge göre değiştir
User prompt
Olmuyor. Oyun konsolunun kolunu düşün. Yukarı aşağı sağ sol hepsi bitişil öyle yap
User prompt
İyice uzaklaştılar Ana çembere uö kısımları değsin her birinin
User prompt
Olmadı oyun simgesindeki gibi bir şekil olması gerekiyor
User prompt
Please fix the bug: 'Timeout.tick error: arcOffset is not defined' in or related to this line: 'return {' Line Number: 247
User prompt
İyice karıştı. Ortada bir çember etrafında 4 adet simetrik çember. Ortadaki çembere hiçbiri dokunmayacak
User prompt
Olmuyor. Ortada bir çember ve etrafında sağ sol yukarı aşağı olacak şekilde 4 adet çeyrek çember olacak. Sağ sol yukarı ve aşağıdan çeyrek çemberlere renkli ışıklar gelecek. Oyuncu doğru zamanda yönlere göre tepki verince yukarıdan gelenlerden tok davul sesi aşağıdan gelenler için soft davul sesi soldan gelenler için güçlü zil sesi sağdan gelenler için zayıf zil sesi çalacak. Aynı zamanda arka plan ışığı doğru basılan renge dönecek. Bölüm şeklinde yapalım. İlk bölümde karışık şekilde yavaş hızda 10 adet sağ sol yukarı aşağı yönlerden ışıklar gelsin.
User prompt
Tekrar kontrol et dıştaki çemberin içine ışık giriyor. Tıklıyorum ama game over diyor.ilk başta yazdığın kodda sıkıntı yoktu. İlk haline çevir
User prompt
Çevredeki çemberler orta çembere çok yaklaştı o yüzden skor alamıyorum game over dşyoe hemen. Dış çemberleri orta çemberden Biraz aç
User prompt
Işıklar hızlı geliyor skor 5 olana kadar tek tek gelsinler. Ve şeklin üstüne gelince tıklansınlar. Hangi çemberin üzerindelerse tıkanınca Arka plan o renge dönsün
User prompt
Şekilleri ilk baştaki haline çevir
User prompt
Etraftakiler çember değilde çeyrek daire yap
User prompt
Çok hızlı oldu biraz yavaşlat
User prompt
Gelmeye devam etmiyor. Gelme düzenini komple en baştan yaz. Sürekli gelsin skor 5e kadar düzenli ve yavaş sonrasında daha düzensiz ve hızlı gelsin. 30dan sonra daha da düzensiz ve hızlı gelsin
User prompt
5teb sonra gelme durdu. Devam etmesi gerekiyor daha hızlı ve daha düzensiz gelmesi gerekiyor
User prompt
Bölüm olayını kaldıralım skor 5 olana kadar bölüm 1deki hızla ve düzenle gelsin. 6ncıdan itibaren bölüm 2 için düşündüğümüz hız ve düzende gelsin
User prompt
İkinci bölümü de 2 katı hızlı yap ve bir tanesi henüz gelmeden diğeri de gelmeye başlamış olsun öncekinin bitmesini beklemesin
User prompt
Birinci bölümü 2 katı hızlı yap. Bölüm başlarında bilgi ver
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Light (note) class var Light = Container.expand(function () { var self = Container.call(this); // Properties to be set on creation: // self.direction: 'up' | 'down' | 'left' | 'right' // self.color: 'red' | 'blue' | 'green' | 'yellow' // self.speed: px per tick // self.targetX, self.targetY: where to move toward // Attach correct asset var assetId = ''; if (self.color === 'red') assetId = 'lightRed';else if (self.color === 'blue') assetId = 'lightBlue';else if (self.color === 'green') assetId = 'lightGreen';else if (self.color === 'yellow') assetId = 'lightYellow'; var light = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // For hit detection self.radius = light.width * 0.5; // For animation self.active = true; // If false, ignore update // Called every tick self.update = function () { if (!self.active) return; // Move towards target var dx = self.targetX - self.x; var dy = self.targetY - self.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < self.speed) { self.x = self.targetX; self.y = self.targetY; } else { self.x += self.speed * dx / dist; self.y += self.speed * dy / dist; } }; // Animate and destroy on hit/miss self.hit = function (_onFinish) { self.active = false; tween(self, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); if (_onFinish) _onFinish(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181818 }); /**** * Game Code ****/ // LK.init.music('bgmusic', {volume: 0.5}); // Music (background, optional, not played in MVP) // Sound effects for each direction // Four colored "light" shapes for incoming notes // Four quarter arcs (quarter circles) for directions: up, down, left, right // --- Layout constants --- var centerX = 2048 / 2; var centerY = 2732 / 2; var centerRadius = 200; // centerCircle radius // Arc positions (relative to center) var arcOffset = 260; // distance from center to arc center // Arc asset sizes var arcW = 300, arcH = 150; // up/down var arcSideW = 150, arcSideH = 300; // left/right // --- Create main elements --- // Center circle var centerCircle = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5 }); centerCircle.x = centerX; centerCircle.y = centerY; game.addChild(centerCircle); // Quarter arcs var arcUp = LK.getAsset('arcUp', { anchorX: 0.5, anchorY: 1.0 }); arcUp.x = centerX; arcUp.y = centerY - arcOffset; game.addChild(arcUp); var arcDown = LK.getAsset('arcDown', { anchorX: 0.5, anchorY: 0.0 }); arcDown.x = centerX; arcDown.y = centerY + arcOffset; game.addChild(arcDown); var arcLeft = LK.getAsset('arcLeft', { anchorX: 1.0, anchorY: 0.5 }); arcLeft.x = centerX - arcOffset; arcLeft.y = centerY; game.addChild(arcLeft); var arcRight = LK.getAsset('arcRight', { anchorX: 0.0, anchorY: 0.5 }); arcRight.x = centerX + arcOffset; arcRight.y = centerY; game.addChild(arcRight); // --- Arc hitboxes for input detection --- var arcHitboxes = [{ dir: 'up', x: arcUp.x, y: arcUp.y - arcH / 2, w: arcW, h: arcH, color: 'red', asset: arcUp }, { dir: 'down', x: arcDown.x, y: arcDown.y + arcH / 2, w: arcW, h: arcH, color: 'blue', asset: arcDown }, { dir: 'left', x: arcLeft.x - arcSideW / 2, y: arcLeft.y, w: arcSideW, h: arcSideH, color: 'green', asset: arcLeft }, { dir: 'right', x: arcRight.x + arcSideW / 2, y: arcRight.y, w: arcSideW, h: arcSideH, color: 'yellow', asset: arcRight }]; // --- Score and wave display --- var score = 0; var wave = 1; var totalWaves = 10; var lightsPerWave = 1; // MVP: 1 light per wave, can be increased for difficulty var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var waveTxt = new Text2('1/10', { size: 60, fill: 0xFFFFFF }); waveTxt.anchor.set(0.5, 0); LK.gui.top.addChild(waveTxt); waveTxt.y = 130; // --- Light management --- var lights = []; var lightActive = false; // Only one light at a time in MVP // --- Color mapping for directions --- var dirColor = { 'up': 'red', 'down': 'blue', 'left': 'green', 'right': 'yellow' }; var dirSound = { 'up': 'drumRed', 'down': 'drumBlue', 'left': 'drumGreen', 'right': 'drumYellow' }; var dirBg = { 'up': 0xff4b4b, 'down': 0x4bafff, 'left': 0x4bff4b, 'right': 0xffe14b }; // --- Light spawn positions (offscreen, towards arcs) --- function getLightSpawn(dir) { var dist = 700; // distance from center if (dir === 'up') return { x: centerX, y: centerY - arcOffset - dist }; if (dir === 'down') return { x: centerX, y: centerY + arcOffset + dist }; if (dir === 'left') return { x: centerX - arcOffset - dist, y: centerY }; if (dir === 'right') return { x: centerX + arcOffset + dist, y: centerY }; return { x: centerX, y: centerY }; } function getLightTarget(dir) { if (dir === 'up') return { x: arcUp.x, y: arcUp.y - arcH / 2 + 50 }; if (dir === 'down') return { x: arcDown.x, y: arcDown.y + arcH / 2 - 50 }; if (dir === 'left') return { x: arcLeft.x - arcSideW / 2 + 50, y: arcLeft.y }; if (dir === 'right') return { x: arcRight.x + arcSideW / 2 - 50, y: arcRight.y }; return { x: centerX, y: centerY }; } // --- Light speed (slower for first waves) --- function getLightSpeed(wave) { // 1.5 px/tick for first wave, up to 3 px/tick for last, then increase by per-level multiplier var level = levelData[currentLevel - 1]; var mult = level ? level.speedMult : 1.10; return (1.5 + (wave - 1) * 0.2) * mult; } // --- Spawn a light (note) --- function spawnLight(dir) { var color = dirColor[dir]; var spawn = getLightSpawn(dir); var target = getLightTarget(dir); var light = new Light(); light.direction = dir; light.color = color; light.x = spawn.x; light.y = spawn.y; light.targetX = target.x; light.targetY = target.y; light.speed = getLightSpeed(wave); lights.push(light); game.addChild(light); lightActive = true; } // --- Start a wave --- // Level management var currentLevel = 1; var levelData = [{ waves: 10, speedMult: 2.00 }, { waves: 20, speedMult: 1.30 }]; function startWave() { var level = levelData[currentLevel - 1]; if (wave > level.waves) { // If there is a next level, start it if (currentLevel < levelData.length) { currentLevel += 1; wave = 1; score = 0; scoreTxt.setText(score); totalWaves = levelData[currentLevel - 1].waves; waveTxt.setText(wave + '/' + totalWaves); // Show info for new level var infoText = new Text2("2. Bölüm: 20 ışık, %30 daha hızlı!", { size: 90, fill: 0xffffff }); infoText.anchor.set(0.5, 0.5); infoText.x = centerX; infoText.y = centerY - 300; LK.gui.center.addChild(infoText); LK.setTimeout(function () { LK.gui.center.removeChild(infoText); startWave(); }, 1600); return; } else { LK.showYouWin(); return; } } // Show info for first level if first wave if (wave === 1 && currentLevel === 1) { var infoText = new Text2("1. Bölüm: 10 ışık, 2 kat hızlı!", { size: 90, fill: 0xffffff }); infoText.anchor.set(0.5, 0.5); infoText.x = centerX; infoText.y = centerY - 300; LK.gui.center.addChild(infoText); LK.setTimeout(function () { LK.gui.center.removeChild(infoText); // Show wave number totalWaves = level.waves; waveTxt.setText(wave + '/' + totalWaves); // Random direction var dirs = ['up', 'down', 'left', 'right']; var dir = dirs[Math.floor(Math.random() * 4)]; spawnLight(dir); }, 1600); return; } // Show wave number totalWaves = level.waves; waveTxt.setText(wave + '/' + totalWaves); // Random direction var dirs = ['up', 'down', 'left', 'right']; var dir = dirs[Math.floor(Math.random() * 4)]; spawnLight(dir); } // --- Handle tap input --- function getDirectionFromPoint(x, y) { // Returns 'up', 'down', 'left', 'right' or null for (var i = 0; i < arcHitboxes.length; ++i) { var arc = arcHitboxes[i]; // Use bounding box for MVP var dx = x - arc.x; var dy = y - arc.y; if (arc.dir === 'up' || arc.dir === 'down') { if (Math.abs(dx) < arc.w / 2 && Math.abs(dy) < arc.h / 2) return arc.dir; } else { if (Math.abs(dx) < arc.w / 2 && Math.abs(dy) < arc.h / 2) return arc.dir; } } return null; } // --- Handle tap (down) --- game.down = function (x, y, obj) { if (!lightActive) return; // Use the provided x, y directly as they are already in game coordinates var dir = getDirectionFromPoint(x, y); if (!dir) return; // Find the active light for (var i = 0; i < lights.length; ++i) { var light = lights[i]; if (!light.active) continue; // If direction matches and light is close enough to arc var target = getLightTarget(dir); var dx = light.x - target.x; var dy = light.y - target.y; var dist = Math.sqrt(dx * dx + dy * dy); if (light.direction === dir && dist < 120) { // Correct! light.hit(function () { // Remove from array for (var j = 0; j < lights.length; ++j) { if (lights[j] === light) { lights.splice(j, 1); break; } } lightActive = false; score += 1; scoreTxt.setText(score); // Play sound LK.getSound(dirSound[dir]).play(); // Flash background tween.stop(game, { backgroundColor: true }); var oldBg = game.backgroundColor; tween(game, { backgroundColor: dirBg[dir] }, { duration: 120, onFinish: function onFinish() { tween(game, { backgroundColor: oldBg }, { duration: 400 }); } }); // Next wave after short delay LK.setTimeout(function () { wave += 1; startWave(); }, 350); }); return; } } // If tap is on arc but no light is close: miss // Flash red and game over LK.effects.flashScreen(0xff0000, 500); LK.showGameOver(); }; // --- Update loop: check for missed lights --- game.update = function () { for (var i = lights.length - 1; i >= 0; --i) { var light = lights[i]; if (!light.active) continue; // If light reached target and not hit: miss var target = getLightTarget(light.direction); var dx = light.x - target.x; var dy = light.y - target.y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 30) { // Missed! light.hit(function () { for (var j = 0; j < lights.length; ++j) { if (lights[j] === light) { lights.splice(j, 1); break; } } lightActive = false; // Flash red and game over LK.effects.flashScreen(0xff0000, 500); LK.showGameOver(); }); } } }; // --- Start game --- score = 0; wave = 1; currentLevel = 1; totalWaves = levelData[0].waves; scoreTxt.setText(score); waveTxt.setText(wave + '/' + totalWaves); LK.setTimeout(function () { startWave(); }, 600);
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Light (note) class
var Light = Container.expand(function () {
var self = Container.call(this);
// Properties to be set on creation:
// self.direction: 'up' | 'down' | 'left' | 'right'
// self.color: 'red' | 'blue' | 'green' | 'yellow'
// self.speed: px per tick
// self.targetX, self.targetY: where to move toward
// Attach correct asset
var assetId = '';
if (self.color === 'red') assetId = 'lightRed';else if (self.color === 'blue') assetId = 'lightBlue';else if (self.color === 'green') assetId = 'lightGreen';else if (self.color === 'yellow') assetId = 'lightYellow';
var light = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// For hit detection
self.radius = light.width * 0.5;
// For animation
self.active = true; // If false, ignore update
// Called every tick
self.update = function () {
if (!self.active) return;
// Move towards target
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < self.speed) {
self.x = self.targetX;
self.y = self.targetY;
} else {
self.x += self.speed * dx / dist;
self.y += self.speed * dy / dist;
}
};
// Animate and destroy on hit/miss
self.hit = function (_onFinish) {
self.active = false;
tween(self, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
if (_onFinish) _onFinish();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// LK.init.music('bgmusic', {volume: 0.5});
// Music (background, optional, not played in MVP)
// Sound effects for each direction
// Four colored "light" shapes for incoming notes
// Four quarter arcs (quarter circles) for directions: up, down, left, right
// --- Layout constants ---
var centerX = 2048 / 2;
var centerY = 2732 / 2;
var centerRadius = 200; // centerCircle radius
// Arc positions (relative to center)
var arcOffset = 260; // distance from center to arc center
// Arc asset sizes
var arcW = 300,
arcH = 150; // up/down
var arcSideW = 150,
arcSideH = 300; // left/right
// --- Create main elements ---
// Center circle
var centerCircle = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
centerCircle.x = centerX;
centerCircle.y = centerY;
game.addChild(centerCircle);
// Quarter arcs
var arcUp = LK.getAsset('arcUp', {
anchorX: 0.5,
anchorY: 1.0
});
arcUp.x = centerX;
arcUp.y = centerY - arcOffset;
game.addChild(arcUp);
var arcDown = LK.getAsset('arcDown', {
anchorX: 0.5,
anchorY: 0.0
});
arcDown.x = centerX;
arcDown.y = centerY + arcOffset;
game.addChild(arcDown);
var arcLeft = LK.getAsset('arcLeft', {
anchorX: 1.0,
anchorY: 0.5
});
arcLeft.x = centerX - arcOffset;
arcLeft.y = centerY;
game.addChild(arcLeft);
var arcRight = LK.getAsset('arcRight', {
anchorX: 0.0,
anchorY: 0.5
});
arcRight.x = centerX + arcOffset;
arcRight.y = centerY;
game.addChild(arcRight);
// --- Arc hitboxes for input detection ---
var arcHitboxes = [{
dir: 'up',
x: arcUp.x,
y: arcUp.y - arcH / 2,
w: arcW,
h: arcH,
color: 'red',
asset: arcUp
}, {
dir: 'down',
x: arcDown.x,
y: arcDown.y + arcH / 2,
w: arcW,
h: arcH,
color: 'blue',
asset: arcDown
}, {
dir: 'left',
x: arcLeft.x - arcSideW / 2,
y: arcLeft.y,
w: arcSideW,
h: arcSideH,
color: 'green',
asset: arcLeft
}, {
dir: 'right',
x: arcRight.x + arcSideW / 2,
y: arcRight.y,
w: arcSideW,
h: arcSideH,
color: 'yellow',
asset: arcRight
}];
// --- Score and wave display ---
var score = 0;
var wave = 1;
var totalWaves = 10;
var lightsPerWave = 1; // MVP: 1 light per wave, can be increased for difficulty
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var waveTxt = new Text2('1/10', {
size: 60,
fill: 0xFFFFFF
});
waveTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(waveTxt);
waveTxt.y = 130;
// --- Light management ---
var lights = [];
var lightActive = false; // Only one light at a time in MVP
// --- Color mapping for directions ---
var dirColor = {
'up': 'red',
'down': 'blue',
'left': 'green',
'right': 'yellow'
};
var dirSound = {
'up': 'drumRed',
'down': 'drumBlue',
'left': 'drumGreen',
'right': 'drumYellow'
};
var dirBg = {
'up': 0xff4b4b,
'down': 0x4bafff,
'left': 0x4bff4b,
'right': 0xffe14b
};
// --- Light spawn positions (offscreen, towards arcs) ---
function getLightSpawn(dir) {
var dist = 700; // distance from center
if (dir === 'up') return {
x: centerX,
y: centerY - arcOffset - dist
};
if (dir === 'down') return {
x: centerX,
y: centerY + arcOffset + dist
};
if (dir === 'left') return {
x: centerX - arcOffset - dist,
y: centerY
};
if (dir === 'right') return {
x: centerX + arcOffset + dist,
y: centerY
};
return {
x: centerX,
y: centerY
};
}
function getLightTarget(dir) {
if (dir === 'up') return {
x: arcUp.x,
y: arcUp.y - arcH / 2 + 50
};
if (dir === 'down') return {
x: arcDown.x,
y: arcDown.y + arcH / 2 - 50
};
if (dir === 'left') return {
x: arcLeft.x - arcSideW / 2 + 50,
y: arcLeft.y
};
if (dir === 'right') return {
x: arcRight.x + arcSideW / 2 - 50,
y: arcRight.y
};
return {
x: centerX,
y: centerY
};
}
// --- Light speed (slower for first waves) ---
function getLightSpeed(wave) {
// 1.5 px/tick for first wave, up to 3 px/tick for last, then increase by per-level multiplier
var level = levelData[currentLevel - 1];
var mult = level ? level.speedMult : 1.10;
return (1.5 + (wave - 1) * 0.2) * mult;
}
// --- Spawn a light (note) ---
function spawnLight(dir) {
var color = dirColor[dir];
var spawn = getLightSpawn(dir);
var target = getLightTarget(dir);
var light = new Light();
light.direction = dir;
light.color = color;
light.x = spawn.x;
light.y = spawn.y;
light.targetX = target.x;
light.targetY = target.y;
light.speed = getLightSpeed(wave);
lights.push(light);
game.addChild(light);
lightActive = true;
}
// --- Start a wave ---
// Level management
var currentLevel = 1;
var levelData = [{
waves: 10,
speedMult: 2.00
}, {
waves: 20,
speedMult: 1.30
}];
function startWave() {
var level = levelData[currentLevel - 1];
if (wave > level.waves) {
// If there is a next level, start it
if (currentLevel < levelData.length) {
currentLevel += 1;
wave = 1;
score = 0;
scoreTxt.setText(score);
totalWaves = levelData[currentLevel - 1].waves;
waveTxt.setText(wave + '/' + totalWaves);
// Show info for new level
var infoText = new Text2("2. Bölüm: 20 ışık, %30 daha hızlı!", {
size: 90,
fill: 0xffffff
});
infoText.anchor.set(0.5, 0.5);
infoText.x = centerX;
infoText.y = centerY - 300;
LK.gui.center.addChild(infoText);
LK.setTimeout(function () {
LK.gui.center.removeChild(infoText);
startWave();
}, 1600);
return;
} else {
LK.showYouWin();
return;
}
}
// Show info for first level if first wave
if (wave === 1 && currentLevel === 1) {
var infoText = new Text2("1. Bölüm: 10 ışık, 2 kat hızlı!", {
size: 90,
fill: 0xffffff
});
infoText.anchor.set(0.5, 0.5);
infoText.x = centerX;
infoText.y = centerY - 300;
LK.gui.center.addChild(infoText);
LK.setTimeout(function () {
LK.gui.center.removeChild(infoText);
// Show wave number
totalWaves = level.waves;
waveTxt.setText(wave + '/' + totalWaves);
// Random direction
var dirs = ['up', 'down', 'left', 'right'];
var dir = dirs[Math.floor(Math.random() * 4)];
spawnLight(dir);
}, 1600);
return;
}
// Show wave number
totalWaves = level.waves;
waveTxt.setText(wave + '/' + totalWaves);
// Random direction
var dirs = ['up', 'down', 'left', 'right'];
var dir = dirs[Math.floor(Math.random() * 4)];
spawnLight(dir);
}
// --- Handle tap input ---
function getDirectionFromPoint(x, y) {
// Returns 'up', 'down', 'left', 'right' or null
for (var i = 0; i < arcHitboxes.length; ++i) {
var arc = arcHitboxes[i];
// Use bounding box for MVP
var dx = x - arc.x;
var dy = y - arc.y;
if (arc.dir === 'up' || arc.dir === 'down') {
if (Math.abs(dx) < arc.w / 2 && Math.abs(dy) < arc.h / 2) return arc.dir;
} else {
if (Math.abs(dx) < arc.w / 2 && Math.abs(dy) < arc.h / 2) return arc.dir;
}
}
return null;
}
// --- Handle tap (down) ---
game.down = function (x, y, obj) {
if (!lightActive) return;
// Use the provided x, y directly as they are already in game coordinates
var dir = getDirectionFromPoint(x, y);
if (!dir) return;
// Find the active light
for (var i = 0; i < lights.length; ++i) {
var light = lights[i];
if (!light.active) continue;
// If direction matches and light is close enough to arc
var target = getLightTarget(dir);
var dx = light.x - target.x;
var dy = light.y - target.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (light.direction === dir && dist < 120) {
// Correct!
light.hit(function () {
// Remove from array
for (var j = 0; j < lights.length; ++j) {
if (lights[j] === light) {
lights.splice(j, 1);
break;
}
}
lightActive = false;
score += 1;
scoreTxt.setText(score);
// Play sound
LK.getSound(dirSound[dir]).play();
// Flash background
tween.stop(game, {
backgroundColor: true
});
var oldBg = game.backgroundColor;
tween(game, {
backgroundColor: dirBg[dir]
}, {
duration: 120,
onFinish: function onFinish() {
tween(game, {
backgroundColor: oldBg
}, {
duration: 400
});
}
});
// Next wave after short delay
LK.setTimeout(function () {
wave += 1;
startWave();
}, 350);
});
return;
}
}
// If tap is on arc but no light is close: miss
// Flash red and game over
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
};
// --- Update loop: check for missed lights ---
game.update = function () {
for (var i = lights.length - 1; i >= 0; --i) {
var light = lights[i];
if (!light.active) continue;
// If light reached target and not hit: miss
var target = getLightTarget(light.direction);
var dx = light.x - target.x;
var dy = light.y - target.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 30) {
// Missed!
light.hit(function () {
for (var j = 0; j < lights.length; ++j) {
if (lights[j] === light) {
lights.splice(j, 1);
break;
}
}
lightActive = false;
// Flash red and game over
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
});
}
}
};
// --- Start game ---
score = 0;
wave = 1;
currentLevel = 1;
totalWaves = levelData[0].waves;
scoreTxt.setText(score);
waveTxt.setText(wave + '/' + totalWaves);
LK.setTimeout(function () {
startWave();
}, 600);
beat
Music
drumRed
Sound effect
drumGreen
Sound effect
beat2
Music
beat3
Music
beat4
Music
harp4
Sound effect
oboe4
Sound effect
harp1
Sound effect
harp2
Sound effect
harp3
Sound effect
piano1
Sound effect
piano2
Sound effect
piano3
Sound effect
piano4
Sound effect
drum4
Sound effect
oboe1
Sound effect
oboe2
Sound effect
oboe3
Sound effect