/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Block = Container.expand(function (color, gridX, gridY) {
var self = Container.call(this);
self.color = color;
self.gridX = gridX;
self.gridY = gridY;
self.moving = false;
var blockAssets = {
1: 'redBlock',
2: 'blueBlock',
3: 'greenBlock',
4: 'yellowBlock',
5: 'purpleBlock',
6: 'orangeBlock'
};
var blockGraphics = self.attachAsset(blockAssets[color] || 'redBlock', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
if (!self.moving && gameState === 'playing') {
tryMoveBlock(self);
}
};
self.moveTo = function (newGridX, newGridY, callback) {
self.moving = true;
var targetX = gridStartX + newGridX * 120 + 60;
var targetY = gridStartY + newGridY * 120 + 60;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.gridX = newGridX;
self.gridY = newGridY;
self.moving = false;
if (callback) callback();
}
});
};
return self;
});
var GridCell = Container.expand(function (gridX, gridY) {
var self = Container.call(this);
self.gridX = gridX;
self.gridY = gridY;
self.block = null;
var background = self.attachAsset('gridBackground', {
anchorX: 0.5,
anchorY: 0.5
});
var emptySpace = self.attachAsset('emptySpace', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2a2a2a
});
/****
* Game Code
****/
var gridSize = 3;
var gridStartX = 1024 - gridSize * 120 / 2;
var gridStartY = 1500;
var grid = [];
var blocks = [];
var emptyX = 2;
var emptyY = 2;
var gameState = 'playing';
var moves = 0;
var level = 1;
// Current level pattern (3x3 grid with colors: 0=empty, 1=red, 2=blue, 3=green)
var targetPattern = [[1, 2, 3], [2, 3, 1], [3, 1, 0]];
var currentPattern = [[2, 1, 3], [3, 0, 2], [1, 3, 1]];
// UI Elements
var titleText = new Text2('Block Shift Puzzle', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
titleText.y = 100;
var levelText = new Text2('Level 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 200;
var movesText = new Text2('Moves: 0', {
size: 50,
fill: 0xFFFFFF
});
movesText.anchor.set(0.5, 0);
LK.gui.top.addChild(movesText);
movesText.y = 280;
var targetText = new Text2('Target Pattern:', {
size: 50,
fill: 0xFFFFFF
});
targetText.anchor.set(0.5, 0);
LK.gui.top.addChild(targetText);
targetText.y = 350;
// Initialize grid
function initializeGrid() {
// Clear existing grid and blocks
for (var i = 0; i < grid.length; i++) {
for (var j = 0; j < grid[i].length; j++) {
if (grid[i][j]) {
grid[i][j].destroy();
}
}
}
for (var b = 0; b < blocks.length; b++) {
blocks[b].destroy();
}
grid = [];
blocks = [];
// Create grid cells
for (var row = 0; row < gridSize; row++) {
grid[row] = [];
for (var col = 0; col < gridSize; col++) {
var cell = new GridCell(col, row);
cell.x = gridStartX + col * 120 + 60;
cell.y = gridStartY + row * 120 + 60;
grid[row][col] = cell;
game.addChild(cell);
}
}
// Create blocks based on current pattern
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var colorValue = currentPattern[row][col];
if (colorValue !== 0) {
var block = new Block(colorValue, col, row);
block.x = gridStartX + col * 120 + 60;
block.y = gridStartY + row * 120 + 60;
blocks.push(block);
game.addChild(block);
grid[row][col].block = block;
} else {
emptyX = col;
emptyY = row;
}
}
}
}
// Create target pattern display
function createTargetDisplay() {
var targetStartX = 1024 - gridSize * 60 / 2;
var targetStartY = 450;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var colorValue = targetPattern[row][col];
if (colorValue !== 0) {
var blockAssets = {
1: 'redBlock',
2: 'blueBlock',
3: 'greenBlock',
4: 'yellowBlock',
5: 'purpleBlock',
6: 'orangeBlock'
};
var targetBlock = LK.getAsset(blockAssets[colorValue] || 'redBlock', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
targetBlock.x = targetStartX + col * 60 + 30;
targetBlock.y = targetStartY + row * 60 + 30;
game.addChild(targetBlock);
} else {
var emptyCell = LK.getAsset('emptySpace', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
emptyCell.x = targetStartX + col * 60 + 30;
emptyCell.y = targetStartY + row * 60 + 30;
game.addChild(emptyCell);
}
}
}
}
function tryMoveBlock(block) {
var blockX = block.gridX;
var blockY = block.gridY;
// Check if block is adjacent to empty space
var canMove = false;
var newX = blockX;
var newY = blockY;
if (blockX === emptyX && Math.abs(blockY - emptyY) === 1) {
// Vertical move
canMove = true;
newX = emptyX;
newY = emptyY;
} else if (blockY === emptyY && Math.abs(blockX - emptyX) === 1) {
// Horizontal move
canMove = true;
newX = emptyX;
newY = emptyY;
}
if (canMove) {
// Update grid
grid[blockY][blockX].block = null;
grid[newY][newX].block = block;
// Update empty position
emptyX = blockX;
emptyY = blockY;
// Move block with animation
block.moveTo(newX, newY, function () {
moves++;
movesText.setText('Moves: ' + moves);
LK.getSound('move').play();
checkWinCondition();
});
}
}
function checkWinCondition() {
var matches = true;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var targetColor = targetPattern[row][col];
var currentBlock = grid[row][col].block;
if (targetColor === 0) {
// Should be empty
if (currentBlock !== null) {
matches = false;
break;
}
} else {
// Should have block with specific color
if (!currentBlock || currentBlock.color !== targetColor) {
matches = false;
break;
}
}
}
if (!matches) break;
}
if (matches) {
gameState = 'won';
LK.getSound('complete').play();
LK.effects.flashScreen(0x44ff44, 1000);
LK.setTimeout(function () {
nextLevel();
}, 1500);
}
}
function nextLevel() {
level++;
moves = 0;
gameState = 'playing';
levelText.setText('Level ' + level);
movesText.setText('Moves: 0');
// Generate new patterns for next level
if (level === 2) {
targetPattern = [[2, 3, 1], [1, 2, 3], [3, 0, 2]];
currentPattern = [[3, 2, 1], [1, 0, 3], [2, 1, 3]];
} else if (level === 3) {
targetPattern = [[1, 2, 3], [3, 1, 2], [2, 3, 0]];
currentPattern = [[2, 3, 1], [3, 2, 0], [1, 2, 3]];
} else {
// Generate random patterns for higher levels
generateRandomLevel();
}
initializeGrid();
createTargetDisplay();
}
function generateRandomLevel() {
// Simple random pattern generation
var colors = [1, 2, 3, 1, 2, 3, 1, 2]; // 8 blocks for 3x3 grid with 1 empty
// Shuffle colors
for (var i = colors.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = colors[i];
colors[i] = colors[j];
colors[j] = temp;
}
var colorIndex = 0;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
if (row === 2 && col === 2) {
targetPattern[row][col] = 0;
currentPattern[row][col] = 0;
} else {
targetPattern[row][col] = colors[colorIndex];
currentPattern[row][col] = colors[(colorIndex + 3) % colors.length];
colorIndex++;
}
}
}
}
// Initialize the game
initializeGrid();
createTargetDisplay();
game.update = function () {
// Game update logic if needed
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Block = Container.expand(function (color, gridX, gridY) {
var self = Container.call(this);
self.color = color;
self.gridX = gridX;
self.gridY = gridY;
self.moving = false;
var blockAssets = {
1: 'redBlock',
2: 'blueBlock',
3: 'greenBlock',
4: 'yellowBlock',
5: 'purpleBlock',
6: 'orangeBlock'
};
var blockGraphics = self.attachAsset(blockAssets[color] || 'redBlock', {
anchorX: 0.5,
anchorY: 0.5
});
self.down = function (x, y, obj) {
if (!self.moving && gameState === 'playing') {
tryMoveBlock(self);
}
};
self.moveTo = function (newGridX, newGridY, callback) {
self.moving = true;
var targetX = gridStartX + newGridX * 120 + 60;
var targetY = gridStartY + newGridY * 120 + 60;
tween(self, {
x: targetX,
y: targetY
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
self.gridX = newGridX;
self.gridY = newGridY;
self.moving = false;
if (callback) callback();
}
});
};
return self;
});
var GridCell = Container.expand(function (gridX, gridY) {
var self = Container.call(this);
self.gridX = gridX;
self.gridY = gridY;
self.block = null;
var background = self.attachAsset('gridBackground', {
anchorX: 0.5,
anchorY: 0.5
});
var emptySpace = self.attachAsset('emptySpace', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2a2a2a
});
/****
* Game Code
****/
var gridSize = 3;
var gridStartX = 1024 - gridSize * 120 / 2;
var gridStartY = 1500;
var grid = [];
var blocks = [];
var emptyX = 2;
var emptyY = 2;
var gameState = 'playing';
var moves = 0;
var level = 1;
// Current level pattern (3x3 grid with colors: 0=empty, 1=red, 2=blue, 3=green)
var targetPattern = [[1, 2, 3], [2, 3, 1], [3, 1, 0]];
var currentPattern = [[2, 1, 3], [3, 0, 2], [1, 3, 1]];
// UI Elements
var titleText = new Text2('Block Shift Puzzle', {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
titleText.y = 100;
var levelText = new Text2('Level 1', {
size: 60,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
levelText.y = 200;
var movesText = new Text2('Moves: 0', {
size: 50,
fill: 0xFFFFFF
});
movesText.anchor.set(0.5, 0);
LK.gui.top.addChild(movesText);
movesText.y = 280;
var targetText = new Text2('Target Pattern:', {
size: 50,
fill: 0xFFFFFF
});
targetText.anchor.set(0.5, 0);
LK.gui.top.addChild(targetText);
targetText.y = 350;
// Initialize grid
function initializeGrid() {
// Clear existing grid and blocks
for (var i = 0; i < grid.length; i++) {
for (var j = 0; j < grid[i].length; j++) {
if (grid[i][j]) {
grid[i][j].destroy();
}
}
}
for (var b = 0; b < blocks.length; b++) {
blocks[b].destroy();
}
grid = [];
blocks = [];
// Create grid cells
for (var row = 0; row < gridSize; row++) {
grid[row] = [];
for (var col = 0; col < gridSize; col++) {
var cell = new GridCell(col, row);
cell.x = gridStartX + col * 120 + 60;
cell.y = gridStartY + row * 120 + 60;
grid[row][col] = cell;
game.addChild(cell);
}
}
// Create blocks based on current pattern
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var colorValue = currentPattern[row][col];
if (colorValue !== 0) {
var block = new Block(colorValue, col, row);
block.x = gridStartX + col * 120 + 60;
block.y = gridStartY + row * 120 + 60;
blocks.push(block);
game.addChild(block);
grid[row][col].block = block;
} else {
emptyX = col;
emptyY = row;
}
}
}
}
// Create target pattern display
function createTargetDisplay() {
var targetStartX = 1024 - gridSize * 60 / 2;
var targetStartY = 450;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var colorValue = targetPattern[row][col];
if (colorValue !== 0) {
var blockAssets = {
1: 'redBlock',
2: 'blueBlock',
3: 'greenBlock',
4: 'yellowBlock',
5: 'purpleBlock',
6: 'orangeBlock'
};
var targetBlock = LK.getAsset(blockAssets[colorValue] || 'redBlock', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
targetBlock.x = targetStartX + col * 60 + 30;
targetBlock.y = targetStartY + row * 60 + 30;
game.addChild(targetBlock);
} else {
var emptyCell = LK.getAsset('emptySpace', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
emptyCell.x = targetStartX + col * 60 + 30;
emptyCell.y = targetStartY + row * 60 + 30;
game.addChild(emptyCell);
}
}
}
}
function tryMoveBlock(block) {
var blockX = block.gridX;
var blockY = block.gridY;
// Check if block is adjacent to empty space
var canMove = false;
var newX = blockX;
var newY = blockY;
if (blockX === emptyX && Math.abs(blockY - emptyY) === 1) {
// Vertical move
canMove = true;
newX = emptyX;
newY = emptyY;
} else if (blockY === emptyY && Math.abs(blockX - emptyX) === 1) {
// Horizontal move
canMove = true;
newX = emptyX;
newY = emptyY;
}
if (canMove) {
// Update grid
grid[blockY][blockX].block = null;
grid[newY][newX].block = block;
// Update empty position
emptyX = blockX;
emptyY = blockY;
// Move block with animation
block.moveTo(newX, newY, function () {
moves++;
movesText.setText('Moves: ' + moves);
LK.getSound('move').play();
checkWinCondition();
});
}
}
function checkWinCondition() {
var matches = true;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
var targetColor = targetPattern[row][col];
var currentBlock = grid[row][col].block;
if (targetColor === 0) {
// Should be empty
if (currentBlock !== null) {
matches = false;
break;
}
} else {
// Should have block with specific color
if (!currentBlock || currentBlock.color !== targetColor) {
matches = false;
break;
}
}
}
if (!matches) break;
}
if (matches) {
gameState = 'won';
LK.getSound('complete').play();
LK.effects.flashScreen(0x44ff44, 1000);
LK.setTimeout(function () {
nextLevel();
}, 1500);
}
}
function nextLevel() {
level++;
moves = 0;
gameState = 'playing';
levelText.setText('Level ' + level);
movesText.setText('Moves: 0');
// Generate new patterns for next level
if (level === 2) {
targetPattern = [[2, 3, 1], [1, 2, 3], [3, 0, 2]];
currentPattern = [[3, 2, 1], [1, 0, 3], [2, 1, 3]];
} else if (level === 3) {
targetPattern = [[1, 2, 3], [3, 1, 2], [2, 3, 0]];
currentPattern = [[2, 3, 1], [3, 2, 0], [1, 2, 3]];
} else {
// Generate random patterns for higher levels
generateRandomLevel();
}
initializeGrid();
createTargetDisplay();
}
function generateRandomLevel() {
// Simple random pattern generation
var colors = [1, 2, 3, 1, 2, 3, 1, 2]; // 8 blocks for 3x3 grid with 1 empty
// Shuffle colors
for (var i = colors.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = colors[i];
colors[i] = colors[j];
colors[j] = temp;
}
var colorIndex = 0;
for (var row = 0; row < gridSize; row++) {
for (var col = 0; col < gridSize; col++) {
if (row === 2 && col === 2) {
targetPattern[row][col] = 0;
currentPattern[row][col] = 0;
} else {
targetPattern[row][col] = colors[colorIndex];
currentPattern[row][col] = colors[(colorIndex + 3) % colors.length];
colorIndex++;
}
}
}
}
// Initialize the game
initializeGrid();
createTargetDisplay();
game.update = function () {
// Game update logic if needed
};