User prompt
Make it so at the top there is another ai player that always follows the y pos of the ball and hits it like the player
User prompt
Make it have modes like easy medium and hard
User prompt
Make the paddle rotate to the left and right a little based on the direction the player is moving it
User prompt
Move the best score counter up 130 pixels
User prompt
Move the high score counter down 200 pixels
User prompt
Please fix the bug: 'TypeError: tween.to is not a function. (In 'tween.to(msg, { alpha: 0 }, 1200)', 'tween.to' is undefined)' in or related to this line: 'tween.to(msg, {' Line Number: 233 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'storage.getItem is not a function. (In 'storage.getItem('bestScore')', 'storage.getItem' is undefined)' in or related to this line: 'var bestScore = storage.getItem('bestScore') || 0;' Line Number: 114 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'storage.get is not a function. (In 'storage.get('bestScore')', 'storage.get' is undefined)' in or related to this line: 'var bestScore = storage.get('bestScore') || 0;' Line Number: 114
User prompt
Make it more competitive
User prompt
Remove leaderboard
User prompt
Please fix the bug: 'LK.showLeaderBoard is not a function. (In 'LK.showLeaderBoard({ onClose: function onClose() { // Game will start after leaderboard is closed } })', 'LK.showLeaderBoard' is undefined)' in or related to this line: 'LK.showLeaderBoard({' Line Number: 230
User prompt
Please fix the bug: 'LK.showLeaderboard is not a function. (In 'LK.showLeaderboard({ onClose: function onClose() { // Game will start after leaderboard is closed } })', 'LK.showLeaderboard' is undefined)' in or related to this line: 'LK.showLeaderboard({' Line Number: 230
User prompt
Make it more competitive by adding a menu that shows people’s scores and the player will try to beat them
User prompt
Make it so every point the ball gets faster
User prompt
Make obstacles that the ball can hit
User prompt
Make the ball more slow moving
Code edit (1 edits merged)
Please save this source code
User prompt
Retro Paddle Pong
Initial prompt
Make a retro styled pong game where you have to move a platform to keep the ball going
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // Ball class var Ball = Container.expand(function () { var self = Container.call(this); var ballAsset = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5 }); self.radius = ballAsset.width / 2; // Ball velocity self.vx = 0; self.vy = 0; // Ball speed (pixels per frame) self.speed = 9; // Ball update self.update = function () { self.x += self.vx; self.y += self.vy; }; return self; }); // Paddle class var Paddle = Container.expand(function () { var self = Container.call(this); var paddleAsset = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); // Paddle width/height for collision self.width = paddleAsset.width; self.height = paddleAsset.height; return self; }); // Wall class (for left, right, and top) var Wall = Container.expand(function () { var self = Container.call(this); var wallAsset = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); self.width = wallAsset.width; self.height = wallAsset.height; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Game area // Paddle: wide, short rectangle // Ball: circle // Wall: thin, tall rectangle (for left/right/top walls) var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; // Paddle setup var paddle = new Paddle(); game.addChild(paddle); paddle.x = GAME_WIDTH / 2; paddle.y = GAME_HEIGHT - 180; // AI Paddle setup (top) var aiPaddle = new Paddle(); game.addChild(aiPaddle); aiPaddle.x = GAME_WIDTH / 2; aiPaddle.y = wallThickness + aiPaddle.height / 2 + 60; // 60px below top wall // Ball setup var ball = new Ball(); game.addChild(ball); // Start ball above player paddle ball.x = GAME_WIDTH / 2; ball.y = paddle.y - paddle.height / 2 - ball.radius - 10; // Ball initial direction: randomize left/right var angle = Math.PI / 4 + (Math.random() < 0.5 ? -1 : 1) * Math.PI / 8; ball.vx = Math.cos(angle) * ball.speed; ball.vy = -Math.abs(Math.sin(angle) * ball.speed); // Walls (left, right, top) var wallThickness = 40; var wallLength = GAME_HEIGHT + 200; // cover full height var leftWall = new Wall(); leftWall.x = wallThickness / 2; leftWall.y = GAME_HEIGHT / 2; leftWall.height = wallLength; game.addChild(leftWall); var rightWall = new Wall(); rightWall.x = GAME_WIDTH - wallThickness / 2; rightWall.y = GAME_HEIGHT / 2; rightWall.height = wallLength; game.addChild(rightWall); var topWall = new Wall(); topWall.width = GAME_WIDTH; topWall.height = wallThickness; topWall.x = GAME_WIDTH / 2; topWall.y = wallThickness / 2; game.addChild(topWall); // Score var score = 0; // Retrieve best score from storage (if any) var bestScore = storage.bestScore || 0; // Score text var scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Best score text (smaller, above score) var bestScoreTxt = new Text2('Best: ' + bestScore, { size: 60, fill: 0xFFD700 }); bestScoreTxt.anchor.set(0.5, 0); bestScoreTxt.y = 160; // moved up by 130 pixels LK.gui.top.addChild(bestScoreTxt); // Dragging paddle var dragging = false; var dragOffsetX = 0; // Prevent paddle from going off screen function clampPaddleX(x) { var halfWidth = paddle.width / 2; if (x < wallThickness + halfWidth) return wallThickness + halfWidth; if (x > GAME_WIDTH - wallThickness - halfWidth) return GAME_WIDTH - wallThickness - halfWidth; return x; } // Touch/mouse events for paddle control game.down = function (x, y, obj) { // Only start drag if touch is near paddle var dx = x - paddle.x; var dy = y - paddle.y; if (Math.abs(dx) <= paddle.width / 2 + 60 && Math.abs(dy) <= paddle.height / 2 + 80) { dragging = true; dragOffsetX = paddle.x - x; // Move paddle immediately paddle.x = clampPaddleX(x + dragOffsetX); } }; game.move = function (x, y, obj) { if (dragging) { var prevX = paddle.x; var newX = clampPaddleX(x + dragOffsetX); paddle.x = newX; // Calculate movement direction and speed var dx = newX - prevX; // Clamp rotation to max ±0.28 radians (~16deg) var maxRot = 0.28; // Scale: full paddle width in one frame = maxRot, otherwise proportional var rot = Math.max(-maxRot, Math.min(maxRot, dx / 40)); paddle.rotation = rot; } else { // Smoothly return to 0 rotation when not dragging if (Math.abs(paddle.rotation) > 0.01) { paddle.rotation *= 0.7; } else { paddle.rotation = 0; } } }; game.up = function (x, y, obj) { dragging = false; paddle.rotation = 0; }; // Ball speed increase timer var speedupInterval = 2000; // ms var speedupAmount = 0.75; // pixels/frame var maxSpeed = 24; var speedupTimer = LK.setInterval(function () { if (ball.speed < maxSpeed) { ball.speed += speedupAmount; // Normalize direction var mag = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy); ball.vx = ball.vx / mag * ball.speed; ball.vy = ball.vy / mag * ball.speed; } }, speedupInterval); // Main game update game.update = function () { // Ball movement ball.update(); // Ball collision with left/right walls if (ball.x - ball.radius <= wallThickness) { ball.x = wallThickness + ball.radius; ball.vx = Math.abs(ball.vx); } if (ball.x + ball.radius >= GAME_WIDTH - wallThickness) { ball.x = GAME_WIDTH - wallThickness - ball.radius; ball.vx = -Math.abs(ball.vx); } // Ball collision with top wall if (ball.y - ball.radius <= wallThickness) { ball.y = wallThickness + ball.radius; ball.vy = Math.abs(ball.vy); } // Ball collision with paddle // Simple AABB check var paddleTop = paddle.y - paddle.height / 2; var paddleBottom = paddle.y + paddle.height / 2; var paddleLeft = paddle.x - paddle.width / 2; var paddleRight = paddle.x + paddle.width / 2; var ballBottom = ball.y + ball.radius; var ballTop = ball.y - ball.radius; var ballLeft = ball.x - ball.radius; var ballRight = ball.x + ball.radius; // AI Paddle follows ball.x (with some speed limit for realism) var aiSpeed = 32; // max px per frame var aiTargetX = ball.x; var aiHalfWidth = aiPaddle.width / 2; var aiMinX = wallThickness + aiHalfWidth; var aiMaxX = GAME_WIDTH - wallThickness - aiHalfWidth; var aiDelta = aiTargetX - aiPaddle.x; if (Math.abs(aiDelta) > aiSpeed) { aiDelta = aiSpeed * (aiDelta > 0 ? 1 : -1); } aiPaddle.x = Math.max(aiMinX, Math.min(aiMaxX, aiPaddle.x + aiDelta)); // Ball collision with AI paddle (top) var aiPaddleTop = aiPaddle.y - aiPaddle.height / 2; var aiPaddleBottom = aiPaddle.y + aiPaddle.height / 2; var aiPaddleLeft = aiPaddle.x - aiPaddle.width / 2; var aiPaddleRight = aiPaddle.x + aiPaddle.width / 2; // Only check if ball is moving up if (ball.vy < 0 && ballTop <= aiPaddleBottom && ballBottom >= aiPaddleTop && ballRight >= aiPaddleLeft && ballLeft <= aiPaddleRight) { // Bounce ball down ball.y = aiPaddleBottom + ball.radius; // Calculate bounce angle based on where it hit the AI paddle var aiHitPos = (ball.x - aiPaddle.x) / (aiPaddle.width / 2); // -1 (left) to 1 (right) var aiBounceAngle = aiHitPos * (Math.PI / 3); // up to 60deg left/right var aiSpeedVal = ball.speed; ball.vx = Math.sin(aiBounceAngle) * aiSpeedVal; ball.vy = Math.abs(Math.cos(aiBounceAngle) * aiSpeedVal); } // Only check if ball is moving down if (ball.vy > 0 && ballBottom >= paddleTop && ballTop <= paddleBottom && ballRight >= paddleLeft && ballLeft <= paddleRight) { // Bounce ball up ball.y = paddleTop - ball.radius; // Calculate bounce angle based on where it hit the paddle var hitPos = (ball.x - paddle.x) / (paddle.width / 2); // -1 (left) to 1 (right) var bounceAngle = hitPos * (Math.PI / 3); // up to 60deg left/right var speed = ball.speed; ball.vx = Math.sin(bounceAngle) * speed; ball.vy = -Math.abs(Math.cos(bounceAngle) * speed); // Score up score += 1; scoreTxt.setText(score); // Check for new best score if (score > bestScore) { bestScore = score; storage.bestScore = bestScore; bestScoreTxt.setText('Best: ' + bestScore); // Show a quick message for new best if (score === bestScore) { var msg = new Text2('New Best!', { size: 100, fill: 0x00FF00 }); msg.anchor.set(0.5, 0.5); msg.x = GAME_WIDTH / 2; msg.y = GAME_HEIGHT / 2; game.addChild(msg); tween(msg, { alpha: 0 }, { duration: 1200, onFinish: function onFinish() { msg.destroy(); } }); } } // Increase ball speed every point, up to maxSpeed if (ball.speed < maxSpeed) { ball.speed += 0.5; // Normalize direction var mag = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy); ball.vx = ball.vx / mag * ball.speed; ball.vy = ball.vy / mag * ball.speed; } } // Ball falls below paddle (game over) if (ball.y - ball.radius > GAME_HEIGHT) { LK.effects.flashScreen(0xff0000, 800); LK.clearInterval(speedupTimer); // Show game over after ball falls below paddle LK.effects.flashScreen(0xff0000, 800); LK.clearInterval(speedupTimer); LK.showGameOver(); return; } }; // Game will start immediately
===================================================================
--- original.js
+++ change.js
@@ -60,97 +60,34 @@
/****
* Game Code
****/
-// Wall: thin, tall rectangle (for left/right/top walls)
-// Ball: circle
-// Paddle: wide, short rectangle
// Game area
+// Paddle: wide, short rectangle
+// Ball: circle
+// Wall: thin, tall rectangle (for left/right/top walls)
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
-// --- Mode selection ---
-var MODES = [{
- name: "Easy",
- ballSpeed: 7,
- paddleWidth: 600
-}, {
- name: "Medium",
- ballSpeed: 10,
- paddleWidth: 400
-}, {
- name: "Hard",
- ballSpeed: 14,
- paddleWidth: 260
-}];
-var selectedMode = 1; // Default to Medium
-// Mode selection UI
-var modeBtns = [];
-var modeBtnY = GAME_HEIGHT / 2 - 200;
-for (var i = 0; i < MODES.length; i++) {
- var btn = new Text2(MODES[i].name, {
- size: 120,
- fill: i === selectedMode ? 0x00FF00 : 0xFFFFFF
- });
- btn.anchor.set(0.5, 0.5);
- btn.x = GAME_WIDTH / 2;
- btn.y = modeBtnY + i * 180;
- btn.modeIndex = i;
- LK.gui.center.addChild(btn);
- modeBtns.push(btn);
-}
-// Block game start until mode is picked
-var modeSelected = false;
-function selectMode(idx) {
- selectedMode = idx;
- for (var j = 0; j < modeBtns.length; j++) {
- modeBtns[j].style.fill = j === idx ? 0x00FF00 : 0xFFFFFF;
- modeBtns[j].setText(MODES[j].name);
- }
- // Remove buttons after short delay
- LK.setTimeout(function () {
- for (var k = 0; k < modeBtns.length; k++) {
- modeBtns[k].destroy();
- }
- modeSelected = true;
- startGame();
- }, 250);
-}
-// Listen for tap on mode buttons
-LK.gui.center.down = function (x, y, obj) {
- for (var i = 0; i < modeBtns.length; i++) {
- var btn = modeBtns[i];
- // Simple bounding box check
- var bx = btn.x,
- by = btn.y;
- var bw = btn.width,
- bh = btn.height;
- if (x >= bx - bw / 2 && x <= bx + bw / 2 && y >= by - bh / 2 && y <= by + bh / 2) {
- selectMode(btn.modeIndex);
- break;
- }
- }
-};
-// --- Game start logic, only after mode is picked ---
-function startGame() {
- // Paddle setup
- paddle = new Paddle();
- paddle.width = MODES[selectedMode].paddleWidth;
- paddle.scale.x = paddle.width / 400; // default asset width is 400
- game.addChild(paddle);
- paddle.x = GAME_WIDTH / 2;
- paddle.y = GAME_HEIGHT - 180;
- // Ball setup
- ball = new Ball();
- ball.speed = MODES[selectedMode].ballSpeed;
- game.addChild(ball);
- // Start ball above paddle
- ball.x = GAME_WIDTH / 2;
- ball.y = paddle.y - paddle.height / 2 - ball.radius - 10;
- // Ball initial direction: randomize left/right
- var angle = Math.PI / 4 + (Math.random() < 0.5 ? -1 : 1) * Math.PI / 8;
- ball.vx = Math.cos(angle) * ball.speed;
- ball.vy = -Math.abs(Math.sin(angle) * ball.speed);
-}
+// Paddle setup
+var paddle = new Paddle();
+game.addChild(paddle);
+paddle.x = GAME_WIDTH / 2;
+paddle.y = GAME_HEIGHT - 180;
+// AI Paddle setup (top)
+var aiPaddle = new Paddle();
+game.addChild(aiPaddle);
+aiPaddle.x = GAME_WIDTH / 2;
+aiPaddle.y = wallThickness + aiPaddle.height / 2 + 60; // 60px below top wall
+// Ball setup
+var ball = new Ball();
+game.addChild(ball);
+// Start ball above player paddle
+ball.x = GAME_WIDTH / 2;
+ball.y = paddle.y - paddle.height / 2 - ball.radius - 10;
+// Ball initial direction: randomize left/right
+var angle = Math.PI / 4 + (Math.random() < 0.5 ? -1 : 1) * Math.PI / 8;
+ball.vx = Math.cos(angle) * ball.speed;
+ball.vy = -Math.abs(Math.sin(angle) * ball.speed);
// Walls (left, right, top)
var wallThickness = 40;
var wallLength = GAME_HEIGHT + 200; // cover full height
var leftWall = new Wall();
@@ -199,9 +136,8 @@
return x;
}
// Touch/mouse events for paddle control
game.down = function (x, y, obj) {
- if (!modeSelected) return;
// Only start drag if touch is near paddle
var dx = x - paddle.x;
var dy = y - paddle.y;
if (Math.abs(dx) <= paddle.width / 2 + 60 && Math.abs(dy) <= paddle.height / 2 + 80) {
@@ -211,9 +147,8 @@
paddle.x = clampPaddleX(x + dragOffsetX);
}
};
game.move = function (x, y, obj) {
- if (!modeSelected) return;
if (dragging) {
var prevX = paddle.x;
var newX = clampPaddleX(x + dragOffsetX);
paddle.x = newX;
@@ -233,18 +168,16 @@
}
}
};
game.up = function (x, y, obj) {
- if (!modeSelected) return;
dragging = false;
paddle.rotation = 0;
};
// Ball speed increase timer
var speedupInterval = 2000; // ms
var speedupAmount = 0.75; // pixels/frame
var maxSpeed = 24;
var speedupTimer = LK.setInterval(function () {
- if (!modeSelected) return;
if (ball.speed < maxSpeed) {
ball.speed += speedupAmount;
// Normalize direction
var mag = Math.sqrt(ball.vx * ball.vx + ball.vy * ball.vy);
@@ -253,9 +186,8 @@
}
}, speedupInterval);
// Main game update
game.update = function () {
- if (!modeSelected) return;
// Ball movement
ball.update();
// Ball collision with left/right walls
if (ball.x - ball.radius <= wallThickness) {
@@ -280,8 +212,35 @@
var ballBottom = ball.y + ball.radius;
var ballTop = ball.y - ball.radius;
var ballLeft = ball.x - ball.radius;
var ballRight = ball.x + ball.radius;
+ // AI Paddle follows ball.x (with some speed limit for realism)
+ var aiSpeed = 32; // max px per frame
+ var aiTargetX = ball.x;
+ var aiHalfWidth = aiPaddle.width / 2;
+ var aiMinX = wallThickness + aiHalfWidth;
+ var aiMaxX = GAME_WIDTH - wallThickness - aiHalfWidth;
+ var aiDelta = aiTargetX - aiPaddle.x;
+ if (Math.abs(aiDelta) > aiSpeed) {
+ aiDelta = aiSpeed * (aiDelta > 0 ? 1 : -1);
+ }
+ aiPaddle.x = Math.max(aiMinX, Math.min(aiMaxX, aiPaddle.x + aiDelta));
+ // Ball collision with AI paddle (top)
+ var aiPaddleTop = aiPaddle.y - aiPaddle.height / 2;
+ var aiPaddleBottom = aiPaddle.y + aiPaddle.height / 2;
+ var aiPaddleLeft = aiPaddle.x - aiPaddle.width / 2;
+ var aiPaddleRight = aiPaddle.x + aiPaddle.width / 2;
+ // Only check if ball is moving up
+ if (ball.vy < 0 && ballTop <= aiPaddleBottom && ballBottom >= aiPaddleTop && ballRight >= aiPaddleLeft && ballLeft <= aiPaddleRight) {
+ // Bounce ball down
+ ball.y = aiPaddleBottom + ball.radius;
+ // Calculate bounce angle based on where it hit the AI paddle
+ var aiHitPos = (ball.x - aiPaddle.x) / (aiPaddle.width / 2); // -1 (left) to 1 (right)
+ var aiBounceAngle = aiHitPos * (Math.PI / 3); // up to 60deg left/right
+ var aiSpeedVal = ball.speed;
+ ball.vx = Math.sin(aiBounceAngle) * aiSpeedVal;
+ ball.vy = Math.abs(Math.cos(aiBounceAngle) * aiSpeedVal);
+ }
// Only check if ball is moving down
if (ball.vy > 0 && ballBottom >= paddleTop && ballTop <= paddleBottom && ballRight >= paddleLeft && ballLeft <= paddleRight) {
// Bounce ball up
ball.y = paddleTop - ball.radius;