User prompt
Generate the first version of the source code of my game: Catch the Ball. āŖš” Consider importing and using the following plugins: @upit/tween.v1
User prompt
Catch the Ball
Initial prompt
š® 1. Catch the Ball Concept: Balls fall from the top of the screen, and the player moves a basket left/right to catch them. Goal: Catch as many as possible before time runs out. Tools: Python (Pygame) or Scratch Bonus idea: Add different colors of balls with different points.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Ball = Container.expand(function (ballType, pointValue) {
var self = Container.call(this);
// Store ball properties
self.ballType = ballType || 'redBall';
self.pointValue = pointValue || 1;
self.speed = Math.random() * 3 + 2; // Random speed between 2-5
// Attach the ball graphics based on type
var ballGraphics = self.attachAsset(self.ballType, {
anchorX: 0.5,
anchorY: 0.5
});
// Track last Y position for collision detection
self.lastY = 0;
self.update = function () {
self.y += self.speed;
// Increase speed slightly over time for difficulty
self.speed += 0.01;
};
return self;
});
var Basket = Container.expand(function () {
var self = Container.call(this);
// Attach basket graphics
var basketGraphics = self.attachAsset('basket', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
// Game variables
var game = new LK.Game({
backgroundColor: 0x001122 // Dark blue background
});
/****
* Game Code
****/
// Game variables
// Initialize basket asset
// Initialize different colored balls with different point values
// Initialize sound effects
var balls = [];
var basket;
var dragNode = null;
var gameTime = 60000; // 60 seconds in milliseconds
var gameTimer;
var ballSpawnTimer;
var ballSpawnRate = 1000; // Start spawning every 1000ms
var minSpawnRate = 300; // Minimum spawn rate
// Ball types with their point values and spawn weights (higher weight = more common)
var ballTypes = [{
asset: 'redBall',
points: 1,
weight: 40
},
// Common - 1 point
{
asset: 'blueBall',
points: 2,
weight: 30
},
// Common - 2 points
{
asset: 'greenBall',
points: 3,
weight: 20
},
// Less common - 3 points
{
asset: 'yellowBall',
points: 5,
weight: 8
},
// Rare - 5 points
{
asset: 'purpleBall',
points: 10,
weight: 2
} // Very rare - 10 points
];
// Create and position basket
basket = game.addChild(new Basket());
basket.x = 2048 / 2; // Center horizontally
basket.y = 2732 - 150; // Near bottom of screen
// Create score display
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
// Create timer display
var timerTxt = new Text2('Time: 60', {
size: 60,
fill: 0xFFFF00
});
timerTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(timerTxt);
timerTxt.y = 150;
// Function to get random ball type based on weights
function getRandomBallType() {
var totalWeight = 0;
for (var i = 0; i < ballTypes.length; i++) {
totalWeight += ballTypes[i].weight;
}
var random = Math.random() * totalWeight;
var currentWeight = 0;
for (var i = 0; i < ballTypes.length; i++) {
currentWeight += ballTypes[i].weight;
if (random <= currentWeight) {
return ballTypes[i];
}
}
return ballTypes[0]; // Fallback
}
// Function to spawn a new ball
function spawnBall() {
var ballType = getRandomBallType();
var ball = new Ball(ballType.asset, ballType.points);
// Random X position across the screen width
ball.x = Math.random() * (2048 - 100) + 50;
ball.y = -50; // Start above screen
ball.lastY = ball.y;
ball.lastIntersecting = false;
balls.push(ball);
game.addChild(ball);
}
// Start game timer
gameTimer = LK.setTimeout(function () {
// Game over - time's up!
LK.showGameOver();
}, gameTime);
// Start ball spawning
function scheduleBallSpawn() {
ballSpawnTimer = LK.setTimeout(function () {
spawnBall();
// Gradually increase spawn rate (decrease interval)
if (ballSpawnRate > minSpawnRate) {
ballSpawnRate -= 10;
}
scheduleBallSpawn(); // Schedule next spawn
}, ballSpawnRate);
}
scheduleBallSpawn(); // Start spawning balls
// Touch/mouse handling
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.x = x;
// Keep basket within screen bounds
if (dragNode.x < 100) dragNode.x = 100;
if (dragNode.x > 2048 - 100) dragNode.x = 2048 - 100;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Allow dragging basket from anywhere on screen
dragNode = basket;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
// Update timer display
var remainingTime = Math.max(0, Math.ceil((gameTime - LK.ticks * (1000 / 60)) / 1000));
timerTxt.setText('Time: ' + remainingTime);
// Process balls
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
// Check if ball fell off screen (missed)
if (ball.lastY < 2732 + 100 && ball.y >= 2732 + 100) {
// Ball missed - remove it
ball.destroy();
balls.splice(i, 1);
LK.getSound('miss').play();
continue;
}
// Check collision with basket
var currentIntersecting = ball.intersects(basket);
if (!ball.lastIntersecting && currentIntersecting) {
// Ball caught!
LK.setScore(LK.getScore() + ball.pointValue);
scoreTxt.setText('Score: ' + LK.getScore());
// Visual feedback - flash the ball before removing
tween(ball, {
alpha: 0,
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
onFinish: function onFinish() {
ball.destroy();
}
});
balls.splice(i, 1);
LK.getSound('catch').play();
continue;
}
// Update tracking variables
ball.lastY = ball.y;
ball.lastIntersecting = currentIntersecting;
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,217 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Ball = Container.expand(function (ballType, pointValue) {
+ var self = Container.call(this);
+ // Store ball properties
+ self.ballType = ballType || 'redBall';
+ self.pointValue = pointValue || 1;
+ self.speed = Math.random() * 3 + 2; // Random speed between 2-5
+ // Attach the ball graphics based on type
+ var ballGraphics = self.attachAsset(self.ballType, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Track last Y position for collision detection
+ self.lastY = 0;
+ self.update = function () {
+ self.y += self.speed;
+ // Increase speed slightly over time for difficulty
+ self.speed += 0.01;
+ };
+ return self;
+});
+var Basket = Container.expand(function () {
+ var self = Container.call(this);
+ // Attach basket graphics
+ var basketGraphics = self.attachAsset('basket', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
+// Game variables
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x001122 // Dark blue background
+});
+
+/****
+* Game Code
+****/
+// Game variables
+// Initialize basket asset
+// Initialize different colored balls with different point values
+// Initialize sound effects
+var balls = [];
+var basket;
+var dragNode = null;
+var gameTime = 60000; // 60 seconds in milliseconds
+var gameTimer;
+var ballSpawnTimer;
+var ballSpawnRate = 1000; // Start spawning every 1000ms
+var minSpawnRate = 300; // Minimum spawn rate
+// Ball types with their point values and spawn weights (higher weight = more common)
+var ballTypes = [{
+ asset: 'redBall',
+ points: 1,
+ weight: 40
+},
+// Common - 1 point
+{
+ asset: 'blueBall',
+ points: 2,
+ weight: 30
+},
+// Common - 2 points
+{
+ asset: 'greenBall',
+ points: 3,
+ weight: 20
+},
+// Less common - 3 points
+{
+ asset: 'yellowBall',
+ points: 5,
+ weight: 8
+},
+// Rare - 5 points
+{
+ asset: 'purpleBall',
+ points: 10,
+ weight: 2
+} // Very rare - 10 points
+];
+// Create and position basket
+basket = game.addChild(new Basket());
+basket.x = 2048 / 2; // Center horizontally
+basket.y = 2732 - 150; // Near bottom of screen
+// Create score display
+var scoreTxt = new Text2('Score: 0', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+scoreTxt.y = 50;
+// Create timer display
+var timerTxt = new Text2('Time: 60', {
+ size: 60,
+ fill: 0xFFFF00
+});
+timerTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(timerTxt);
+timerTxt.y = 150;
+// Function to get random ball type based on weights
+function getRandomBallType() {
+ var totalWeight = 0;
+ for (var i = 0; i < ballTypes.length; i++) {
+ totalWeight += ballTypes[i].weight;
+ }
+ var random = Math.random() * totalWeight;
+ var currentWeight = 0;
+ for (var i = 0; i < ballTypes.length; i++) {
+ currentWeight += ballTypes[i].weight;
+ if (random <= currentWeight) {
+ return ballTypes[i];
+ }
+ }
+ return ballTypes[0]; // Fallback
+}
+// Function to spawn a new ball
+function spawnBall() {
+ var ballType = getRandomBallType();
+ var ball = new Ball(ballType.asset, ballType.points);
+ // Random X position across the screen width
+ ball.x = Math.random() * (2048 - 100) + 50;
+ ball.y = -50; // Start above screen
+ ball.lastY = ball.y;
+ ball.lastIntersecting = false;
+ balls.push(ball);
+ game.addChild(ball);
+}
+// Start game timer
+gameTimer = LK.setTimeout(function () {
+ // Game over - time's up!
+ LK.showGameOver();
+}, gameTime);
+// Start ball spawning
+function scheduleBallSpawn() {
+ ballSpawnTimer = LK.setTimeout(function () {
+ spawnBall();
+ // Gradually increase spawn rate (decrease interval)
+ if (ballSpawnRate > minSpawnRate) {
+ ballSpawnRate -= 10;
+ }
+ scheduleBallSpawn(); // Schedule next spawn
+ }, ballSpawnRate);
+}
+scheduleBallSpawn(); // Start spawning balls
+// Touch/mouse handling
+function handleMove(x, y, obj) {
+ if (dragNode) {
+ dragNode.x = x;
+ // Keep basket within screen bounds
+ if (dragNode.x < 100) dragNode.x = 100;
+ if (dragNode.x > 2048 - 100) dragNode.x = 2048 - 100;
+ }
+}
+game.move = handleMove;
+game.down = function (x, y, obj) {
+ // Allow dragging basket from anywhere on screen
+ dragNode = basket;
+ handleMove(x, y, obj);
+};
+game.up = function (x, y, obj) {
+ dragNode = null;
+};
+// Main game update loop
+game.update = function () {
+ // Update timer display
+ var remainingTime = Math.max(0, Math.ceil((gameTime - LK.ticks * (1000 / 60)) / 1000));
+ timerTxt.setText('Time: ' + remainingTime);
+ // Process balls
+ for (var i = balls.length - 1; i >= 0; i--) {
+ var ball = balls[i];
+ // Check if ball fell off screen (missed)
+ if (ball.lastY < 2732 + 100 && ball.y >= 2732 + 100) {
+ // Ball missed - remove it
+ ball.destroy();
+ balls.splice(i, 1);
+ LK.getSound('miss').play();
+ continue;
+ }
+ // Check collision with basket
+ var currentIntersecting = ball.intersects(basket);
+ if (!ball.lastIntersecting && currentIntersecting) {
+ // Ball caught!
+ LK.setScore(LK.getScore() + ball.pointValue);
+ scoreTxt.setText('Score: ' + LK.getScore());
+ // Visual feedback - flash the ball before removing
+ tween(ball, {
+ alpha: 0,
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ ball.destroy();
+ }
+ });
+ balls.splice(i, 1);
+ LK.getSound('catch').play();
+ continue;
+ }
+ // Update tracking variables
+ ball.lastY = ball.y;
+ ball.lastIntersecting = currentIntersecting;
+ }
+};
\ No newline at end of file