/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// IceBlock class: represents a tappable ice block (good or bad)
var IceBlock = Container.expand(function () {
var self = Container.call(this);
// Properties
self.isGood = true; // true = good, false = bad
// Attach asset (default to good, can be changed)
var blockAsset = null;
// Set up block type and visuals
self.setType = function (isGood) {
self.isGood = isGood;
if (blockAsset) {
blockAsset.destroy();
}
blockAsset = self.attachAsset(isGood ? 'ice_good' : 'ice_bad', {
anchorX: 0.5,
anchorY: 0.5
});
};
// Animate in (pop effect)
self.popIn = function () {
self.scaleX = 0.5;
self.scaleY = 0.5;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeOut
});
};
// Handle tap
self.down = function (x, y, obj) {
if (self.isGood) {
// Good block tapped: score up, pop, remove
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
// Animate pop out
tween(self, {
scaleX: 1.3,
scaleY: 1.3,
alpha: 0
}, {
duration: 120,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
// Remove from array in main game
for (var i = iceBlocks.length - 1; i >= 0; i--) {
if (iceBlocks[i] === self) {
iceBlocks.splice(i, 1);
break;
}
}
}
});
} else {
// Bad block tapped: game over
LK.effects.flashScreen(0xff0000, 600);
LK.showGameOver();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a2a3a
});
/****
* Game Code
****/
// Bad ice block: red box
// Good ice block: white box
// Score display
var scoreTxt = new Text2('0', {
size: 140,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Array to hold active ice blocks
var iceBlocks = [];
// Block spawn timing
var spawnInterval = 900; // ms, will decrease as score increases
var minInterval = 350; // ms, minimum spawn interval
var spawnTimer = null;
// Block lifetime (how long before it disappears if not tapped)
var blockLifetime = 1200; // ms
// Block spawn area (avoid top 200px and bottom 200px, and left 100px for menu)
var marginTop = 200;
var marginBottom = 200;
var marginLeft = 120;
var marginRight = 120;
// Block size (get from asset)
var blockSize = 180;
// Helper: spawn a new block
function spawnBlock() {
// Decide if good or bad block (80% good, 20% bad)
var isGood = Math.random() < 0.8;
var block = new IceBlock();
block.setType(isGood);
// Random position (avoid overlap with menu and edges)
var x = marginLeft + blockSize / 2 + Math.random() * (2048 - marginLeft - marginRight - blockSize);
var y = marginTop + blockSize / 2 + Math.random() * (2732 - marginTop - marginBottom - blockSize);
block.x = x;
block.y = y;
block.alpha = 1;
block.scaleX = 1;
block.scaleY = 1;
// Animate in
block.popIn();
// Add to game and array
game.addChild(block);
iceBlocks.push(block);
// Remove after lifetime if not tapped
block._timeout = LK.setTimeout(function () {
// If still present, remove (only for good blocks, bad blocks just fade)
for (var i = iceBlocks.length - 1; i >= 0; i--) {
if (iceBlocks[i] === block) {
// Animate fade out
tween(block, {
alpha: 0
}, {
duration: 120,
onFinish: function onFinish() {
block.destroy();
}
});
iceBlocks.splice(i, 1);
break;
}
}
}, blockLifetime);
}
// Helper: clear all blocks (on game over)
function clearBlocks() {
for (var i = iceBlocks.length - 1; i >= 0; i--) {
var block = iceBlocks[i];
if (block._timeout) LK.clearTimeout(block._timeout);
block.destroy();
iceBlocks.splice(i, 1);
}
}
// Handle tap anywhere: check if tap is on a block
game.down = function (x, y, obj) {
// Check from topmost to bottom
for (var i = iceBlocks.length - 1; i >= 0; i--) {
var block = iceBlocks[i];
// Use .containsPoint to check if tap is inside block
// Since we don't have .containsPoint, check distance to center
var dx = x - block.x;
var dy = y - block.y;
if (dx * dx + dy * dy < blockSize / 2 * (blockSize / 2)) {
// Forward event to block
block.down(x, y, obj);
return;
}
}
// Tapped empty space: do nothing
};
// Game update: not needed for this game, but required for block lifetime
game.update = function () {
// Increase difficulty: decrease spawn interval as score increases
var score = LK.getScore();
var newInterval = spawnInterval;
if (score < 10) {
newInterval = 900;
} else if (score < 20) {
newInterval = 750;
} else if (score < 35) {
newInterval = 600;
} else if (score < 50) {
newInterval = 500;
} else {
newInterval = 400;
}
if (newInterval !== spawnInterval) {
spawnInterval = newInterval;
// Restart timer
if (spawnTimer) LK.clearInterval(spawnTimer);
spawnTimer = LK.setInterval(spawnBlock, spawnInterval);
}
};
// Start game: reset score, clear blocks, start spawning
function startGame() {
LK.setScore(0);
scoreTxt.setText('0');
clearBlocks();
if (spawnTimer) LK.clearInterval(spawnTimer);
spawnInterval = 900;
spawnTimer = LK.setInterval(spawnBlock, spawnInterval);
// Spawn first block immediately
spawnBlock();
}
// On game over, clear blocks and stop timer
LK.on('gameover', function () {
clearBlocks();
if (spawnTimer) LK.clearInterval(spawnTimer);
});
// On game start (including after restart)
LK.on('gamestart', function () {
startGame();
});
// Start the game for the first time
startGame(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// IceBlock class: represents a tappable ice block (good or bad)
var IceBlock = Container.expand(function () {
var self = Container.call(this);
// Properties
self.isGood = true; // true = good, false = bad
// Attach asset (default to good, can be changed)
var blockAsset = null;
// Set up block type and visuals
self.setType = function (isGood) {
self.isGood = isGood;
if (blockAsset) {
blockAsset.destroy();
}
blockAsset = self.attachAsset(isGood ? 'ice_good' : 'ice_bad', {
anchorX: 0.5,
anchorY: 0.5
});
};
// Animate in (pop effect)
self.popIn = function () {
self.scaleX = 0.5;
self.scaleY = 0.5;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.easeOut
});
};
// Handle tap
self.down = function (x, y, obj) {
if (self.isGood) {
// Good block tapped: score up, pop, remove
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
// Animate pop out
tween(self, {
scaleX: 1.3,
scaleY: 1.3,
alpha: 0
}, {
duration: 120,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
// Remove from array in main game
for (var i = iceBlocks.length - 1; i >= 0; i--) {
if (iceBlocks[i] === self) {
iceBlocks.splice(i, 1);
break;
}
}
}
});
} else {
// Bad block tapped: game over
LK.effects.flashScreen(0xff0000, 600);
LK.showGameOver();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a2a3a
});
/****
* Game Code
****/
// Bad ice block: red box
// Good ice block: white box
// Score display
var scoreTxt = new Text2('0', {
size: 140,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Array to hold active ice blocks
var iceBlocks = [];
// Block spawn timing
var spawnInterval = 900; // ms, will decrease as score increases
var minInterval = 350; // ms, minimum spawn interval
var spawnTimer = null;
// Block lifetime (how long before it disappears if not tapped)
var blockLifetime = 1200; // ms
// Block spawn area (avoid top 200px and bottom 200px, and left 100px for menu)
var marginTop = 200;
var marginBottom = 200;
var marginLeft = 120;
var marginRight = 120;
// Block size (get from asset)
var blockSize = 180;
// Helper: spawn a new block
function spawnBlock() {
// Decide if good or bad block (80% good, 20% bad)
var isGood = Math.random() < 0.8;
var block = new IceBlock();
block.setType(isGood);
// Random position (avoid overlap with menu and edges)
var x = marginLeft + blockSize / 2 + Math.random() * (2048 - marginLeft - marginRight - blockSize);
var y = marginTop + blockSize / 2 + Math.random() * (2732 - marginTop - marginBottom - blockSize);
block.x = x;
block.y = y;
block.alpha = 1;
block.scaleX = 1;
block.scaleY = 1;
// Animate in
block.popIn();
// Add to game and array
game.addChild(block);
iceBlocks.push(block);
// Remove after lifetime if not tapped
block._timeout = LK.setTimeout(function () {
// If still present, remove (only for good blocks, bad blocks just fade)
for (var i = iceBlocks.length - 1; i >= 0; i--) {
if (iceBlocks[i] === block) {
// Animate fade out
tween(block, {
alpha: 0
}, {
duration: 120,
onFinish: function onFinish() {
block.destroy();
}
});
iceBlocks.splice(i, 1);
break;
}
}
}, blockLifetime);
}
// Helper: clear all blocks (on game over)
function clearBlocks() {
for (var i = iceBlocks.length - 1; i >= 0; i--) {
var block = iceBlocks[i];
if (block._timeout) LK.clearTimeout(block._timeout);
block.destroy();
iceBlocks.splice(i, 1);
}
}
// Handle tap anywhere: check if tap is on a block
game.down = function (x, y, obj) {
// Check from topmost to bottom
for (var i = iceBlocks.length - 1; i >= 0; i--) {
var block = iceBlocks[i];
// Use .containsPoint to check if tap is inside block
// Since we don't have .containsPoint, check distance to center
var dx = x - block.x;
var dy = y - block.y;
if (dx * dx + dy * dy < blockSize / 2 * (blockSize / 2)) {
// Forward event to block
block.down(x, y, obj);
return;
}
}
// Tapped empty space: do nothing
};
// Game update: not needed for this game, but required for block lifetime
game.update = function () {
// Increase difficulty: decrease spawn interval as score increases
var score = LK.getScore();
var newInterval = spawnInterval;
if (score < 10) {
newInterval = 900;
} else if (score < 20) {
newInterval = 750;
} else if (score < 35) {
newInterval = 600;
} else if (score < 50) {
newInterval = 500;
} else {
newInterval = 400;
}
if (newInterval !== spawnInterval) {
spawnInterval = newInterval;
// Restart timer
if (spawnTimer) LK.clearInterval(spawnTimer);
spawnTimer = LK.setInterval(spawnBlock, spawnInterval);
}
};
// Start game: reset score, clear blocks, start spawning
function startGame() {
LK.setScore(0);
scoreTxt.setText('0');
clearBlocks();
if (spawnTimer) LK.clearInterval(spawnTimer);
spawnInterval = 900;
spawnTimer = LK.setInterval(spawnBlock, spawnInterval);
// Spawn first block immediately
spawnBlock();
}
// On game over, clear blocks and stop timer
LK.on('gameover', function () {
clearBlocks();
if (spawnTimer) LK.clearInterval(spawnTimer);
});
// On game start (including after restart)
LK.on('gamestart', function () {
startGame();
});
// Start the game for the first time
startGame();