/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Ball = Container.expand(function (color) { var self = Container.call(this); self.ballColor = color; var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, tint: color }); return self; }); var Tube = Container.expand(function (tubeIndex) { var self = Container.call(this); self.tubeIndex = tubeIndex; self.balls = []; self.maxBalls = 5; self.isSelected = false; self.wasSorted = false; // Tube outline (darker background) var outline = self.attachAsset('tubeOutline', { anchorX: 0.5, anchorY: 1.0 }); // Tube body var tubeBody = self.attachAsset('tube', { anchorX: 0.5, anchorY: 1.0 }); self.tubeBody = tubeBody; self.addBall = function (ball) { if (self.balls.length < self.maxBalls) { self.balls.push(ball); self.addChild(ball); self.updateBallPositions(); return true; } return false; }; self.removeBall = function () { if (self.balls.length > 0) { var ball = self.balls.pop(); self.removeChild(ball); return ball; } return null; }; self.getTopBall = function () { if (self.balls.length > 0) { return self.balls[self.balls.length - 1]; } return null; }; self.canAcceptBall = function (ballColor) { if (self.balls.length === 0) return true; if (self.balls.length >= self.maxBalls) return false; var topBall = self.getTopBall(); return topBall && topBall.ballColor === ballColor; }; self.updateBallPositions = function () { for (var i = 0; i < self.balls.length; i++) { var ball = self.balls[i]; ball.x = 0; ball.y = -120 - i * 110; } }; self.setSelected = function (selected) { self.isSelected = selected; if (selected) { self.tubeBody.tint = 0xffff00; } else { self.tubeBody.tint = 0xffffff; } }; self.isSorted = function () { if (self.balls.length === 0) return true; var firstColor = self.balls[0].ballColor; for (var i = 1; i < self.balls.length; i++) { if (self.balls[i].ballColor !== firstColor) { return false; } } return true; }; self.down = function (x, y, obj) { handleTubeClick(self); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xd3d3d3 }); /**** * Game Code ****/ var tubes = []; var selectedTube = null; var gameWon = false; // Ball colors var ballColors = [0x0066ff, // blue (mavi) 0xffff00, // yellow (sarı) 0x00ff00, // green (yeşil) 0xffffff, // white (beyaz) 0xff69b4, // pink (pembe) 0x800080, // purple (mor) 0xff8c00, // orange (turuncu) 0xff0000 // red (kırmızı) ]; // Create tubes function createTubes() { var margin = 50; // Smaller margin from screen edges var availableWidth = 2048 - 2 * margin; // Screen width minus margins var tubeSpacing = availableWidth / 5; // Space for 5 tubes with proper spacing var startX = margin + tubeSpacing / 2; // Center the tubes by adding half spacing // Top row - 5 tubes for (var i = 0; i < 5; i++) { var tube = new Tube(i); tube.x = startX + i * tubeSpacing; tube.y = 1000; tubes.push(tube); game.addChild(tube); } // Bottom row - 5 tubes for (var i = 0; i < 5; i++) { var tube = new Tube(i + 5); tube.x = startX + i * tubeSpacing; tube.y = 1800; tubes.push(tube); game.addChild(tube); } } // Initialize balls in tubes function initializeBalls() { // Create a mix of colored balls for each tube var ballsPerTube = 4; var totalBalls = ballColors.length * ballsPerTube; var allBalls = []; // Create balls for each color for (var c = 0; c < ballColors.length; c++) { for (var b = 0; b < ballsPerTube; b++) { allBalls.push(ballColors[c]); } } // Shuffle the balls for (var i = allBalls.length - 1; i > 0; i--) { var j = Math.floor(Math.random() * (i + 1)); var temp = allBalls[i]; allBalls[i] = allBalls[j]; allBalls[j] = temp; } // Distribute balls to tubes (8 tubes get balls, 2 remain empty) var ballIndex = 0; for (var t = 0; t < 8; t++) { for (var b = 0; b < ballsPerTube; b++) { var ball = new Ball(allBalls[ballIndex]); tubes[t].addBall(ball); ballIndex++; } } } function handleTubeClick(clickedTube) { if (gameWon) return; if (selectedTube === null) { // Select tube if it has balls if (clickedTube.balls.length > 0) { selectedTube = clickedTube; clickedTube.setSelected(true); LK.getSound('ballMove').play(); } } else { if (selectedTube === clickedTube) { // Deselect current tube selectedTube.setSelected(false); selectedTube = null; } else { // Try to move ball from selected tube to clicked tube var topBall = selectedTube.getTopBall(); if (topBall && clickedTube.canAcceptBall(topBall.ballColor)) { var ball = selectedTube.removeBall(); clickedTube.addBall(ball); LK.getSound('ballPlace').play(); LK.getSound('ballMove').play(); // Check for win condition checkWinCondition(); } // Deselect tube selectedTube.setSelected(false); selectedTube = null; } } } function checkWinCondition() { var sortedTubes = 0; var emptyTubes = 0; for (var i = 0; i < tubes.length; i++) { var tube = tubes[i]; if (tube.balls.length === 0) { emptyTubes++; } else if (tube.isSorted()) { // Check if this tube just became completely full with same color (wasn't sorted before) if (!tube.wasSorted && tube.balls.length === tube.maxBalls && tube.isSorted()) { createConfetti(tube); tube.wasSorted = true; } sortedTubes++; } } // Win if we have exactly 8 sorted tubes (one for each color) and 2 empty tubes if (sortedTubes === 8 && emptyTubes === 2) { gameWon = true; LK.getSound('winSound').play(); // Flash screen green LK.effects.flashScreen(0x2ecc71, 2000); // Show win after a delay LK.setTimeout(function () { LK.showYouWin(); }, 1000); } } // Create UI var titleText = new Text2('Color Sort Tubes', { size: 120, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); LK.gui.top.addChild(titleText); var instructionText = new Text2('Tap a tube to select, then tap another to move the top ball', { size: 60, fill: 0xBDC3C7 }); instructionText.anchor.set(0.5, 1); instructionText.y = -50; LK.gui.bottom.addChild(instructionText); function createConfetti(tube) { var confettiColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff]; var confettiPieces = []; // Create confetti pieces around the tube for (var i = 0; i < 20; i++) { var confetti = LK.getAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3, tint: confettiColors[Math.floor(Math.random() * confettiColors.length)] }); // Position confetti at tube location confetti.x = tube.x; confetti.y = tube.y - 200; game.addChild(confetti); confettiPieces.push(confetti); // Animate confetti with random directions var randomX = tube.x + (Math.random() - 0.5) * 400; var randomY = tube.y - 400 - Math.random() * 200; var duration = 1000 + Math.random() * 500; tween(confetti, { x: randomX, y: randomY, rotation: Math.random() * Math.PI * 4, alpha: 0 }, { duration: duration, easing: tween.easeOut, onFinish: function onFinish() { if (confetti.parent) { confetti.parent.removeChild(confetti); } } }); } } // Initialize game createTubes(); initializeBalls(); game.update = function () { // Game logic is handled by events };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Ball = Container.expand(function (color) {
var self = Container.call(this);
self.ballColor = color;
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
tint: color
});
return self;
});
var Tube = Container.expand(function (tubeIndex) {
var self = Container.call(this);
self.tubeIndex = tubeIndex;
self.balls = [];
self.maxBalls = 5;
self.isSelected = false;
self.wasSorted = false;
// Tube outline (darker background)
var outline = self.attachAsset('tubeOutline', {
anchorX: 0.5,
anchorY: 1.0
});
// Tube body
var tubeBody = self.attachAsset('tube', {
anchorX: 0.5,
anchorY: 1.0
});
self.tubeBody = tubeBody;
self.addBall = function (ball) {
if (self.balls.length < self.maxBalls) {
self.balls.push(ball);
self.addChild(ball);
self.updateBallPositions();
return true;
}
return false;
};
self.removeBall = function () {
if (self.balls.length > 0) {
var ball = self.balls.pop();
self.removeChild(ball);
return ball;
}
return null;
};
self.getTopBall = function () {
if (self.balls.length > 0) {
return self.balls[self.balls.length - 1];
}
return null;
};
self.canAcceptBall = function (ballColor) {
if (self.balls.length === 0) return true;
if (self.balls.length >= self.maxBalls) return false;
var topBall = self.getTopBall();
return topBall && topBall.ballColor === ballColor;
};
self.updateBallPositions = function () {
for (var i = 0; i < self.balls.length; i++) {
var ball = self.balls[i];
ball.x = 0;
ball.y = -120 - i * 110;
}
};
self.setSelected = function (selected) {
self.isSelected = selected;
if (selected) {
self.tubeBody.tint = 0xffff00;
} else {
self.tubeBody.tint = 0xffffff;
}
};
self.isSorted = function () {
if (self.balls.length === 0) return true;
var firstColor = self.balls[0].ballColor;
for (var i = 1; i < self.balls.length; i++) {
if (self.balls[i].ballColor !== firstColor) {
return false;
}
}
return true;
};
self.down = function (x, y, obj) {
handleTubeClick(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xd3d3d3
});
/****
* Game Code
****/
var tubes = [];
var selectedTube = null;
var gameWon = false;
// Ball colors
var ballColors = [0x0066ff,
// blue (mavi)
0xffff00,
// yellow (sarı)
0x00ff00,
// green (yeşil)
0xffffff,
// white (beyaz)
0xff69b4,
// pink (pembe)
0x800080,
// purple (mor)
0xff8c00,
// orange (turuncu)
0xff0000 // red (kırmızı)
];
// Create tubes
function createTubes() {
var margin = 50; // Smaller margin from screen edges
var availableWidth = 2048 - 2 * margin; // Screen width minus margins
var tubeSpacing = availableWidth / 5; // Space for 5 tubes with proper spacing
var startX = margin + tubeSpacing / 2; // Center the tubes by adding half spacing
// Top row - 5 tubes
for (var i = 0; i < 5; i++) {
var tube = new Tube(i);
tube.x = startX + i * tubeSpacing;
tube.y = 1000;
tubes.push(tube);
game.addChild(tube);
}
// Bottom row - 5 tubes
for (var i = 0; i < 5; i++) {
var tube = new Tube(i + 5);
tube.x = startX + i * tubeSpacing;
tube.y = 1800;
tubes.push(tube);
game.addChild(tube);
}
}
// Initialize balls in tubes
function initializeBalls() {
// Create a mix of colored balls for each tube
var ballsPerTube = 4;
var totalBalls = ballColors.length * ballsPerTube;
var allBalls = [];
// Create balls for each color
for (var c = 0; c < ballColors.length; c++) {
for (var b = 0; b < ballsPerTube; b++) {
allBalls.push(ballColors[c]);
}
}
// Shuffle the balls
for (var i = allBalls.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = allBalls[i];
allBalls[i] = allBalls[j];
allBalls[j] = temp;
}
// Distribute balls to tubes (8 tubes get balls, 2 remain empty)
var ballIndex = 0;
for (var t = 0; t < 8; t++) {
for (var b = 0; b < ballsPerTube; b++) {
var ball = new Ball(allBalls[ballIndex]);
tubes[t].addBall(ball);
ballIndex++;
}
}
}
function handleTubeClick(clickedTube) {
if (gameWon) return;
if (selectedTube === null) {
// Select tube if it has balls
if (clickedTube.balls.length > 0) {
selectedTube = clickedTube;
clickedTube.setSelected(true);
LK.getSound('ballMove').play();
}
} else {
if (selectedTube === clickedTube) {
// Deselect current tube
selectedTube.setSelected(false);
selectedTube = null;
} else {
// Try to move ball from selected tube to clicked tube
var topBall = selectedTube.getTopBall();
if (topBall && clickedTube.canAcceptBall(topBall.ballColor)) {
var ball = selectedTube.removeBall();
clickedTube.addBall(ball);
LK.getSound('ballPlace').play();
LK.getSound('ballMove').play();
// Check for win condition
checkWinCondition();
}
// Deselect tube
selectedTube.setSelected(false);
selectedTube = null;
}
}
}
function checkWinCondition() {
var sortedTubes = 0;
var emptyTubes = 0;
for (var i = 0; i < tubes.length; i++) {
var tube = tubes[i];
if (tube.balls.length === 0) {
emptyTubes++;
} else if (tube.isSorted()) {
// Check if this tube just became completely full with same color (wasn't sorted before)
if (!tube.wasSorted && tube.balls.length === tube.maxBalls && tube.isSorted()) {
createConfetti(tube);
tube.wasSorted = true;
}
sortedTubes++;
}
}
// Win if we have exactly 8 sorted tubes (one for each color) and 2 empty tubes
if (sortedTubes === 8 && emptyTubes === 2) {
gameWon = true;
LK.getSound('winSound').play();
// Flash screen green
LK.effects.flashScreen(0x2ecc71, 2000);
// Show win after a delay
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
}
}
// Create UI
var titleText = new Text2('Color Sort Tubes', {
size: 120,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
var instructionText = new Text2('Tap a tube to select, then tap another to move the top ball', {
size: 60,
fill: 0xBDC3C7
});
instructionText.anchor.set(0.5, 1);
instructionText.y = -50;
LK.gui.bottom.addChild(instructionText);
function createConfetti(tube) {
var confettiColors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
var confettiPieces = [];
// Create confetti pieces around the tube
for (var i = 0; i < 20; i++) {
var confetti = LK.getAsset('ball', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.3,
tint: confettiColors[Math.floor(Math.random() * confettiColors.length)]
});
// Position confetti at tube location
confetti.x = tube.x;
confetti.y = tube.y - 200;
game.addChild(confetti);
confettiPieces.push(confetti);
// Animate confetti with random directions
var randomX = tube.x + (Math.random() - 0.5) * 400;
var randomY = tube.y - 400 - Math.random() * 200;
var duration = 1000 + Math.random() * 500;
tween(confetti, {
x: randomX,
y: randomY,
rotation: Math.random() * Math.PI * 4,
alpha: 0
}, {
duration: duration,
easing: tween.easeOut,
onFinish: function onFinish() {
if (confetti.parent) {
confetti.parent.removeChild(confetti);
}
}
});
}
}
// Initialize game
createTubes();
initializeBalls();
game.update = function () {
// Game logic is handled by events
};