/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GamePiece = Container.expand(function (type, player) {
var self = Container.call(this);
self.pieceType = type;
self.player = player;
self.gridX = 0;
self.gridY = 0;
var graphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.setGridPosition = function (gridX, gridY) {
self.gridX = gridX;
self.gridY = gridY;
var worldPos = gridToWorld(gridX, gridY);
self.x = worldPos.x;
self.y = worldPos.y;
};
self.getValidMoves = function () {
var moves = [];
// All pieces move in any direction until blocked
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];
for (var d = 0; d < directions.length; d++) {
for (var dist = 1; dist < 5; dist++) {
var newX = self.gridX + directions[d][0] * dist;
var newY = self.gridY + directions[d][1] * dist;
if (!isValidPosition(newX, newY)) break;
if (isPieceAt(newX, newY)) {
// Can move to position just before the blocking piece
if (dist > 1) {
moves.push({
x: self.gridX + directions[d][0] * (dist - 1),
y: self.gridY + directions[d][1] * (dist - 1)
});
}
break;
}
moves.push({
x: newX,
y: newY
});
}
}
return moves;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2f4f2f
});
/****
* Game Code
****/
// Game state variables
var currentPlayer = 1;
var gamePhase = 'move_orb'; // 'move_orb' or 'move_piece'
var selectedPiece = null;
var validMoves = [];
var gameBoard = [];
var pieces = [];
var highlights = [];
var magicOrb = null;
// Board setup
var BOARD_SIZE = 5;
var TILE_SIZE = 400;
// Center the board on screen
var BOARD_OFFSET_X = (2048 - BOARD_SIZE * TILE_SIZE) / 2;
var BOARD_OFFSET_Y = (2732 - BOARD_SIZE * TILE_SIZE) / 2;
function gridToWorld(gridX, gridY) {
return {
x: BOARD_OFFSET_X + gridX * TILE_SIZE + TILE_SIZE / 2,
y: BOARD_OFFSET_Y + gridY * TILE_SIZE + TILE_SIZE / 2
};
}
function worldToGrid(worldX, worldY) {
return {
x: Math.floor((worldX - BOARD_OFFSET_X) / TILE_SIZE),
y: Math.floor((worldY - BOARD_OFFSET_Y) / TILE_SIZE)
};
}
function isValidPosition(x, y) {
return x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE;
}
function isPieceAt(x, y) {
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].gridX === x && pieces[i].gridY === y) {
return pieces[i];
}
}
return null;
}
function clearHighlights() {
for (var i = 0; i < highlights.length; i++) {
highlights[i].destroy();
}
highlights = [];
}
function showValidMoves(moves) {
clearHighlights();
for (var i = 0; i < moves.length; i++) {
var highlight = LK.getAsset('highlight', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
var worldPos = gridToWorld(moves[i].x, moves[i].y);
highlight.x = worldPos.x;
highlight.y = worldPos.y;
game.addChild(highlight);
highlights.push(highlight);
}
}
function showSelection(piece) {
clearHighlights();
var selection = LK.getAsset('selected', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
var worldPos = gridToWorld(piece.gridX, piece.gridY);
selection.x = worldPos.x;
selection.y = worldPos.y;
game.addChild(selection);
highlights.push(selection);
}
function movePiece(piece, gridX, gridY) {
piece.setGridPosition(gridX, gridY);
tween(piece, {
x: piece.x,
y: piece.y
}, {
duration: 300
});
LK.getSound('move').play();
}
function checkWinCondition() {
// Check if orb reached starting positions
if (magicOrb.gridY === 4) {
// Orb in player 1's starting row - Player 2 wins (because they moved it there)
if (currentPlayer === 1) {
// Player 1 moved orb to their own starting row, so Player 2 wins
var winnerText = new Text2('Player 2 Wins!', {
size: 120,
fill: 0xff0000
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else {
// Player 2 moved orb to Player 1's starting row, so Player 1 wins
var winnerText = new Text2('Player 1 Wins!', {
size: 120,
fill: 0x0000ff
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
return true;
}
if (magicOrb.gridY === 0) {
// Orb in player 2's starting row - Player 1 wins (because they moved it there)
if (currentPlayer === 2) {
// Player 2 moved orb to their own starting row, so Player 1 wins
var winnerText = new Text2('Player 1 Wins!', {
size: 120,
fill: 0x0000ff
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else {
// Player 1 moved orb to Player 2's starting row, so Player 2 wins
var winnerText = new Text2('Player 2 Wins!', {
size: 120,
fill: 0xff0000
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
return true;
}
return false;
}
function switchTurn() {
if (gamePhase === 'move_orb') {
gamePhase = 'move_piece';
} else {
gamePhase = 'move_orb';
currentPlayer = currentPlayer === 1 ? 2 : 1;
}
selectedPiece = null;
clearHighlights();
}
// Create game board
for (var x = 0; x < BOARD_SIZE; x++) {
gameBoard[x] = [];
for (var y = 0; y < BOARD_SIZE; y++) {
var tileType = (x + y) % 2 === 0 ? 'tile_light' : 'tile_dark';
var tile = LK.getAsset(tileType, {
anchorX: 0.5,
anchorY: 0.5
});
var worldPos = gridToWorld(x, y);
tile.x = worldPos.x;
tile.y = worldPos.y;
game.addChild(tile);
gameBoard[x][y] = tile;
}
}
// Create pieces
var pieceTypes = ['knight', 'archer', 'wizard', 'archer', 'knight'];
// Player 1 pieces (bottom)
for (var i = 0; i < 5; i++) {
var piece = new GamePiece(pieceTypes[i], 1);
piece.setGridPosition(i, 4);
game.addChild(piece);
pieces.push(piece);
}
// Player 2 pieces (top)
for (var i = 0; i < 5; i++) {
var piece = new GamePiece(pieceTypes[i], 2);
piece.setGridPosition(i, 0);
game.addChild(piece);
pieces.push(piece);
}
// Magic orb in center
magicOrb = new GamePiece('magic_orb', 0);
magicOrb.setGridPosition(2, 2);
game.addChild(magicOrb);
pieces.push(magicOrb);
// Status text
var statusText = new Text2('Player 1 Turn', {
size: 60,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0);
LK.gui.top.addChild(statusText);
function updateStatusText() {
var phaseText = gamePhase === 'move_orb' ? ' - Move Orb' : ' - Move Piece';
statusText.setText('Player ' + currentPlayer + phaseText);
}
game.down = function (x, y, obj) {
var gridPos = worldToGrid(x, y);
if (!isValidPosition(gridPos.x, gridPos.y)) return;
var clickedPiece = isPieceAt(gridPos.x, gridPos.y);
if (selectedPiece && validMoves.length > 0) {
// Check if clicked position is a valid move
var isValidMove = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].x === gridPos.x && validMoves[i].y === gridPos.y) {
isValidMove = true;
break;
}
}
if (isValidMove) {
movePiece(selectedPiece, gridPos.x, gridPos.y);
if (checkWinCondition()) return;
switchTurn();
updateStatusText();
return;
}
}
// Select piece based on current phase
if (clickedPiece) {
if (gamePhase === 'move_orb' && clickedPiece.pieceType === 'magic_orb') {
selectedPiece = clickedPiece;
validMoves = clickedPiece.getValidMoves();
showSelection(clickedPiece);
showValidMoves(validMoves);
LK.getSound('select').play();
} else if (gamePhase === 'move_piece' && clickedPiece.player === currentPlayer) {
selectedPiece = clickedPiece;
validMoves = clickedPiece.getValidMoves();
showSelection(clickedPiece);
showValidMoves(validMoves);
LK.getSound('select').play();
}
} else {
selectedPiece = null;
validMoves = [];
clearHighlights();
}
};
updateStatusText(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var GamePiece = Container.expand(function (type, player) {
var self = Container.call(this);
self.pieceType = type;
self.player = player;
self.gridX = 0;
self.gridY = 0;
var graphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.setGridPosition = function (gridX, gridY) {
self.gridX = gridX;
self.gridY = gridY;
var worldPos = gridToWorld(gridX, gridY);
self.x = worldPos.x;
self.y = worldPos.y;
};
self.getValidMoves = function () {
var moves = [];
// All pieces move in any direction until blocked
var directions = [[-1, 0], [1, 0], [0, -1], [0, 1], [-1, -1], [-1, 1], [1, -1], [1, 1]];
for (var d = 0; d < directions.length; d++) {
for (var dist = 1; dist < 5; dist++) {
var newX = self.gridX + directions[d][0] * dist;
var newY = self.gridY + directions[d][1] * dist;
if (!isValidPosition(newX, newY)) break;
if (isPieceAt(newX, newY)) {
// Can move to position just before the blocking piece
if (dist > 1) {
moves.push({
x: self.gridX + directions[d][0] * (dist - 1),
y: self.gridY + directions[d][1] * (dist - 1)
});
}
break;
}
moves.push({
x: newX,
y: newY
});
}
}
return moves;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2f4f2f
});
/****
* Game Code
****/
// Game state variables
var currentPlayer = 1;
var gamePhase = 'move_orb'; // 'move_orb' or 'move_piece'
var selectedPiece = null;
var validMoves = [];
var gameBoard = [];
var pieces = [];
var highlights = [];
var magicOrb = null;
// Board setup
var BOARD_SIZE = 5;
var TILE_SIZE = 400;
// Center the board on screen
var BOARD_OFFSET_X = (2048 - BOARD_SIZE * TILE_SIZE) / 2;
var BOARD_OFFSET_Y = (2732 - BOARD_SIZE * TILE_SIZE) / 2;
function gridToWorld(gridX, gridY) {
return {
x: BOARD_OFFSET_X + gridX * TILE_SIZE + TILE_SIZE / 2,
y: BOARD_OFFSET_Y + gridY * TILE_SIZE + TILE_SIZE / 2
};
}
function worldToGrid(worldX, worldY) {
return {
x: Math.floor((worldX - BOARD_OFFSET_X) / TILE_SIZE),
y: Math.floor((worldY - BOARD_OFFSET_Y) / TILE_SIZE)
};
}
function isValidPosition(x, y) {
return x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE;
}
function isPieceAt(x, y) {
for (var i = 0; i < pieces.length; i++) {
if (pieces[i].gridX === x && pieces[i].gridY === y) {
return pieces[i];
}
}
return null;
}
function clearHighlights() {
for (var i = 0; i < highlights.length; i++) {
highlights[i].destroy();
}
highlights = [];
}
function showValidMoves(moves) {
clearHighlights();
for (var i = 0; i < moves.length; i++) {
var highlight = LK.getAsset('highlight', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
var worldPos = gridToWorld(moves[i].x, moves[i].y);
highlight.x = worldPos.x;
highlight.y = worldPos.y;
game.addChild(highlight);
highlights.push(highlight);
}
}
function showSelection(piece) {
clearHighlights();
var selection = LK.getAsset('selected', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.3
});
var worldPos = gridToWorld(piece.gridX, piece.gridY);
selection.x = worldPos.x;
selection.y = worldPos.y;
game.addChild(selection);
highlights.push(selection);
}
function movePiece(piece, gridX, gridY) {
piece.setGridPosition(gridX, gridY);
tween(piece, {
x: piece.x,
y: piece.y
}, {
duration: 300
});
LK.getSound('move').play();
}
function checkWinCondition() {
// Check if orb reached starting positions
if (magicOrb.gridY === 4) {
// Orb in player 1's starting row - Player 2 wins (because they moved it there)
if (currentPlayer === 1) {
// Player 1 moved orb to their own starting row, so Player 2 wins
var winnerText = new Text2('Player 2 Wins!', {
size: 120,
fill: 0xff0000
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else {
// Player 2 moved orb to Player 1's starting row, so Player 1 wins
var winnerText = new Text2('Player 1 Wins!', {
size: 120,
fill: 0x0000ff
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
return true;
}
if (magicOrb.gridY === 0) {
// Orb in player 2's starting row - Player 1 wins (because they moved it there)
if (currentPlayer === 2) {
// Player 2 moved orb to their own starting row, so Player 1 wins
var winnerText = new Text2('Player 1 Wins!', {
size: 120,
fill: 0x0000ff
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showGameOver();
}, 2000);
} else {
// Player 1 moved orb to Player 2's starting row, so Player 2 wins
var winnerText = new Text2('Player 2 Wins!', {
size: 120,
fill: 0xff0000
});
winnerText.anchor.set(0.5, 0.5);
winnerText.x = 2048 / 2;
winnerText.y = 2732 / 2;
game.addChild(winnerText);
LK.setTimeout(function () {
LK.showYouWin();
}, 2000);
}
return true;
}
return false;
}
function switchTurn() {
if (gamePhase === 'move_orb') {
gamePhase = 'move_piece';
} else {
gamePhase = 'move_orb';
currentPlayer = currentPlayer === 1 ? 2 : 1;
}
selectedPiece = null;
clearHighlights();
}
// Create game board
for (var x = 0; x < BOARD_SIZE; x++) {
gameBoard[x] = [];
for (var y = 0; y < BOARD_SIZE; y++) {
var tileType = (x + y) % 2 === 0 ? 'tile_light' : 'tile_dark';
var tile = LK.getAsset(tileType, {
anchorX: 0.5,
anchorY: 0.5
});
var worldPos = gridToWorld(x, y);
tile.x = worldPos.x;
tile.y = worldPos.y;
game.addChild(tile);
gameBoard[x][y] = tile;
}
}
// Create pieces
var pieceTypes = ['knight', 'archer', 'wizard', 'archer', 'knight'];
// Player 1 pieces (bottom)
for (var i = 0; i < 5; i++) {
var piece = new GamePiece(pieceTypes[i], 1);
piece.setGridPosition(i, 4);
game.addChild(piece);
pieces.push(piece);
}
// Player 2 pieces (top)
for (var i = 0; i < 5; i++) {
var piece = new GamePiece(pieceTypes[i], 2);
piece.setGridPosition(i, 0);
game.addChild(piece);
pieces.push(piece);
}
// Magic orb in center
magicOrb = new GamePiece('magic_orb', 0);
magicOrb.setGridPosition(2, 2);
game.addChild(magicOrb);
pieces.push(magicOrb);
// Status text
var statusText = new Text2('Player 1 Turn', {
size: 60,
fill: 0xFFFFFF
});
statusText.anchor.set(0.5, 0);
LK.gui.top.addChild(statusText);
function updateStatusText() {
var phaseText = gamePhase === 'move_orb' ? ' - Move Orb' : ' - Move Piece';
statusText.setText('Player ' + currentPlayer + phaseText);
}
game.down = function (x, y, obj) {
var gridPos = worldToGrid(x, y);
if (!isValidPosition(gridPos.x, gridPos.y)) return;
var clickedPiece = isPieceAt(gridPos.x, gridPos.y);
if (selectedPiece && validMoves.length > 0) {
// Check if clicked position is a valid move
var isValidMove = false;
for (var i = 0; i < validMoves.length; i++) {
if (validMoves[i].x === gridPos.x && validMoves[i].y === gridPos.y) {
isValidMove = true;
break;
}
}
if (isValidMove) {
movePiece(selectedPiece, gridPos.x, gridPos.y);
if (checkWinCondition()) return;
switchTurn();
updateStatusText();
return;
}
}
// Select piece based on current phase
if (clickedPiece) {
if (gamePhase === 'move_orb' && clickedPiece.pieceType === 'magic_orb') {
selectedPiece = clickedPiece;
validMoves = clickedPiece.getValidMoves();
showSelection(clickedPiece);
showValidMoves(validMoves);
LK.getSound('select').play();
} else if (gamePhase === 'move_piece' && clickedPiece.player === currentPlayer) {
selectedPiece = clickedPiece;
validMoves = clickedPiece.getValidMoves();
showSelection(clickedPiece);
showValidMoves(validMoves);
LK.getSound('select').play();
}
} else {
selectedPiece = null;
validMoves = [];
clearHighlights();
}
};
updateStatusText();