User prompt
code the shape of fruits
Code edit (1 edits merged)
Please save this source code
User prompt
Color Stack Tower
User prompt
Please continue polishing my design document.
Initial prompt
Game: Pop the Balloons Objective: Tap to pop balloons and earn points before time runs out. Gameplay: Balloons float upward. Player taps to pop them. Each balloon has different points or effects. Balloon Types: Red: +1 point Blue: +5 points Green: +10 points Black: -5 points (avoid) Golden: Slows time for 5 seconds Features: 60-second timer Score display Increasing difficulty Sound effects and fun visuals Optional Add-ons: Levels with faster balloons Power-ups (freeze time, double score) Leaderboard and background themes
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Block = Container.expand(function (color, width) { var self = Container.call(this); // Default values if not provided color = color || 0x3498db; width = width || 512; // Create block graphics var blockGraphics = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5, width: width, tint: color }); // State tracking self.placed = false; self.originalWidth = width; self.fallDirection = 0; // 0: none, -1: left, 1: right self.movementSpeed = 8; self.movementDirection = 1; // 1: right, -1: left // Resize the block (used when block partially falls off) self.resize = function (newWidth, offsetX) { if (newWidth <= 0) { return; } blockGraphics.width = newWidth; if (offsetX !== undefined) { self.x += offsetX; } }; // Update method called every frame self.update = function () { if (!self.placed) { // Move block back and forth self.x += self.movementSpeed * self.movementDirection; // Check if we need to change direction if (self.x > 2048 - self.originalWidth / 2) { self.movementDirection = -1; } else if (self.x < self.originalWidth / 2) { self.movementDirection = 1; } } else if (self.fallDirection !== 0) { // If block is set to fall, make it fall and rotate self.y += 15; self.rotation += 0.1 * self.fallDirection; // Remove the block when it's off-screen if (self.y > 2732 + 200) { self.destroy(); } } }; return self; }); var Fruit = Container.expand(function (type) { var self = Container.call(this); // Define fruit types and their properties var fruitTypes = { apple: { width: 80, height: 80, color: 0xe74c3c, shape: 'ellipse' }, banana: { width: 120, height: 60, color: 0xf1c40f, shape: 'ellipse' }, orange: { width: 75, height: 75, color: 0xf39c12, shape: 'ellipse' }, grape: { width: 60, height: 60, color: 0x9b59b6, shape: 'ellipse' }, watermelon: { width: 120, height: 90, color: 0x2ecc71, shape: 'ellipse' } }; // Set default if type not provided or invalid type = fruitTypes[type] ? type : 'apple'; // Initialize fruit properties var props = fruitTypes[type]; // Create shape for the fruit // Attach fruit asset var fruitGraphics = self.attachAsset('fruit_' + type, { anchorX: 0.5, anchorY: 0.5 }); // Add movement properties self.speedY = 2 + Math.random() * 3; self.speedX = (Math.random() * 2 - 1) * 2; self.rotationSpeed = Math.random() * 0.04 - 0.02; // Track last position for collision detection self.lastY = self.y; self.lastX = self.x; self.value = 0; switch (type) { case 'apple': self.value = 1; break; case 'banana': self.value = 2; break; case 'orange': self.value = 5; break; case 'grape': self.value = 3; break; case 'watermelon': self.value = 10; break; } // Update method called every frame self.update = function () { // Store last position self.lastY = self.y; self.lastX = self.x; // Move fruit self.y -= self.speedY; self.x += self.speedX; // Rotate fruit self.rotation += self.rotationSpeed; // Bounce off walls if (self.x < self.width / 2 || self.x > 2048 - self.width / 2) { self.speedX *= -1; } // Remove if off screen at top if (self.y < -100) { self.destroy(); } }; return self; }); var ScoreDisplay = Container.expand(function () { var self = Container.call(this); // Background for score var background = self.attachAsset('scoreBackground', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); // Score text self.scoreText = new Text2('0', { size: 60, fill: 0xFFFFFF }); self.scoreText.anchor.set(0.5, 0.5); self.addChild(self.scoreText); // Height text self.heightText = new Text2('Height: 0m', { size: 30, fill: 0xFFFFFF }); self.heightText.anchor.set(0.5, 0.5); self.heightText.y = 50; self.addChild(self.heightText); // Update score display self.updateScore = function (score, height) { self.scoreText.setText(score.toString()); self.heightText.setText('Height: ' + height.toFixed(1) + 'm'); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB // Sky blue background }); /**** * Game Code ****/ // Game state variables var score = 0; var towerHeight = 0; var gameActive = true; var level = 1; var blockSpeed = 8; var perfectMatches = 0; var blockColors = [0x3498db, // Blue 0xe74c3c, // Red 0x2ecc71, // Green 0xf39c12, // Orange 0x9b59b6, // Purple 0x1abc9c // Turquoise ]; // Fruit variables var fruits = []; var fruitTypes = ['apple', 'banana', 'orange', 'grape', 'watermelon']; var lastFruitTime = 0; var fruitGenerationRate = 120; // frames between fruit generation // Game objects var blocks = []; var currentBlock = null; var baseFloor = null; var scoreDisplay = null; var lastBlockPosition = { x: 2048 / 2, width: 512 }; var dropY = 200; // Starting Y position for dropping blocks // Initialize the game function initGame() { // Create base floor baseFloor = LK.getAsset('baseFloor', { anchorX: 0.5, anchorY: 0.5 }); baseFloor.x = 2048 / 2; baseFloor.y = 2732 - 100; game.addChild(baseFloor); // Set last block position to match the base floor lastBlockPosition = { x: baseFloor.x, width: baseFloor.width, y: baseFloor.y - baseFloor.height / 2 }; // Initialize score display scoreDisplay = new ScoreDisplay(); scoreDisplay.x = 2048 / 2; scoreDisplay.y = 100; game.addChild(scoreDisplay); // Create first block createNewBlock(); // Play background music LK.playMusic('backgroundMusic'); } // Create a new block to drop function createNewBlock() { if (!gameActive) { return; } // Select a random color var color = blockColors[Math.floor(Math.random() * blockColors.length)]; // Create new block with the current platform width currentBlock = new Block(color, lastBlockPosition.width); currentBlock.y = dropY; currentBlock.movementSpeed = blockSpeed; // Add block to the game and blocks array game.addChild(currentBlock); blocks.push(currentBlock); } // Handle game clicks/taps function handleTap() { if (!currentBlock || !gameActive) { return; } // Calculate overlap with previous block var overlapLeft = Math.max(lastBlockPosition.x - lastBlockPosition.width / 2, currentBlock.x - currentBlock.originalWidth / 2); var overlapRight = Math.min(lastBlockPosition.x + lastBlockPosition.width / 2, currentBlock.x + currentBlock.originalWidth / 2); var overlapWidth = overlapRight - overlapLeft; // If blocks don't overlap at all, game over if (overlapWidth <= 0) { gameOver(); return; } // Play place block sound LK.getSound('placeBlock').play(); // Mark the block as placed currentBlock.placed = true; // Calculate the new position and width for the current block var newCenterX = overlapLeft + overlapWidth / 2; var newWidth = overlapWidth; // Handle partial block if (newWidth < currentBlock.originalWidth) { // Determine which side falls off var fallBlockWidth = currentBlock.originalWidth - newWidth; var fallBlock = new Block(currentBlock.tint, fallBlockWidth); if (currentBlock.x < newCenterX) { // Left part falls off fallBlock.x = currentBlock.x - newWidth / 2; fallBlock.fallDirection = -1; currentBlock.resize(newWidth, newCenterX - currentBlock.x); } else { // Right part falls off fallBlock.x = currentBlock.x + newWidth / 2; fallBlock.fallDirection = 1; currentBlock.resize(newWidth, newCenterX - currentBlock.x); } fallBlock.y = currentBlock.y; fallBlock.placed = true; game.addChild(fallBlock); blocks.push(fallBlock); // Play falling sound LK.getSound('fallBlock').play(); } else { // Perfect match! perfectMatches++; LK.getSound('perfectMatch').play(); // Visual effect for perfect match LK.effects.flashObject(currentBlock, 0xFFFFFF, 300); } // Update the position of the current block currentBlock.x = newCenterX; // Calculate score based on match accuracy var accuracy = newWidth / currentBlock.originalWidth; var blockScore = Math.round(accuracy * 100); // Perfect bonus if (accuracy >= 0.95) { blockScore += 50; } score += blockScore; // Update tower height (each block adds height) towerHeight += currentBlock.height / 150; // Convert to "meters" // Update last block position for next block lastBlockPosition = { x: currentBlock.x, width: newWidth, y: currentBlock.y - currentBlock.height / 2 }; // Update score display scoreDisplay.updateScore(score, towerHeight); // Move the tower down if it's getting too high if (currentBlock.y < 2732 / 2) { var shiftAmount = 100; for (var i = 0; i < blocks.length; i++) { if (blocks[i].placed && !blocks[i].fallDirection) { blocks[i].y += shiftAmount; } } lastBlockPosition.y += shiftAmount; } // Increase difficulty based on tower height increaseGameDifficulty(); // Create a new block createNewBlock(); } // Increase game difficulty as tower gets higher function increaseGameDifficulty() { // Increase movement speed based on tower height level = Math.floor(towerHeight / 10) + 1; blockSpeed = 8 + level; // Every 5 levels, reduce block width by 10% (min 30% of original) var widthReduction = Math.min(0.7, 1 - Math.floor(level / 5) * 0.1); lastBlockPosition.width = Math.max(150, baseFloor.width * widthReduction); } // Game over function function gameOver() { gameActive = false; // Play falling sound LK.getSound('fallBlock').play(); // Make current block fall if (currentBlock) { currentBlock.fallDirection = currentBlock.x > 2048 / 2 ? 1 : -1; } // Flash screen LK.effects.flashScreen(0xff0000, 500); // Show game over after a short delay LK.setTimeout(function () { LK.showGameOver(); }, 1000); } // Game tick update game.update = function () { // Update all blocks for (var i = blocks.length - 1; i >= 0; i--) { if (blocks[i]) { blocks[i].update(); } } // Generate fruits periodically when game is active if (gameActive && LK.ticks - lastFruitTime > fruitGenerationRate) { lastFruitTime = LK.ticks; // Create a random fruit var fruitType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)]; var fruit = new Fruit(fruitType); // Position at bottom of screen with random x fruit.x = Math.random() * 2048; fruit.y = 2732 + 50; // Add to game game.addChild(fruit); fruits.push(fruit); // Adjust generation rate based on level (faster fruit generation at higher levels) fruitGenerationRate = Math.max(60, 120 - level * 5); } // Update fruits and check for collisions for (var i = fruits.length - 1; i >= 0; i--) { if (fruits[i]) { fruits[i].update(); // Check if fruit has been tapped if (fruits[i].tapped) { // Add points based on fruit value score += fruits[i].value; scoreDisplay.updateScore(score, towerHeight); // Remove the fruit fruits[i].destroy(); fruits.splice(i, 1); } // Remove if off screen if (fruits[i] && fruits[i].y < -100) { fruits[i].destroy(); fruits.splice(i, 1); } } } }; // Event handlers game.down = function (x, y, obj) { // First check if we tapped on a fruit var fruitTapped = false; for (var i = 0; i < fruits.length; i++) { // Convert tap position to fruit's parent coordinates var localPos = fruits[i].parent.toLocal({ x: x, y: y }); // Check if tap is within fruit bounds if (Math.abs(localPos.x - fruits[i].x) < fruits[i].width / 2 && Math.abs(localPos.y - fruits[i].y) < fruits[i].height / 2) { // Mark fruit as tapped fruits[i].tapped = true; // Visual effect for tapped fruit LK.effects.flashObject(fruits[i], 0xFFFFFF, 100); fruitTapped = true; break; } } // If no fruit was tapped, handle normal block tap if (!fruitTapped) { handleTap(); } }; // Initialize the game initGame();
===================================================================
--- original.js
+++ change.js
@@ -57,8 +57,99 @@
}
};
return self;
});
+var Fruit = Container.expand(function (type) {
+ var self = Container.call(this);
+ // Define fruit types and their properties
+ var fruitTypes = {
+ apple: {
+ width: 80,
+ height: 80,
+ color: 0xe74c3c,
+ shape: 'ellipse'
+ },
+ banana: {
+ width: 120,
+ height: 60,
+ color: 0xf1c40f,
+ shape: 'ellipse'
+ },
+ orange: {
+ width: 75,
+ height: 75,
+ color: 0xf39c12,
+ shape: 'ellipse'
+ },
+ grape: {
+ width: 60,
+ height: 60,
+ color: 0x9b59b6,
+ shape: 'ellipse'
+ },
+ watermelon: {
+ width: 120,
+ height: 90,
+ color: 0x2ecc71,
+ shape: 'ellipse'
+ }
+ };
+ // Set default if type not provided or invalid
+ type = fruitTypes[type] ? type : 'apple';
+ // Initialize fruit properties
+ var props = fruitTypes[type];
+ // Create shape for the fruit
+ // Attach fruit asset
+ var fruitGraphics = self.attachAsset('fruit_' + type, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Add movement properties
+ self.speedY = 2 + Math.random() * 3;
+ self.speedX = (Math.random() * 2 - 1) * 2;
+ self.rotationSpeed = Math.random() * 0.04 - 0.02;
+ // Track last position for collision detection
+ self.lastY = self.y;
+ self.lastX = self.x;
+ self.value = 0;
+ switch (type) {
+ case 'apple':
+ self.value = 1;
+ break;
+ case 'banana':
+ self.value = 2;
+ break;
+ case 'orange':
+ self.value = 5;
+ break;
+ case 'grape':
+ self.value = 3;
+ break;
+ case 'watermelon':
+ self.value = 10;
+ break;
+ }
+ // Update method called every frame
+ self.update = function () {
+ // Store last position
+ self.lastY = self.y;
+ self.lastX = self.x;
+ // Move fruit
+ self.y -= self.speedY;
+ self.x += self.speedX;
+ // Rotate fruit
+ self.rotation += self.rotationSpeed;
+ // Bounce off walls
+ if (self.x < self.width / 2 || self.x > 2048 - self.width / 2) {
+ self.speedX *= -1;
+ }
+ // Remove if off screen at top
+ if (self.y < -100) {
+ self.destroy();
+ }
+ };
+ return self;
+});
var ScoreDisplay = Container.expand(function () {
var self = Container.call(this);
// Background for score
var background = self.attachAsset('scoreBackground', {
@@ -117,8 +208,13 @@
0x9b59b6,
// Purple
0x1abc9c // Turquoise
];
+// Fruit variables
+var fruits = [];
+var fruitTypes = ['apple', 'banana', 'orange', 'grape', 'watermelon'];
+var lastFruitTime = 0;
+var fruitGenerationRate = 120; // frames between fruit generation
// Game objects
var blocks = [];
var currentBlock = null;
var baseFloor = null;
@@ -286,11 +382,67 @@
if (blocks[i]) {
blocks[i].update();
}
}
+ // Generate fruits periodically when game is active
+ if (gameActive && LK.ticks - lastFruitTime > fruitGenerationRate) {
+ lastFruitTime = LK.ticks;
+ // Create a random fruit
+ var fruitType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)];
+ var fruit = new Fruit(fruitType);
+ // Position at bottom of screen with random x
+ fruit.x = Math.random() * 2048;
+ fruit.y = 2732 + 50;
+ // Add to game
+ game.addChild(fruit);
+ fruits.push(fruit);
+ // Adjust generation rate based on level (faster fruit generation at higher levels)
+ fruitGenerationRate = Math.max(60, 120 - level * 5);
+ }
+ // Update fruits and check for collisions
+ for (var i = fruits.length - 1; i >= 0; i--) {
+ if (fruits[i]) {
+ fruits[i].update();
+ // Check if fruit has been tapped
+ if (fruits[i].tapped) {
+ // Add points based on fruit value
+ score += fruits[i].value;
+ scoreDisplay.updateScore(score, towerHeight);
+ // Remove the fruit
+ fruits[i].destroy();
+ fruits.splice(i, 1);
+ }
+ // Remove if off screen
+ if (fruits[i] && fruits[i].y < -100) {
+ fruits[i].destroy();
+ fruits.splice(i, 1);
+ }
+ }
+ }
};
// Event handlers
game.down = function (x, y, obj) {
- handleTap();
+ // First check if we tapped on a fruit
+ var fruitTapped = false;
+ for (var i = 0; i < fruits.length; i++) {
+ // Convert tap position to fruit's parent coordinates
+ var localPos = fruits[i].parent.toLocal({
+ x: x,
+ y: y
+ });
+ // Check if tap is within fruit bounds
+ if (Math.abs(localPos.x - fruits[i].x) < fruits[i].width / 2 && Math.abs(localPos.y - fruits[i].y) < fruits[i].height / 2) {
+ // Mark fruit as tapped
+ fruits[i].tapped = true;
+ // Visual effect for tapped fruit
+ LK.effects.flashObject(fruits[i], 0xFFFFFF, 100);
+ fruitTapped = true;
+ break;
+ }
+ }
+ // If no fruit was tapped, handle normal block tap
+ if (!fruitTapped) {
+ handleTap();
+ }
};
// Initialize the game
initGame();
\ No newline at end of file