/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Import music beat plugin
// Note class: represents a falling note
var Note = Container.expand(function () {
var self = Container.call(this);
// Properties: keyIndex (0-3), speed, hit, missed
self.keyIndex = 0;
self.speed = 12; // px per frame
self.hit = false;
self.missed = false;
self.noteAsset = null;
// Set up note asset
self.setType = function (keyIndex) {
self.keyIndex = keyIndex;
var assetId = 'note' + (keyIndex + 1);
self.noteAsset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
// Called every tick
self.update = function () {
self.y += self.speed;
};
// Flash feedback (hit/miss)
self.flash = function (type) {
var flashId = type === 'hit' ? 'hitFlash' : 'missFlash';
var flash = LK.getAsset(flashId, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
flash.alpha = 0.7;
self.addChild(flash);
tween(flash, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
flash.destroy();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xcccccc
});
/****
* Game Code
****/
var NUM_KEYS = 4;
var KEY_WIDTH = 400;
var KEY_HEIGHT = 300;
var KEY_GAP = 12;
var NOTE_WIDTH = 320;
var NOTE_HEIGHT = 120;
var GAME_W = 2048;
var GAME_H = 2732;
var KEY_Y = 120; // distance from bottom
// Add background image (fills the screen, behind all elements)
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: GAME_W,
height: GAME_H
});
game.addChild(background);
// Music
// Sound for hit/miss
// Feedback flash
// Notes: colored ellipses
// Piano keys: white rectangles
// 4 piano keys (white), 4 note shapes (colored), 1 background music
// Piano key layout: 4 keys, bottom of screen, evenly spaced
// Key positions (centered)
var keyPositions = [];
var totalWidth = NUM_KEYS * KEY_WIDTH + (NUM_KEYS - 1) * KEY_GAP;
var startX = (GAME_W - totalWidth) / 2 + KEY_WIDTH / 2;
for (var i = 0; i < NUM_KEYS; i++) {
keyPositions[i] = {
x: startX + i * (KEY_WIDTH + KEY_GAP),
y: GAME_H - KEY_HEIGHT / 2 - KEY_Y
};
}
// Create piano keys
var pianoKeys = [];
for (var i = 0; i < NUM_KEYS; i++) {
var keyAssetId = 'pianoKey' + (i + 1);
var key = new Container();
var keyShape = key.attachAsset(keyAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
key.x = keyPositions[i].x;
key.y = keyPositions[i].y;
key.keyIndex = i;
game.addChild(key);
pianoKeys.push(key);
}
// Score display
var score = 0;
var bestScore = storage.bestScore || 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Best score display (smaller, top right)
var bestScoreTxt = new Text2('Rekor: ' + bestScore, {
size: 60,
fill: "#fff"
});
bestScoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(bestScoreTxt);
// Notes array
var notes = [];
// Note spawn timing
var noteInterval = 38; // frames between notes (approx 1.5 notes/sec)
var noteTimer = 0;
// Feedback for key press (flash)
function flashKey(keyIndex, type) {
var key = pianoKeys[keyIndex];
var flashId = type === 'hit' ? 'hitFlash' : 'missFlash';
var flash = LK.getAsset(flashId, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
flash.alpha = 0.7;
key.addChild(flash);
tween(flash, {
alpha: 0
}, {
duration: 250,
onFinish: function onFinish() {
flash.destroy();
}
});
}
// Touch handling
game.down = function (x, y, obj) {
// Check if touch is on a key
for (var i = 0; i < pianoKeys.length; i++) {
var key = pianoKeys[i];
// Rectangle hit test
var left = key.x - KEY_WIDTH / 2;
var right = key.x + KEY_WIDTH / 2;
var top = key.y - KEY_HEIGHT / 2;
var bottom = key.y + KEY_HEIGHT / 2;
if (x >= left && x <= right && y >= top && y <= bottom) {
// Find the lowest note in this column that is hittable
var hitNote = null;
var hitWindow = 120; // px, how close to key to count as hit
for (var j = 0; j < notes.length; j++) {
var note = notes[j];
if (note.keyIndex === i && !note.hit && !note.missed) {
// Note is in this column
var noteBottom = note.y + NOTE_HEIGHT / 2;
var keyTop = key.y - KEY_HEIGHT / 2;
var keyBottom = key.y + KEY_HEIGHT / 2;
// If note is within hit window above the key (falling down)
if (noteBottom >= keyTop - hitWindow && noteBottom <= keyBottom + hitWindow) {
// For falling notes, prefer the lowest note (closest to the key)
if (!hitNote || note.y > hitNote.y) {
hitNote = note;
}
}
}
}
if (hitNote) {
// Hit!
hitNote.hit = true;
hitNote.flash('hit');
flashKey(i, 'hit');
LK.getSound('hit').play();
score += 1;
if (score > bestScore) {
bestScore = score;
storage.bestScore = bestScore;
bestScoreTxt.setText('Rekor: ' + bestScore);
}
scoreTxt.setText(score);
} else {
// Miss (touched key but no note in window)
flashKey(i, 'miss');
LK.getSound('miss').play();
// Optionally, penalize or just give feedback
}
break;
}
}
};
// No drag or move needed for this game
game.move = function (x, y, obj) {};
game.up = function (x, y, obj) {};
// Game update loop
game.update = function () {
// Adjust note speed based on score
var baseSpeed = 6; // much slower than before
var speedStep = 2.5; // how much to increase per step
var stepScore = 10; // every 10 points after 20, increase speed
var minScore = 20;
var maxSpeed = 22; // cap speed so it doesn't get too fast
var currentSpeed = baseSpeed;
if (score >= minScore) {
// For every stepScore after minScore, increase speed by speedStep
var steps = Math.floor((score - minScore) / stepScore) + 1;
currentSpeed = baseSpeed + steps * speedStep;
if (currentSpeed > maxSpeed) currentSpeed = maxSpeed;
}
// Spawn notes at regular interval
noteTimer++;
if (noteTimer >= noteInterval) {
noteTimer = 0;
var keyIndex = Math.floor(Math.random() * NUM_KEYS);
var note = new Note();
note.setType(keyIndex);
note.x = keyPositions[keyIndex].x;
note.y = 0 - NOTE_HEIGHT / 2; // Spawn at the very top
note.lastY = note.y;
note.lastHit = false;
note.speed = currentSpeed; // set speed based on score
notes.push(note);
game.addChild(note);
}
// Update notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
note.update();
// If note is hit, remove after short delay
if (note.hit) {
note.destroy();
notes.splice(i, 1);
continue;
}
// If note passes below the key and not hit, mark as missed
var key = pianoKeys[note.keyIndex];
var keyBottom = key.y + KEY_HEIGHT / 2;
if (!note.missed && note.y - NOTE_HEIGHT / 2 > keyBottom + 40) {
note.missed = true;
note.flash('miss');
flashKey(note.keyIndex, 'miss');
LK.getSound('miss').play();
// End game on miss
LK.effects.flashScreen(0xe57373, 600);
if (score > bestScore) {
bestScore = score;
storage.bestScore = bestScore;
}
LK.stopMusic();
LK.showGameOver();
return;
}
// Remove notes that are far off screen
if (note.y - NOTE_HEIGHT / 2 > GAME_H + 200) {
note.destroy();
notes.splice(i, 1);
}
}
};
// Start music
game.onStart = function () {
LK.stopMusic();
LK.playMusic('piano', {
loop: true,
fade: {
start: 1,
end: 1,
duration: 0
},
start: 0 // always start from the beginning
});
// Reset note timer
noteTimer = 0;
};
// Stop music when game ends
game.onGameOver = function () {
LK.stopMusic();
noteTimer = 0;
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// Import music beat plugin
// Note class: represents a falling note
var Note = Container.expand(function () {
var self = Container.call(this);
// Properties: keyIndex (0-3), speed, hit, missed
self.keyIndex = 0;
self.speed = 12; // px per frame
self.hit = false;
self.missed = false;
self.noteAsset = null;
// Set up note asset
self.setType = function (keyIndex) {
self.keyIndex = keyIndex;
var assetId = 'note' + (keyIndex + 1);
self.noteAsset = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
};
// Called every tick
self.update = function () {
self.y += self.speed;
};
// Flash feedback (hit/miss)
self.flash = function (type) {
var flashId = type === 'hit' ? 'hitFlash' : 'missFlash';
var flash = LK.getAsset(flashId, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
flash.alpha = 0.7;
self.addChild(flash);
tween(flash, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
flash.destroy();
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xcccccc
});
/****
* Game Code
****/
var NUM_KEYS = 4;
var KEY_WIDTH = 400;
var KEY_HEIGHT = 300;
var KEY_GAP = 12;
var NOTE_WIDTH = 320;
var NOTE_HEIGHT = 120;
var GAME_W = 2048;
var GAME_H = 2732;
var KEY_Y = 120; // distance from bottom
// Add background image (fills the screen, behind all elements)
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0,
width: GAME_W,
height: GAME_H
});
game.addChild(background);
// Music
// Sound for hit/miss
// Feedback flash
// Notes: colored ellipses
// Piano keys: white rectangles
// 4 piano keys (white), 4 note shapes (colored), 1 background music
// Piano key layout: 4 keys, bottom of screen, evenly spaced
// Key positions (centered)
var keyPositions = [];
var totalWidth = NUM_KEYS * KEY_WIDTH + (NUM_KEYS - 1) * KEY_GAP;
var startX = (GAME_W - totalWidth) / 2 + KEY_WIDTH / 2;
for (var i = 0; i < NUM_KEYS; i++) {
keyPositions[i] = {
x: startX + i * (KEY_WIDTH + KEY_GAP),
y: GAME_H - KEY_HEIGHT / 2 - KEY_Y
};
}
// Create piano keys
var pianoKeys = [];
for (var i = 0; i < NUM_KEYS; i++) {
var keyAssetId = 'pianoKey' + (i + 1);
var key = new Container();
var keyShape = key.attachAsset(keyAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
key.x = keyPositions[i].x;
key.y = keyPositions[i].y;
key.keyIndex = i;
game.addChild(key);
pianoKeys.push(key);
}
// Score display
var score = 0;
var bestScore = storage.bestScore || 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Best score display (smaller, top right)
var bestScoreTxt = new Text2('Rekor: ' + bestScore, {
size: 60,
fill: "#fff"
});
bestScoreTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(bestScoreTxt);
// Notes array
var notes = [];
// Note spawn timing
var noteInterval = 38; // frames between notes (approx 1.5 notes/sec)
var noteTimer = 0;
// Feedback for key press (flash)
function flashKey(keyIndex, type) {
var key = pianoKeys[keyIndex];
var flashId = type === 'hit' ? 'hitFlash' : 'missFlash';
var flash = LK.getAsset(flashId, {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
flash.alpha = 0.7;
key.addChild(flash);
tween(flash, {
alpha: 0
}, {
duration: 250,
onFinish: function onFinish() {
flash.destroy();
}
});
}
// Touch handling
game.down = function (x, y, obj) {
// Check if touch is on a key
for (var i = 0; i < pianoKeys.length; i++) {
var key = pianoKeys[i];
// Rectangle hit test
var left = key.x - KEY_WIDTH / 2;
var right = key.x + KEY_WIDTH / 2;
var top = key.y - KEY_HEIGHT / 2;
var bottom = key.y + KEY_HEIGHT / 2;
if (x >= left && x <= right && y >= top && y <= bottom) {
// Find the lowest note in this column that is hittable
var hitNote = null;
var hitWindow = 120; // px, how close to key to count as hit
for (var j = 0; j < notes.length; j++) {
var note = notes[j];
if (note.keyIndex === i && !note.hit && !note.missed) {
// Note is in this column
var noteBottom = note.y + NOTE_HEIGHT / 2;
var keyTop = key.y - KEY_HEIGHT / 2;
var keyBottom = key.y + KEY_HEIGHT / 2;
// If note is within hit window above the key (falling down)
if (noteBottom >= keyTop - hitWindow && noteBottom <= keyBottom + hitWindow) {
// For falling notes, prefer the lowest note (closest to the key)
if (!hitNote || note.y > hitNote.y) {
hitNote = note;
}
}
}
}
if (hitNote) {
// Hit!
hitNote.hit = true;
hitNote.flash('hit');
flashKey(i, 'hit');
LK.getSound('hit').play();
score += 1;
if (score > bestScore) {
bestScore = score;
storage.bestScore = bestScore;
bestScoreTxt.setText('Rekor: ' + bestScore);
}
scoreTxt.setText(score);
} else {
// Miss (touched key but no note in window)
flashKey(i, 'miss');
LK.getSound('miss').play();
// Optionally, penalize or just give feedback
}
break;
}
}
};
// No drag or move needed for this game
game.move = function (x, y, obj) {};
game.up = function (x, y, obj) {};
// Game update loop
game.update = function () {
// Adjust note speed based on score
var baseSpeed = 6; // much slower than before
var speedStep = 2.5; // how much to increase per step
var stepScore = 10; // every 10 points after 20, increase speed
var minScore = 20;
var maxSpeed = 22; // cap speed so it doesn't get too fast
var currentSpeed = baseSpeed;
if (score >= minScore) {
// For every stepScore after minScore, increase speed by speedStep
var steps = Math.floor((score - minScore) / stepScore) + 1;
currentSpeed = baseSpeed + steps * speedStep;
if (currentSpeed > maxSpeed) currentSpeed = maxSpeed;
}
// Spawn notes at regular interval
noteTimer++;
if (noteTimer >= noteInterval) {
noteTimer = 0;
var keyIndex = Math.floor(Math.random() * NUM_KEYS);
var note = new Note();
note.setType(keyIndex);
note.x = keyPositions[keyIndex].x;
note.y = 0 - NOTE_HEIGHT / 2; // Spawn at the very top
note.lastY = note.y;
note.lastHit = false;
note.speed = currentSpeed; // set speed based on score
notes.push(note);
game.addChild(note);
}
// Update notes
for (var i = notes.length - 1; i >= 0; i--) {
var note = notes[i];
note.update();
// If note is hit, remove after short delay
if (note.hit) {
note.destroy();
notes.splice(i, 1);
continue;
}
// If note passes below the key and not hit, mark as missed
var key = pianoKeys[note.keyIndex];
var keyBottom = key.y + KEY_HEIGHT / 2;
if (!note.missed && note.y - NOTE_HEIGHT / 2 > keyBottom + 40) {
note.missed = true;
note.flash('miss');
flashKey(note.keyIndex, 'miss');
LK.getSound('miss').play();
// End game on miss
LK.effects.flashScreen(0xe57373, 600);
if (score > bestScore) {
bestScore = score;
storage.bestScore = bestScore;
}
LK.stopMusic();
LK.showGameOver();
return;
}
// Remove notes that are far off screen
if (note.y - NOTE_HEIGHT / 2 > GAME_H + 200) {
note.destroy();
notes.splice(i, 1);
}
}
};
// Start music
game.onStart = function () {
LK.stopMusic();
LK.playMusic('piano', {
loop: true,
fade: {
start: 1,
end: 1,
duration: 0
},
start: 0 // always start from the beginning
});
// Reset note timer
noteTimer = 0;
};
// Stop music when game ends
game.onGameOver = function () {
LK.stopMusic();
noteTimer = 0;
};
piyano tuşu. In-Game asset. 2d. High contrast. No shadows
dark mode müzik çalınan mekan. In-Game asset. 2d. High contrast. No shadows
kızgın surat. In-Game asset. 2d. High contrast. No shadows
müzik dinleyen neşeli surat. In-Game asset. 2d. High contrast. No shadows
müzik aleti beyaz. In-Game asset. 2d. High contrast. No shadows