User prompt
göselinide ekle
User prompt
gezinen tuğlalar olsun
User prompt
kuş tuğla özelliğinde olmalı
User prompt
olmadı top kuşa değdiğinde kuş yok olmalı
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'if (bullet.x + bullet.width / 2 > bird.x - bird.width / 2 && bullet.x - bullet.width / 2 < bird.x + bird.width / 2 && bullet.y + bullet.height / 2 > bird.y - bird.height / 2 && bullet.y - bullet.height / 2 < bird.y + bird.height / 2) {' Line Number: 811
User prompt
kuşlar tuğlalar gibi kırılabilsin
User prompt
Please fix the bug: 'ReferenceError: flyingBricks is not defined' in or related to this line: 'for (var b = flyingBricks.length - 1; b >= 0; b--) {' Line Number: 789
User prompt
kuşları tuğlaya çevir
User prompt
Please fix the bug: 'ReferenceError: birds is not defined' in or related to this line: 'for (var b = birds.length - 1; b >= 0; b--) {' Line Number: 788
User prompt
orta kısımda sağa sola yukarı aşağı random kuşlar uçsun ve top bu kuşlara değdiğinde kuş kırılsın
User prompt
Please fix the bug: 'ReferenceError: birds is not defined' in or related to this line: 'checkCollisions();' Line Number: 804
User prompt
Please fix the bug: 'ReferenceError: birds is not defined' in or related to this line: 'for (var b = 0; b < birds.length; b++) {' Line Number: 806
User prompt
orta kısımda sağa sola yukarı aşağı random kuşlar uçsun ve top bu kuşlara değdiğinde tuğla gibi kırılsın
User prompt
kuşlar tuğlalar gibi parçalansın
User prompt
Please fix the bug: 'ReferenceError: birds is not defined' in or related to this line: 'for (var b = 0; b < birds.length; b++) {' Line Number: 788
User prompt
orta kısımda sağa sola yukarı aşağı random kuşlar uçsun ve top bu kuşlara değdiğinde kuş kırılsın
User prompt
the ball may hit the birds
User prompt
top kuşlara çarpabilsin
User prompt
Please fix the bug: 'ReferenceError: birds is not defined' in or related to this line: 'for (var b = birds.length - 1; b >= 0; b--) {' Line Number: 788
User prompt
orta kısımda sağa sola yukarı aşağı random kuşlar uçsun ve top bu kuşlara değdiğinde kuş yok olsun
User prompt
top kuşlarada çarpsın
User prompt
rastgele uçsunlar sağa sola yukarı ve aşağı top onlara değdiğinde yok olsunlar
User prompt
Please fix the bug: 'ReferenceError: birds is not defined' in or related to this line: 'for (var b = 0; b < birds.length; b++) {' Line Number: 783
User prompt
orta kısımlarda kuşlarda uçsun ve top bu kuşlara değdiğinde kuş parçalansın
User prompt
daha sık spawn olsun
/**** * 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.speed = 10; self.directionX = 0; self.directionY = -1; self.active = false; self.radius = ballGraphics.width / 2; self.reset = function (paddle) { self.active = false; self.x = paddle.x; self.y = paddle.y - paddle.height / 2 - self.radius; self.directionX = 0; self.directionY = -1; }; self.launch = function () { if (!self.active) { self.active = true; // Random angle between -45 and 45 degrees var angle = (Math.random() * 90 - 45) * Math.PI / 180; self.directionX = Math.sin(angle); self.directionY = -Math.cos(angle); } }; self.update = function () { if (self.active) { self.x += self.directionX * self.speed; self.y += self.directionY * self.speed; // Wall collision if (self.x - self.radius < 0) { self.x = self.radius; self.directionX = -self.directionX; LK.getSound('hit').play(); } else if (self.x + self.radius > 2048) { self.x = 2048 - self.radius; self.directionX = -self.directionX; LK.getSound('hit').play(); } // Ceiling collision if (self.y - self.radius < 0) { self.y = self.radius; self.directionY = -self.directionY; LK.getSound('hit').play(); } } }; self.bounceOff = function (object) { // Calculate bounce angle based on where the ball hit the object var relativeX = (self.x - object.x) / (object.width / 2); relativeX = Math.max(-1, Math.min(1, relativeX)); // Clamp between -1 and 1 // Calculate new direction - bouncing upward (for paddle) self.directionX = relativeX * 0.8; self.directionY = -Math.sqrt(1 - self.directionX * self.directionX); // Normalize var magnitude = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY); self.directionX /= magnitude; self.directionY /= magnitude; LK.getSound('hit').play(); }; return self; }); var Bird = Container.expand(function () { var self = Container.call(this); var birdGraphics = self.attachAsset('bird', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; self.update = function () { self.x += self.speed; if (self.x > 2048 + birdGraphics.width / 2) { self.x = -birdGraphics.width / 2; } }; return self; }); var Brick = Container.expand(function () { var self = Container.call(this); var brickGraphics = self.attachAsset('brick', { anchorX: 0.5, anchorY: 0.5 }); self.width = brickGraphics.width; self.height = brickGraphics.height; self.hitPoints = 1; self.powerupChance = 0.2; self.setColor = function (color) { brickGraphics.tint = color; }; self.hit = function () { self.hitPoints--; if (self.hitPoints <= 0) { LK.getSound('break').play(); return true; // Brick destroyed } else { // Make brick darker brickGraphics.tint = (brickGraphics.tint & 0xfefefe) >> 1; LK.getSound('hit').play(); return false; // Brick not destroyed yet } }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -10; self.update = function () { self.y += self.speed; }; return self; }); var Paddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); self.width = paddleGraphics.width; self.height = paddleGraphics.height; self.normalWidth = paddleGraphics.width; self.expand = function () { tween(paddleGraphics, { width: self.normalWidth * 1.5 }, { duration: 300, easing: tween.easeOut }); self.width = self.normalWidth * 1.5; LK.setTimeout(function () { tween(paddleGraphics, { width: self.normalWidth }, { duration: 300, easing: tween.easeOut }); self.width = self.normalWidth; }, 10000); // 10 seconds }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics; self.setType = function (type) { self.type = type; switch (type) { case 'expand': powerupGraphics = self.attachAsset('powerup_expand', { anchorX: 0.5, anchorY: 0.5 }); break; case 'multiball': powerupGraphics = self.attachAsset('powerup_multiball', { anchorX: 0.5, anchorY: 0.5 }); break; case 'slow': powerupGraphics = self.attachAsset('powerup_slow', { anchorX: 0.5, anchorY: 0.5 }); break; } }; self.type = 'expand'; // Default powerup type self.fallSpeed = 5; // Set different colors for different powerup types self.setType = function (type) { self.type = type; switch (type) { case 'expand': powerupGraphics = self.attachAsset('powerup_expand', { anchorX: 0.5, anchorY: 0.5 }); break; case 'multiball': powerupGraphics = self.attachAsset('powerup_multiball', { anchorX: 0.5, anchorY: 0.5 }); break; case 'slow': powerupGraphics = self.attachAsset('powerup_slow', { anchorX: 0.5, anchorY: 0.5 }); break; case 'grow': powerupGraphics = self.attachAsset('powerup_grow', { anchorX: 0.5, anchorY: 0.5 }); break; case 'laser': powerupGraphics = self.attachAsset('powerup_laser', { anchorX: 0.5, anchorY: 0.5 }); break; case 'freeze': powerupGraphics = self.attachAsset('powerup_freeze', { anchorX: 0.5, anchorY: 0.5 }); break; case 'shrink': powerupGraphics = self.attachAsset('powerup_shrink', { anchorX: 0.5, anchorY: 0.5 }); break; case 'invert': powerupGraphics = self.attachAsset('powerup_invert', { anchorX: 0.5, anchorY: 0.5 }); break; } }; self.update = function () { self.y += self.fallSpeed; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // New visual for 'grow' powerup // Add background image Paddle.prototype.setTint = function (color) { this.children[0].tint = color; // Assuming the first child is paddleGraphics }; var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 }); background.x = 2048 / 2; background.y = 2732 / 2; game.addChild(background); // Initialize game elements var level = 1; var paddle = null; var balls = []; var bricks = []; var bullets = []; // Define bullets array to track bullet instances var powerups = []; var gameState = 'ready'; // 'ready', 'playing', 'gameover' var dragNode = null; // Colors for bricks var BRICK_COLORS = [0xFF0000, // Red 0xFF7F00, // Orange 0xFFFF00, // Yellow 0x00FF00, // Green 0x0000FF, // Blue 0x4B0082, // Indigo 0x9400D3 // Violet ]; // Create UI elements var lives = 100; // Initial number of lives var livesTxt = new Text2('Lives: ' + lives, { size: 80, fill: 0xFFFFFF }); livesTxt.anchor.set(0.5, 0); livesTxt.x = 165; // Move a few pixels further to the right LK.gui.topLeft.addChild(livesTxt); var scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var levelTxt = new Text2('Level: 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); levelTxt.x = 100; levelTxt.y = 20; LK.gui.topRight.addChild(levelTxt); var instructionTxt = new Text2('Tap to start - Drag paddle to play', { size: 60, fill: 0xFFFFFF }); instructionTxt.anchor.set(0.5, 0); instructionTxt.y = 150; LK.gui.top.addChild(instructionTxt); // Initialize game elements function initGame() { // Reset score LK.setScore(0); scoreTxt.setText('0'); // Create paddle paddle = new Paddle(); paddle.x = 2048 / 2; paddle.y = 2732 - 150; game.addChild(paddle); // Assign the down event handler to the paddle after it is initialized paddle.down = function (x, y, obj) { // Check if enough time has passed since the last bullet was fired if (!paddle.lastBulletTime || Date.now() - paddle.lastBulletTime > 500) { // 500ms interval // Fire a bullet from the paddle var bullet = new Bullet(); bullet.x = paddle.x; bullet.y = paddle.y - paddle.height / 2; game.addChild(bullet); bullets.push(bullet); // Play bullet sound LK.getSound('shoot').play(); // Update the last bullet time paddle.lastBulletTime = Date.now(); } }; // Create initial ball createBall(); // Create brick layout for level 1 createLevel(1); // Set game state gameState = 'ready'; instructionTxt.visible = true; // Start background music LK.playMusic('bgmusic', { fade: { start: 0, end: 0.3, duration: 1000 } }); } function createBall() { var ball = new Ball(); ball.reset(paddle); game.addChild(ball); balls.push(ball); return ball; } function createLevel(level) { // Clear existing bricks for (var i = bricks.length - 1; i >= 0; i--) { bricks[i].destroy(); } bricks = []; levelTxt.setText('Level: ' + level); // Define grid dimensions based on level var rows = Math.min(5 + Math.floor(level / 2), 10); var cols = Math.min(10 + Math.floor(level / 3), 13); var brickWidth = 150; var brickHeight = 60; var padding = 10; var totalWidth = cols * (brickWidth + padding) - padding; var startX = (2048 - totalWidth) / 2 + brickWidth / 2; var startY = 200; // Create brick layout for (var row = 0; row < rows; row++) { for (var col = 0; col < cols; col++) { var brick = new Brick(); brick.attachAsset('brick' + row % BRICK_COLORS.length, { anchorX: 0.5, anchorY: 0.5 }); // Position brick brick.x = startX + col * (brickWidth + padding); brick.y = startY + row * (brickHeight + padding); // Color based on row brick.setColor(BRICK_COLORS[row % BRICK_COLORS.length]); // Higher levels have stronger bricks if (level > 2 && row < 2) { brick.hitPoints = 2; } game.addChild(brick); bricks.push(brick); } } } function startGame() { if (gameState === 'ready') { gameState = 'playing'; instructionTxt.visible = false; // Launch the first ball if (balls.length > 0) { balls[0].launch(); } } } function checkCollisions() { // Check for ball-bird collisions for (var i = 0; i < balls.length; i++) { var ball = balls[i]; if (ball.active) { for (var j = game.children.length - 1; j >= 0; j--) { var child = game.children[j]; if (child instanceof Bird) { if (ball.x + ball.radius > child.x - child.width / 2 && ball.x - ball.radius < child.x + child.width / 2 && ball.y + ball.radius > child.y - child.height / 2 && ball.y - ball.radius < child.y + child.height / 2) { // Ball hits the bird game.removeChild(child); ball.bounceOff(child); break; } } } } } // Ball-paddle collision for (var i = 0; i < balls.length; i++) { var ball = balls[i]; if (ball.active) { // Check for paddle collision if (ball.y + ball.radius > paddle.y - paddle.height / 2 && ball.y - ball.radius < paddle.y + paddle.height / 2 && ball.x + ball.radius > paddle.x - paddle.width / 2 && ball.x - ball.radius < paddle.x + paddle.width / 2 && ball.directionY > 0) { // Only bounce if moving downward ball.y = paddle.y - paddle.height / 2 - ball.radius; ball.bounceOff(paddle); } // Check for brick collisions for (var j = bricks.length - 1; j >= 0; j--) { var brick = bricks[j]; if (ball.x + ball.radius > brick.x - brick.width / 2 && ball.x - ball.radius < brick.x + brick.width / 2 && ball.y + ball.radius > brick.y - brick.height / 2 && ball.y - ball.radius < brick.y + brick.height / 2) { // Determine which side of the brick was hit var dx = ball.x - brick.x; var dy = ball.y - brick.y; var width = brick.width / 2 + ball.radius; var height = brick.height / 2 + ball.radius; var crossWidth = width * dy; var crossHeight = height * dx; if (Math.abs(dx) <= width && Math.abs(dy) <= height) { if (crossWidth > crossHeight) { if (crossWidth > -crossHeight) { // Bottom collision ball.directionY = Math.abs(ball.directionY); } else { // Left collision ball.directionX = -Math.abs(ball.directionX); } } else { if (crossWidth > -crossHeight) { // Right collision ball.directionX = Math.abs(ball.directionX); } else { // Top collision ball.directionY = -Math.abs(ball.directionY); } } // Hit the brick if (brick.hit()) { // Brick destroyed LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); // Check if score is a multiple of 200 if (LK.getScore() % 200 === 0) { lives++; // Increase lives by 1 livesTxt.setText('Lives: ' + lives); // Update lives display } // Chance to spawn powerup if (Math.random() < brick.powerupChance) { spawnPowerup(brick.x, brick.y); } bricks.splice(j, 1); brick.destroy(); } break; // Only hit one brick per frame } } } // Check for bullet-brick collisions for (var b = bullets.length - 1; b >= 0; b--) { var bullet = bullets[b]; for (var j = bricks.length - 1; j >= 0; j--) { var brick = bricks[j]; if (bullet.x + bullet.width / 2 > brick.x - brick.width / 2 && bullet.x - bullet.width / 2 < brick.x + brick.width / 2 && bullet.y + bullet.height / 2 > brick.y - brick.height / 2 && bullet.y - bullet.height / 2 < brick.y + brick.height / 2) { // Hit the brick if (brick.hit()) { LK.getSound('hit').play(); // Play sound when bullet hits a brick // Brick destroyed LK.setScore(LK.getScore() + 10); scoreTxt.setText(LK.getScore()); // Chance to spawn powerup from bullet-destroyed brick if (Math.random() < brick.powerupChance) { spawnPowerup(brick.x, brick.y); } bricks.splice(j, 1); brick.destroy(); } // Destroy the bullet bullets.splice(b, 1); bullet.destroy(); break; } } } // Check if ball is below screen if (ball.y - ball.radius > 2732) { // Reset the ball position to the paddle lives--; // Decrease lives count livesTxt.setText('Lives: ' + lives); // Update lives display if (lives > 0) { ball.reset(paddle); ball.launch(); LK.getSound('fall').play(); } else { gameOver(); // Trigger game over if no lives left } } } } // Powerup-paddle collision for (var k = powerups.length - 1; k >= 0; k--) { var powerup = powerups[k]; if (powerup.y - 20 > 2732) { // Powerup fell off screen game.removeChild(powerup); powerups.splice(k, 1); } else if (powerup.y + 20 > paddle.y - paddle.height / 2 && powerup.y - 20 < paddle.y + paddle.height / 2 && powerup.x + 20 > paddle.x - paddle.width / 2 && powerup.x - 20 < paddle.x + paddle.width / 2) { // Collected powerup applyPowerup(powerup.type); LK.getSound('powerup').play(); game.removeChild(powerup); powerups.splice(k, 1); } } // Check if all bricks are gone if (bricks.length === 0 && gameState === 'playing') { levelComplete(); } } function spawnPowerup(x, y) { var powerup = new PowerUp(); powerup.x = x; powerup.y = y; // Random powerup type var types = ['expand', 'multiball', 'slow', 'grow', 'laser', 'freeze', 'shrink', 'invert']; var randomType = types[Math.floor(Math.random() * types.length)]; powerup.setType(randomType); game.addChild(powerup); powerups.push(powerup); } function applyPowerup(type) { switch (type) { case 'expand': paddle.expand(); break; case 'multiball': // Create two new balls for (var i = 0; i < 2; i++) { var newBall = createBall(); newBall.x = balls[0].x; newBall.y = balls[0].y; // Random direction var angle = Math.random() * 360 * Math.PI / 180; newBall.directionX = Math.sin(angle); newBall.directionY = Math.cos(angle); if (newBall.directionY > 0) { newBall.directionY = -newBall.directionY; // Make sure ball goes upward } newBall.active = true; } break; case 'grow': for (var i = 0; i < balls.length; i++) { tween(balls[i], { scaleX: 2.0, scaleY: 2.0 }, { duration: 300, easing: tween.easeOut }); balls[i].radius *= 2.0; } LK.setTimeout(function () { for (var i = 0; i < balls.length; i++) { tween(balls[i], { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); balls[i].radius /= 2.0; } }, 10000); break; case 'slow': // Slow down all balls for 10 seconds for (var j = 0; j < balls.length; j++) { balls[j].speed = 5; } LK.setTimeout(function () { for (var j = 0; j < balls.length; j++) { balls[j].speed = 10; } }, 10000); break; case 'laser': // Implement laser effect: allow the paddle to shoot lasers for a short duration // Example: Change paddle color to indicate laser mode paddle.setTint(0xFF0000); // Change paddle color to red LK.getSound('laser').play(); // Play laser sound when laser powerup is activated var laserInterval = LK.setInterval(function () { var laser = new Bullet(); laser.x = paddle.x; laser.y = paddle.y - paddle.height / 2; game.addChild(laser); bullets.push(laser); LK.getSound('laser').play(); // Play laser sound on each shot }, 500); // Fire laser every 500ms LK.setTimeout(function () { LK.clearInterval(laserInterval); paddle.setTint(0xFFFFFF); // Revert paddle color after laser duration }, 10000); // Laser mode lasts for 10 seconds break; case 'freeze': // Freeze all balls for 5 seconds for (var j = 0; j < balls.length; j++) { balls[j].speed = 0; } LK.setTimeout(function () { for (var j = 0; j < balls.length; j++) { balls[j].speed = 10; // Restore original speed } }, 5000); // Freeze duration break; case 'shrink': // Shrink all balls for 10 seconds for (var i = 0; i < balls.length; i++) { tween(balls[i], { scaleX: 0.5, scaleY: 0.5 }, { duration: 300, easing: tween.easeOut }); balls[i].radius *= 0.5; } LK.setTimeout(function () { for (var i = 0; i < balls.length; i++) { tween(balls[i], { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeOut }); balls[i].radius /= 0.5; } }, 10000); break; case 'invert': // Invert the direction of all balls for 5 seconds for (var j = 0; j < balls.length; j++) { balls[j].directionX = -balls[j].directionX; balls[j].directionY = -balls[j].directionY; } LK.setTimeout(function () { for (var j = 0; j < balls.length; j++) { balls[j].directionX = -balls[j].directionX; balls[j].directionY = -balls[j].directionY; } }, 5000); // Invert duration break; } } function levelComplete() { // Increment level level++; // Clear powerups for (var i = powerups.length - 1; i >= 0; i--) { game.removeChild(powerups[i]); } powerups = []; // Reset balls for (var j = balls.length - 1; j >= 0; j--) { game.removeChild(balls[j]); } balls = []; // Create new ball createBall(); // Create new level createLevel(level); // Show level message instructionTxt.setText('Level ' + level + ' - Tap to start'); instructionTxt.visible = true; // Reset game state gameState = 'ready'; } function gameOver() { gameState = 'gameover'; // Clear powerups for (var i = powerups.length - 1; i >= 0; i--) { game.removeChild(powerups[i]); } powerups = []; // Show game over LK.effects.flashScreen(0xFF0000, 1000); LK.showGameOver(); } // Event handlers function handleMove(x, y, obj) { if (dragNode && gameState === 'playing') { dragNode.x = Math.max(paddle.width / 2, Math.min(2048 - paddle.width / 2, x)); // If ball is attached to paddle, move it too for (var i = 0; i < balls.length; i++) { if (!balls[i].active) { balls[i].x = dragNode.x; } } } } game.down = function (x, y, obj) { if (gameState === 'ready') { startGame(); } dragNode = paddle; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; game.move = handleMove; game.update = function () { // Update balls for (var i = 0; i < balls.length; i++) { balls[i].update(); } // Update bullets for (var k = bullets.length - 1; k >= 0; k--) { var bullet = bullets[k]; bullet.update(); // Remove bullet if it goes off-screen if (bullet.y < 0) { bullets.splice(k, 1); bullet.destroy(); } } // Update powerups for (var j = 0; j < powerups.length; j++) { powerups[j].update(); } // Check collisions if (gameState === 'playing') { checkCollisions(); } }; // Initialize the game initGame(); if (Math.random() < 0.05) { // 5% chance to spawn a bird each frame // 1% chance to spawn a bird each frame var bird = new Bird(); bird.x = -bird.width / 2; bird.y = Math.random() * 1000 + 500; // Random Y position between 500 and 1500 game.addChild(bird); }
/****
* 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.speed = 10;
self.directionX = 0;
self.directionY = -1;
self.active = false;
self.radius = ballGraphics.width / 2;
self.reset = function (paddle) {
self.active = false;
self.x = paddle.x;
self.y = paddle.y - paddle.height / 2 - self.radius;
self.directionX = 0;
self.directionY = -1;
};
self.launch = function () {
if (!self.active) {
self.active = true;
// Random angle between -45 and 45 degrees
var angle = (Math.random() * 90 - 45) * Math.PI / 180;
self.directionX = Math.sin(angle);
self.directionY = -Math.cos(angle);
}
};
self.update = function () {
if (self.active) {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Wall collision
if (self.x - self.radius < 0) {
self.x = self.radius;
self.directionX = -self.directionX;
LK.getSound('hit').play();
} else if (self.x + self.radius > 2048) {
self.x = 2048 - self.radius;
self.directionX = -self.directionX;
LK.getSound('hit').play();
}
// Ceiling collision
if (self.y - self.radius < 0) {
self.y = self.radius;
self.directionY = -self.directionY;
LK.getSound('hit').play();
}
}
};
self.bounceOff = function (object) {
// Calculate bounce angle based on where the ball hit the object
var relativeX = (self.x - object.x) / (object.width / 2);
relativeX = Math.max(-1, Math.min(1, relativeX)); // Clamp between -1 and 1
// Calculate new direction - bouncing upward (for paddle)
self.directionX = relativeX * 0.8;
self.directionY = -Math.sqrt(1 - self.directionX * self.directionX);
// Normalize
var magnitude = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY);
self.directionX /= magnitude;
self.directionY /= magnitude;
LK.getSound('hit').play();
};
return self;
});
var Bird = Container.expand(function () {
var self = Container.call(this);
var birdGraphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5;
self.update = function () {
self.x += self.speed;
if (self.x > 2048 + birdGraphics.width / 2) {
self.x = -birdGraphics.width / 2;
}
};
return self;
});
var Brick = Container.expand(function () {
var self = Container.call(this);
var brickGraphics = self.attachAsset('brick', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = brickGraphics.width;
self.height = brickGraphics.height;
self.hitPoints = 1;
self.powerupChance = 0.2;
self.setColor = function (color) {
brickGraphics.tint = color;
};
self.hit = function () {
self.hitPoints--;
if (self.hitPoints <= 0) {
LK.getSound('break').play();
return true; // Brick destroyed
} else {
// Make brick darker
brickGraphics.tint = (brickGraphics.tint & 0xfefefe) >> 1;
LK.getSound('hit').play();
return false; // Brick not destroyed yet
}
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -10;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = paddleGraphics.width;
self.height = paddleGraphics.height;
self.normalWidth = paddleGraphics.width;
self.expand = function () {
tween(paddleGraphics, {
width: self.normalWidth * 1.5
}, {
duration: 300,
easing: tween.easeOut
});
self.width = self.normalWidth * 1.5;
LK.setTimeout(function () {
tween(paddleGraphics, {
width: self.normalWidth
}, {
duration: 300,
easing: tween.easeOut
});
self.width = self.normalWidth;
}, 10000); // 10 seconds
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics;
self.setType = function (type) {
self.type = type;
switch (type) {
case 'expand':
powerupGraphics = self.attachAsset('powerup_expand', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'multiball':
powerupGraphics = self.attachAsset('powerup_multiball', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'slow':
powerupGraphics = self.attachAsset('powerup_slow', {
anchorX: 0.5,
anchorY: 0.5
});
break;
}
};
self.type = 'expand'; // Default powerup type
self.fallSpeed = 5;
// Set different colors for different powerup types
self.setType = function (type) {
self.type = type;
switch (type) {
case 'expand':
powerupGraphics = self.attachAsset('powerup_expand', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'multiball':
powerupGraphics = self.attachAsset('powerup_multiball', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'slow':
powerupGraphics = self.attachAsset('powerup_slow', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'grow':
powerupGraphics = self.attachAsset('powerup_grow', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'laser':
powerupGraphics = self.attachAsset('powerup_laser', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'freeze':
powerupGraphics = self.attachAsset('powerup_freeze', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'shrink':
powerupGraphics = self.attachAsset('powerup_shrink', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'invert':
powerupGraphics = self.attachAsset('powerup_invert', {
anchorX: 0.5,
anchorY: 0.5
});
break;
}
};
self.update = function () {
self.y += self.fallSpeed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// New visual for 'grow' powerup
// Add background image
Paddle.prototype.setTint = function (color) {
this.children[0].tint = color; // Assuming the first child is paddleGraphics
};
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
background.x = 2048 / 2;
background.y = 2732 / 2;
game.addChild(background);
// Initialize game elements
var level = 1;
var paddle = null;
var balls = [];
var bricks = [];
var bullets = []; // Define bullets array to track bullet instances
var powerups = [];
var gameState = 'ready'; // 'ready', 'playing', 'gameover'
var dragNode = null;
// Colors for bricks
var BRICK_COLORS = [0xFF0000,
// Red
0xFF7F00,
// Orange
0xFFFF00,
// Yellow
0x00FF00,
// Green
0x0000FF,
// Blue
0x4B0082,
// Indigo
0x9400D3 // Violet
];
// Create UI elements
var lives = 100; // Initial number of lives
var livesTxt = new Text2('Lives: ' + lives, {
size: 80,
fill: 0xFFFFFF
});
livesTxt.anchor.set(0.5, 0);
livesTxt.x = 165; // Move a few pixels further to the right
LK.gui.topLeft.addChild(livesTxt);
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var levelTxt = new Text2('Level: 1', {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
levelTxt.x = 100;
levelTxt.y = 20;
LK.gui.topRight.addChild(levelTxt);
var instructionTxt = new Text2('Tap to start - Drag paddle to play', {
size: 60,
fill: 0xFFFFFF
});
instructionTxt.anchor.set(0.5, 0);
instructionTxt.y = 150;
LK.gui.top.addChild(instructionTxt);
// Initialize game elements
function initGame() {
// Reset score
LK.setScore(0);
scoreTxt.setText('0');
// Create paddle
paddle = new Paddle();
paddle.x = 2048 / 2;
paddle.y = 2732 - 150;
game.addChild(paddle);
// Assign the down event handler to the paddle after it is initialized
paddle.down = function (x, y, obj) {
// Check if enough time has passed since the last bullet was fired
if (!paddle.lastBulletTime || Date.now() - paddle.lastBulletTime > 500) {
// 500ms interval
// Fire a bullet from the paddle
var bullet = new Bullet();
bullet.x = paddle.x;
bullet.y = paddle.y - paddle.height / 2;
game.addChild(bullet);
bullets.push(bullet);
// Play bullet sound
LK.getSound('shoot').play();
// Update the last bullet time
paddle.lastBulletTime = Date.now();
}
};
// Create initial ball
createBall();
// Create brick layout for level 1
createLevel(1);
// Set game state
gameState = 'ready';
instructionTxt.visible = true;
// Start background music
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
}
function createBall() {
var ball = new Ball();
ball.reset(paddle);
game.addChild(ball);
balls.push(ball);
return ball;
}
function createLevel(level) {
// Clear existing bricks
for (var i = bricks.length - 1; i >= 0; i--) {
bricks[i].destroy();
}
bricks = [];
levelTxt.setText('Level: ' + level);
// Define grid dimensions based on level
var rows = Math.min(5 + Math.floor(level / 2), 10);
var cols = Math.min(10 + Math.floor(level / 3), 13);
var brickWidth = 150;
var brickHeight = 60;
var padding = 10;
var totalWidth = cols * (brickWidth + padding) - padding;
var startX = (2048 - totalWidth) / 2 + brickWidth / 2;
var startY = 200;
// Create brick layout
for (var row = 0; row < rows; row++) {
for (var col = 0; col < cols; col++) {
var brick = new Brick();
brick.attachAsset('brick' + row % BRICK_COLORS.length, {
anchorX: 0.5,
anchorY: 0.5
});
// Position brick
brick.x = startX + col * (brickWidth + padding);
brick.y = startY + row * (brickHeight + padding);
// Color based on row
brick.setColor(BRICK_COLORS[row % BRICK_COLORS.length]);
// Higher levels have stronger bricks
if (level > 2 && row < 2) {
brick.hitPoints = 2;
}
game.addChild(brick);
bricks.push(brick);
}
}
}
function startGame() {
if (gameState === 'ready') {
gameState = 'playing';
instructionTxt.visible = false;
// Launch the first ball
if (balls.length > 0) {
balls[0].launch();
}
}
}
function checkCollisions() {
// Check for ball-bird collisions
for (var i = 0; i < balls.length; i++) {
var ball = balls[i];
if (ball.active) {
for (var j = game.children.length - 1; j >= 0; j--) {
var child = game.children[j];
if (child instanceof Bird) {
if (ball.x + ball.radius > child.x - child.width / 2 && ball.x - ball.radius < child.x + child.width / 2 && ball.y + ball.radius > child.y - child.height / 2 && ball.y - ball.radius < child.y + child.height / 2) {
// Ball hits the bird
game.removeChild(child);
ball.bounceOff(child);
break;
}
}
}
}
}
// Ball-paddle collision
for (var i = 0; i < balls.length; i++) {
var ball = balls[i];
if (ball.active) {
// Check for paddle collision
if (ball.y + ball.radius > paddle.y - paddle.height / 2 && ball.y - ball.radius < paddle.y + paddle.height / 2 && ball.x + ball.radius > paddle.x - paddle.width / 2 && ball.x - ball.radius < paddle.x + paddle.width / 2 && ball.directionY > 0) {
// Only bounce if moving downward
ball.y = paddle.y - paddle.height / 2 - ball.radius;
ball.bounceOff(paddle);
}
// Check for brick collisions
for (var j = bricks.length - 1; j >= 0; j--) {
var brick = bricks[j];
if (ball.x + ball.radius > brick.x - brick.width / 2 && ball.x - ball.radius < brick.x + brick.width / 2 && ball.y + ball.radius > brick.y - brick.height / 2 && ball.y - ball.radius < brick.y + brick.height / 2) {
// Determine which side of the brick was hit
var dx = ball.x - brick.x;
var dy = ball.y - brick.y;
var width = brick.width / 2 + ball.radius;
var height = brick.height / 2 + ball.radius;
var crossWidth = width * dy;
var crossHeight = height * dx;
if (Math.abs(dx) <= width && Math.abs(dy) <= height) {
if (crossWidth > crossHeight) {
if (crossWidth > -crossHeight) {
// Bottom collision
ball.directionY = Math.abs(ball.directionY);
} else {
// Left collision
ball.directionX = -Math.abs(ball.directionX);
}
} else {
if (crossWidth > -crossHeight) {
// Right collision
ball.directionX = Math.abs(ball.directionX);
} else {
// Top collision
ball.directionY = -Math.abs(ball.directionY);
}
}
// Hit the brick
if (brick.hit()) {
// Brick destroyed
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Check if score is a multiple of 200
if (LK.getScore() % 200 === 0) {
lives++; // Increase lives by 1
livesTxt.setText('Lives: ' + lives); // Update lives display
}
// Chance to spawn powerup
if (Math.random() < brick.powerupChance) {
spawnPowerup(brick.x, brick.y);
}
bricks.splice(j, 1);
brick.destroy();
}
break; // Only hit one brick per frame
}
}
}
// Check for bullet-brick collisions
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
for (var j = bricks.length - 1; j >= 0; j--) {
var brick = bricks[j];
if (bullet.x + bullet.width / 2 > brick.x - brick.width / 2 && bullet.x - bullet.width / 2 < brick.x + brick.width / 2 && bullet.y + bullet.height / 2 > brick.y - brick.height / 2 && bullet.y - bullet.height / 2 < brick.y + brick.height / 2) {
// Hit the brick
if (brick.hit()) {
LK.getSound('hit').play(); // Play sound when bullet hits a brick
// Brick destroyed
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Chance to spawn powerup from bullet-destroyed brick
if (Math.random() < brick.powerupChance) {
spawnPowerup(brick.x, brick.y);
}
bricks.splice(j, 1);
brick.destroy();
}
// Destroy the bullet
bullets.splice(b, 1);
bullet.destroy();
break;
}
}
}
// Check if ball is below screen
if (ball.y - ball.radius > 2732) {
// Reset the ball position to the paddle
lives--; // Decrease lives count
livesTxt.setText('Lives: ' + lives); // Update lives display
if (lives > 0) {
ball.reset(paddle);
ball.launch();
LK.getSound('fall').play();
} else {
gameOver(); // Trigger game over if no lives left
}
}
}
}
// Powerup-paddle collision
for (var k = powerups.length - 1; k >= 0; k--) {
var powerup = powerups[k];
if (powerup.y - 20 > 2732) {
// Powerup fell off screen
game.removeChild(powerup);
powerups.splice(k, 1);
} else if (powerup.y + 20 > paddle.y - paddle.height / 2 && powerup.y - 20 < paddle.y + paddle.height / 2 && powerup.x + 20 > paddle.x - paddle.width / 2 && powerup.x - 20 < paddle.x + paddle.width / 2) {
// Collected powerup
applyPowerup(powerup.type);
LK.getSound('powerup').play();
game.removeChild(powerup);
powerups.splice(k, 1);
}
}
// Check if all bricks are gone
if (bricks.length === 0 && gameState === 'playing') {
levelComplete();
}
}
function spawnPowerup(x, y) {
var powerup = new PowerUp();
powerup.x = x;
powerup.y = y;
// Random powerup type
var types = ['expand', 'multiball', 'slow', 'grow', 'laser', 'freeze', 'shrink', 'invert'];
var randomType = types[Math.floor(Math.random() * types.length)];
powerup.setType(randomType);
game.addChild(powerup);
powerups.push(powerup);
}
function applyPowerup(type) {
switch (type) {
case 'expand':
paddle.expand();
break;
case 'multiball':
// Create two new balls
for (var i = 0; i < 2; i++) {
var newBall = createBall();
newBall.x = balls[0].x;
newBall.y = balls[0].y;
// Random direction
var angle = Math.random() * 360 * Math.PI / 180;
newBall.directionX = Math.sin(angle);
newBall.directionY = Math.cos(angle);
if (newBall.directionY > 0) {
newBall.directionY = -newBall.directionY; // Make sure ball goes upward
}
newBall.active = true;
}
break;
case 'grow':
for (var i = 0; i < balls.length; i++) {
tween(balls[i], {
scaleX: 2.0,
scaleY: 2.0
}, {
duration: 300,
easing: tween.easeOut
});
balls[i].radius *= 2.0;
}
LK.setTimeout(function () {
for (var i = 0; i < balls.length; i++) {
tween(balls[i], {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
balls[i].radius /= 2.0;
}
}, 10000);
break;
case 'slow':
// Slow down all balls for 10 seconds
for (var j = 0; j < balls.length; j++) {
balls[j].speed = 5;
}
LK.setTimeout(function () {
for (var j = 0; j < balls.length; j++) {
balls[j].speed = 10;
}
}, 10000);
break;
case 'laser':
// Implement laser effect: allow the paddle to shoot lasers for a short duration
// Example: Change paddle color to indicate laser mode
paddle.setTint(0xFF0000); // Change paddle color to red
LK.getSound('laser').play(); // Play laser sound when laser powerup is activated
var laserInterval = LK.setInterval(function () {
var laser = new Bullet();
laser.x = paddle.x;
laser.y = paddle.y - paddle.height / 2;
game.addChild(laser);
bullets.push(laser);
LK.getSound('laser').play(); // Play laser sound on each shot
}, 500); // Fire laser every 500ms
LK.setTimeout(function () {
LK.clearInterval(laserInterval);
paddle.setTint(0xFFFFFF); // Revert paddle color after laser duration
}, 10000); // Laser mode lasts for 10 seconds
break;
case 'freeze':
// Freeze all balls for 5 seconds
for (var j = 0; j < balls.length; j++) {
balls[j].speed = 0;
}
LK.setTimeout(function () {
for (var j = 0; j < balls.length; j++) {
balls[j].speed = 10; // Restore original speed
}
}, 5000); // Freeze duration
break;
case 'shrink':
// Shrink all balls for 10 seconds
for (var i = 0; i < balls.length; i++) {
tween(balls[i], {
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 300,
easing: tween.easeOut
});
balls[i].radius *= 0.5;
}
LK.setTimeout(function () {
for (var i = 0; i < balls.length; i++) {
tween(balls[i], {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeOut
});
balls[i].radius /= 0.5;
}
}, 10000);
break;
case 'invert':
// Invert the direction of all balls for 5 seconds
for (var j = 0; j < balls.length; j++) {
balls[j].directionX = -balls[j].directionX;
balls[j].directionY = -balls[j].directionY;
}
LK.setTimeout(function () {
for (var j = 0; j < balls.length; j++) {
balls[j].directionX = -balls[j].directionX;
balls[j].directionY = -balls[j].directionY;
}
}, 5000); // Invert duration
break;
}
}
function levelComplete() {
// Increment level
level++;
// Clear powerups
for (var i = powerups.length - 1; i >= 0; i--) {
game.removeChild(powerups[i]);
}
powerups = [];
// Reset balls
for (var j = balls.length - 1; j >= 0; j--) {
game.removeChild(balls[j]);
}
balls = [];
// Create new ball
createBall();
// Create new level
createLevel(level);
// Show level message
instructionTxt.setText('Level ' + level + ' - Tap to start');
instructionTxt.visible = true;
// Reset game state
gameState = 'ready';
}
function gameOver() {
gameState = 'gameover';
// Clear powerups
for (var i = powerups.length - 1; i >= 0; i--) {
game.removeChild(powerups[i]);
}
powerups = [];
// Show game over
LK.effects.flashScreen(0xFF0000, 1000);
LK.showGameOver();
}
// Event handlers
function handleMove(x, y, obj) {
if (dragNode && gameState === 'playing') {
dragNode.x = Math.max(paddle.width / 2, Math.min(2048 - paddle.width / 2, x));
// If ball is attached to paddle, move it too
for (var i = 0; i < balls.length; i++) {
if (!balls[i].active) {
balls[i].x = dragNode.x;
}
}
}
}
game.down = function (x, y, obj) {
if (gameState === 'ready') {
startGame();
}
dragNode = paddle;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
game.move = handleMove;
game.update = function () {
// Update balls
for (var i = 0; i < balls.length; i++) {
balls[i].update();
}
// Update bullets
for (var k = bullets.length - 1; k >= 0; k--) {
var bullet = bullets[k];
bullet.update();
// Remove bullet if it goes off-screen
if (bullet.y < 0) {
bullets.splice(k, 1);
bullet.destroy();
}
}
// Update powerups
for (var j = 0; j < powerups.length; j++) {
powerups[j].update();
}
// Check collisions
if (gameState === 'playing') {
checkCollisions();
}
};
// Initialize the game
initGame();
if (Math.random() < 0.05) {
// 5% chance to spawn a bird each frame
// 1% chance to spawn a bird each frame
var bird = new Bird();
bird.x = -bird.width / 2;
bird.y = Math.random() * 1000 + 500; // Random Y position between 500 and 1500
game.addChild(bird);
}