/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LegoBrick = Container.expand(function (primeNumber) {
var self = Container.call(this);
self.primeNumber = primeNumber;
self.isConnected = false;
self.connectedBricks = [];
self.snapDistance = 45;
self.borderElements = [];
// Create brick graphics
var brickGraphics = self.attachAsset('brick_' + primeNumber, {
anchorX: 0.5,
anchorY: 0.5
});
// Create number text
var numberText = new Text2(primeNumber.toString(), {
size: 60,
fill: 0xFFFFFF
});
numberText.anchor.set(0.5, 0.5);
self.addChild(numberText);
self.checkForConnections = function () {
for (var i = 0; i < allBricks.length; i++) {
var otherBrick = allBricks[i];
if (otherBrick === self) continue;
var distance = Math.sqrt(Math.pow(self.x - otherBrick.x, 2) + Math.pow(self.y - otherBrick.y, 2));
// Check if bricks are overlapping (more lenient for stacking)
var isOverlapping = distance < Math.max(self.snapDistance, 120);
var wasConnected = self.isConnectedTo(otherBrick);
if (isOverlapping && !wasConnected) {
self.connectTo(otherBrick);
} else if (!isOverlapping && wasConnected) {
self.disconnectFrom(otherBrick);
}
}
// Update multiplication board after checking all connections
updateMultiplicationBoard();
};
self.isConnectedTo = function (brick) {
return self.connectedBricks.indexOf(brick) !== -1;
};
self.connectTo = function (brick) {
if (self.isConnectedTo(brick)) return;
self.connectedBricks.push(brick);
brick.connectedBricks.push(self);
// Snap bricks together - position side by side to avoid overlapping numbers
var spacing = 10; // Small gap between bricks
if (self.x < brick.x) {
// Self is on the left, move brick to the right of self
tween(brick, {
x: self.x + (self.width + brick.width) / 2 + spacing,
y: self.y
}, {
duration: 300,
easing: tween.easeOut
});
} else {
// Brick is on the left, move self to the right of brick
tween(self, {
x: brick.x + (self.width + brick.width) / 2 + spacing,
y: brick.y
}, {
duration: 300,
easing: tween.easeOut
});
}
// Visual feedback
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
LK.getSound('connect').play();
// Show borders for connected bricks
self.createBorder();
brick.createBorder();
// Award points
LK.setScore(LK.getScore() + 10);
};
self.disconnectFrom = function (brick) {
var index = self.connectedBricks.indexOf(brick);
if (index !== -1) {
self.connectedBricks.splice(index, 1);
}
var otherIndex = brick.connectedBricks.indexOf(self);
if (otherIndex !== -1) {
brick.connectedBricks.splice(otherIndex, 1);
}
LK.getSound('disconnect').play();
// Remove borders if no longer connected to any bricks
if (self.connectedBricks.length === 0) {
self.removeBorder();
}
if (brick.connectedBricks.length === 0) {
brick.removeBorder();
}
};
self.createBorder = function () {
self.removeBorder();
var borderThickness = 8;
var padding = 5;
var borderWidth = self.width + padding * 2;
var borderHeight = self.height + padding * 2;
// Top border
var topBorder = LK.getAsset('border_outline', {
width: borderWidth,
height: borderThickness,
anchorX: 0.5,
anchorY: 0.5
});
topBorder.x = 0;
topBorder.y = -borderHeight / 2;
self.addChild(topBorder);
self.borderElements.push(topBorder);
// Bottom border
var bottomBorder = LK.getAsset('border_outline', {
width: borderWidth,
height: borderThickness,
anchorX: 0.5,
anchorY: 0.5
});
bottomBorder.x = 0;
bottomBorder.y = borderHeight / 2;
self.addChild(bottomBorder);
self.borderElements.push(bottomBorder);
// Left border
var leftBorder = LK.getAsset('border_outline', {
width: borderThickness,
height: borderHeight,
anchorX: 0.5,
anchorY: 0.5
});
leftBorder.x = -borderWidth / 2;
leftBorder.y = 0;
self.addChild(leftBorder);
self.borderElements.push(leftBorder);
// Right border
var rightBorder = LK.getAsset('border_outline', {
width: borderThickness,
height: borderHeight,
anchorX: 0.5,
anchorY: 0.5
});
rightBorder.x = borderWidth / 2;
rightBorder.y = 0;
self.addChild(rightBorder);
self.borderElements.push(rightBorder);
};
self.removeBorder = function () {
for (var i = 0; i < self.borderElements.length; i++) {
self.removeChild(self.borderElements[i]);
}
self.borderElements = [];
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var primeNumbers = [2, 3, 5, 7, 11];
var allBricks = [];
var draggedBrick = null;
// Create display board for multiplication results
var multiplicationBoard = new Text2('0', {
size: 50,
fill: 0xFFFFFF
});
multiplicationBoard.anchor.set(0.5, 0);
LK.gui.top.addChild(multiplicationBoard);
multiplicationBoard.y = 60;
// Function to update multiplication board with all connected groups
function updateMultiplicationBoard() {
var processedBricks = [];
var connectedGroups = [];
// Find all connected groups
for (var i = 0; i < allBricks.length; i++) {
var brick = allBricks[i];
if (processedBricks.indexOf(brick) !== -1) continue;
if (brick.connectedBricks.length === 0) continue;
// Find all bricks in this connected group
var group = [brick];
var toProcess = [brick];
processedBricks.push(brick);
while (toProcess.length > 0) {
var currentBrick = toProcess.shift();
for (var j = 0; j < currentBrick.connectedBricks.length; j++) {
var connectedBrick = currentBrick.connectedBricks[j];
if (processedBricks.indexOf(connectedBrick) === -1) {
group.push(connectedBrick);
toProcess.push(connectedBrick);
processedBricks.push(connectedBrick);
}
}
}
if (group.length > 1) {
connectedGroups.push(group);
}
}
// Display results - each group on separate line
if (connectedGroups.length === 0) {
multiplicationBoard.setText('0');
} else {
var displayLines = [];
for (var i = 0; i < connectedGroups.length; i++) {
var group = connectedGroups[i];
var product = 1;
var multiplication = '';
for (var j = 0; j < group.length; j++) {
product *= group[j].primeNumber;
if (j > 0) multiplication += ' × ';
multiplication += group[j].primeNumber;
}
displayLines.push(multiplication + ' = ' + product);
}
multiplicationBoard.setText(displayLines.join('\n'));
}
}
// Create Lego bricks across full screen (6 for 2,3,5 and 3 for others)
for (var i = 0; i < primeNumbers.length; i++) {
var brickCount = primeNumbers[i] === 2 || primeNumbers[i] === 3 || primeNumbers[i] === 5 ? 6 : 3;
for (var j = 0; j < brickCount; j++) {
// Create bricks based on prime number
var brick = new LegoBrick(primeNumbers[i]);
// Position bricks randomly across full screen
var margin = 200;
brick.x = margin + Math.random() * (2048 - 2 * margin);
brick.y = 400 + Math.random() * (2332 - margin); // Full screen: 400-2732 (leaving room for UI)
allBricks.push(brick);
game.addChild(brick);
}
}
// Mouse/touch event handlers
game.down = function (x, y, obj) {
// Find the topmost brick at this position
for (var i = allBricks.length - 1; i >= 0; i--) {
var brick = allBricks[i];
// Simple distance-based hit detection
var distance = Math.sqrt(Math.pow(x - brick.x, 2) + Math.pow(y - brick.y, 2));
if (distance <= Math.max(brick.width, brick.height) / 2) {
draggedBrick = brick;
// Bring to front by removing and re-adding
game.removeChild(brick);
game.addChild(brick);
break;
}
}
};
game.move = function (x, y, obj) {
if (draggedBrick) {
draggedBrick.x = x;
draggedBrick.y = y;
// Keep brick within bounds for full screen gameplay
draggedBrick.x = Math.max(draggedBrick.width / 2, Math.min(2048 - draggedBrick.width / 2, draggedBrick.x));
draggedBrick.y = Math.max(draggedBrick.height / 2, Math.min(2732 - draggedBrick.height / 2, draggedBrick.y));
}
};
game.up = function (x, y, obj) {
if (draggedBrick) {
draggedBrick.checkForConnections();
draggedBrick = null;
}
};
game.update = function () {}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var LegoBrick = Container.expand(function (primeNumber) {
var self = Container.call(this);
self.primeNumber = primeNumber;
self.isConnected = false;
self.connectedBricks = [];
self.snapDistance = 45;
self.borderElements = [];
// Create brick graphics
var brickGraphics = self.attachAsset('brick_' + primeNumber, {
anchorX: 0.5,
anchorY: 0.5
});
// Create number text
var numberText = new Text2(primeNumber.toString(), {
size: 60,
fill: 0xFFFFFF
});
numberText.anchor.set(0.5, 0.5);
self.addChild(numberText);
self.checkForConnections = function () {
for (var i = 0; i < allBricks.length; i++) {
var otherBrick = allBricks[i];
if (otherBrick === self) continue;
var distance = Math.sqrt(Math.pow(self.x - otherBrick.x, 2) + Math.pow(self.y - otherBrick.y, 2));
// Check if bricks are overlapping (more lenient for stacking)
var isOverlapping = distance < Math.max(self.snapDistance, 120);
var wasConnected = self.isConnectedTo(otherBrick);
if (isOverlapping && !wasConnected) {
self.connectTo(otherBrick);
} else if (!isOverlapping && wasConnected) {
self.disconnectFrom(otherBrick);
}
}
// Update multiplication board after checking all connections
updateMultiplicationBoard();
};
self.isConnectedTo = function (brick) {
return self.connectedBricks.indexOf(brick) !== -1;
};
self.connectTo = function (brick) {
if (self.isConnectedTo(brick)) return;
self.connectedBricks.push(brick);
brick.connectedBricks.push(self);
// Snap bricks together - position side by side to avoid overlapping numbers
var spacing = 10; // Small gap between bricks
if (self.x < brick.x) {
// Self is on the left, move brick to the right of self
tween(brick, {
x: self.x + (self.width + brick.width) / 2 + spacing,
y: self.y
}, {
duration: 300,
easing: tween.easeOut
});
} else {
// Brick is on the left, move self to the right of brick
tween(self, {
x: brick.x + (self.width + brick.width) / 2 + spacing,
y: brick.y
}, {
duration: 300,
easing: tween.easeOut
});
}
// Visual feedback
tween(self, {
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 200,
easing: tween.easeOut
});
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
easing: tween.easeOut
});
LK.getSound('connect').play();
// Show borders for connected bricks
self.createBorder();
brick.createBorder();
// Award points
LK.setScore(LK.getScore() + 10);
};
self.disconnectFrom = function (brick) {
var index = self.connectedBricks.indexOf(brick);
if (index !== -1) {
self.connectedBricks.splice(index, 1);
}
var otherIndex = brick.connectedBricks.indexOf(self);
if (otherIndex !== -1) {
brick.connectedBricks.splice(otherIndex, 1);
}
LK.getSound('disconnect').play();
// Remove borders if no longer connected to any bricks
if (self.connectedBricks.length === 0) {
self.removeBorder();
}
if (brick.connectedBricks.length === 0) {
brick.removeBorder();
}
};
self.createBorder = function () {
self.removeBorder();
var borderThickness = 8;
var padding = 5;
var borderWidth = self.width + padding * 2;
var borderHeight = self.height + padding * 2;
// Top border
var topBorder = LK.getAsset('border_outline', {
width: borderWidth,
height: borderThickness,
anchorX: 0.5,
anchorY: 0.5
});
topBorder.x = 0;
topBorder.y = -borderHeight / 2;
self.addChild(topBorder);
self.borderElements.push(topBorder);
// Bottom border
var bottomBorder = LK.getAsset('border_outline', {
width: borderWidth,
height: borderThickness,
anchorX: 0.5,
anchorY: 0.5
});
bottomBorder.x = 0;
bottomBorder.y = borderHeight / 2;
self.addChild(bottomBorder);
self.borderElements.push(bottomBorder);
// Left border
var leftBorder = LK.getAsset('border_outline', {
width: borderThickness,
height: borderHeight,
anchorX: 0.5,
anchorY: 0.5
});
leftBorder.x = -borderWidth / 2;
leftBorder.y = 0;
self.addChild(leftBorder);
self.borderElements.push(leftBorder);
// Right border
var rightBorder = LK.getAsset('border_outline', {
width: borderThickness,
height: borderHeight,
anchorX: 0.5,
anchorY: 0.5
});
rightBorder.x = borderWidth / 2;
rightBorder.y = 0;
self.addChild(rightBorder);
self.borderElements.push(rightBorder);
};
self.removeBorder = function () {
for (var i = 0; i < self.borderElements.length; i++) {
self.removeChild(self.borderElements[i]);
}
self.borderElements = [];
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var primeNumbers = [2, 3, 5, 7, 11];
var allBricks = [];
var draggedBrick = null;
// Create display board for multiplication results
var multiplicationBoard = new Text2('0', {
size: 50,
fill: 0xFFFFFF
});
multiplicationBoard.anchor.set(0.5, 0);
LK.gui.top.addChild(multiplicationBoard);
multiplicationBoard.y = 60;
// Function to update multiplication board with all connected groups
function updateMultiplicationBoard() {
var processedBricks = [];
var connectedGroups = [];
// Find all connected groups
for (var i = 0; i < allBricks.length; i++) {
var brick = allBricks[i];
if (processedBricks.indexOf(brick) !== -1) continue;
if (brick.connectedBricks.length === 0) continue;
// Find all bricks in this connected group
var group = [brick];
var toProcess = [brick];
processedBricks.push(brick);
while (toProcess.length > 0) {
var currentBrick = toProcess.shift();
for (var j = 0; j < currentBrick.connectedBricks.length; j++) {
var connectedBrick = currentBrick.connectedBricks[j];
if (processedBricks.indexOf(connectedBrick) === -1) {
group.push(connectedBrick);
toProcess.push(connectedBrick);
processedBricks.push(connectedBrick);
}
}
}
if (group.length > 1) {
connectedGroups.push(group);
}
}
// Display results - each group on separate line
if (connectedGroups.length === 0) {
multiplicationBoard.setText('0');
} else {
var displayLines = [];
for (var i = 0; i < connectedGroups.length; i++) {
var group = connectedGroups[i];
var product = 1;
var multiplication = '';
for (var j = 0; j < group.length; j++) {
product *= group[j].primeNumber;
if (j > 0) multiplication += ' × ';
multiplication += group[j].primeNumber;
}
displayLines.push(multiplication + ' = ' + product);
}
multiplicationBoard.setText(displayLines.join('\n'));
}
}
// Create Lego bricks across full screen (6 for 2,3,5 and 3 for others)
for (var i = 0; i < primeNumbers.length; i++) {
var brickCount = primeNumbers[i] === 2 || primeNumbers[i] === 3 || primeNumbers[i] === 5 ? 6 : 3;
for (var j = 0; j < brickCount; j++) {
// Create bricks based on prime number
var brick = new LegoBrick(primeNumbers[i]);
// Position bricks randomly across full screen
var margin = 200;
brick.x = margin + Math.random() * (2048 - 2 * margin);
brick.y = 400 + Math.random() * (2332 - margin); // Full screen: 400-2732 (leaving room for UI)
allBricks.push(brick);
game.addChild(brick);
}
}
// Mouse/touch event handlers
game.down = function (x, y, obj) {
// Find the topmost brick at this position
for (var i = allBricks.length - 1; i >= 0; i--) {
var brick = allBricks[i];
// Simple distance-based hit detection
var distance = Math.sqrt(Math.pow(x - brick.x, 2) + Math.pow(y - brick.y, 2));
if (distance <= Math.max(brick.width, brick.height) / 2) {
draggedBrick = brick;
// Bring to front by removing and re-adding
game.removeChild(brick);
game.addChild(brick);
break;
}
}
};
game.move = function (x, y, obj) {
if (draggedBrick) {
draggedBrick.x = x;
draggedBrick.y = y;
// Keep brick within bounds for full screen gameplay
draggedBrick.x = Math.max(draggedBrick.width / 2, Math.min(2048 - draggedBrick.width / 2, draggedBrick.x));
draggedBrick.y = Math.max(draggedBrick.height / 2, Math.min(2732 - draggedBrick.height / 2, draggedBrick.y));
}
};
game.up = function (x, y, obj) {
if (draggedBrick) {
draggedBrick.checkForConnections();
draggedBrick = null;
}
};
game.update = function () {};