/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.velocity = { x: 0, y: 0 }; self.gravity = 0.2; self.bounceFactor = 0.7; self.active = true; self.update = function () { if (!self.active) { return; } // Apply gravity self.velocity.y += self.gravity; // Update position self.x += self.velocity.x; self.y += self.velocity.y; // Check for collisions with pins for (var i = 0; i < pins.length; i++) { if (self.intersects(pins[i])) { self.handlePinCollision(pins[i]); } } // Check for wall collisions if (self.x < leftWall.x + leftWall.width / 2 + ballGraphics.width / 2) { self.x = leftWall.x + leftWall.width / 2 + ballGraphics.width / 2; self.velocity.x = Math.abs(self.velocity.x) * self.bounceFactor; LK.getSound('bounce').play(); } else if (self.x > rightWall.x - rightWall.width / 2 - ballGraphics.width / 2) { self.x = rightWall.x - rightWall.width / 2 - ballGraphics.width / 2; self.velocity.x = -Math.abs(self.velocity.x) * self.bounceFactor; LK.getSound('bounce').play(); } // Check for score zones if (self.y > gameHeight - 150) { if (self.intersects(scoreZone1)) { self.score(10); } else if (self.intersects(scoreZone2)) { self.score(30); } else if (self.intersects(scoreZone3)) { self.score(10); } } // Remove ball if it goes out of bounds if (self.y > gameHeight + 100) { self.destroy(); var index = balls.indexOf(self); if (index !== -1) { balls.splice(index, 1); } } }; self.handlePinCollision = function (pin) { // Calculate collision vector var dx = self.x - pin.x; var dy = self.y - pin.y; var distance = Math.sqrt(dx * dx + dy * dy); // Minimum distance to prevent overlap var minDistance = ballGraphics.width / 2 + pin.width / 2; if (distance < minDistance) { // Normalize direction vector var nx = dx / distance; var ny = dy / distance; // Move ball outside of pin var penetrationDepth = minDistance - distance; self.x += nx * penetrationDepth; self.y += ny * penetrationDepth; // Calculate bounce var dotProduct = self.velocity.x * nx + self.velocity.y * ny; // Apply bounce with some randomness self.velocity.x = (self.velocity.x - 2 * dotProduct * nx) * self.bounceFactor; self.velocity.y = (self.velocity.y - 2 * dotProduct * ny) * self.bounceFactor; // Add a bit of randomness for more interesting gameplay self.velocity.x += (Math.random() - 0.5) * 0.5; LK.getSound('bounce').play(); } }; self.score = function (points) { if (self.active) { LK.setScore(LK.getScore() + points); scoreTxt.setText(LK.getScore()); LK.getSound('score').play(); self.active = false; // Flash the ball LK.effects.flashObject(self, 0xFFFFFF, 500); // Check for win condition if (LK.getScore() >= winScore) { LK.showYouWin(); } } }; return self; }); var Launcher = Container.expand(function () { var self = Container.call(this); var launcherGraphics = self.attachAsset('launcher', { anchorX: 0.5, anchorY: 0.5 }); self.cooldown = 0; self.cooldownTime = 45; // Number of frames to wait between ball launches self.update = function () { if (self.cooldown > 0) { self.cooldown--; } }; self.launch = function () { if (self.cooldown > 0 || remainingBalls <= 0) { return; } var ball = new Ball(); ball.x = self.x; ball.y = self.y + 30; ball.velocity.x = (Math.random() - 0.5) * 2; // Small random horizontal velocity ball.velocity.y = 1; // Initial downward velocity game.addChild(ball); balls.push(ball); self.cooldown = self.cooldownTime; remainingBalls--; ballCountTxt.setText("Balls: " + remainingBalls); // Game over if no balls left and no active balls if (remainingBalls <= 0) { checkGameOver(); } }; self.down = function (x, y, obj) { self.launch(); }; return self; }); var Pin = Container.expand(function () { var self = Container.call(this); var pinGraphics = self.attachAsset('pin', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x4477BB }); /**** * Game Code ****/ // Game constants var gameWidth = 2048; var gameHeight = 2732; var winScore = 500; var initialBalls = 20; var remainingBalls = initialBalls; var balls = []; var pins = []; // Create timer UI var timeLimit = 120; // 120 seconds time limit var timeRemaining = timeLimit; var timerTxt = new Text2("Time: " + timeRemaining, { size: 80, fill: 0xFFFFFF }); timerTxt.anchor.set(0.5, 0); timerTxt.x = gameWidth / 2; timerTxt.y = 50; LK.gui.top.addChild(timerTxt); // Create scoring UI var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var ballCountTxt = new Text2("Balls: " + remainingBalls, { size: 80, fill: 0xFFFFFF }); ballCountTxt.anchor.set(0, 0); ballCountTxt.x = 150; ballCountTxt.y = 50; LK.gui.topRight.addChild(ballCountTxt); // Add background image var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: gameWidth / 2, y: gameHeight / 2, scaleX: gameWidth / 100, scaleY: gameHeight / 100 }); game.addChild(background); // Create game elements var launcher = new Launcher(); launcher.x = gameWidth / 2; launcher.y = 100; game.addChild(launcher); // Create walls var leftWall = game.addChild(LK.getAsset('wall', { anchorX: 0.5, anchorY: 0.5, x: 20, y: gameHeight / 2 })); var rightWall = game.addChild(LK.getAsset('wall', { anchorX: 0.5, anchorY: 0.5, x: gameWidth - 20, y: gameHeight / 2 })); // Create score zones at the bottom var scoreZone1 = game.addChild(LK.getAsset('scoreZone1', { anchorX: 0.5, anchorY: 0.5, x: gameWidth / 6 + 100, y: gameHeight - 50 })); var scoreZone2 = game.addChild(LK.getAsset('scoreZone2', { anchorX: 0.5, anchorY: 0.5, x: gameWidth / 2, y: gameHeight - 50 })); var scoreZone3 = game.addChild(LK.getAsset('scoreZone3', { anchorX: 0.5, anchorY: 0.5, x: gameWidth - (gameWidth / 6 + 100), y: gameHeight - 50 })); // Create pins in a triangle pattern function createPins() { var rowSpacing = 150; var pinSpacing = 120; var startY = 400; var rows = 10; for (var row = 0; row < rows; row++) { var pinsInRow = row + 5; var rowWidth = pinSpacing * (pinsInRow - 1); var startX = (gameWidth - rowWidth) / 2; for (var i = 0; i < pinsInRow; i++) { var pin = new Pin(); pin.x = startX + i * pinSpacing; pin.y = startY + row * rowSpacing; // Add some randomness to pin positions pin.x += (Math.random() - 0.5) * 20; pin.y += (Math.random() - 0.5) * 20; game.addChild(pin); pins.push(pin); } } } // Create game instructions var instructionsTxt = new Text2("Tap anywhere to launch balls!", { size: 70, fill: 0xFFFFFF }); instructionsTxt.anchor.set(0.5, 0); instructionsTxt.y = 180; LK.gui.top.addChild(instructionsTxt); function checkGameOver() { var timeout = LK.setTimeout(function () { if (remainingBalls <= 0 && balls.length === 0) { LK.showGameOver(); } else { checkGameOver(); } }, 1000); } // Game touch controls game.down = function (x, y, obj) { launcher.launch(); }; // Initialize pins createPins(); // Play background music LK.playMusic('bgmusic', { fade: { start: 0, end: 0.6, duration: 1000 } }); // Main game update loop game.update = function () { launcher.update(); // Update all balls for (var i = 0; i < balls.length; i++) { if (balls[i]) { balls[i].update(); // Decrease the timer if (timeRemaining > 0) { timeRemaining -= 1 / 60; // Decrease by 1 second every 60 frames timerTxt.setText("Time: " + Math.ceil(timeRemaining)); } else { // Time is up, show game over LK.showGameOver(); } } ; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocity = {
x: 0,
y: 0
};
self.gravity = 0.2;
self.bounceFactor = 0.7;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
// Apply gravity
self.velocity.y += self.gravity;
// Update position
self.x += self.velocity.x;
self.y += self.velocity.y;
// Check for collisions with pins
for (var i = 0; i < pins.length; i++) {
if (self.intersects(pins[i])) {
self.handlePinCollision(pins[i]);
}
}
// Check for wall collisions
if (self.x < leftWall.x + leftWall.width / 2 + ballGraphics.width / 2) {
self.x = leftWall.x + leftWall.width / 2 + ballGraphics.width / 2;
self.velocity.x = Math.abs(self.velocity.x) * self.bounceFactor;
LK.getSound('bounce').play();
} else if (self.x > rightWall.x - rightWall.width / 2 - ballGraphics.width / 2) {
self.x = rightWall.x - rightWall.width / 2 - ballGraphics.width / 2;
self.velocity.x = -Math.abs(self.velocity.x) * self.bounceFactor;
LK.getSound('bounce').play();
}
// Check for score zones
if (self.y > gameHeight - 150) {
if (self.intersects(scoreZone1)) {
self.score(10);
} else if (self.intersects(scoreZone2)) {
self.score(30);
} else if (self.intersects(scoreZone3)) {
self.score(10);
}
}
// Remove ball if it goes out of bounds
if (self.y > gameHeight + 100) {
self.destroy();
var index = balls.indexOf(self);
if (index !== -1) {
balls.splice(index, 1);
}
}
};
self.handlePinCollision = function (pin) {
// Calculate collision vector
var dx = self.x - pin.x;
var dy = self.y - pin.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Minimum distance to prevent overlap
var minDistance = ballGraphics.width / 2 + pin.width / 2;
if (distance < minDistance) {
// Normalize direction vector
var nx = dx / distance;
var ny = dy / distance;
// Move ball outside of pin
var penetrationDepth = minDistance - distance;
self.x += nx * penetrationDepth;
self.y += ny * penetrationDepth;
// Calculate bounce
var dotProduct = self.velocity.x * nx + self.velocity.y * ny;
// Apply bounce with some randomness
self.velocity.x = (self.velocity.x - 2 * dotProduct * nx) * self.bounceFactor;
self.velocity.y = (self.velocity.y - 2 * dotProduct * ny) * self.bounceFactor;
// Add a bit of randomness for more interesting gameplay
self.velocity.x += (Math.random() - 0.5) * 0.5;
LK.getSound('bounce').play();
}
};
self.score = function (points) {
if (self.active) {
LK.setScore(LK.getScore() + points);
scoreTxt.setText(LK.getScore());
LK.getSound('score').play();
self.active = false;
// Flash the ball
LK.effects.flashObject(self, 0xFFFFFF, 500);
// Check for win condition
if (LK.getScore() >= winScore) {
LK.showYouWin();
}
}
};
return self;
});
var Launcher = Container.expand(function () {
var self = Container.call(this);
var launcherGraphics = self.attachAsset('launcher', {
anchorX: 0.5,
anchorY: 0.5
});
self.cooldown = 0;
self.cooldownTime = 45; // Number of frames to wait between ball launches
self.update = function () {
if (self.cooldown > 0) {
self.cooldown--;
}
};
self.launch = function () {
if (self.cooldown > 0 || remainingBalls <= 0) {
return;
}
var ball = new Ball();
ball.x = self.x;
ball.y = self.y + 30;
ball.velocity.x = (Math.random() - 0.5) * 2; // Small random horizontal velocity
ball.velocity.y = 1; // Initial downward velocity
game.addChild(ball);
balls.push(ball);
self.cooldown = self.cooldownTime;
remainingBalls--;
ballCountTxt.setText("Balls: " + remainingBalls);
// Game over if no balls left and no active balls
if (remainingBalls <= 0) {
checkGameOver();
}
};
self.down = function (x, y, obj) {
self.launch();
};
return self;
});
var Pin = Container.expand(function () {
var self = Container.call(this);
var pinGraphics = self.attachAsset('pin', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x4477BB
});
/****
* Game Code
****/
// Game constants
var gameWidth = 2048;
var gameHeight = 2732;
var winScore = 500;
var initialBalls = 20;
var remainingBalls = initialBalls;
var balls = [];
var pins = [];
// Create timer UI
var timeLimit = 120; // 120 seconds time limit
var timeRemaining = timeLimit;
var timerTxt = new Text2("Time: " + timeRemaining, {
size: 80,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0.5, 0);
timerTxt.x = gameWidth / 2;
timerTxt.y = 50;
LK.gui.top.addChild(timerTxt);
// Create scoring UI
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var ballCountTxt = new Text2("Balls: " + remainingBalls, {
size: 80,
fill: 0xFFFFFF
});
ballCountTxt.anchor.set(0, 0);
ballCountTxt.x = 150;
ballCountTxt.y = 50;
LK.gui.topRight.addChild(ballCountTxt);
// Add background image
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: gameWidth / 2,
y: gameHeight / 2,
scaleX: gameWidth / 100,
scaleY: gameHeight / 100
});
game.addChild(background);
// Create game elements
var launcher = new Launcher();
launcher.x = gameWidth / 2;
launcher.y = 100;
game.addChild(launcher);
// Create walls
var leftWall = game.addChild(LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: 20,
y: gameHeight / 2
}));
var rightWall = game.addChild(LK.getAsset('wall', {
anchorX: 0.5,
anchorY: 0.5,
x: gameWidth - 20,
y: gameHeight / 2
}));
// Create score zones at the bottom
var scoreZone1 = game.addChild(LK.getAsset('scoreZone1', {
anchorX: 0.5,
anchorY: 0.5,
x: gameWidth / 6 + 100,
y: gameHeight - 50
}));
var scoreZone2 = game.addChild(LK.getAsset('scoreZone2', {
anchorX: 0.5,
anchorY: 0.5,
x: gameWidth / 2,
y: gameHeight - 50
}));
var scoreZone3 = game.addChild(LK.getAsset('scoreZone3', {
anchorX: 0.5,
anchorY: 0.5,
x: gameWidth - (gameWidth / 6 + 100),
y: gameHeight - 50
}));
// Create pins in a triangle pattern
function createPins() {
var rowSpacing = 150;
var pinSpacing = 120;
var startY = 400;
var rows = 10;
for (var row = 0; row < rows; row++) {
var pinsInRow = row + 5;
var rowWidth = pinSpacing * (pinsInRow - 1);
var startX = (gameWidth - rowWidth) / 2;
for (var i = 0; i < pinsInRow; i++) {
var pin = new Pin();
pin.x = startX + i * pinSpacing;
pin.y = startY + row * rowSpacing;
// Add some randomness to pin positions
pin.x += (Math.random() - 0.5) * 20;
pin.y += (Math.random() - 0.5) * 20;
game.addChild(pin);
pins.push(pin);
}
}
}
// Create game instructions
var instructionsTxt = new Text2("Tap anywhere to launch balls!", {
size: 70,
fill: 0xFFFFFF
});
instructionsTxt.anchor.set(0.5, 0);
instructionsTxt.y = 180;
LK.gui.top.addChild(instructionsTxt);
function checkGameOver() {
var timeout = LK.setTimeout(function () {
if (remainingBalls <= 0 && balls.length === 0) {
LK.showGameOver();
} else {
checkGameOver();
}
}, 1000);
}
// Game touch controls
game.down = function (x, y, obj) {
launcher.launch();
};
// Initialize pins
createPins();
// Play background music
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 0.6,
duration: 1000
}
});
// Main game update loop
game.update = function () {
launcher.update();
// Update all balls
for (var i = 0; i < balls.length; i++) {
if (balls[i]) {
balls[i].update();
// Decrease the timer
if (timeRemaining > 0) {
timeRemaining -= 1 / 60; // Decrease by 1 second every 60 frames
timerTxt.setText("Time: " + Math.ceil(timeRemaining));
} else {
// Time is up, show game over
LK.showGameOver();
}
}
;
}
};
clown face. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
circus tent. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
gold blocks. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
silver blocks. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
anime circus tent field. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows