/**** * 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, alpha: 0.9 }); var glowBall = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4, scaleX: 1.5, scaleY: 1.5 }); self.velocityX = 0; self.velocityY = 0; self.speed = 10; self.gravityAffected = true; self.lastX = 0; self.lastY = 0; self.trailElements = []; self.maxTrailLength = 5; self.createTrailElement = function () { var trailElement = LK.getAsset('ball', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: 0.7, scaleY: 0.7, tint: 0x87CEFA }); return trailElement; }; self.updateTrail = function () { // Add new trail element if (Math.abs(self.x - self.lastX) > 5 || Math.abs(self.y - self.lastY) > 5) { var trail = self.createTrailElement(); trail.x = self.x; trail.y = self.y; game.addChildAt(trail, game.getChildIndex(self)); self.trailElements.push(trail); // Fade out and remove tween(trail, { alpha: 0 }, { duration: 400, easing: tween.linear, onFinish: function onFinish() { if (trail.parent) { trail.parent.removeChild(trail); } } }); // Remove old elements if too many if (self.trailElements.length > self.maxTrailLength) { var oldTrail = self.trailElements.shift(); if (oldTrail.parent) { oldTrail.parent.removeChild(oldTrail); } } } // Update last position self.lastX = self.x; self.lastY = self.y; }; self.reset = function () { self.x = 2048 / 2; self.y = 2732 / 2; self.velocityX = (Math.random() > 0.5 ? 1 : -1) * self.speed; self.velocityY = (Math.random() * 2 - 1) * self.speed * 0.5; self.lastX = self.x; self.lastY = self.y; // Clear any existing trail elements for (var i = 0; i < self.trailElements.length; i++) { if (self.trailElements[i].parent) { self.trailElements[i].parent.removeChild(self.trailElements[i]); } } self.trailElements = []; // Add pulsating glow effect self.startGlowAnimation(); }; self.startGlowAnimation = function () { tween(glowBall.scale, { x: 1.8, y: 1.8 }, { duration: 800, easing: tween.sinceOut, onFinish: function onFinish() { tween(glowBall.scale, { x: 1.5, y: 1.5 }, { duration: 800, easing: tween.sinceIn, onFinish: function onFinish() { self.startGlowAnimation(); } }); } }); }; self.update = function () { self.x += self.velocityX; self.y += self.velocityY; // Update the trail self.updateTrail(); // Handle wall collisions if (self.x < 0 + ballGraphics.width / 2) { self.x = ballGraphics.width / 2; self.velocityX = -self.velocityX; // Play wall bounce sound LK.getSound('bounce').play(); } else if (self.x > 2048 - ballGraphics.width / 2) { self.x = 2048 - ballGraphics.width / 2; self.velocityX = -self.velocityX; // Play wall bounce sound LK.getSound('bounce').play(); } }; return self; }); var GravityField = Container.expand(function () { var self = Container.call(this); var fieldGraphics = self.attachAsset('gravitationField', { anchorX: 0.5, anchorY: 0.5, alpha: 0.2 }); self.strength = 0.1; self.maxStrength = 0.5; self.setup = function () { self.x = 2048 / 2; self.y = 2732 / 2; self.strength = 0.1; self.scale.set(1); }; self.increaseStrength = function () { self.strength = Math.min(self.maxStrength, self.strength + 0.05); // Play powerup sound when gravity field increases strength LK.getSound('powerup').play(); tween(self.scale, { x: 1 + self.strength, y: 1 + self.strength }, { duration: 1000, easing: tween.elasticOut }); }; self.reverseGravity = function () { self.strength = -self.strength; // Play sound for gravity reversal LK.getSound('powerup').play(); tween(fieldGraphics, { tint: 0xFF5733 }, { duration: 300, easing: tween.linear, onFinish: function onFinish() { tween(fieldGraphics, { tint: 0x4287f5 }, { duration: 5000, easing: tween.linear, onFinish: function onFinish() { self.strength = Math.abs(self.strength); } }); } }); }; self.applyGravityTo = function (ball) { if (!ball.gravityAffected) { return; } var dx = self.x - ball.x; var dy = self.y - ball.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 10) { var forceX = dx / distance * self.strength; var forceY = dy / distance * self.strength; ball.velocityX += forceX; ball.velocityY += forceY; // Cap maximum velocity var speed = Math.sqrt(ball.velocityX * ball.velocityX + ball.velocityY * ball.velocityY); if (speed > ball.speed * 2) { ball.velocityX = ball.velocityX / speed * ball.speed * 2; ball.velocityY = ball.velocityY / speed * ball.speed * 2; } } }; return self; }); var Paddle = Container.expand(function () { var self = Container.call(this); // Create shadow effect var paddleShadow = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3, scaleX: 1.05, scaleY: 1.8, y: 8 }); var paddleGraphics = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); self.targetX = 0; self.speed = 15; self.isPlayer = false; self.score = 0; self.setup = function (isPlayer) { self.isPlayer = isPlayer; if (isPlayer) { self.y = 2732 - 200; paddleGraphics.tint = 0x4287f5; // Blue for player } else { self.y = 200; paddleGraphics.tint = 0xff5733; // Orange for AI } self.x = 2048 / 2; self.targetX = self.x; // Create entrance animation self.scale.set(0.1); // Play sound for paddle appearance LK.getSound('powerup').play(); tween(self.scale, { x: 1, y: 1 }, { duration: 800, easing: tween.elasticOut }); }; self.update = function () { // Move toward target position with easing if (Math.abs(self.x - self.targetX) > 1) { self.x += (self.targetX - self.x) * 0.2; } // Boundary check if (self.x < paddleGraphics.width / 2) { self.x = paddleGraphics.width / 2; } else if (self.x > 2048 - paddleGraphics.width / 2) { self.x = 2048 - paddleGraphics.width / 2; } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var type = 'gravity'; // Default type var powerUpGraphics; self.setup = function (powerType) { type = powerType; if (self.children.length > 0) { self.removeChildAt(0); } if (type === 'gravity') { powerUpGraphics = self.attachAsset('powerUpGravity', { anchorX: 0.5, anchorY: 0.5 }); } else if (type === 'multiball') { powerUpGraphics = self.attachAsset('powerUpMultiBall', { anchorX: 0.5, anchorY: 0.5 }); } self.x = Math.random() * (2048 - 200) + 100; self.y = Math.random() * (2732 - 600) + 300; self.alpha = 1; // Play sound on first appearance (not on pulse refresh) if (arguments.length > 0) { LK.getSound('powerup').play(); } // Pulsating animation tween(self, { alpha: 0.6 }, { duration: 800, easing: tween.sinceOut, onFinish: function onFinish() { tween(self, { alpha: 1 }, { duration: 800, easing: tween.sinceIn, onFinish: function onFinish() { if (self.parent) { self.setup(type); } } }); } }); }; self.getType = function () { return type; }; return self; }); var PredictionLine = Container.expand(function () { var self = Container.call(this); var lineSegments = []; var numSegments = 10; var segmentLength = 15; var segmentGap = 10; self.setup = function () { // Create line segments for (var i = 0; i < numSegments; i++) { var segment = LK.getAsset('paddle', { anchorX: 0.5, anchorY: 0.5, width: 5, height: segmentLength, alpha: 0.6 - i * 0.05, tint: 0x4287f5 }); lineSegments.push(segment); self.addChild(segment); } self.visible = false; }; self.updatePosition = function (startX, startY, targetX, targetY) { if (!self.visible) { self.visible = true; } var dx = targetX - startX; var dy = targetY - startY; var angle = Math.atan2(dy, dx); for (var i = 0; i < lineSegments.length; i++) { var distance = i * (segmentLength + segmentGap); lineSegments[i].x = startX + Math.cos(angle) * distance; lineSegments[i].y = startY + Math.sin(angle) * distance; lineSegments[i].rotation = angle; } }; self.hide = function () { self.visible = false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // (Removed custom background, branding, and starfield per LK guidelines) // Create game elements var playerPaddle = new Paddle(); var aiPaddle = new Paddle(); var gravityField = new GravityField(); var balls = []; var powerUps = []; var centerLine; var playerScoreText; var aiScoreText; var dragTarget = null; var difficultyTimer; var powerUpTimer; var gameActive = false; var predictionLine; var mouseX = 0; var mouseY = 0; var isMouseOver = false; // Animate score text function function animateScoreText(textObject, newValue) { // Store original scale var originalScale = { x: textObject.scale.x, y: textObject.scale.y }; // Set the new text textObject.setText(newValue); // Animate scale up and back down tween.stop(textObject.scale); textObject.scale.set(originalScale.x * 1.5, originalScale.y * 1.5); tween(textObject.scale, { x: originalScale.x, y: originalScale.y }, { duration: 500, easing: tween.elasticOut }); } // Initialize game state function initGame() { // Setup players playerPaddle.setup(true); aiPaddle.setup(false); game.addChild(playerPaddle); game.addChild(aiPaddle); // Setup gravity field gravityField.setup(); game.addChild(gravityField); // Create center line with animation centerLine = new Container(); centerLine.alpha = 0; for (var i = 0; i < 20; i++) { var dash = LK.getAsset('paddle', { anchorX: 0.5, anchorY: 0.5, width: 50, height: 10, alpha: 0.5 }); dash.x = i * 110; // Add staggered animation to each dash (function (element, delay) { element.alpha = 0; element.scale.set(0.5); LK.setTimeout(function () { tween(element, { alpha: 0.5 }, { duration: 400, easing: tween.linear }); tween(element.scale, { x: 1, y: 1 }, { duration: 600, easing: tween.elasticOut }); }, delay); })(dash, i * 30); centerLine.addChild(dash); } centerLine.x = 50; centerLine.y = 2732 / 2; game.addChild(centerLine); tween(centerLine, { alpha: 1 }, { duration: 800, easing: tween.linear }); // Create score text with animated appearance playerScoreText = new Text2('0', { size: 150, fill: 0xFFFFFF }); playerScoreText.anchor.set(0.5, 1); playerScoreText.x = 2048 / 2; playerScoreText.y = 2732 - 50; playerScoreText.alpha = 0; playerScoreText.scale.set(0.5); game.addChild(playerScoreText); aiScoreText = new Text2('0', { size: 150, fill: 0xFFFFFF }); aiScoreText.anchor.set(0.5, 0); aiScoreText.x = 2048 / 2; aiScoreText.y = 50; aiScoreText.alpha = 0; aiScoreText.scale.set(0.5); game.addChild(aiScoreText); // Animate score text appearance tween(playerScoreText, { alpha: 1 }, { duration: 800, easing: tween.linear }); tween(playerScoreText.scale, { x: 1, y: 1 }, { duration: 1000, easing: tween.elasticOut }); tween(aiScoreText, { alpha: 1 }, { duration: 800, easing: tween.linear }); tween(aiScoreText.scale, { x: 1, y: 1 }, { duration: 1000, easing: tween.elasticOut }); // Create first ball with delay to allow UI elements to animate in LK.setTimeout(function () { createBall(); }, 1200); // Setup difficulty increases difficultyTimer = LK.setInterval(function () { if (gameActive) { gravityField.increaseStrength(); } }, 10000); // Setup power-up spawning powerUpTimer = LK.setInterval(function () { if (gameActive && powerUps.length < 1) { spawnPowerUp(); } }, 15000); // Create prediction line predictionLine = new PredictionLine(); predictionLine.setup(); game.addChild(predictionLine); // Start game gameActive = true; LK.playMusic('gameMusic'); } // Function to create a new ball function createBall() { var ball = new Ball(); ball.reset(); balls.push(ball); game.addChild(ball); // Play sound when creating a new ball LK.getSound('powerup').play(); return ball; } // Function to spawn a power-up function spawnPowerUp() { var powerUp = new PowerUp(); var type = Math.random() > 0.5 ? 'gravity' : 'multiball'; powerUp.setup(type); powerUps.push(powerUp); game.addChild(powerUp); // Play sound when spawning power-up (now handled in PowerUp.setup) } // Check for collisions between ball and paddle function checkPaddleCollision(ball, paddle) { if (ball.y + 25 >= paddle.y - 25 && ball.y - 25 <= paddle.y + 25) { if (ball.x + 25 >= paddle.x - 125 && ball.x - 25 <= paddle.x + 125) { // Calculate bounce angle based on where ball hit the paddle var relativeIntersectX = ball.x - paddle.x; var normalizedRelativeIntersectionX = relativeIntersectX / 125; var bounceAngle = normalizedRelativeIntersectionX * (Math.PI / 3); // Maximum angle: 60 degrees // Invert Y velocity and adjust X velocity based on bounce angle ball.velocityY = -ball.velocityY; ball.velocityX = ball.speed * Math.sin(bounceAngle); // Increase speed slightly ball.speed = Math.min(20, ball.speed * 1.05); // Play bounce sound LK.getSound('bounce').play(); // Enhanced paddle hit effect - scale and flash tween.stop(paddle.scale); paddle.scale.set(1.2, 0.8); tween(paddle.scale, { x: 1, y: 1 }, { duration: 300, easing: tween.elasticOut }); // Flash paddle with color based on player LK.effects.flashObject(paddle, paddle.isPlayer ? 0x4287f5 : 0xff5733, 300); return true; } } return false; } // Check for collisions between ball and power-up function checkPowerUpCollision(ball) { for (var i = powerUps.length - 1; i >= 0; i--) { var powerUp = powerUps[i]; if (ball.intersects(powerUp)) { // Create explosion effect at power-up location var explosionEffect = new Container(); explosionEffect.x = powerUp.x; explosionEffect.y = powerUp.y; game.addChild(explosionEffect); // Create multiple particles for explosion for (var p = 0; p < 10; p++) { var particle = LK.getAsset(powerUp.getType() === 'gravity' ? 'powerUpGravity' : 'powerUpMultiBall', { anchorX: 0.5, anchorY: 0.5, scale: 0.5, alpha: 0.8 }); // Randomize particle position and movement var angle = Math.random() * Math.PI * 2; var distance = Math.random() * 100 + 50; var duration = Math.random() * 500 + 500; particle.x = 0; particle.y = 0; explosionEffect.addChild(particle); // Animate particle movement and fade tween(particle, { x: Math.cos(angle) * distance, y: Math.sin(angle) * distance, alpha: 0 }, { duration: duration, easing: tween.cubicOut }); // Ensure particle has proper scale object particle.scale = particle.scale || { x: 0.5, y: 0.5 }; // Ensure particle has scale object before tweening if (!particle.scale || typeof particle.scale === 'number') { particle.scale = { x: 0.5, y: 0.5 }; } // Now safely tween the scale property tween(particle.scale, { x: 0.1, y: 0.1 }, { duration: duration, easing: tween.linear }); } // Remove explosion container after animation completes LK.setTimeout(function () { explosionEffect.destroy(); }, 1000); // Apply power-up effect with enhanced visuals if (powerUp.getType() === 'gravity') { // Shake gravity field for dramatic effect var originalX = gravityField.x; var originalY = gravityField.y; var shakeCount = 0; var shakeInterval = LK.setInterval(function () { gravityField.x = originalX + (Math.random() * 20 - 10); gravityField.y = originalY + (Math.random() * 20 - 10); shakeCount++; if (shakeCount >= 10) { LK.clearInterval(shakeInterval); gravityField.x = originalX; gravityField.y = originalY; gravityField.reverseGravity(); } }, 50); } else if (powerUp.getType() === 'multiball') { for (var j = 0; j < 2; j++) { var newBall = createBall(); // Add a scale animation to new balls newBall.scale.set(0.2); tween(newBall.scale, { x: 1, y: 1 }, { duration: 500, easing: tween.elasticOut }); } } // Play sound and remove power-up LK.getSound('powerup').play(); LK.effects.flashScreen(0x33FF57, 300); powerUp.destroy(); powerUps.splice(i, 1); } } } // Handle AI movement function updateAI() { // Find the closest ball var closestBall = null; var closestDistance = Infinity; for (var i = 0; i < balls.length; i++) { var ball = balls[i]; if (ball.velocityY < 0) { // Ball is moving towards AI var distance = Math.abs(ball.x - aiPaddle.x); if (distance < closestDistance) { closestDistance = distance; closestBall = ball; } } } if (closestBall) { // Add some prediction based on velocity and gravity var predictedX = closestBall.x + closestBall.velocityX * (aiPaddle.y - closestBall.y) / Math.abs(closestBall.velocityY); aiPaddle.targetX = predictedX; // Add some difficulty scaling var difficultyFactor = 0.3 + gravityField.strength / gravityField.maxStrength * 0.6; aiPaddle.targetX = aiPaddle.x + (predictedX - aiPaddle.x) * difficultyFactor; } } // Event handler for touch/mouse down game.down = function (x, y, obj) { // Only allow dragging the player paddle if (y > 2732 / 2) { dragTarget = playerPaddle; playerPaddle.targetX = x; isMouseOver = true; mouseX = x; mouseY = y; } }; // Event handler for touch/mouse move game.move = function (x, y, obj) { mouseX = x; mouseY = y; isMouseOver = true; if (dragTarget) { playerPaddle.targetX = x; } }; // Event handler for touch/mouse up game.up = function (x, y, obj) { dragTarget = null; }; // Game update loop game.update = function () { if (!gameActive) { return; } // Update AI updateAI(); // Update paddles playerPaddle.update(); aiPaddle.update(); // Update prediction line if (isMouseOver && balls.length > 0) { // Show prediction line from closest ball to mouse position var closestBall = null; var minDistance = Infinity; for (var i = 0; i < balls.length; i++) { var dist = Math.sqrt(Math.pow(balls[i].x - mouseX, 2) + Math.pow(balls[i].y - mouseY, 2)); if (dist < minDistance) { minDistance = dist; closestBall = balls[i]; } } if (closestBall) { predictionLine.updatePosition(closestBall.x, closestBall.y, mouseX, playerPaddle.y); } } else { predictionLine.hide(); } // Reset mouse tracking after update isMouseOver = false; // Update balls for (var i = balls.length - 1; i >= 0; i--) { var ball = balls[i]; // Apply gravity gravityField.applyGravityTo(ball); // Update ball position ball.update(); // Check for paddle collisions var hitPlayer = checkPaddleCollision(ball, playerPaddle); var hitAI = checkPaddleCollision(ball, aiPaddle); // Check if ball is out of bounds (scoring) if (ball.y > 2732 + 50) { // AI scores aiPaddle.score++; // Animated score update animateScoreText(aiScoreText, aiPaddle.score.toString()); LK.getSound('score').play(); // Create a visual effect at ball position before destroying var scoreEffect = LK.getAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: ball.x, y: 2732, alpha: 0.8, scaleX: 1, scaleY: 1, tint: 0xff5733 }); game.addChild(scoreEffect); tween(scoreEffect.scale, { x: 3, y: 3 }, { duration: 500, easing: tween.cubicOut, onFinish: function onFinish() { tween(scoreEffect, { alpha: 0 }, { duration: 300, easing: tween.linear, onFinish: function onFinish() { scoreEffect.destroy(); } }); } }); ball.destroy(); balls.splice(i, 1); if (balls.length === 0) { createBall(); } // Check for game over if (aiPaddle.score >= 10) { gameActive = false; LK.showGameOver(); } } else if (ball.y < -50) { // Player scores playerPaddle.score++; // Animated score update animateScoreText(playerScoreText, playerPaddle.score.toString()); LK.getSound('score').play(); // Create a visual effect at ball position before destroying var scoreEffect = LK.getAsset('ball', { anchorX: 0.5, anchorY: 0.5, x: ball.x, y: 0, alpha: 0.8, scaleX: 1, scaleY: 1, tint: 0x4287f5 }); game.addChild(scoreEffect); tween(scoreEffect.scale, { x: 3, y: 3 }, { duration: 500, easing: tween.cubicOut, onFinish: function onFinish() { tween(scoreEffect, { alpha: 0 }, { duration: 300, easing: tween.linear, onFinish: function onFinish() { scoreEffect.destroy(); } }); } }); ball.destroy(); balls.splice(i, 1); if (balls.length === 0) { createBall(); } // Check for win if (playerPaddle.score >= 10) { gameActive = false; LK.showYouWin(); } } // Check for power-up collisions checkPowerUpCollision(ball); } }; // Initialize the game when code loads initGame();
===================================================================
--- original.js
+++ change.js
@@ -361,64 +361,9 @@
/****
* Game Code
****/
-// Set a beautiful dark gradient background
-game.setBackgroundColor(0x0a0a2a);
-// Add "Glaud" text in small orange to the upper right corner
-var glaudText = new Text2('Glaud', {
- size: 40,
- fill: 0xff8c00 // Orange color
-});
-glaudText.anchor.set(1, 0); // Anchor to top right
-glaudText.x = 2048 - 20; // 20px margin from right edge
-glaudText.y = 20; // 20px margin from top edge
-game.addChild(glaudText);
-// Create a star field background
-function createStarfield() {
- var starfield = new Container();
- // Create stars with different sizes and opacities
- for (var i = 0; i < 100; i++) {
- var size = Math.random() * 4 + 1;
- var star = LK.getAsset('ball', {
- anchorX: 0.5,
- anchorY: 0.5,
- width: size,
- height: size,
- alpha: Math.random() * 0.7 + 0.3
- });
- star.x = Math.random() * 2048;
- star.y = Math.random() * 2732;
- // Create twinkling animation
- var duration = Math.random() * 3000 + 2000;
- // Create closure to keep reference to the current star
- (function (starElement) {
- function animateStar() {
- tween(starElement, {
- alpha: Math.random() * 0.5 + 0.1
- }, {
- duration: duration,
- easing: tween.sinceInOut,
- onFinish: function onFinish() {
- tween(starElement, {
- alpha: Math.random() * 0.7 + 0.3
- }, {
- duration: duration,
- easing: tween.sinceInOut,
- onFinish: animateStar
- });
- }
- });
- }
- animateStar();
- })(star);
- starfield.addChild(star);
- }
- game.addChildAt(starfield, 0); // Add at the bottom layer
- return starfield;
-}
-// Create starfield
-var starfield = createStarfield();
+// (Removed custom background, branding, and starfield per LK guidelines)
// Create game elements
var playerPaddle = new Paddle();
var aiPaddle = new Paddle();
var gravityField = new GravityField();
Eminem's evil face. In-Game asset. 2d. High contrast. No shadows
a hover board with colorful blue and red flames underneath. In-Game asset. 2d. High contrast. No shadows
snowball with effect. In-Game asset. 2d. High contrast. No shadows
tangled. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat