/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Decoy character class var DecoyChar = Container.expand(function () { var self = Container.call(this); var _char = self.attachAsset('decoyChar', { anchorX: 0.5, anchorY: 0.5 }); // Add "X" text centered var txt = new Text2('X', { size: 90, fill: 0xFFFFFF }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; self.addChild(txt); self.isMerhaba = false; self.isActive = true; // Tap handler self.down = function (x, y, obj) { if (!self.isActive) return; self.isActive = false; handleDecoyTap(self); }; return self; }); // Merhaba character class var MerhabaChar = Container.expand(function () { var self = Container.call(this); var _char2 = self.attachAsset('merhabaChar', { anchorX: 0.5, anchorY: 0.5 }); // Add "Click" text centered var txt = new Text2('Click', { size: 70, fill: 0xFFFFFF }); txt.anchor.set(0.5, 0.5); txt.x = 0; txt.y = 0; self.addChild(txt); self.isMerhaba = true; self.isActive = true; // Tap handler self.down = function (x, y, obj) { if (!self.isActive) return; self.isActive = false; handleMerhabaTap(self); }; return self; }); // Tap effect class var TapEffect = Container.expand(function () { var self = Container.call(this); var eff = self.attachAsset('tapEffect', { anchorX: 0.5, anchorY: 0.5 }); eff.alpha = 0.5; self.eff = eff; self.play = function (x, y) { self.x = x; self.y = y; self.visible = true; eff.scaleX = 1; eff.scaleY = 1; eff.alpha = 0.5; tween(eff, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 350, easing: tween.easeOut, onFinish: function onFinish() { self.visible = false; } }); }; self.visible = false; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222831 }); /**** * Game Code ****/ // Game variables // Friendly "Merhaba" character: green ellipse with "Merhaba" text // Decoy character: red ellipse with "X" text // Life icon: small yellow ellipse // Tap effect: white ellipse // Sound for correct tap // Sound for wrong tap // Sound for losing a life // Sound for new spawn var score = 0; var lives = 3; var maxLives = 3; var activeChars = []; var charLifetime = 1200; // ms, will decrease as score increases var minCharLifetime = 500; // ms var spawnInterval = 900; // ms, will decrease as score increases var minSpawnInterval = 350; // ms var lastSpawnTime = 0; var isGameOver = false; var tapEffect; // Score display var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Lives display var lifeIcons = []; function updateLivesDisplay() { // Remove old icons for (var i = 0; i < lifeIcons.length; i++) { if (lifeIcons[i].parent) lifeIcons[i].parent.removeChild(lifeIcons[i]); } lifeIcons = []; // Place at top right, with margin var margin = 30; for (var i = 0; i < lives; i++) { var icon = LK.getAsset('lifeIcon', { anchorX: 0.5, anchorY: 0.5 }); icon.x = -(i * 70) - 60; icon.y = 60; LK.gui.topRight.addChild(icon); lifeIcons.push(icon); } } updateLivesDisplay(); // Tap effect instance tapEffect = new TapEffect(); game.addChild(tapEffect); // Helper: get random position for character, avoiding top left 100x100 function getRandomCharPos() { var margin = 180; var x = margin + Math.random() * (2048 - 2 * margin); var y = margin + Math.random() * (2732 - 2 * margin); // Avoid top left 100x100 if (x < 100 && y < 100) x = 100 + margin; return { x: x, y: y }; } // Helper: spawn a character (merhaba or decoy) function spawnChar() { if (isGameOver) return; var isMerhaba = Math.random() < 0.7; // 70% chance merhaba, 30% decoy var _char3; if (isMerhaba) { _char3 = new MerhabaChar(); } else { _char3 = new DecoyChar(); } var pos = getRandomCharPos(); _char3.x = pos.x; _char3.y = pos.y; _char3.scaleX = 0.7; _char3.scaleY = 0.7; _char3.alpha = 0; // Animate in tween(_char3, { scaleX: 1, scaleY: 1, alpha: 1 }, { duration: 180, easing: tween.easeOut }); game.addChild(_char3); activeChars.push({ obj: _char3, isMerhaba: isMerhaba, spawnTime: Date.now(), isActive: true }); LK.getSound('spawn').play(); } // Helper: handle tap on Merhaba function handleMerhabaTap(charObj) { if (isGameOver) return; // Find in activeChars for (var i = 0; i < activeChars.length; i++) { var c = activeChars[i]; if (c.obj === charObj && c.isActive) { c.isActive = false; // Score up score += 1; LK.setScore(score); scoreTxt.setText(score); // Tap effect tapEffect.play(charObj.x, charObj.y); // Animate out tween(charObj, { scaleX: 1.3, scaleY: 1.3, alpha: 0 }, { duration: 180, easing: tween.easeIn, onFinish: function onFinish() { charObj.destroy(); } }); LK.getSound('goodTap').play(); // Remove from activeChars activeChars.splice(i, 1); // Speed up game updateDifficulty(); return; } } } // Helper: handle tap on Decoy function handleDecoyTap(charObj) { if (isGameOver) return; // Find in activeChars for (var i = 0; i < activeChars.length; i++) { var c = activeChars[i]; if (c.obj === charObj && c.isActive) { c.isActive = false; // Lose a life loseLife(charObj.x, charObj.y); // Animate out tween(charObj, { scaleX: 0.7, scaleY: 0.7, alpha: 0 }, { duration: 180, easing: tween.easeIn, onFinish: function onFinish() { charObj.destroy(); } }); LK.getSound('badTap').play(); // Remove from activeChars activeChars.splice(i, 1); return; } } } // Helper: lose a life function loseLife(x, y) { if (isGameOver) return; lives -= 1; updateLivesDisplay(); LK.getSound('loseLife').play(); // Flash screen LK.effects.flashScreen(0xff0000, 300); if (lives <= 0) { endGame(); } } // Helper: update difficulty as score increases function updateDifficulty() { // Decrease charLifetime and spawnInterval as score increases var speedup = Math.floor(score / 5); charLifetime = Math.max(minCharLifetime, 1200 - speedup * 70); spawnInterval = Math.max(minSpawnInterval, 900 - speedup * 40); } // Helper: end game function endGame() { isGameOver = true; // Remove all active chars for (var i = 0; i < activeChars.length; i++) { if (activeChars[i].obj && activeChars[i].obj.parent) { activeChars[i].obj.destroy(); } } activeChars = []; // Show game over LK.showGameOver(); } // Game tap handler (for missed taps) game.down = function (x, y, obj) { // If tap is not on any character, do nothing // (Characters handle their own tap events) }; // Main update loop game.update = function () { if (isGameOver) return; var now = Date.now(); // Spawn new char if enough time has passed if (activeChars.length < 2 && now - lastSpawnTime > spawnInterval) { spawnChar(); lastSpawnTime = now; } // Remove expired chars for (var i = activeChars.length - 1; i >= 0; i--) { var c = activeChars[i]; if (!c || !c.isActive) continue; if (now - c.spawnTime > charLifetime) { // If it's a Merhaba, missing it costs a life if (c.isMerhaba) { loseLife(c.obj.x, c.obj.y); // Animate out tween(c.obj, { scaleX: 0.7, scaleY: 0.7, alpha: 0 }, { duration: 180, easing: tween.easeIn, onFinish: function (obj) { if (obj && obj.parent) obj.destroy(); }.bind(null, c.obj) }); } else { // Decoy just disappears tween(c.obj, { scaleX: 0.7, scaleY: 0.7, alpha: 0 }, { duration: 180, easing: tween.easeIn, onFinish: function (obj) { if (obj && obj.parent) obj.destroy(); }.bind(null, c.obj) }); } c.isActive = false; activeChars.splice(i, 1); } } }; // Reset game state on new game LK.on('gameStart', function () { score = 0; lives = maxLives; isGameOver = false; activeChars = []; charLifetime = 1200; spawnInterval = 900; lastSpawnTime = 0; scoreTxt.setText(score); updateLivesDisplay(); // Remove all children except tapEffect var toRemove = []; for (var i = 0; i < game.children.length; i++) { var ch = game.children[i]; if (ch !== tapEffect) toRemove.push(ch); } for (var i = 0; i < toRemove.length; i++) { if (toRemove[i].parent) toRemove[i].parent.removeChild(toRemove[i]); } tapEffect.visible = false; // Play background music LK.playMusic('1'); });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Decoy character class
var DecoyChar = Container.expand(function () {
var self = Container.call(this);
var _char = self.attachAsset('decoyChar', {
anchorX: 0.5,
anchorY: 0.5
});
// Add "X" text centered
var txt = new Text2('X', {
size: 90,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = 0;
self.addChild(txt);
self.isMerhaba = false;
self.isActive = true;
// Tap handler
self.down = function (x, y, obj) {
if (!self.isActive) return;
self.isActive = false;
handleDecoyTap(self);
};
return self;
});
// Merhaba character class
var MerhabaChar = Container.expand(function () {
var self = Container.call(this);
var _char2 = self.attachAsset('merhabaChar', {
anchorX: 0.5,
anchorY: 0.5
});
// Add "Click" text centered
var txt = new Text2('Click', {
size: 70,
fill: 0xFFFFFF
});
txt.anchor.set(0.5, 0.5);
txt.x = 0;
txt.y = 0;
self.addChild(txt);
self.isMerhaba = true;
self.isActive = true;
// Tap handler
self.down = function (x, y, obj) {
if (!self.isActive) return;
self.isActive = false;
handleMerhabaTap(self);
};
return self;
});
// Tap effect class
var TapEffect = Container.expand(function () {
var self = Container.call(this);
var eff = self.attachAsset('tapEffect', {
anchorX: 0.5,
anchorY: 0.5
});
eff.alpha = 0.5;
self.eff = eff;
self.play = function (x, y) {
self.x = x;
self.y = y;
self.visible = true;
eff.scaleX = 1;
eff.scaleY = 1;
eff.alpha = 0.5;
tween(eff, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 350,
easing: tween.easeOut,
onFinish: function onFinish() {
self.visible = false;
}
});
};
self.visible = false;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222831
});
/****
* Game Code
****/
// Game variables
// Friendly "Merhaba" character: green ellipse with "Merhaba" text
// Decoy character: red ellipse with "X" text
// Life icon: small yellow ellipse
// Tap effect: white ellipse
// Sound for correct tap
// Sound for wrong tap
// Sound for losing a life
// Sound for new spawn
var score = 0;
var lives = 3;
var maxLives = 3;
var activeChars = [];
var charLifetime = 1200; // ms, will decrease as score increases
var minCharLifetime = 500; // ms
var spawnInterval = 900; // ms, will decrease as score increases
var minSpawnInterval = 350; // ms
var lastSpawnTime = 0;
var isGameOver = false;
var tapEffect;
// Score display
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Lives display
var lifeIcons = [];
function updateLivesDisplay() {
// Remove old icons
for (var i = 0; i < lifeIcons.length; i++) {
if (lifeIcons[i].parent) lifeIcons[i].parent.removeChild(lifeIcons[i]);
}
lifeIcons = [];
// Place at top right, with margin
var margin = 30;
for (var i = 0; i < lives; i++) {
var icon = LK.getAsset('lifeIcon', {
anchorX: 0.5,
anchorY: 0.5
});
icon.x = -(i * 70) - 60;
icon.y = 60;
LK.gui.topRight.addChild(icon);
lifeIcons.push(icon);
}
}
updateLivesDisplay();
// Tap effect instance
tapEffect = new TapEffect();
game.addChild(tapEffect);
// Helper: get random position for character, avoiding top left 100x100
function getRandomCharPos() {
var margin = 180;
var x = margin + Math.random() * (2048 - 2 * margin);
var y = margin + Math.random() * (2732 - 2 * margin);
// Avoid top left 100x100
if (x < 100 && y < 100) x = 100 + margin;
return {
x: x,
y: y
};
}
// Helper: spawn a character (merhaba or decoy)
function spawnChar() {
if (isGameOver) return;
var isMerhaba = Math.random() < 0.7; // 70% chance merhaba, 30% decoy
var _char3;
if (isMerhaba) {
_char3 = new MerhabaChar();
} else {
_char3 = new DecoyChar();
}
var pos = getRandomCharPos();
_char3.x = pos.x;
_char3.y = pos.y;
_char3.scaleX = 0.7;
_char3.scaleY = 0.7;
_char3.alpha = 0;
// Animate in
tween(_char3, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 180,
easing: tween.easeOut
});
game.addChild(_char3);
activeChars.push({
obj: _char3,
isMerhaba: isMerhaba,
spawnTime: Date.now(),
isActive: true
});
LK.getSound('spawn').play();
}
// Helper: handle tap on Merhaba
function handleMerhabaTap(charObj) {
if (isGameOver) return;
// Find in activeChars
for (var i = 0; i < activeChars.length; i++) {
var c = activeChars[i];
if (c.obj === charObj && c.isActive) {
c.isActive = false;
// Score up
score += 1;
LK.setScore(score);
scoreTxt.setText(score);
// Tap effect
tapEffect.play(charObj.x, charObj.y);
// Animate out
tween(charObj, {
scaleX: 1.3,
scaleY: 1.3,
alpha: 0
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
charObj.destroy();
}
});
LK.getSound('goodTap').play();
// Remove from activeChars
activeChars.splice(i, 1);
// Speed up game
updateDifficulty();
return;
}
}
}
// Helper: handle tap on Decoy
function handleDecoyTap(charObj) {
if (isGameOver) return;
// Find in activeChars
for (var i = 0; i < activeChars.length; i++) {
var c = activeChars[i];
if (c.obj === charObj && c.isActive) {
c.isActive = false;
// Lose a life
loseLife(charObj.x, charObj.y);
// Animate out
tween(charObj, {
scaleX: 0.7,
scaleY: 0.7,
alpha: 0
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function onFinish() {
charObj.destroy();
}
});
LK.getSound('badTap').play();
// Remove from activeChars
activeChars.splice(i, 1);
return;
}
}
}
// Helper: lose a life
function loseLife(x, y) {
if (isGameOver) return;
lives -= 1;
updateLivesDisplay();
LK.getSound('loseLife').play();
// Flash screen
LK.effects.flashScreen(0xff0000, 300);
if (lives <= 0) {
endGame();
}
}
// Helper: update difficulty as score increases
function updateDifficulty() {
// Decrease charLifetime and spawnInterval as score increases
var speedup = Math.floor(score / 5);
charLifetime = Math.max(minCharLifetime, 1200 - speedup * 70);
spawnInterval = Math.max(minSpawnInterval, 900 - speedup * 40);
}
// Helper: end game
function endGame() {
isGameOver = true;
// Remove all active chars
for (var i = 0; i < activeChars.length; i++) {
if (activeChars[i].obj && activeChars[i].obj.parent) {
activeChars[i].obj.destroy();
}
}
activeChars = [];
// Show game over
LK.showGameOver();
}
// Game tap handler (for missed taps)
game.down = function (x, y, obj) {
// If tap is not on any character, do nothing
// (Characters handle their own tap events)
};
// Main update loop
game.update = function () {
if (isGameOver) return;
var now = Date.now();
// Spawn new char if enough time has passed
if (activeChars.length < 2 && now - lastSpawnTime > spawnInterval) {
spawnChar();
lastSpawnTime = now;
}
// Remove expired chars
for (var i = activeChars.length - 1; i >= 0; i--) {
var c = activeChars[i];
if (!c || !c.isActive) continue;
if (now - c.spawnTime > charLifetime) {
// If it's a Merhaba, missing it costs a life
if (c.isMerhaba) {
loseLife(c.obj.x, c.obj.y);
// Animate out
tween(c.obj, {
scaleX: 0.7,
scaleY: 0.7,
alpha: 0
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function (obj) {
if (obj && obj.parent) obj.destroy();
}.bind(null, c.obj)
});
} else {
// Decoy just disappears
tween(c.obj, {
scaleX: 0.7,
scaleY: 0.7,
alpha: 0
}, {
duration: 180,
easing: tween.easeIn,
onFinish: function (obj) {
if (obj && obj.parent) obj.destroy();
}.bind(null, c.obj)
});
}
c.isActive = false;
activeChars.splice(i, 1);
}
}
};
// Reset game state on new game
LK.on('gameStart', function () {
score = 0;
lives = maxLives;
isGameOver = false;
activeChars = [];
charLifetime = 1200;
spawnInterval = 900;
lastSpawnTime = 0;
scoreTxt.setText(score);
updateLivesDisplay();
// Remove all children except tapEffect
var toRemove = [];
for (var i = 0; i < game.children.length; i++) {
var ch = game.children[i];
if (ch !== tapEffect) toRemove.push(ch);
}
for (var i = 0; i < toRemove.length; i++) {
if (toRemove[i].parent) toRemove[i].parent.removeChild(toRemove[i]);
}
tapEffect.visible = false;
// Play background music
LK.playMusic('1');
});
goat. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
evil heart. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
goat's hand. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat