User prompt
Edit the number of boxes according to the level and make them lower
User prompt
There should be no space between the boxes. There is a 50% chance of 1 space. There is a 35% chance of 2 spaces. There is a 25% chance of 3 spaces. There is a 10% chance of 4 spaces. There is a 5% chance of 5 spaces.
User prompt
Let's change the spawning percentages: 50% chance 2 times, 25% chance 4 times, 15% chance 8 times, 5% chance 16 times, according to the level
User prompt
There is a 20% chance that you will get a box that is twice the level number, and a 3% chance that you will get a box that is 4 times the level number.
User prompt
Make the number of balls thrown equal to the level number
Code edit (2 edits merged)
Please save this source code
User prompt
The problem occurs when you reach level 4.
User prompt
again the bug has entered, find the problem and solve it
User prompt
Level 4 is also bugged, it doesn't start again when the balls run out, fix this
User prompt
No, it's not like that, start from one again, go up to 100 and the boxes are proportional to the level, even double the level number with a 15% chance.
User prompt
Keep the level and the number of balls equal and make the level number 100
User prompt
the game is bugged, start the levels properly and edit them
User prompt
Coins and +1 balls should stay fixed between the boxes and not fall.
User prompt
Let's also throw a ball equal to the level.
User prompt
add things like coins and extra balls +1 that are placed behind the boxes
User prompt
Make the boxes a little bigger with the text and zoom in
Code edit (1 edits merged)
Please save this source code
User prompt
Ball Blast Brick Breaker
Initial prompt
Make me a game very similar to BBTAN and research it with everything and make it completely similar to it.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.speed = 20; self.isActive = false; self.hasHitBlock = false; self.update = function () { if (!self.isActive) { return; } self.x += self.velocityX; self.y += self.velocityY; // Bounce off walls if (self.x <= 20 || self.x >= 2028) { self.velocityX = -self.velocityX; self.x = Math.max(20, Math.min(2028, self.x)); } // Bounce off top if (self.y <= 20) { self.velocityY = -self.velocityY; self.y = 20; } // Check if ball reached bottom if (self.y >= 2700) { self.isActive = false; ballsActive--; } }; return self; }); var Block = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('block', { anchorX: 0.5, anchorY: 0.5 }); self.hitPoints = 1; self.maxHitPoints = 1; self.numberText = new Text2('1', { size: 30, fill: 0xFFFFFF }); self.numberText.anchor.set(0.5, 0.5); self.addChild(self.numberText); self.setHitPoints = function (points) { self.hitPoints = points; self.maxHitPoints = points; self.numberText.setText(points.toString()); // Color based on hit points var intensity = Math.min(points / 10, 1); var red = Math.floor(255 * intensity); var green = Math.floor(100 * (1 - intensity)); var blue = Math.floor(100 * (1 - intensity)); var color = red << 16 | green << 8 | blue; blockGraphics.tint = color; }; self.hit = function () { self.hitPoints--; self.numberText.setText(self.hitPoints.toString()); if (self.hitPoints <= 0) { LK.getSound('blockDestroy').play(); return true; // Block destroyed } else { LK.getSound('blockHit').play(); // Flash effect tween(blockGraphics, { tint: 0xffffff }, { duration: 100, onFinish: function onFinish() { var intensity = Math.min(self.hitPoints / 10, 1); var red = Math.floor(255 * intensity); var green = Math.floor(100 * (1 - intensity)); var blue = Math.floor(100 * (1 - intensity)); var color = red << 16 | green << 8 | blue; tween(blockGraphics, { tint: color }, { duration: 100 }); } }); return false; // Block still alive } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Game state variables var blocks = []; var balls = []; var ballsActive = 0; var maxBalls = 0; var gameState = 'aiming'; // 'aiming', 'shooting', 'waiting' var aimAngle = 0; var shooterX = 1024; var shooterY = 2600; var level = 1; var ballsToShoot = level; var aimLine = null; // UI Elements var ballCountText = new Text2(level.toString(), { size: 40, fill: 0xFFFFFF }); ballCountText.anchor.set(0.5, 0.5); ballCountText.x = 150; ballCountText.y = 2650; game.addChild(ballCountText); var levelText = new Text2('Level 1', { size: 50, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); // Create aim line aimLine = LK.getAsset('aimLine', { anchorX: 0.5, anchorY: 1 }); aimLine.x = shooterX; aimLine.y = shooterY; aimLine.visible = false; game.addChild(aimLine); // Initialize first level function createBlockRow(rowY, startLevel) { var blockWidth = 130; var spacing = 140; // Block width + small gap var startX = 100; var maxX = 1948; // Keep blocks within screen bounds var currentX = startX; // Calculate maximum blocks for this level (decreases as level increases) var maxBlocksForLevel = Math.max(3, 12 - Math.floor(startLevel / 2)); var blocksCreated = 0; while (currentX + blockWidth / 2 <= maxX && blocksCreated < maxBlocksForLevel) { // Create a block at current position var block = new Block(); block.x = currentX + blockWidth / 2; block.y = rowY; var hitPoints; var chance = Math.random(); if (chance < 0.05) { // 5% chance for 16x level hit points hitPoints = startLevel * 16; } else if (chance < 0.20) { // 15% chance for 8x level hit points (5% + 15% = 20%) hitPoints = startLevel * 8; } else if (chance < 0.45) { // 25% chance for 4x level hit points (20% + 25% = 45%) hitPoints = startLevel * 4; } else if (chance < 0.95) { // 50% chance for 2x level hit points (45% + 50% = 95%) hitPoints = startLevel * 2; } else { // 5% chance for normal hit points hitPoints = Math.floor(Math.random() * startLevel) + 1; } block.setHitPoints(hitPoints); blocks.push(block); game.addChild(block); blocksCreated++; // Determine gap size for next block var gapChance = Math.random(); var gapSize; if (gapChance < 0.50) { // 50% chance for 1 space gap gapSize = 1; } else if (gapChance < 0.85) { // 35% chance for 2 spaces gap (50% + 35% = 85%) gapSize = 2; } else if (gapChance < 0.95) { // 10% chance for 3 spaces gap (85% + 10% = 95%) gapSize = 3; } else if (gapChance < 0.99) { // 4% chance for 4 spaces gap (95% + 4% = 99%) gapSize = 4; } else { // 1% chance for 5 spaces gap gapSize = 5; } // Move to next position (block width + gap) currentX += spacing + (gapSize - 1) * spacing; } } // Create initial blocks createBlockRow(800, level); function checkBallBlockCollisions() { for (var i = balls.length - 1; i >= 0; i--) { var ball = balls[i]; if (!ball.isActive) { continue; } for (var j = blocks.length - 1; j >= 0; j--) { var block = blocks[j]; if (ball.intersects(block)) { // Simple bounce physics var dx = ball.x - block.x; var dy = ball.y - block.y; if (Math.abs(dx) > Math.abs(dy)) { ball.velocityX = -ball.velocityX; } else { ball.velocityY = -ball.velocityY; } // Hit the block if (block.hit()) { // Block destroyed block.destroy(); blocks.splice(j, 1); } ball.hasHitBlock = true; break; } } } } function moveBlocksDown() { for (var i = 0; i < blocks.length; i++) { blocks[i].y += 120; // Move down by block height } // Check if any block reached bottom for (var i = 0; i < blocks.length; i++) { if (blocks[i].y >= 2500) { LK.showGameOver(); return; } } } function nextLevel() { level++; ballsToShoot = level; ballCountText.setText(ballsToShoot.toString()); levelText.setText('Level ' + level); // Move existing blocks down moveBlocksDown(); // Add new row at top createBlockRow(800, level); // Check win condition if (blocks.length === 0) { // Add multiple rows for next level for (var row = 0; row < 3; row++) { createBlockRow(800 + row * 120, level); } } gameState = 'aiming'; } function shootBall() { if (ballsToShoot <= 0) { return; } var ball = new Ball(); ball.x = shooterX; ball.y = shooterY; ball.velocityX = Math.cos(aimAngle) * ball.speed; ball.velocityY = Math.sin(aimAngle) * ball.speed; ball.isActive = true; balls.push(ball); game.addChild(ball); ballsActive++; maxBalls++; ballsToShoot--; ballCountText.setText(ballsToShoot.toString()); LK.getSound('shoot').play(); } game.move = function (x, y, obj) { if (gameState !== 'aiming') { return; } var dx = x - shooterX; var dy = y - shooterY; aimAngle = Math.atan2(dy, dx); // Limit aim angle to upward direction if (aimAngle > -0.1 && aimAngle < Math.PI + 0.1) { aimAngle = Math.max(Math.min(aimAngle, -0.1), -Math.PI + 0.1); } // Update aim line aimLine.rotation = aimAngle + Math.PI / 2; aimLine.visible = true; }; game.down = function (x, y, obj) { if (gameState === 'aiming' && ballsToShoot > 0) { gameState = 'shooting'; aimLine.visible = false; // Shoot first ball immediately shootBall(); // Set up timer for remaining balls if (ballsToShoot > 0) { var shootTimer = LK.setInterval(function () { if (ballsToShoot > 0) { shootBall(); } else { LK.clearInterval(shootTimer); } }, 150); } } }; game.update = function () { // Update balls for (var i = balls.length - 1; i >= 0; i--) { var ball = balls[i]; if (!ball.isActive) { ball.destroy(); balls.splice(i, 1); } } // Check collisions checkBallBlockCollisions(); // Check if all balls are done if (gameState === 'shooting' && ballsActive === 0 && ballsToShoot === 0) { ballsToShoot = level + 1; ballCountText.setText(ballsToShoot.toString()); maxBalls = 0; // Wait a moment then start next level LK.setTimeout(function () { nextLevel(); }, 500); } // Reset ballsActive counter ballsActive = 0; for (var i = 0; i < balls.length; i++) { if (balls[i].isActive) { ballsActive++; } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Ball = Container.expand(function () {
var self = Container.call(this);
var ballGraphics = self.attachAsset('ball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 20;
self.isActive = false;
self.hasHitBlock = false;
self.update = function () {
if (!self.isActive) {
return;
}
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off walls
if (self.x <= 20 || self.x >= 2028) {
self.velocityX = -self.velocityX;
self.x = Math.max(20, Math.min(2028, self.x));
}
// Bounce off top
if (self.y <= 20) {
self.velocityY = -self.velocityY;
self.y = 20;
}
// Check if ball reached bottom
if (self.y >= 2700) {
self.isActive = false;
ballsActive--;
}
};
return self;
});
var Block = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('block', {
anchorX: 0.5,
anchorY: 0.5
});
self.hitPoints = 1;
self.maxHitPoints = 1;
self.numberText = new Text2('1', {
size: 30,
fill: 0xFFFFFF
});
self.numberText.anchor.set(0.5, 0.5);
self.addChild(self.numberText);
self.setHitPoints = function (points) {
self.hitPoints = points;
self.maxHitPoints = points;
self.numberText.setText(points.toString());
// Color based on hit points
var intensity = Math.min(points / 10, 1);
var red = Math.floor(255 * intensity);
var green = Math.floor(100 * (1 - intensity));
var blue = Math.floor(100 * (1 - intensity));
var color = red << 16 | green << 8 | blue;
blockGraphics.tint = color;
};
self.hit = function () {
self.hitPoints--;
self.numberText.setText(self.hitPoints.toString());
if (self.hitPoints <= 0) {
LK.getSound('blockDestroy').play();
return true; // Block destroyed
} else {
LK.getSound('blockHit').play();
// Flash effect
tween(blockGraphics, {
tint: 0xffffff
}, {
duration: 100,
onFinish: function onFinish() {
var intensity = Math.min(self.hitPoints / 10, 1);
var red = Math.floor(255 * intensity);
var green = Math.floor(100 * (1 - intensity));
var blue = Math.floor(100 * (1 - intensity));
var color = red << 16 | green << 8 | blue;
tween(blockGraphics, {
tint: color
}, {
duration: 100
});
}
});
return false; // Block still alive
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game state variables
var blocks = [];
var balls = [];
var ballsActive = 0;
var maxBalls = 0;
var gameState = 'aiming'; // 'aiming', 'shooting', 'waiting'
var aimAngle = 0;
var shooterX = 1024;
var shooterY = 2600;
var level = 1;
var ballsToShoot = level;
var aimLine = null;
// UI Elements
var ballCountText = new Text2(level.toString(), {
size: 40,
fill: 0xFFFFFF
});
ballCountText.anchor.set(0.5, 0.5);
ballCountText.x = 150;
ballCountText.y = 2650;
game.addChild(ballCountText);
var levelText = new Text2('Level 1', {
size: 50,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
// Create aim line
aimLine = LK.getAsset('aimLine', {
anchorX: 0.5,
anchorY: 1
});
aimLine.x = shooterX;
aimLine.y = shooterY;
aimLine.visible = false;
game.addChild(aimLine);
// Initialize first level
function createBlockRow(rowY, startLevel) {
var blockWidth = 130;
var spacing = 140; // Block width + small gap
var startX = 100;
var maxX = 1948; // Keep blocks within screen bounds
var currentX = startX;
// Calculate maximum blocks for this level (decreases as level increases)
var maxBlocksForLevel = Math.max(3, 12 - Math.floor(startLevel / 2));
var blocksCreated = 0;
while (currentX + blockWidth / 2 <= maxX && blocksCreated < maxBlocksForLevel) {
// Create a block at current position
var block = new Block();
block.x = currentX + blockWidth / 2;
block.y = rowY;
var hitPoints;
var chance = Math.random();
if (chance < 0.05) {
// 5% chance for 16x level hit points
hitPoints = startLevel * 16;
} else if (chance < 0.20) {
// 15% chance for 8x level hit points (5% + 15% = 20%)
hitPoints = startLevel * 8;
} else if (chance < 0.45) {
// 25% chance for 4x level hit points (20% + 25% = 45%)
hitPoints = startLevel * 4;
} else if (chance < 0.95) {
// 50% chance for 2x level hit points (45% + 50% = 95%)
hitPoints = startLevel * 2;
} else {
// 5% chance for normal hit points
hitPoints = Math.floor(Math.random() * startLevel) + 1;
}
block.setHitPoints(hitPoints);
blocks.push(block);
game.addChild(block);
blocksCreated++;
// Determine gap size for next block
var gapChance = Math.random();
var gapSize;
if (gapChance < 0.50) {
// 50% chance for 1 space gap
gapSize = 1;
} else if (gapChance < 0.85) {
// 35% chance for 2 spaces gap (50% + 35% = 85%)
gapSize = 2;
} else if (gapChance < 0.95) {
// 10% chance for 3 spaces gap (85% + 10% = 95%)
gapSize = 3;
} else if (gapChance < 0.99) {
// 4% chance for 4 spaces gap (95% + 4% = 99%)
gapSize = 4;
} else {
// 1% chance for 5 spaces gap
gapSize = 5;
}
// Move to next position (block width + gap)
currentX += spacing + (gapSize - 1) * spacing;
}
}
// Create initial blocks
createBlockRow(800, level);
function checkBallBlockCollisions() {
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
if (!ball.isActive) {
continue;
}
for (var j = blocks.length - 1; j >= 0; j--) {
var block = blocks[j];
if (ball.intersects(block)) {
// Simple bounce physics
var dx = ball.x - block.x;
var dy = ball.y - block.y;
if (Math.abs(dx) > Math.abs(dy)) {
ball.velocityX = -ball.velocityX;
} else {
ball.velocityY = -ball.velocityY;
}
// Hit the block
if (block.hit()) {
// Block destroyed
block.destroy();
blocks.splice(j, 1);
}
ball.hasHitBlock = true;
break;
}
}
}
}
function moveBlocksDown() {
for (var i = 0; i < blocks.length; i++) {
blocks[i].y += 120; // Move down by block height
}
// Check if any block reached bottom
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].y >= 2500) {
LK.showGameOver();
return;
}
}
}
function nextLevel() {
level++;
ballsToShoot = level;
ballCountText.setText(ballsToShoot.toString());
levelText.setText('Level ' + level);
// Move existing blocks down
moveBlocksDown();
// Add new row at top
createBlockRow(800, level);
// Check win condition
if (blocks.length === 0) {
// Add multiple rows for next level
for (var row = 0; row < 3; row++) {
createBlockRow(800 + row * 120, level);
}
}
gameState = 'aiming';
}
function shootBall() {
if (ballsToShoot <= 0) {
return;
}
var ball = new Ball();
ball.x = shooterX;
ball.y = shooterY;
ball.velocityX = Math.cos(aimAngle) * ball.speed;
ball.velocityY = Math.sin(aimAngle) * ball.speed;
ball.isActive = true;
balls.push(ball);
game.addChild(ball);
ballsActive++;
maxBalls++;
ballsToShoot--;
ballCountText.setText(ballsToShoot.toString());
LK.getSound('shoot').play();
}
game.move = function (x, y, obj) {
if (gameState !== 'aiming') {
return;
}
var dx = x - shooterX;
var dy = y - shooterY;
aimAngle = Math.atan2(dy, dx);
// Limit aim angle to upward direction
if (aimAngle > -0.1 && aimAngle < Math.PI + 0.1) {
aimAngle = Math.max(Math.min(aimAngle, -0.1), -Math.PI + 0.1);
}
// Update aim line
aimLine.rotation = aimAngle + Math.PI / 2;
aimLine.visible = true;
};
game.down = function (x, y, obj) {
if (gameState === 'aiming' && ballsToShoot > 0) {
gameState = 'shooting';
aimLine.visible = false;
// Shoot first ball immediately
shootBall();
// Set up timer for remaining balls
if (ballsToShoot > 0) {
var shootTimer = LK.setInterval(function () {
if (ballsToShoot > 0) {
shootBall();
} else {
LK.clearInterval(shootTimer);
}
}, 150);
}
}
};
game.update = function () {
// Update balls
for (var i = balls.length - 1; i >= 0; i--) {
var ball = balls[i];
if (!ball.isActive) {
ball.destroy();
balls.splice(i, 1);
}
}
// Check collisions
checkBallBlockCollisions();
// Check if all balls are done
if (gameState === 'shooting' && ballsActive === 0 && ballsToShoot === 0) {
ballsToShoot = level + 1;
ballCountText.setText(ballsToShoot.toString());
maxBalls = 0;
// Wait a moment then start next level
LK.setTimeout(function () {
nextLevel();
}, 500);
}
// Reset ballsActive counter
ballsActive = 0;
for (var i = 0; i < balls.length; i++) {
if (balls[i].isActive) {
ballsActive++;
}
}
};