/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ChainLetter = Container.expand(function (letter, targetX, targetY) { var self = Container.call(this); var graphics = self.attachAsset('chainLetter', { anchorX: 0.5, anchorY: 0.5 }); var letterText = new Text2(letter, { size: 60, fill: 0xFFFFFF }); letterText.anchor.set(0.5, 0.5); self.addChild(letterText); self.letter = letter; self.targetX = targetX; self.targetY = targetY; self.followDistance = 150; return self; }); var LetterD = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('letterD', { anchorX: 0.5, anchorY: 0.5 }); var letterText = new Text2('Д', { size: 80, fill: 0xFFFFFF }); letterText.anchor.set(0.5, 0.5); self.addChild(letterText); return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var Target = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('target', { anchorX: 0.5, anchorY: 0.5 }); self.collected = false; self.update = function () { self.rotation += 0.05; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2F4F4F }); /**** * Game Code ****/ var cyrillicAlphabet = ['Й', 'Ц', 'У', 'К', 'Е', 'Н', 'Г', 'Ш', 'Щ', 'З', 'Ф', 'Ы', 'В', 'А', 'П', 'Р', 'О', 'Л', 'Я', 'Ч', 'С', 'М', 'И', 'Т', 'Ь']; var letterD = game.addChild(new LetterD()); letterD.x = 1024; letterD.y = 1366; var chainLetters = []; var targets = []; var obstacles = []; var currentLetterIndex = 0; var birthTimer = 0; var birthInterval = 180; // 3 seconds at 60fps var level = 1; var targetsCollected = 0; var targetsRequired = 5; var dragNode = null; // Level text var levelText = new Text2('Level ' + level, { size: 100, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); // Score text var scoreText = new Text2('Chain: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 50; scoreText.y = 50; game.addChild(scoreText); // Progress text var progressText = new Text2('Targets: 0/' + targetsRequired, { size: 60, fill: 0xFFFFFF }); progressText.anchor.set(1, 0); progressText.x = 1998; progressText.y = 50; game.addChild(progressText); function createLevel() { // Clear existing targets and obstacles for (var i = targets.length - 1; i >= 0; i--) { targets[i].destroy(); targets.splice(i, 1); } for (var i = obstacles.length - 1; i >= 0; i--) { obstacles[i].destroy(); obstacles.splice(i, 1); } // Create targets for (var i = 0; i < targetsRequired; i++) { var target = game.addChild(new Target()); target.x = Math.random() * 1800 + 124; target.y = Math.random() * 2400 + 166; targets.push(target); } // Create obstacles var numObstacles = Math.min(level + 2, 8); for (var i = 0; i < numObstacles; i++) { var obstacle = game.addChild(new Obstacle()); obstacle.x = Math.random() * 1800 + 124; obstacle.y = Math.random() * 2400 + 166; // Make sure obstacles don't spawn too close to player start var distToPlayer = Math.sqrt(Math.pow(obstacle.x - letterD.x, 2) + Math.pow(obstacle.y - letterD.y, 2)); if (distToPlayer < 300) { obstacle.x = Math.random() * 1000 + 1000; obstacle.y = Math.random() * 1000 + 1500; } obstacles.push(obstacle); } targetsCollected = 0; progressText.setText('Targets: 0/' + targetsRequired); } function giveBirth() { if (currentLetterIndex < cyrillicAlphabet.length) { var newLetter = game.addChild(new ChainLetter(cyrillicAlphabet[currentLetterIndex])); newLetter.x = letterD.x; newLetter.y = letterD.y; chainLetters.push(newLetter); currentLetterIndex++; LK.getSound('birth').play(); scoreText.setText('Chain: ' + chainLetters.length); // Flash effect for birth LK.effects.flashObject(letterD, 0xFFFFFF, 300); } } function updateChain() { if (chainLetters.length > 0) { // First letter follows D var firstLetter = chainLetters[0]; var dx = letterD.x - firstLetter.x; var dy = letterD.y - firstLetter.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > firstLetter.followDistance) { var moveX = dx / distance * 3; var moveY = dy / distance * 3; firstLetter.x += moveX; firstLetter.y += moveY; } // Other letters follow the previous letter for (var i = 1; i < chainLetters.length; i++) { var currentLetter = chainLetters[i]; var previousLetter = chainLetters[i - 1]; dx = previousLetter.x - currentLetter.x; dy = previousLetter.y - currentLetter.y; distance = Math.sqrt(dx * dx + dy * dy); if (distance > currentLetter.followDistance) { moveX = dx / distance * 3; moveY = dy / distance * 3; currentLetter.x += moveX; currentLetter.y += moveY; } } } } function checkCollisions() { // Check D collision with obstacles for (var i = 0; i < obstacles.length; i++) { if (letterD.intersects(obstacles[i])) { // Game over - chain broken LK.effects.flashScreen(0xFF0000, 1000); LK.showGameOver(); return; } } // Check chain collision with obstacles for (var i = 0; i < chainLetters.length; i++) { for (var j = 0; j < obstacles.length; j++) { if (chainLetters[i].intersects(obstacles[j])) { LK.effects.flashScreen(0xFF0000, 1000); LK.showGameOver(); return; } } } // Check target collection for (var i = targets.length - 1; i >= 0; i--) { var target = targets[i]; if (!target.collected && letterD.intersects(target)) { target.collected = true; target.destroy(); targets.splice(i, 1); targetsCollected++; LK.setScore(LK.getScore() + 10); LK.getSound('collect').play(); progressText.setText('Targets: ' + targetsCollected + '/' + targetsRequired); if (targetsCollected >= targetsRequired) { // Level complete level++; targetsRequired = Math.min(targetsRequired + 2, 10); levelText.setText('Level ' + level); LK.getSound('complete').play(); LK.effects.flashScreen(0x00FF00, 500); // Check win condition if (currentLetterIndex >= cyrillicAlphabet.length && level > 3) { LK.showYouWin(); return; } createLevel(); } } } } function handleMove(x, y, obj) { if (dragNode) { dragNode.x = x; dragNode.y = y; // Keep D within bounds dragNode.x = Math.max(60, Math.min(dragNode.x, 1988)); dragNode.y = Math.max(60, Math.min(dragNode.y, 2672)); } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = letterD; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; game.update = function () { birthTimer++; if (birthTimer >= birthInterval) { giveBirth(); birthTimer = 0; // Decrease birth interval slightly each time for increasing difficulty birthInterval = Math.max(120, birthInterval - 2); } updateChain(); checkCollisions(); }; // Initialize first level createLevel();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var ChainLetter = Container.expand(function (letter, targetX, targetY) {
var self = Container.call(this);
var graphics = self.attachAsset('chainLetter', {
anchorX: 0.5,
anchorY: 0.5
});
var letterText = new Text2(letter, {
size: 60,
fill: 0xFFFFFF
});
letterText.anchor.set(0.5, 0.5);
self.addChild(letterText);
self.letter = letter;
self.targetX = targetX;
self.targetY = targetY;
self.followDistance = 150;
return self;
});
var LetterD = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('letterD', {
anchorX: 0.5,
anchorY: 0.5
});
var letterText = new Text2('Д', {
size: 80,
fill: 0xFFFFFF
});
letterText.anchor.set(0.5, 0.5);
self.addChild(letterText);
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.update = function () {
self.rotation += 0.05;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F4F
});
/****
* Game Code
****/
var cyrillicAlphabet = ['Й', 'Ц', 'У', 'К', 'Е', 'Н', 'Г', 'Ш', 'Щ', 'З', 'Ф', 'Ы', 'В', 'А', 'П', 'Р', 'О', 'Л', 'Я', 'Ч', 'С', 'М', 'И', 'Т', 'Ь'];
var letterD = game.addChild(new LetterD());
letterD.x = 1024;
letterD.y = 1366;
var chainLetters = [];
var targets = [];
var obstacles = [];
var currentLetterIndex = 0;
var birthTimer = 0;
var birthInterval = 180; // 3 seconds at 60fps
var level = 1;
var targetsCollected = 0;
var targetsRequired = 5;
var dragNode = null;
// Level text
var levelText = new Text2('Level ' + level, {
size: 100,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
// Score text
var scoreText = new Text2('Chain: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 50;
scoreText.y = 50;
game.addChild(scoreText);
// Progress text
var progressText = new Text2('Targets: 0/' + targetsRequired, {
size: 60,
fill: 0xFFFFFF
});
progressText.anchor.set(1, 0);
progressText.x = 1998;
progressText.y = 50;
game.addChild(progressText);
function createLevel() {
// Clear existing targets and obstacles
for (var i = targets.length - 1; i >= 0; i--) {
targets[i].destroy();
targets.splice(i, 1);
}
for (var i = obstacles.length - 1; i >= 0; i--) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
// Create targets
for (var i = 0; i < targetsRequired; i++) {
var target = game.addChild(new Target());
target.x = Math.random() * 1800 + 124;
target.y = Math.random() * 2400 + 166;
targets.push(target);
}
// Create obstacles
var numObstacles = Math.min(level + 2, 8);
for (var i = 0; i < numObstacles; i++) {
var obstacle = game.addChild(new Obstacle());
obstacle.x = Math.random() * 1800 + 124;
obstacle.y = Math.random() * 2400 + 166;
// Make sure obstacles don't spawn too close to player start
var distToPlayer = Math.sqrt(Math.pow(obstacle.x - letterD.x, 2) + Math.pow(obstacle.y - letterD.y, 2));
if (distToPlayer < 300) {
obstacle.x = Math.random() * 1000 + 1000;
obstacle.y = Math.random() * 1000 + 1500;
}
obstacles.push(obstacle);
}
targetsCollected = 0;
progressText.setText('Targets: 0/' + targetsRequired);
}
function giveBirth() {
if (currentLetterIndex < cyrillicAlphabet.length) {
var newLetter = game.addChild(new ChainLetter(cyrillicAlphabet[currentLetterIndex]));
newLetter.x = letterD.x;
newLetter.y = letterD.y;
chainLetters.push(newLetter);
currentLetterIndex++;
LK.getSound('birth').play();
scoreText.setText('Chain: ' + chainLetters.length);
// Flash effect for birth
LK.effects.flashObject(letterD, 0xFFFFFF, 300);
}
}
function updateChain() {
if (chainLetters.length > 0) {
// First letter follows D
var firstLetter = chainLetters[0];
var dx = letterD.x - firstLetter.x;
var dy = letterD.y - firstLetter.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > firstLetter.followDistance) {
var moveX = dx / distance * 3;
var moveY = dy / distance * 3;
firstLetter.x += moveX;
firstLetter.y += moveY;
}
// Other letters follow the previous letter
for (var i = 1; i < chainLetters.length; i++) {
var currentLetter = chainLetters[i];
var previousLetter = chainLetters[i - 1];
dx = previousLetter.x - currentLetter.x;
dy = previousLetter.y - currentLetter.y;
distance = Math.sqrt(dx * dx + dy * dy);
if (distance > currentLetter.followDistance) {
moveX = dx / distance * 3;
moveY = dy / distance * 3;
currentLetter.x += moveX;
currentLetter.y += moveY;
}
}
}
}
function checkCollisions() {
// Check D collision with obstacles
for (var i = 0; i < obstacles.length; i++) {
if (letterD.intersects(obstacles[i])) {
// Game over - chain broken
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
}
// Check chain collision with obstacles
for (var i = 0; i < chainLetters.length; i++) {
for (var j = 0; j < obstacles.length; j++) {
if (chainLetters[i].intersects(obstacles[j])) {
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
return;
}
}
}
// Check target collection
for (var i = targets.length - 1; i >= 0; i--) {
var target = targets[i];
if (!target.collected && letterD.intersects(target)) {
target.collected = true;
target.destroy();
targets.splice(i, 1);
targetsCollected++;
LK.setScore(LK.getScore() + 10);
LK.getSound('collect').play();
progressText.setText('Targets: ' + targetsCollected + '/' + targetsRequired);
if (targetsCollected >= targetsRequired) {
// Level complete
level++;
targetsRequired = Math.min(targetsRequired + 2, 10);
levelText.setText('Level ' + level);
LK.getSound('complete').play();
LK.effects.flashScreen(0x00FF00, 500);
// Check win condition
if (currentLetterIndex >= cyrillicAlphabet.length && level > 3) {
LK.showYouWin();
return;
}
createLevel();
}
}
}
}
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
// Keep D within bounds
dragNode.x = Math.max(60, Math.min(dragNode.x, 1988));
dragNode.y = Math.max(60, Math.min(dragNode.y, 2672));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = letterD;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.update = function () {
birthTimer++;
if (birthTimer >= birthInterval) {
giveBirth();
birthTimer = 0;
// Decrease birth interval slightly each time for increasing difficulty
birthInterval = Math.max(120, birthInterval - 2);
}
updateChain();
checkCollisions();
};
// Initialize first level
createLevel();