/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Block = Container.expand(function () {
var self = Container.call(this);
self.blockType = 'normal';
self.fallSpeed = 5;
self.points = 10;
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
self.setColor = function (color) {
blockGraphics.tint = color;
};
self.setPowerUp = function (type) {
self.blockType = type;
self.removeChildren();
var powerupGraphics = self.attachAsset('powerupBlock', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 50;
};
self.update = function () {
self.y += self.fallSpeed;
// Add subtle rotation while falling
self.rotation += 0.02;
};
self.down = function (x, y, obj) {
if (self.parent) {
handleBlockTap(self);
}
};
return self;
});
var Heart = Container.expand(function () {
var self = Container.call(this);
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var MenuScreen = Container.expand(function () {
var self = Container.call(this);
// Background overlay
var bg = self.attachAsset('menuBg', {
width: 2048,
height: 2732,
color: 0x000000,
shape: 'box',
anchorX: 0,
anchorY: 0
});
bg.alpha = 0;
// Animate background fade in
tween(bg, {
alpha: 0.8
}, {
duration: 800,
easing: tween.easeOut
});
// Game title
var titleTxt = new Text2(getText('title'), {
size: 120,
fill: 0xFFFF00
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 1024;
titleTxt.y = 350; // Start higher
titleTxt.alpha = 0;
self.addChild(titleTxt);
// Animate title slide down and fade in
tween(titleTxt, {
y: 550,
alpha: 1
}, {
duration: 1000,
easing: tween.elasticOut
});
var subtitleTxt = new Text2(getText('subtitle'), {
size: 100,
fill: 0xFF4444
});
subtitleTxt.anchor.set(0.5, 0.5);
subtitleTxt.x = 1024;
subtitleTxt.y = 700;
self.addChild(subtitleTxt);
// Language selection
var languageTxt = new Text2(getText('language'), {
size: 60,
fill: 0xFFFFFF
});
languageTxt.anchor.set(0.5, 0.5);
languageTxt.x = 1024;
languageTxt.y = 850;
self.addChild(languageTxt);
// Language buttons
var enBtn = self.attachAsset('startBtn', {
width: 200,
height: 80,
color: 0x4444FF,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
enBtn.x = 700;
enBtn.y = 920;
var enTxt = new Text2('EN', {
size: 50,
fill: 0x000000
});
enTxt.anchor.set(0.5, 0.5);
enTxt.x = 700;
enTxt.y = 920;
self.addChild(enTxt);
var trBtn = self.attachAsset('startBtn', {
width: 200,
height: 80,
color: 0x4444FF,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
trBtn.x = 1024;
trBtn.y = 920;
var trTxt = new Text2('TR', {
size: 50,
fill: 0x000000
});
trTxt.anchor.set(0.5, 0.5);
trTxt.x = 1024;
trTxt.y = 920;
self.addChild(trTxt);
var deBtn = self.attachAsset('startBtn', {
width: 200,
height: 80,
color: 0x4444FF,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
deBtn.x = 1348;
deBtn.y = 920;
var deTxt = new Text2('DE', {
size: 50,
fill: 0x000000
});
deTxt.anchor.set(0.5, 0.5);
deTxt.x = 1348;
deTxt.y = 920;
self.addChild(deTxt);
// Difficulty selection
var difficultyTxt = new Text2(getText('difficulty'), {
size: 70,
fill: 0xFFFFFF
});
difficultyTxt.anchor.set(0.5, 0.5);
difficultyTxt.x = 1024;
difficultyTxt.y = 1050;
self.addChild(difficultyTxt);
// Easy button
var easyBtn = self.attachAsset('startBtn', {
width: 300,
height: 100,
color: 0x44FF44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
easyBtn.x = 700;
easyBtn.y = 1200;
var easyTxt = new Text2(getText('easy'), {
size: 60,
fill: 0x000000
});
easyTxt.anchor.set(0.5, 0.5);
easyTxt.x = 700;
easyTxt.y = 1200;
self.addChild(easyTxt);
// Medium button
var mediumBtn = self.attachAsset('startBtn', {
width: 300,
height: 100,
color: 0xFFFF44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
mediumBtn.x = 1024;
mediumBtn.y = 1200;
var mediumTxt = new Text2(getText('medium'), {
size: 60,
fill: 0x000000
});
mediumTxt.anchor.set(0.5, 0.5);
mediumTxt.x = 1024;
mediumTxt.y = 1200;
self.addChild(mediumTxt);
// Hard button
var hardBtn = self.attachAsset('startBtn', {
width: 300,
height: 100,
color: 0xFF4444,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
hardBtn.x = 1348;
hardBtn.y = 1200;
var hardTxt = new Text2(getText('hard'), {
size: 60,
fill: 0x4444FF
});
hardTxt.anchor.set(0.5, 0.5);
hardTxt.x = 1348;
hardTxt.y = 1200;
self.addChild(hardTxt);
// Start button
var startBtn = self.attachAsset('startBtn', {
width: 400,
height: 150,
color: 0x44FF44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
startBtn.x = 1024;
startBtn.y = 1500;
var startTxt = new Text2(getText('start'), {
size: 80,
fill: 0x000000
});
startTxt.anchor.set(0.5, 0.5);
startTxt.x = 1024;
startTxt.y = 1500;
self.addChild(startTxt);
// High score display
var highScoreTxt = new Text2(getText('highScore') + '0', {
size: 60,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0.5, 0.5);
highScoreTxt.x = 1024;
highScoreTxt.y = 1800;
self.addChild(highScoreTxt);
// Selected difficulty
var selectedDifficulty = 1; // 0=easy, 1=medium, 2=hard
var selectedTxt = new Text2(getText('selected') + getText('medium'), {
size: 50,
fill: 0xFFFF00
});
selectedTxt.anchor.set(0.5, 0.5);
selectedTxt.x = 1024;
selectedTxt.y = 1350;
self.addChild(selectedTxt);
self.updateHighScore = function () {
var highScore = storage.highScore || 0;
highScoreTxt.setText(getText('highScore') + highScore);
};
self.refreshLanguage = function () {
titleTxt.setText(getText('title'));
subtitleTxt.setText(getText('subtitle'));
languageTxt.setText(getText('language'));
difficultyTxt.setText(getText('difficulty'));
easyTxt.setText(getText('easy'));
mediumTxt.setText(getText('medium'));
hardTxt.setText(getText('hard'));
startTxt.setText(getText('start'));
var diffNames = [getText('easy'), getText('medium'), getText('hard')];
selectedTxt.setText(getText('selected') + diffNames[selectedDifficulty]);
self.updateHighScore();
};
// Language button handlers
enBtn.down = function () {
LK.getSound('menuClick').play();
currentLanguage = 'en';
storage.language = 'en';
self.refreshLanguage();
enBtn.tint = 0xAAAAFF;
trBtn.tint = 0xFFFFFF;
deBtn.tint = 0xFFFFFF;
};
trBtn.down = function () {
LK.getSound('menuClick').play();
currentLanguage = 'tr';
storage.language = 'tr';
self.refreshLanguage();
enBtn.tint = 0xFFFFFF;
trBtn.tint = 0xAAAAFF;
deBtn.tint = 0xFFFFFF;
};
deBtn.down = function () {
LK.getSound('menuClick').play();
currentLanguage = 'de';
storage.language = 'de';
self.refreshLanguage();
enBtn.tint = 0xFFFFFF;
trBtn.tint = 0xFFFFFF;
deBtn.tint = 0xAAAAFF;
};
// Set initial language highlight
if (currentLanguage === 'en') {
enBtn.tint = 0xAAAAFF;
} else if (currentLanguage === 'tr') {
trBtn.tint = 0xAAAAFF;
} else if (currentLanguage === 'de') {
deBtn.tint = 0xAAAAFF;
}
easyBtn.down = function () {
LK.getSound('menuClick').play();
selectedDifficulty = 0;
selectedTxt.setText(getText('selected') + getText('easy'));
easyBtn.tint = 0xAAFFAA;
mediumBtn.tint = 0xFFFFFF;
hardBtn.tint = 0xFFFFFF;
// Animate button press
tween(easyBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(easyBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
mediumBtn.down = function () {
LK.getSound('menuClick').play();
selectedDifficulty = 1;
selectedTxt.setText(getText('selected') + getText('medium'));
easyBtn.tint = 0xFFFFFF;
mediumBtn.tint = 0xFFFFAA;
hardBtn.tint = 0xFFFFFF;
// Animate button press
tween(mediumBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(mediumBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
hardBtn.down = function () {
LK.getSound('menuClick').play();
selectedDifficulty = 2;
selectedTxt.setText(getText('selected') + getText('hard'));
easyBtn.tint = 0xFFFFFF;
mediumBtn.tint = 0xFFFFFF;
hardBtn.tint = 0xFFAAAA;
// Animate button press
tween(hardBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(hardBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
startBtn.down = function () {
LK.getSound('gameStart').play();
// Animate start button
tween(startBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(startBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
if (self.onStart) {
self.onStart(selectedDifficulty);
}
};
// Set initial selection highlight
mediumBtn.tint = 0xFFFFAA;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Language system
var currentLanguage = storage.language || 'tr'; // Default to Turkish
var languages = {
en: {
title: 'SNOTTY KID',
subtitle: 'ON THE RUN',
difficulty: 'Difficulty Level',
easy: 'EASY',
medium: 'MEDIUM',
hard: 'HARD',
start: 'START',
highScore: 'High Score: ',
selected: 'Selected: ',
score: 'Score: ',
combo: 'Combo x',
language: 'Language'
},
tr: {
title: 'SÜMÜKLÜ ÇOCUK',
subtitle: 'FİRARDA',
difficulty: 'Zorluk Seviyesi',
easy: 'KOLAY',
medium: 'ORTA',
hard: 'ZOR',
start: 'BAŞLA',
highScore: 'En Yüksek Skor: ',
selected: 'Seçilen: ',
score: 'Score: ',
combo: 'Combo x',
language: 'Dil'
},
de: {
title: 'ROTZIGES KIND',
subtitle: 'AUF DER FLUCHT',
difficulty: 'Schwierigkeitsgrad',
easy: 'EINFACH',
medium: 'MITTEL',
hard: 'SCHWER',
start: 'START',
highScore: 'Höchste Punktzahl: ',
selected: 'Ausgewählt: ',
score: 'Punkte: ',
combo: 'Combo x',
language: 'Sprache'
}
};
function getText(key) {
return languages[currentLanguage][key];
}
// Game variables
var blocks = [];
var lives = 3;
var score = 0;
var combo = 0;
var bestCombo = 0;
var gameSpeed = 5;
var powerUpActive = null;
var powerUpTimer = null;
var difficultyTimer = null;
var spawnTimer = null;
var hearts = [];
var gameStarted = false;
var menuScreen = null;
var gameDifficulty = 1; // 0=easy, 1=medium, 2=hard
var difficultySettings = {
0: {
startSpeed: 3,
maxSpeed: 15,
spawnRate: 1000,
powerUpChance: 0.05
},
// Easy
1: {
startSpeed: 5,
maxSpeed: 25,
spawnRate: 800,
powerUpChance: 0.03
},
// Medium
2: {
startSpeed: 8,
maxSpeed: 35,
spawnRate: 600,
powerUpChance: 0.02
} // Hard
};
// Block colors
var blockColors = [0xff4444, 0x44ff44, 0x4444ff, 0xff44ff, 0x44ffff];
var powerUpTypes = ['slowmo', 'clear', 'extralife'];
// UI Elements
var scoreTxt = new Text2(getText('score') + '0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var comboTxt = new Text2('', {
size: 60,
fill: 0xFFFF00
});
comboTxt.anchor.set(0.5, 0);
comboTxt.y = 100;
LK.gui.top.addChild(comboTxt);
// Lives display
var livesContainer = new Container();
livesContainer.x = -50; // Moved left to ensure hearts stay on screen
livesContainer.y = 50;
LK.gui.topRight.addChild(livesContainer);
// Initialize hearts
function updateLivesDisplay() {
livesContainer.removeChildren();
hearts = [];
for (var i = 0; i < lives; i++) {
var heart = new Heart();
heart.x = -i * 50; // Reduced spacing to fit better
hearts.push(heart);
livesContainer.addChild(heart);
// Add gentle pulsing animation to hearts
var pulseHeart = function pulseHeart(h, delay) {
LK.setTimeout(function () {
var _pulse = function pulse() {
tween(h, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(h, {
scaleX: 1,
scaleY: 1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: _pulse
});
}
});
};
_pulse();
}, delay);
};
pulseHeart(heart, i * 200);
}
}
// Game functions
function spawnBlock() {
var block = new Block();
block.x = Math.random() * (2048 - 200) + 100;
block.y = -100;
// Random chance for power-up
if (Math.random() < difficultySettings[gameDifficulty].powerUpChance) {
// Power-up chance based on difficulty
var powerUpType = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
block.setPowerUp(powerUpType);
} else {
// Normal block with random color
var color = blockColors[Math.floor(Math.random() * blockColors.length)];
block.setColor(color);
}
block.fallSpeed = gameSpeed;
blocks.push(block);
game.addChild(block);
// Add spawn animation with floating effect
block.scaleX = 0;
block.scaleY = 0;
block.alpha = 0.7;
tween(block, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 500,
easing: tween.elasticOut
});
// Removed floating animation to allow proper falling
}
function handleBlockTap(block) {
var index = blocks.indexOf(block);
if (index > -1) {
blocks.splice(index, 1);
// Handle power-ups
if (block.blockType !== 'normal') {
activatePowerUp(block.blockType);
LK.getSound('powerup').play();
} else {
LK.getSound('tap').play();
}
// Update score and combo
combo++;
var points = block.points * Math.min(combo, 10);
score += points;
LK.setScore(score);
scoreTxt.setText(getText('score') + score);
// Enhanced score text animation with glow effect
scoreTxt.tint = 0xFFFF88; // Slight yellow tint for glow
tween(scoreTxt, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(scoreTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
// Reset tint after animation
LK.setTimeout(function () {
scoreTxt.tint = 0xFFFFFF;
}, 300);
}
});
// Increase speed based on score - more aggressive scaling
if (!powerUpActive) {
var settings = difficultySettings[gameDifficulty];
var newSpeed = Math.min(settings.startSpeed + Math.floor(score / 50), settings.maxSpeed);
if (newSpeed > gameSpeed) {
gameSpeed = newSpeed;
// Update existing blocks' speed
for (var k = 0; k < blocks.length; k++) {
blocks[k].fallSpeed = gameSpeed;
}
}
}
// Spawn extra blocks at higher scores
if (score > 200 && Math.random() < 0.3) {
LK.setTimeout(function () {
if (gameStarted) {
spawnBlock();
}
}, 200);
}
if (combo > bestCombo) {
bestCombo = combo;
}
// Show combo
if (combo > 1) {
comboTxt.setText(getText('combo') + combo);
// Enhanced combo text animation with rotation and glow effect
comboTxt.scaleX = 1.5;
comboTxt.scaleY = 1.5;
comboTxt.rotation = -0.2;
comboTxt.alpha = 0.8;
tween(comboTxt, {
scaleX: 1,
scaleY: 1,
rotation: 0,
alpha: 1
}, {
duration: 400,
easing: tween.elasticOut
});
// Add subtle pulsing for high combos
if (combo >= 5) {
var _comboPulse = function comboPulse() {
tween(comboTxt, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: _comboPulse
});
}
});
};
_comboPulse();
}
if (combo % 5 === 0) {
LK.getSound('combo').play();
}
}
// Visual feedback
LK.effects.flashObject(block, 0xffffff, 200);
// Animate block disappearing
tween(block, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
// Remove block after animation
LK.setTimeout(function () {
if (block.parent) {
block.destroy();
}
}, 200);
}
}
function activatePowerUp(type) {
if (powerUpTimer) {
LK.clearTimeout(powerUpTimer);
}
// Flash and scale effect for power-up activation
for (var p = 0; p < blocks.length; p++) {
if (blocks[p].blockType === 'normal') {
tween(blocks[p], {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function (b) {
return function () {
tween(b, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeInOut
});
};
}(blocks[p])
});
}
}
switch (type) {
case 'slowmo':
powerUpActive = 'slowmo';
gameSpeed = 2;
for (var i = 0; i < blocks.length; i++) {
blocks[i].fallSpeed = gameSpeed;
}
powerUpTimer = LK.setTimeout(function () {
powerUpActive = null;
var settings = difficultySettings[gameDifficulty];
gameSpeed = Math.min(settings.startSpeed + Math.floor(score / 50), settings.maxSpeed);
}, 3000); // Reduced from 5000 to 3000
break;
case 'clear':
var clearDelay = 0;
for (var j = blocks.length - 1; j >= 0; j--) {
var block = blocks[j];
if (block.blockType === 'normal') {
LK.effects.flashObject(block, 0xffffff, 300);
blocks.splice(j, 1);
// Enhanced staggered clear animation with multiple effects
LK.setTimeout(function (b, delay) {
return function () {
// First pulse the block
tween(b, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Then shrink and spin
tween(b, {
scaleX: 0,
scaleY: 0,
rotation: Math.PI * 2,
alpha: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
if (b.parent) {
b.destroy();
}
}
});
}
});
};
}(block, clearDelay), clearDelay);
clearDelay += 80; // Slightly longer stagger for smoother effect
score += 5;
}
}
LK.setScore(score);
scoreTxt.setText(getText('score') + score);
break;
case 'extralife':
if (lives < 5) {
lives++;
updateLivesDisplay();
} else {
score += 100;
LK.setScore(score);
scoreTxt.setText(getText('score') + score);
}
break;
}
}
function missBlock() {
lives--;
combo = 0;
comboTxt.setText('');
LK.getSound('miss').play();
// Animate hearts before updating
for (var h = 0; h < hearts.length; h++) {
(function (heart) {
tween(heart, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(heart, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeIn
});
}
});
})(hearts[h]);
}
updateLivesDisplay();
// Flash screen red
LK.effects.flashScreen(0xff0000, 500);
if (lives <= 0) {
LK.getSound('gameOver').play();
// Save high score
var highScore = storage.highScore || 0;
if (score > highScore) {
storage.highScore = score;
}
var bestComboSaved = storage.bestCombo || 0;
if (bestCombo > bestComboSaved) {
storage.bestCombo = bestCombo;
}
LK.showGameOver();
LK.setTimeout(function () {
showMenu();
}, 2000);
}
}
// Initialize game
function startGame(difficulty) {
gameStarted = true;
gameDifficulty = difficulty || 1;
var settings = difficultySettings[gameDifficulty];
lives = 3;
score = 0;
combo = 0;
bestCombo = 0;
gameSpeed = settings.startSpeed;
blocks = [];
powerUpActive = null;
if (menuScreen && menuScreen.parent) {
menuScreen.destroy();
}
updateLivesDisplay();
scoreTxt.setText(getText('score') + '0');
comboTxt.setText('');
// Play background music when game starts
LK.playMusic('gameMusic', {
volume: 0.5
});
// Start spawning blocks
spawnTimer = LK.setInterval(function () {
if (powerUpActive !== 'slowmo') {
spawnBlock();
} else {
if (LK.ticks % 2 === 0) {
spawnBlock();
}
}
}, difficultySettings[gameDifficulty].spawnRate);
}
// Show menu on start
function showMenu() {
gameStarted = false;
// Stop music when returning to menu
LK.stopMusic();
// Clear any existing game state
if (spawnTimer) {
LK.clearInterval(spawnTimer);
spawnTimer = null;
}
// Clear all blocks
for (var i = blocks.length - 1; i >= 0; i--) {
blocks[i].destroy();
}
blocks = [];
menuScreen = new MenuScreen();
menuScreen.updateHighScore();
menuScreen.onStart = function (difficulty) {
startGame(difficulty);
};
game.addChild(menuScreen);
}
// Show menu initially
showMenu();
// Difficulty now increases based on score, not time
// Game update loop
game.update = function () {
if (!gameStarted) return;
for (var i = blocks.length - 1; i >= 0; i--) {
var block = blocks[i];
// Update block position (make it fall)
if (block.update) {
block.update();
}
// Check if block reached bottom
if (block.y > 2732 + 100) {
blocks.splice(i, 1);
block.destroy();
if (block.blockType === 'normal') {
missBlock();
}
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Block = Container.expand(function () {
var self = Container.call(this);
self.blockType = 'normal';
self.fallSpeed = 5;
self.points = 10;
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
self.setColor = function (color) {
blockGraphics.tint = color;
};
self.setPowerUp = function (type) {
self.blockType = type;
self.removeChildren();
var powerupGraphics = self.attachAsset('powerupBlock', {
anchorX: 0.5,
anchorY: 0.5
});
self.points = 50;
};
self.update = function () {
self.y += self.fallSpeed;
// Add subtle rotation while falling
self.rotation += 0.02;
};
self.down = function (x, y, obj) {
if (self.parent) {
handleBlockTap(self);
}
};
return self;
});
var Heart = Container.expand(function () {
var self = Container.call(this);
var heartGraphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var MenuScreen = Container.expand(function () {
var self = Container.call(this);
// Background overlay
var bg = self.attachAsset('menuBg', {
width: 2048,
height: 2732,
color: 0x000000,
shape: 'box',
anchorX: 0,
anchorY: 0
});
bg.alpha = 0;
// Animate background fade in
tween(bg, {
alpha: 0.8
}, {
duration: 800,
easing: tween.easeOut
});
// Game title
var titleTxt = new Text2(getText('title'), {
size: 120,
fill: 0xFFFF00
});
titleTxt.anchor.set(0.5, 0.5);
titleTxt.x = 1024;
titleTxt.y = 350; // Start higher
titleTxt.alpha = 0;
self.addChild(titleTxt);
// Animate title slide down and fade in
tween(titleTxt, {
y: 550,
alpha: 1
}, {
duration: 1000,
easing: tween.elasticOut
});
var subtitleTxt = new Text2(getText('subtitle'), {
size: 100,
fill: 0xFF4444
});
subtitleTxt.anchor.set(0.5, 0.5);
subtitleTxt.x = 1024;
subtitleTxt.y = 700;
self.addChild(subtitleTxt);
// Language selection
var languageTxt = new Text2(getText('language'), {
size: 60,
fill: 0xFFFFFF
});
languageTxt.anchor.set(0.5, 0.5);
languageTxt.x = 1024;
languageTxt.y = 850;
self.addChild(languageTxt);
// Language buttons
var enBtn = self.attachAsset('startBtn', {
width: 200,
height: 80,
color: 0x4444FF,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
enBtn.x = 700;
enBtn.y = 920;
var enTxt = new Text2('EN', {
size: 50,
fill: 0x000000
});
enTxt.anchor.set(0.5, 0.5);
enTxt.x = 700;
enTxt.y = 920;
self.addChild(enTxt);
var trBtn = self.attachAsset('startBtn', {
width: 200,
height: 80,
color: 0x4444FF,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
trBtn.x = 1024;
trBtn.y = 920;
var trTxt = new Text2('TR', {
size: 50,
fill: 0x000000
});
trTxt.anchor.set(0.5, 0.5);
trTxt.x = 1024;
trTxt.y = 920;
self.addChild(trTxt);
var deBtn = self.attachAsset('startBtn', {
width: 200,
height: 80,
color: 0x4444FF,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
deBtn.x = 1348;
deBtn.y = 920;
var deTxt = new Text2('DE', {
size: 50,
fill: 0x000000
});
deTxt.anchor.set(0.5, 0.5);
deTxt.x = 1348;
deTxt.y = 920;
self.addChild(deTxt);
// Difficulty selection
var difficultyTxt = new Text2(getText('difficulty'), {
size: 70,
fill: 0xFFFFFF
});
difficultyTxt.anchor.set(0.5, 0.5);
difficultyTxt.x = 1024;
difficultyTxt.y = 1050;
self.addChild(difficultyTxt);
// Easy button
var easyBtn = self.attachAsset('startBtn', {
width: 300,
height: 100,
color: 0x44FF44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
easyBtn.x = 700;
easyBtn.y = 1200;
var easyTxt = new Text2(getText('easy'), {
size: 60,
fill: 0x000000
});
easyTxt.anchor.set(0.5, 0.5);
easyTxt.x = 700;
easyTxt.y = 1200;
self.addChild(easyTxt);
// Medium button
var mediumBtn = self.attachAsset('startBtn', {
width: 300,
height: 100,
color: 0xFFFF44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
mediumBtn.x = 1024;
mediumBtn.y = 1200;
var mediumTxt = new Text2(getText('medium'), {
size: 60,
fill: 0x000000
});
mediumTxt.anchor.set(0.5, 0.5);
mediumTxt.x = 1024;
mediumTxt.y = 1200;
self.addChild(mediumTxt);
// Hard button
var hardBtn = self.attachAsset('startBtn', {
width: 300,
height: 100,
color: 0xFF4444,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
hardBtn.x = 1348;
hardBtn.y = 1200;
var hardTxt = new Text2(getText('hard'), {
size: 60,
fill: 0x4444FF
});
hardTxt.anchor.set(0.5, 0.5);
hardTxt.x = 1348;
hardTxt.y = 1200;
self.addChild(hardTxt);
// Start button
var startBtn = self.attachAsset('startBtn', {
width: 400,
height: 150,
color: 0x44FF44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5
});
startBtn.x = 1024;
startBtn.y = 1500;
var startTxt = new Text2(getText('start'), {
size: 80,
fill: 0x000000
});
startTxt.anchor.set(0.5, 0.5);
startTxt.x = 1024;
startTxt.y = 1500;
self.addChild(startTxt);
// High score display
var highScoreTxt = new Text2(getText('highScore') + '0', {
size: 60,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0.5, 0.5);
highScoreTxt.x = 1024;
highScoreTxt.y = 1800;
self.addChild(highScoreTxt);
// Selected difficulty
var selectedDifficulty = 1; // 0=easy, 1=medium, 2=hard
var selectedTxt = new Text2(getText('selected') + getText('medium'), {
size: 50,
fill: 0xFFFF00
});
selectedTxt.anchor.set(0.5, 0.5);
selectedTxt.x = 1024;
selectedTxt.y = 1350;
self.addChild(selectedTxt);
self.updateHighScore = function () {
var highScore = storage.highScore || 0;
highScoreTxt.setText(getText('highScore') + highScore);
};
self.refreshLanguage = function () {
titleTxt.setText(getText('title'));
subtitleTxt.setText(getText('subtitle'));
languageTxt.setText(getText('language'));
difficultyTxt.setText(getText('difficulty'));
easyTxt.setText(getText('easy'));
mediumTxt.setText(getText('medium'));
hardTxt.setText(getText('hard'));
startTxt.setText(getText('start'));
var diffNames = [getText('easy'), getText('medium'), getText('hard')];
selectedTxt.setText(getText('selected') + diffNames[selectedDifficulty]);
self.updateHighScore();
};
// Language button handlers
enBtn.down = function () {
LK.getSound('menuClick').play();
currentLanguage = 'en';
storage.language = 'en';
self.refreshLanguage();
enBtn.tint = 0xAAAAFF;
trBtn.tint = 0xFFFFFF;
deBtn.tint = 0xFFFFFF;
};
trBtn.down = function () {
LK.getSound('menuClick').play();
currentLanguage = 'tr';
storage.language = 'tr';
self.refreshLanguage();
enBtn.tint = 0xFFFFFF;
trBtn.tint = 0xAAAAFF;
deBtn.tint = 0xFFFFFF;
};
deBtn.down = function () {
LK.getSound('menuClick').play();
currentLanguage = 'de';
storage.language = 'de';
self.refreshLanguage();
enBtn.tint = 0xFFFFFF;
trBtn.tint = 0xFFFFFF;
deBtn.tint = 0xAAAAFF;
};
// Set initial language highlight
if (currentLanguage === 'en') {
enBtn.tint = 0xAAAAFF;
} else if (currentLanguage === 'tr') {
trBtn.tint = 0xAAAAFF;
} else if (currentLanguage === 'de') {
deBtn.tint = 0xAAAAFF;
}
easyBtn.down = function () {
LK.getSound('menuClick').play();
selectedDifficulty = 0;
selectedTxt.setText(getText('selected') + getText('easy'));
easyBtn.tint = 0xAAFFAA;
mediumBtn.tint = 0xFFFFFF;
hardBtn.tint = 0xFFFFFF;
// Animate button press
tween(easyBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(easyBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
mediumBtn.down = function () {
LK.getSound('menuClick').play();
selectedDifficulty = 1;
selectedTxt.setText(getText('selected') + getText('medium'));
easyBtn.tint = 0xFFFFFF;
mediumBtn.tint = 0xFFFFAA;
hardBtn.tint = 0xFFFFFF;
// Animate button press
tween(mediumBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(mediumBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
hardBtn.down = function () {
LK.getSound('menuClick').play();
selectedDifficulty = 2;
selectedTxt.setText(getText('selected') + getText('hard'));
easyBtn.tint = 0xFFFFFF;
mediumBtn.tint = 0xFFFFFF;
hardBtn.tint = 0xFFAAAA;
// Animate button press
tween(hardBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(hardBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
};
startBtn.down = function () {
LK.getSound('gameStart').play();
// Animate start button
tween(startBtn, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(startBtn, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeOut
});
}
});
if (self.onStart) {
self.onStart(selectedDifficulty);
}
};
// Set initial selection highlight
mediumBtn.tint = 0xFFFFAA;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Language system
var currentLanguage = storage.language || 'tr'; // Default to Turkish
var languages = {
en: {
title: 'SNOTTY KID',
subtitle: 'ON THE RUN',
difficulty: 'Difficulty Level',
easy: 'EASY',
medium: 'MEDIUM',
hard: 'HARD',
start: 'START',
highScore: 'High Score: ',
selected: 'Selected: ',
score: 'Score: ',
combo: 'Combo x',
language: 'Language'
},
tr: {
title: 'SÜMÜKLÜ ÇOCUK',
subtitle: 'FİRARDA',
difficulty: 'Zorluk Seviyesi',
easy: 'KOLAY',
medium: 'ORTA',
hard: 'ZOR',
start: 'BAŞLA',
highScore: 'En Yüksek Skor: ',
selected: 'Seçilen: ',
score: 'Score: ',
combo: 'Combo x',
language: 'Dil'
},
de: {
title: 'ROTZIGES KIND',
subtitle: 'AUF DER FLUCHT',
difficulty: 'Schwierigkeitsgrad',
easy: 'EINFACH',
medium: 'MITTEL',
hard: 'SCHWER',
start: 'START',
highScore: 'Höchste Punktzahl: ',
selected: 'Ausgewählt: ',
score: 'Punkte: ',
combo: 'Combo x',
language: 'Sprache'
}
};
function getText(key) {
return languages[currentLanguage][key];
}
// Game variables
var blocks = [];
var lives = 3;
var score = 0;
var combo = 0;
var bestCombo = 0;
var gameSpeed = 5;
var powerUpActive = null;
var powerUpTimer = null;
var difficultyTimer = null;
var spawnTimer = null;
var hearts = [];
var gameStarted = false;
var menuScreen = null;
var gameDifficulty = 1; // 0=easy, 1=medium, 2=hard
var difficultySettings = {
0: {
startSpeed: 3,
maxSpeed: 15,
spawnRate: 1000,
powerUpChance: 0.05
},
// Easy
1: {
startSpeed: 5,
maxSpeed: 25,
spawnRate: 800,
powerUpChance: 0.03
},
// Medium
2: {
startSpeed: 8,
maxSpeed: 35,
spawnRate: 600,
powerUpChance: 0.02
} // Hard
};
// Block colors
var blockColors = [0xff4444, 0x44ff44, 0x4444ff, 0xff44ff, 0x44ffff];
var powerUpTypes = ['slowmo', 'clear', 'extralife'];
// UI Elements
var scoreTxt = new Text2(getText('score') + '0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var comboTxt = new Text2('', {
size: 60,
fill: 0xFFFF00
});
comboTxt.anchor.set(0.5, 0);
comboTxt.y = 100;
LK.gui.top.addChild(comboTxt);
// Lives display
var livesContainer = new Container();
livesContainer.x = -50; // Moved left to ensure hearts stay on screen
livesContainer.y = 50;
LK.gui.topRight.addChild(livesContainer);
// Initialize hearts
function updateLivesDisplay() {
livesContainer.removeChildren();
hearts = [];
for (var i = 0; i < lives; i++) {
var heart = new Heart();
heart.x = -i * 50; // Reduced spacing to fit better
hearts.push(heart);
livesContainer.addChild(heart);
// Add gentle pulsing animation to hearts
var pulseHeart = function pulseHeart(h, delay) {
LK.setTimeout(function () {
var _pulse = function pulse() {
tween(h, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(h, {
scaleX: 1,
scaleY: 1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: _pulse
});
}
});
};
_pulse();
}, delay);
};
pulseHeart(heart, i * 200);
}
}
// Game functions
function spawnBlock() {
var block = new Block();
block.x = Math.random() * (2048 - 200) + 100;
block.y = -100;
// Random chance for power-up
if (Math.random() < difficultySettings[gameDifficulty].powerUpChance) {
// Power-up chance based on difficulty
var powerUpType = powerUpTypes[Math.floor(Math.random() * powerUpTypes.length)];
block.setPowerUp(powerUpType);
} else {
// Normal block with random color
var color = blockColors[Math.floor(Math.random() * blockColors.length)];
block.setColor(color);
}
block.fallSpeed = gameSpeed;
blocks.push(block);
game.addChild(block);
// Add spawn animation with floating effect
block.scaleX = 0;
block.scaleY = 0;
block.alpha = 0.7;
tween(block, {
scaleX: 1,
scaleY: 1,
alpha: 1
}, {
duration: 500,
easing: tween.elasticOut
});
// Removed floating animation to allow proper falling
}
function handleBlockTap(block) {
var index = blocks.indexOf(block);
if (index > -1) {
blocks.splice(index, 1);
// Handle power-ups
if (block.blockType !== 'normal') {
activatePowerUp(block.blockType);
LK.getSound('powerup').play();
} else {
LK.getSound('tap').play();
}
// Update score and combo
combo++;
var points = block.points * Math.min(combo, 10);
score += points;
LK.setScore(score);
scoreTxt.setText(getText('score') + score);
// Enhanced score text animation with glow effect
scoreTxt.tint = 0xFFFF88; // Slight yellow tint for glow
tween(scoreTxt, {
scaleX: 1.15,
scaleY: 1.15
}, {
duration: 200,
easing: tween.elasticOut,
onFinish: function onFinish() {
tween(scoreTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
// Reset tint after animation
LK.setTimeout(function () {
scoreTxt.tint = 0xFFFFFF;
}, 300);
}
});
// Increase speed based on score - more aggressive scaling
if (!powerUpActive) {
var settings = difficultySettings[gameDifficulty];
var newSpeed = Math.min(settings.startSpeed + Math.floor(score / 50), settings.maxSpeed);
if (newSpeed > gameSpeed) {
gameSpeed = newSpeed;
// Update existing blocks' speed
for (var k = 0; k < blocks.length; k++) {
blocks[k].fallSpeed = gameSpeed;
}
}
}
// Spawn extra blocks at higher scores
if (score > 200 && Math.random() < 0.3) {
LK.setTimeout(function () {
if (gameStarted) {
spawnBlock();
}
}, 200);
}
if (combo > bestCombo) {
bestCombo = combo;
}
// Show combo
if (combo > 1) {
comboTxt.setText(getText('combo') + combo);
// Enhanced combo text animation with rotation and glow effect
comboTxt.scaleX = 1.5;
comboTxt.scaleY = 1.5;
comboTxt.rotation = -0.2;
comboTxt.alpha = 0.8;
tween(comboTxt, {
scaleX: 1,
scaleY: 1,
rotation: 0,
alpha: 1
}, {
duration: 400,
easing: tween.elasticOut
});
// Add subtle pulsing for high combos
if (combo >= 5) {
var _comboPulse = function comboPulse() {
tween(comboTxt, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(comboTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeInOut,
onFinish: _comboPulse
});
}
});
};
_comboPulse();
}
if (combo % 5 === 0) {
LK.getSound('combo').play();
}
}
// Visual feedback
LK.effects.flashObject(block, 0xffffff, 200);
// Animate block disappearing
tween(block, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 200,
easing: tween.easeOut
});
// Remove block after animation
LK.setTimeout(function () {
if (block.parent) {
block.destroy();
}
}, 200);
}
}
function activatePowerUp(type) {
if (powerUpTimer) {
LK.clearTimeout(powerUpTimer);
}
// Flash and scale effect for power-up activation
for (var p = 0; p < blocks.length; p++) {
if (blocks[p].blockType === 'normal') {
tween(blocks[p], {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function (b) {
return function () {
tween(b, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeInOut
});
};
}(blocks[p])
});
}
}
switch (type) {
case 'slowmo':
powerUpActive = 'slowmo';
gameSpeed = 2;
for (var i = 0; i < blocks.length; i++) {
blocks[i].fallSpeed = gameSpeed;
}
powerUpTimer = LK.setTimeout(function () {
powerUpActive = null;
var settings = difficultySettings[gameDifficulty];
gameSpeed = Math.min(settings.startSpeed + Math.floor(score / 50), settings.maxSpeed);
}, 3000); // Reduced from 5000 to 3000
break;
case 'clear':
var clearDelay = 0;
for (var j = blocks.length - 1; j >= 0; j--) {
var block = blocks[j];
if (block.blockType === 'normal') {
LK.effects.flashObject(block, 0xffffff, 300);
blocks.splice(j, 1);
// Enhanced staggered clear animation with multiple effects
LK.setTimeout(function (b, delay) {
return function () {
// First pulse the block
tween(b, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Then shrink and spin
tween(b, {
scaleX: 0,
scaleY: 0,
rotation: Math.PI * 2,
alpha: 0
}, {
duration: 400,
easing: tween.easeIn,
onFinish: function onFinish() {
if (b.parent) {
b.destroy();
}
}
});
}
});
};
}(block, clearDelay), clearDelay);
clearDelay += 80; // Slightly longer stagger for smoother effect
score += 5;
}
}
LK.setScore(score);
scoreTxt.setText(getText('score') + score);
break;
case 'extralife':
if (lives < 5) {
lives++;
updateLivesDisplay();
} else {
score += 100;
LK.setScore(score);
scoreTxt.setText(getText('score') + score);
}
break;
}
}
function missBlock() {
lives--;
combo = 0;
comboTxt.setText('');
LK.getSound('miss').play();
// Animate hearts before updating
for (var h = 0; h < hearts.length; h++) {
(function (heart) {
tween(heart, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(heart, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeIn
});
}
});
})(hearts[h]);
}
updateLivesDisplay();
// Flash screen red
LK.effects.flashScreen(0xff0000, 500);
if (lives <= 0) {
LK.getSound('gameOver').play();
// Save high score
var highScore = storage.highScore || 0;
if (score > highScore) {
storage.highScore = score;
}
var bestComboSaved = storage.bestCombo || 0;
if (bestCombo > bestComboSaved) {
storage.bestCombo = bestCombo;
}
LK.showGameOver();
LK.setTimeout(function () {
showMenu();
}, 2000);
}
}
// Initialize game
function startGame(difficulty) {
gameStarted = true;
gameDifficulty = difficulty || 1;
var settings = difficultySettings[gameDifficulty];
lives = 3;
score = 0;
combo = 0;
bestCombo = 0;
gameSpeed = settings.startSpeed;
blocks = [];
powerUpActive = null;
if (menuScreen && menuScreen.parent) {
menuScreen.destroy();
}
updateLivesDisplay();
scoreTxt.setText(getText('score') + '0');
comboTxt.setText('');
// Play background music when game starts
LK.playMusic('gameMusic', {
volume: 0.5
});
// Start spawning blocks
spawnTimer = LK.setInterval(function () {
if (powerUpActive !== 'slowmo') {
spawnBlock();
} else {
if (LK.ticks % 2 === 0) {
spawnBlock();
}
}
}, difficultySettings[gameDifficulty].spawnRate);
}
// Show menu on start
function showMenu() {
gameStarted = false;
// Stop music when returning to menu
LK.stopMusic();
// Clear any existing game state
if (spawnTimer) {
LK.clearInterval(spawnTimer);
spawnTimer = null;
}
// Clear all blocks
for (var i = blocks.length - 1; i >= 0; i--) {
blocks[i].destroy();
}
blocks = [];
menuScreen = new MenuScreen();
menuScreen.updateHighScore();
menuScreen.onStart = function (difficulty) {
startGame(difficulty);
};
game.addChild(menuScreen);
}
// Show menu initially
showMenu();
// Difficulty now increases based on score, not time
// Game update loop
game.update = function () {
if (!gameStarted) return;
for (var i = blocks.length - 1; i >= 0; i--) {
var block = blocks[i];
// Update block position (make it fall)
if (block.update) {
block.update();
}
// Check if block reached bottom
if (block.y > 2732 + 100) {
blocks.splice(i, 1);
block.destroy();
if (block.blockType === 'normal') {
missBlock();
}
}
}
};