/**** * 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();
/****
* 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();
Glaud text. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Produce an image that says G. This G will be big.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
bakstenen muurpatroon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows