/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.8;
self.isLaunched = false;
self.health = 1;
self.update = function () {
if (self.isLaunched) {
self.velocityY += self.gravity;
self.x += self.velocityX;
self.y += self.velocityY;
// Ground collision
if (self.y > 2650) {
self.velocityX *= 0.7;
self.velocityY = -self.velocityY * 1.2; // Increased bounce height
self.y = 2650;
// Add bounce scale effect
tween(birdGraphics, {
scaleX: 1.3,
scaleY: 0.8
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(birdGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
}
// Side bounds
if (self.x < 0 || self.x > 2048) {
self.velocityX = -self.velocityX * 0.5;
}
// Stop if moving too slowly
if (Math.abs(self.velocityX) < 0.5 && Math.abs(self.velocityY) < 0.5 && self.y >= 2650) {
self.isLaunched = false;
self.velocityX = 0;
self.velocityY = 0;
}
}
};
self.launch = function (vx, vy) {
self.velocityX = vx;
self.velocityY = vy;
self.isLaunched = true;
LK.getSound('launch').play();
};
return self;
});
var Block = Container.expand(function (type) {
var self = Container.call(this);
var blockGraphics = self.attachAsset(type + 'Block', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
self.isDestroyed = false;
// Set health based on material
if (type === 'glass') {
self.health = 1;
} else if (type === 'wood') {
self.health = 2;
} else if (type === 'stone') {
self.health = 3;
}
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
// Add destruction animation
tween(blockGraphics, {
scaleX: 0.3,
scaleY: 0.3,
rotation: Math.PI,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
self.isDestroyed = true;
LK.getSound('destroy').play();
LK.effects.flashObject(self, 0xff0000, 300);
} else {
// Add damage shake effect
tween(blockGraphics, {
rotation: 0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(blockGraphics, {
rotation: -0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(blockGraphics, {
rotation: 0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
});
LK.effects.flashObject(self, 0xffff00, 200);
LK.getSound('hit').play();
}
};
return self;
});
var Pig = Container.expand(function () {
var self = Container.call(this);
var pigGraphics = self.attachAsset('pig', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.isDestroyed = false;
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
// Add pig destruction animation
tween(pigGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
self.isDestroyed = true;
LK.getSound('destroy').play();
LK.effects.flashObject(self, 0xff0000, 300);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var slingshot;
var currentBird;
var birds = [];
var pigs = [];
var blocks = [];
var trajectoryPoints = [];
var isDragging = false;
var dragStartX = 0;
var dragStartY = 0;
var slingshotX = 300;
var slingshotY = 2400;
var birdsUsed = 0;
var maxBirds = 3;
var levelComplete = false;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var birdsLeftText = new Text2('Birds: 3', {
size: 60,
fill: 0xFFFFFF
});
birdsLeftText.anchor.set(0, 0);
birdsLeftText.x = 150;
birdsLeftText.y = 50;
LK.gui.top.addChild(birdsLeftText);
// Create slingshot
slingshot = game.addChild(LK.getAsset('slingshot', {
anchorX: 0.5,
anchorY: 1.0,
x: slingshotX,
y: slingshotY
}));
// Create level
function createLevel() {
// Create pigs
var pig1 = game.addChild(new Pig());
pig1.x = 1400;
pig1.y = 2200;
pigs.push(pig1);
var pig2 = game.addChild(new Pig());
pig2.x = 1600;
pig2.y = 2200;
pigs.push(pig2);
// Create structure
var woodBlock1 = game.addChild(new Block('wood'));
woodBlock1.x = 1300;
woodBlock1.y = 2300;
blocks.push(woodBlock1);
var woodBlock2 = game.addChild(new Block('wood'));
woodBlock2.x = 1500;
woodBlock2.y = 2300;
blocks.push(woodBlock2);
var woodBlock3 = game.addChild(new Block('wood'));
woodBlock3.x = 1700;
woodBlock3.y = 2300;
blocks.push(woodBlock3);
var glassBlock1 = game.addChild(new Block('glass'));
glassBlock1.x = 1400;
glassBlock1.y = 2250;
blocks.push(glassBlock1);
var glassBlock2 = game.addChild(new Block('glass'));
glassBlock2.x = 1600;
glassBlock2.y = 2250;
blocks.push(glassBlock2);
var stoneBlock1 = game.addChild(new Block('stone'));
stoneBlock1.x = 1500;
stoneBlock1.y = 2200;
blocks.push(stoneBlock1);
}
// Create first bird
function createBird() {
if (birdsUsed < maxBirds) {
currentBird = game.addChild(new Bird());
currentBird.x = slingshotX;
currentBird.y = slingshotY - 100;
birds.push(currentBird);
}
}
// Clear trajectory
function clearTrajectory() {
for (var i = 0; i < trajectoryPoints.length; i++) {
trajectoryPoints[i].destroy();
}
trajectoryPoints = [];
}
// Show trajectory
function showTrajectory(startX, startY, velocityX, velocityY) {
clearTrajectory();
var x = startX;
var y = startY;
var vx = velocityX;
var vy = velocityY;
for (var i = 0; i < 20; i++) {
vy += 0.8;
x += vx;
y += vy;
if (y > 2650) break;
var point = game.addChild(LK.getAsset('trajectory', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
alpha: 0.5
}));
trajectoryPoints.push(point);
}
}
// Check collisions
function checkCollisions() {
for (var i = birds.length - 1; i >= 0; i--) {
var bird = birds[i];
if (!bird.isLaunched) continue;
// Check pig collisions
for (var j = pigs.length - 1; j >= 0; j--) {
var pig = pigs[j];
if (!pig.isDestroyed && bird.intersects(pig)) {
pig.takeDamage();
if (pig.isDestroyed) {
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
pigs.splice(j, 1);
}
}
}
// Check block collisions
for (var k = blocks.length - 1; k >= 0; k--) {
var block = blocks[k];
if (!block.isDestroyed && bird.intersects(block)) {
block.takeDamage();
bird.velocityX *= 0.5;
bird.velocityY *= 0.5;
if (block.isDestroyed) {
LK.setScore(LK.getScore() + 50);
scoreText.setText('Score: ' + LK.getScore());
blocks.splice(k, 1);
}
}
}
}
}
// Check win condition
function checkWinCondition() {
if (pigs.length === 0 && !levelComplete) {
levelComplete = true;
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
} else if (birdsUsed >= maxBirds && pigs.length > 0 && !levelComplete) {
levelComplete = true;
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
// Game event handlers
game.down = function (x, y, obj) {
if (currentBird && !currentBird.isLaunched && !levelComplete) {
isDragging = true;
dragStartX = x;
dragStartY = y;
}
};
game.move = function (x, y, obj) {
if (isDragging && currentBird && !currentBird.isLaunched) {
var deltaX = dragStartX - x;
var deltaY = dragStartY - y;
// Limit drag distance
var maxDrag = 150;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > maxDrag) {
deltaX = deltaX / distance * maxDrag;
deltaY = deltaY / distance * maxDrag;
}
currentBird.x = slingshotX - deltaX;
currentBird.y = slingshotY - 100 - deltaY;
// Add slingshot stretch effect
var stretchAmount = 1 + distance / 300;
tween(slingshot, {
scaleX: stretchAmount,
scaleY: 1 + distance / 500
}, {
duration: 100,
easing: tween.easeOut
});
// Show trajectory
var velocityX = deltaX * 0.4; // Increased launch power
var velocityY = deltaY * 0.4; // Increased launch power
showTrajectory(currentBird.x, currentBird.y, velocityX, velocityY);
}
};
game.up = function (x, y, obj) {
if (isDragging && currentBird && !currentBird.isLaunched) {
isDragging = false;
clearTrajectory();
var deltaX = dragStartX - x;
var deltaY = dragStartY - y;
// Limit drag distance
var maxDrag = 150;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > maxDrag) {
deltaX = deltaX / distance * maxDrag;
deltaY = deltaY / distance * maxDrag;
}
if (distance > 10) {
var velocityX = deltaX * 0.4; // Increased launch power
var velocityY = deltaY * 0.4; // Increased launch power
currentBird.launch(velocityX, velocityY);
birdsUsed++;
birdsLeftText.setText('Birds: ' + (maxBirds - birdsUsed));
// Reset slingshot with animation
tween(slingshot, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
// Create next bird after delay
LK.setTimeout(function () {
if (birdsUsed < maxBirds && pigs.length > 0) {
createBird();
}
}, 2000);
currentBird = null;
} else {
// Reset bird position with animation
tween(currentBird, {
x: slingshotX,
y: slingshotY - 100
}, {
duration: 300,
easing: tween.easeOut
});
// Reset slingshot
tween(slingshot, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
}
};
game.update = function () {
checkCollisions();
checkWinCondition();
};
// Initialize level
createLevel();
createBird(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.gravity = 0.8;
self.isLaunched = false;
self.health = 1;
self.update = function () {
if (self.isLaunched) {
self.velocityY += self.gravity;
self.x += self.velocityX;
self.y += self.velocityY;
// Ground collision
if (self.y > 2650) {
self.velocityX *= 0.7;
self.velocityY = -self.velocityY * 1.2; // Increased bounce height
self.y = 2650;
// Add bounce scale effect
tween(birdGraphics, {
scaleX: 1.3,
scaleY: 0.8
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(birdGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 150,
easing: tween.easeOut
});
}
});
}
// Side bounds
if (self.x < 0 || self.x > 2048) {
self.velocityX = -self.velocityX * 0.5;
}
// Stop if moving too slowly
if (Math.abs(self.velocityX) < 0.5 && Math.abs(self.velocityY) < 0.5 && self.y >= 2650) {
self.isLaunched = false;
self.velocityX = 0;
self.velocityY = 0;
}
}
};
self.launch = function (vx, vy) {
self.velocityX = vx;
self.velocityY = vy;
self.isLaunched = true;
LK.getSound('launch').play();
};
return self;
});
var Block = Container.expand(function (type) {
var self = Container.call(this);
var blockGraphics = self.attachAsset(type + 'Block', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = type;
self.isDestroyed = false;
// Set health based on material
if (type === 'glass') {
self.health = 1;
} else if (type === 'wood') {
self.health = 2;
} else if (type === 'stone') {
self.health = 3;
}
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
// Add destruction animation
tween(blockGraphics, {
scaleX: 0.3,
scaleY: 0.3,
rotation: Math.PI,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
self.isDestroyed = true;
LK.getSound('destroy').play();
LK.effects.flashObject(self, 0xff0000, 300);
} else {
// Add damage shake effect
tween(blockGraphics, {
rotation: 0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(blockGraphics, {
rotation: -0.2
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(blockGraphics, {
rotation: 0
}, {
duration: 100,
easing: tween.easeOut
});
}
});
}
});
LK.effects.flashObject(self, 0xffff00, 200);
LK.getSound('hit').play();
}
};
return self;
});
var Pig = Container.expand(function () {
var self = Container.call(this);
var pigGraphics = self.attachAsset('pig', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 1;
self.isDestroyed = false;
self.takeDamage = function () {
self.health--;
if (self.health <= 0) {
// Add pig destruction animation
tween(pigGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
self.destroy();
}
});
self.isDestroyed = true;
LK.getSound('destroy').play();
LK.effects.flashObject(self, 0xff0000, 300);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Game variables
var slingshot;
var currentBird;
var birds = [];
var pigs = [];
var blocks = [];
var trajectoryPoints = [];
var isDragging = false;
var dragStartX = 0;
var dragStartY = 0;
var slingshotX = 300;
var slingshotY = 2400;
var birdsUsed = 0;
var maxBirds = 3;
var levelComplete = false;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreText);
var birdsLeftText = new Text2('Birds: 3', {
size: 60,
fill: 0xFFFFFF
});
birdsLeftText.anchor.set(0, 0);
birdsLeftText.x = 150;
birdsLeftText.y = 50;
LK.gui.top.addChild(birdsLeftText);
// Create slingshot
slingshot = game.addChild(LK.getAsset('slingshot', {
anchorX: 0.5,
anchorY: 1.0,
x: slingshotX,
y: slingshotY
}));
// Create level
function createLevel() {
// Create pigs
var pig1 = game.addChild(new Pig());
pig1.x = 1400;
pig1.y = 2200;
pigs.push(pig1);
var pig2 = game.addChild(new Pig());
pig2.x = 1600;
pig2.y = 2200;
pigs.push(pig2);
// Create structure
var woodBlock1 = game.addChild(new Block('wood'));
woodBlock1.x = 1300;
woodBlock1.y = 2300;
blocks.push(woodBlock1);
var woodBlock2 = game.addChild(new Block('wood'));
woodBlock2.x = 1500;
woodBlock2.y = 2300;
blocks.push(woodBlock2);
var woodBlock3 = game.addChild(new Block('wood'));
woodBlock3.x = 1700;
woodBlock3.y = 2300;
blocks.push(woodBlock3);
var glassBlock1 = game.addChild(new Block('glass'));
glassBlock1.x = 1400;
glassBlock1.y = 2250;
blocks.push(glassBlock1);
var glassBlock2 = game.addChild(new Block('glass'));
glassBlock2.x = 1600;
glassBlock2.y = 2250;
blocks.push(glassBlock2);
var stoneBlock1 = game.addChild(new Block('stone'));
stoneBlock1.x = 1500;
stoneBlock1.y = 2200;
blocks.push(stoneBlock1);
}
// Create first bird
function createBird() {
if (birdsUsed < maxBirds) {
currentBird = game.addChild(new Bird());
currentBird.x = slingshotX;
currentBird.y = slingshotY - 100;
birds.push(currentBird);
}
}
// Clear trajectory
function clearTrajectory() {
for (var i = 0; i < trajectoryPoints.length; i++) {
trajectoryPoints[i].destroy();
}
trajectoryPoints = [];
}
// Show trajectory
function showTrajectory(startX, startY, velocityX, velocityY) {
clearTrajectory();
var x = startX;
var y = startY;
var vx = velocityX;
var vy = velocityY;
for (var i = 0; i < 20; i++) {
vy += 0.8;
x += vx;
y += vy;
if (y > 2650) break;
var point = game.addChild(LK.getAsset('trajectory', {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y,
alpha: 0.5
}));
trajectoryPoints.push(point);
}
}
// Check collisions
function checkCollisions() {
for (var i = birds.length - 1; i >= 0; i--) {
var bird = birds[i];
if (!bird.isLaunched) continue;
// Check pig collisions
for (var j = pigs.length - 1; j >= 0; j--) {
var pig = pigs[j];
if (!pig.isDestroyed && bird.intersects(pig)) {
pig.takeDamage();
if (pig.isDestroyed) {
LK.setScore(LK.getScore() + 100);
scoreText.setText('Score: ' + LK.getScore());
pigs.splice(j, 1);
}
}
}
// Check block collisions
for (var k = blocks.length - 1; k >= 0; k--) {
var block = blocks[k];
if (!block.isDestroyed && bird.intersects(block)) {
block.takeDamage();
bird.velocityX *= 0.5;
bird.velocityY *= 0.5;
if (block.isDestroyed) {
LK.setScore(LK.getScore() + 50);
scoreText.setText('Score: ' + LK.getScore());
blocks.splice(k, 1);
}
}
}
}
}
// Check win condition
function checkWinCondition() {
if (pigs.length === 0 && !levelComplete) {
levelComplete = true;
LK.setTimeout(function () {
LK.showYouWin();
}, 1000);
} else if (birdsUsed >= maxBirds && pigs.length > 0 && !levelComplete) {
levelComplete = true;
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
}
}
// Game event handlers
game.down = function (x, y, obj) {
if (currentBird && !currentBird.isLaunched && !levelComplete) {
isDragging = true;
dragStartX = x;
dragStartY = y;
}
};
game.move = function (x, y, obj) {
if (isDragging && currentBird && !currentBird.isLaunched) {
var deltaX = dragStartX - x;
var deltaY = dragStartY - y;
// Limit drag distance
var maxDrag = 150;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > maxDrag) {
deltaX = deltaX / distance * maxDrag;
deltaY = deltaY / distance * maxDrag;
}
currentBird.x = slingshotX - deltaX;
currentBird.y = slingshotY - 100 - deltaY;
// Add slingshot stretch effect
var stretchAmount = 1 + distance / 300;
tween(slingshot, {
scaleX: stretchAmount,
scaleY: 1 + distance / 500
}, {
duration: 100,
easing: tween.easeOut
});
// Show trajectory
var velocityX = deltaX * 0.4; // Increased launch power
var velocityY = deltaY * 0.4; // Increased launch power
showTrajectory(currentBird.x, currentBird.y, velocityX, velocityY);
}
};
game.up = function (x, y, obj) {
if (isDragging && currentBird && !currentBird.isLaunched) {
isDragging = false;
clearTrajectory();
var deltaX = dragStartX - x;
var deltaY = dragStartY - y;
// Limit drag distance
var maxDrag = 150;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > maxDrag) {
deltaX = deltaX / distance * maxDrag;
deltaY = deltaY / distance * maxDrag;
}
if (distance > 10) {
var velocityX = deltaX * 0.4; // Increased launch power
var velocityY = deltaY * 0.4; // Increased launch power
currentBird.launch(velocityX, velocityY);
birdsUsed++;
birdsLeftText.setText('Birds: ' + (maxBirds - birdsUsed));
// Reset slingshot with animation
tween(slingshot, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
// Create next bird after delay
LK.setTimeout(function () {
if (birdsUsed < maxBirds && pigs.length > 0) {
createBird();
}
}, 2000);
currentBird = null;
} else {
// Reset bird position with animation
tween(currentBird, {
x: slingshotX,
y: slingshotY - 100
}, {
duration: 300,
easing: tween.easeOut
});
// Reset slingshot
tween(slingshot, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
}
};
game.update = function () {
checkCollisions();
checkWinCondition();
};
// Initialize level
createLevel();
createBird();