/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Class for Bird
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.update = function () {
self.x += self.speed;
self.y += Math.sin(self.x / 100) * 2; // Add vertical movement based on sine wave
if (self.x > 2048 + birdGraphics.width / 2) {
self.x = -birdGraphics.width / 2;
}
};
});
// Class for Crane
var Crane = Container.expand(function () {
var self = Container.call(this);
var craneGraphics = self.attachAsset('crane', {
anchorX: 0.5,
anchorY: 0.0
});
});
// Class for Dove
var Dove = Container.expand(function () {
var self = Container.call(this);
var doveGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.update = function () {
self.x += self.speed;
self.y += Math.sin(self.x / 100) * 2; // Add vertical movement based on sine wave
if (self.x > 2048 + doveGraphics.width / 2) {
self.x = -doveGraphics.width / 2;
}
};
});
var DoveBird = Container.expand(function () {
var self = Container.call(this);
var doveBirdGraphics = self.attachAsset('dovebird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.update = function () {
self.x -= self.speed;
self.y += Math.sin(self.x / 100) * 2; // Add vertical movement based on sine wave
if (self.x < -doveBirdGraphics.width / 2) {
self.x = 2048 + doveBirdGraphics.width / 2;
}
};
});
// Class for TowerBlock
var TowerBlock = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('towerBlock', {
anchorX: 0.5,
anchorY: 0.5
});
self.swayDirection = 1;
self.swaySpeed = 1;
self.velocityX = 0;
self.isSettled = false;
self.update = function () {
self.x += self.swaySpeed * self.swayDirection * 1.5;
if (self.x > 2048 - blockGraphics.width / 2 || self.x < blockGraphics.width / 2) {
self.swayDirection *= -1; // Reverse direction when reaching the edge
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Light blue background
});
/****
* Game Code
****/
var sky = game.addChild(LK.getAsset('sky', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var crane = new Crane();
crane.x = currentBlock ? currentBlock.x : 2048 / 2;
crane.y = 0;
game.addChild(crane);
var grass = game.addChild(LK.getAsset('grass', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
}));
// Initialize variables
var towerBlocks = [];
var baseY = 2500; // Base row position
var currentBlock = null;
var blockCount = 0; // Track number of blocks created
var dropCooldownActive = false; // Track if drop cooldown is active
// Function to drop the current block
function dropBlock() {
if (currentBlock) {
currentBlock.swaySpeed = 0; // Stop swaying
towerBlocks.push(currentBlock);
currentBlock = null;
}
}
// Create a new block at the top of the screen
function createNewBlock() {
if (blockCount < 20) {
currentBlock = new TowerBlock();
currentBlock.x = crane.x;
currentBlock.y = crane.y + 100;
game.addChild(currentBlock);
blockCount++;
}
}
// Handle screen tap to drop the block
game.down = function (x, y, obj) {
// Prevent dropping if cooldown is active
if (dropCooldownActive) {
return;
}
if (!currentBlock) {
if (blockCount < 20) {
currentBlock = new TowerBlock();
currentBlock.x = crane.x;
currentBlock.y = crane.y + 100;
game.addChild(currentBlock);
blockCount++;
}
}
var lastSwayDirection = currentBlock ? currentBlock.swayDirection : 1; // Save the sway direction of the current block, default to 1 if null
dropBlock();
if (blockCount < 20) {
createNewBlock();
}
if (currentBlock) {
currentBlock.x = towerBlocks[towerBlocks.length - 1].x; // Set the x position of the new block to the x position of the last block in the towerBlocks array
currentBlock.swayDirection = lastSwayDirection; // Set the sway direction of the new block to the saved sway direction
// Reduce opacity during cooldown
tween(currentBlock, {
alpha: 0.5
}, {
duration: 1000,
onFinish: function onFinish() {
// Restore full opacity when cooldown ends
if (currentBlock) {
currentBlock.alpha = 1.0;
}
dropCooldownActive = false;
}
});
}
// Activate cooldown
dropCooldownActive = true;
};
// Initialize the first block
createNewBlock();
// Add birds to the game
for (var i = 0; i < 2; i++) {
var bird = new Bird();
bird.x = Math.random() * 2048;
bird.y = Math.random() * (2732 / 2);
game.addChild(bird);
}
// Add doves to the game
for (var i = 0; i < 3; i++) {
var dove = new Dove();
dove.x = Math.random() * 2048;
dove.y = Math.random() * (2732 / 2);
game.addChild(dove);
}
// Add dovebirds to the game
for (var i = 0; i < 2; i++) {
var doveBird = new DoveBird();
doveBird.x = Math.random() * 2048;
doveBird.y = Math.random() * (2732 / 2);
game.addChild(doveBird);
}
// Update function for the game
game.update = function () {
if (currentBlock) {
currentBlock.update();
crane.x = currentBlock ? currentBlock.x : towerBlocks.length > 0 ? towerBlocks[towerBlocks.length - 1].x : crane.x;
}
// Update positions of all blocks
for (var i = towerBlocks.length - 1; i >= 0; i--) {
towerBlocks[i].y += 10; // Increase the falling speed of blocks
// Check if the block has collided with the grass
if (towerBlocks[i].intersects(grass)) {
towerBlocks[i].y = grass.y - towerBlocks[i].height / 2; // Position the block on top of the grass
towerBlocks[i].swaySpeed = 0; // Stop the block from moving
}
// Check if the block has collided with another block
for (var j = 0; j < towerBlocks.length; j++) {
if (i != j && towerBlocks[i] && towerBlocks[j] && towerBlocks[i].intersects(towerBlocks[j])) {
towerBlocks[i].y = towerBlocks[j].y - towerBlocks[i].height; // Position the block on top of the other block
towerBlocks[i].swaySpeed = 0; // Stop the block from moving
towerBlocks[i].swayDirection = 0; // Ensure no further movement occurs
// Initialize lastX for tracking changes on X
if (towerBlocks[i].lastX === undefined) {
towerBlocks[i].lastX = towerBlocks[i].x;
}
// Calculate support percentage - how much of current block overlaps with block below
var blockLeftEdge = towerBlocks[i].x - towerBlocks[i].width / 2;
var blockRightEdge = towerBlocks[i].x + towerBlocks[i].width / 2;
var supportLeftEdge = towerBlocks[j].x - towerBlocks[j].width / 2;
var supportRightEdge = towerBlocks[j].x + towerBlocks[j].width / 2;
// Calculate overlap region
var overlapStart = Math.max(blockLeftEdge, supportLeftEdge);
var overlapEnd = Math.min(blockRightEdge, supportRightEdge);
var overlapWidth = Math.max(0, overlapEnd - overlapStart);
var supportPercentage = overlapWidth / towerBlocks[i].width;
if (supportPercentage < 0.5) {
// Less than 50% supported - block should fall/tip
if (towerBlocks[i].isFalling === undefined) {
towerBlocks[i].isFalling = true;
}
towerBlocks[i].x += towerBlocks[i].x < towerBlocks[j].x ? -5 : 5;
// Check if the block has fallen off completely
if (towerBlocks[i].x < 0 || towerBlocks[i].x > 2048) {
towerBlocks[i].destroy(); // Remove the block from the game
towerBlocks.splice(i, 1); // Remove the block from the array
}
} else {
// Block is properly supported (50% or more)
towerBlocks[i].isSettled = true;
towerBlocks[i].velocityX = 0;
if (towerBlocks[i].y > 2732) {
towerBlocks[i].destroy(); // Remove the block from the game
towerBlocks.splice(i, 1); // Remove the block from the array
}
}
// Update last known states
if (towerBlocks[i]) {
towerBlocks[i].lastX = towerBlocks[i].x;
}
break; // Prevent block from bouncing by breaking the loop once a collision is detected
}
}
}
// Play dove sound in loop
if (LK.ticks % 420 == 0) {
LK.getSound('Dove').play();
LK.playMusic('Birds');
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Class for Bird
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.update = function () {
self.x += self.speed;
self.y += Math.sin(self.x / 100) * 2; // Add vertical movement based on sine wave
if (self.x > 2048 + birdGraphics.width / 2) {
self.x = -birdGraphics.width / 2;
}
};
});
// Class for Crane
var Crane = Container.expand(function () {
var self = Container.call(this);
var craneGraphics = self.attachAsset('crane', {
anchorX: 0.5,
anchorY: 0.0
});
});
// Class for Dove
var Dove = Container.expand(function () {
var self = Container.call(this);
var doveGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.update = function () {
self.x += self.speed;
self.y += Math.sin(self.x / 100) * 2; // Add vertical movement based on sine wave
if (self.x > 2048 + doveGraphics.width / 2) {
self.x = -doveGraphics.width / 2;
}
};
});
var DoveBird = Container.expand(function () {
var self = Container.call(this);
var doveBirdGraphics = self.attachAsset('dovebird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.update = function () {
self.x -= self.speed;
self.y += Math.sin(self.x / 100) * 2; // Add vertical movement based on sine wave
if (self.x < -doveBirdGraphics.width / 2) {
self.x = 2048 + doveBirdGraphics.width / 2;
}
};
});
// Class for TowerBlock
var TowerBlock = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('towerBlock', {
anchorX: 0.5,
anchorY: 0.5
});
self.swayDirection = 1;
self.swaySpeed = 1;
self.velocityX = 0;
self.isSettled = false;
self.update = function () {
self.x += self.swaySpeed * self.swayDirection * 1.5;
if (self.x > 2048 - blockGraphics.width / 2 || self.x < blockGraphics.width / 2) {
self.swayDirection *= -1; // Reverse direction when reaching the edge
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB // Light blue background
});
/****
* Game Code
****/
var sky = game.addChild(LK.getAsset('sky', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
var crane = new Crane();
crane.x = currentBlock ? currentBlock.x : 2048 / 2;
crane.y = 0;
game.addChild(crane);
var grass = game.addChild(LK.getAsset('grass', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
}));
// Initialize variables
var towerBlocks = [];
var baseY = 2500; // Base row position
var currentBlock = null;
var blockCount = 0; // Track number of blocks created
var dropCooldownActive = false; // Track if drop cooldown is active
// Function to drop the current block
function dropBlock() {
if (currentBlock) {
currentBlock.swaySpeed = 0; // Stop swaying
towerBlocks.push(currentBlock);
currentBlock = null;
}
}
// Create a new block at the top of the screen
function createNewBlock() {
if (blockCount < 20) {
currentBlock = new TowerBlock();
currentBlock.x = crane.x;
currentBlock.y = crane.y + 100;
game.addChild(currentBlock);
blockCount++;
}
}
// Handle screen tap to drop the block
game.down = function (x, y, obj) {
// Prevent dropping if cooldown is active
if (dropCooldownActive) {
return;
}
if (!currentBlock) {
if (blockCount < 20) {
currentBlock = new TowerBlock();
currentBlock.x = crane.x;
currentBlock.y = crane.y + 100;
game.addChild(currentBlock);
blockCount++;
}
}
var lastSwayDirection = currentBlock ? currentBlock.swayDirection : 1; // Save the sway direction of the current block, default to 1 if null
dropBlock();
if (blockCount < 20) {
createNewBlock();
}
if (currentBlock) {
currentBlock.x = towerBlocks[towerBlocks.length - 1].x; // Set the x position of the new block to the x position of the last block in the towerBlocks array
currentBlock.swayDirection = lastSwayDirection; // Set the sway direction of the new block to the saved sway direction
// Reduce opacity during cooldown
tween(currentBlock, {
alpha: 0.5
}, {
duration: 1000,
onFinish: function onFinish() {
// Restore full opacity when cooldown ends
if (currentBlock) {
currentBlock.alpha = 1.0;
}
dropCooldownActive = false;
}
});
}
// Activate cooldown
dropCooldownActive = true;
};
// Initialize the first block
createNewBlock();
// Add birds to the game
for (var i = 0; i < 2; i++) {
var bird = new Bird();
bird.x = Math.random() * 2048;
bird.y = Math.random() * (2732 / 2);
game.addChild(bird);
}
// Add doves to the game
for (var i = 0; i < 3; i++) {
var dove = new Dove();
dove.x = Math.random() * 2048;
dove.y = Math.random() * (2732 / 2);
game.addChild(dove);
}
// Add dovebirds to the game
for (var i = 0; i < 2; i++) {
var doveBird = new DoveBird();
doveBird.x = Math.random() * 2048;
doveBird.y = Math.random() * (2732 / 2);
game.addChild(doveBird);
}
// Update function for the game
game.update = function () {
if (currentBlock) {
currentBlock.update();
crane.x = currentBlock ? currentBlock.x : towerBlocks.length > 0 ? towerBlocks[towerBlocks.length - 1].x : crane.x;
}
// Update positions of all blocks
for (var i = towerBlocks.length - 1; i >= 0; i--) {
towerBlocks[i].y += 10; // Increase the falling speed of blocks
// Check if the block has collided with the grass
if (towerBlocks[i].intersects(grass)) {
towerBlocks[i].y = grass.y - towerBlocks[i].height / 2; // Position the block on top of the grass
towerBlocks[i].swaySpeed = 0; // Stop the block from moving
}
// Check if the block has collided with another block
for (var j = 0; j < towerBlocks.length; j++) {
if (i != j && towerBlocks[i] && towerBlocks[j] && towerBlocks[i].intersects(towerBlocks[j])) {
towerBlocks[i].y = towerBlocks[j].y - towerBlocks[i].height; // Position the block on top of the other block
towerBlocks[i].swaySpeed = 0; // Stop the block from moving
towerBlocks[i].swayDirection = 0; // Ensure no further movement occurs
// Initialize lastX for tracking changes on X
if (towerBlocks[i].lastX === undefined) {
towerBlocks[i].lastX = towerBlocks[i].x;
}
// Calculate support percentage - how much of current block overlaps with block below
var blockLeftEdge = towerBlocks[i].x - towerBlocks[i].width / 2;
var blockRightEdge = towerBlocks[i].x + towerBlocks[i].width / 2;
var supportLeftEdge = towerBlocks[j].x - towerBlocks[j].width / 2;
var supportRightEdge = towerBlocks[j].x + towerBlocks[j].width / 2;
// Calculate overlap region
var overlapStart = Math.max(blockLeftEdge, supportLeftEdge);
var overlapEnd = Math.min(blockRightEdge, supportRightEdge);
var overlapWidth = Math.max(0, overlapEnd - overlapStart);
var supportPercentage = overlapWidth / towerBlocks[i].width;
if (supportPercentage < 0.5) {
// Less than 50% supported - block should fall/tip
if (towerBlocks[i].isFalling === undefined) {
towerBlocks[i].isFalling = true;
}
towerBlocks[i].x += towerBlocks[i].x < towerBlocks[j].x ? -5 : 5;
// Check if the block has fallen off completely
if (towerBlocks[i].x < 0 || towerBlocks[i].x > 2048) {
towerBlocks[i].destroy(); // Remove the block from the game
towerBlocks.splice(i, 1); // Remove the block from the array
}
} else {
// Block is properly supported (50% or more)
towerBlocks[i].isSettled = true;
towerBlocks[i].velocityX = 0;
if (towerBlocks[i].y > 2732) {
towerBlocks[i].destroy(); // Remove the block from the game
towerBlocks.splice(i, 1); // Remove the block from the array
}
}
// Update last known states
if (towerBlocks[i]) {
towerBlocks[i].lastX = towerBlocks[i].x;
}
break; // Prevent block from bouncing by breaking the loop once a collision is detected
}
}
}
// Play dove sound in loop
if (LK.ticks % 420 == 0) {
LK.getSound('Dove').play();
LK.playMusic('Birds');
}
};