User prompt
Please fix the bug: 'TypeError: tween.isTweening is not a function' in or related to this line: 'if (trail && !tween.isTweening(trail) && trail.alpha <= 0) {' Line Number: 441 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'TypeError: tween.isTweening is not a function' in or related to this line: 'if (trail && !tween.isTweening(trail) && trail.alpha <= 0) {' Line Number: 441 ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (4 edits merged)
Please save this source code
User prompt
yazı nerde oyun başlamadan önce ekranda görenmedik istersen rengi değiştir
User prompt
oyun başlama ekranın da Pongi yazsın arka plan saydam gir olsun ve tam olarak ortada olsun ve yazı ve arka plan uyumu çok önemli
Code edit (1 edits merged)
Please save this source code
Initial prompt
Pongi 3D
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Assuming tween is used in the 3D classes /***********************************************************************************/ /********************************** CUBE CLASS ************************************/ /***********************************************************************************/ var Cube = Container.expand(function (wRatio, hRatio, dRatio) { var self = Container.call(this); wRatio = wRatio || 1; hRatio = hRatio || 1; dRatio = dRatio || 1; self.z = 0; self.baseSize = 100; // Initialize cube faces using SimpleFace class self.frontFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: 0, dy: 0, dz: 1 * dRatio, rx: 0, ry: 0, rz: 0, ti: 0xFFFFFF }); self.backFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: 0, dy: 0, dz: -1 * dRatio, rx: Math.PI, ry: 0, rz: 0, ti: 0xFFFFFF }); self.leftFace = new SimpleFace({ w: self.baseSize * dRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: -1 * wRatio / dRatio, dy: 0, dz: 0, rx: 0, ry: Math.PI / 2, rz: 0, ti: 0xFFFFFF }); self.rightFace = new SimpleFace({ w: self.baseSize * dRatio, h: self.baseSize * hRatio, d: self.baseSize, dx: 1 * wRatio / dRatio, dy: 0, dz: 0, rx: 0, ry: -Math.PI * 0.5, rz: 0, ti: 0xFFFFFF }); self.topFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * dRatio, d: self.baseSize, dx: 0, dy: -1 * hRatio / dRatio, dz: 0, rx: -Math.PI / 2, ry: 0, rz: 0, ti: 0xFFFFFF }); self.bottomFace = new SimpleFace({ w: self.baseSize * wRatio, h: self.baseSize * dRatio, d: self.baseSize, dx: 0, dy: 1 * hRatio / dRatio, dz: 0, rx: Math.PI / 2, ry: 0, rz: 0, ti: 0xFFFFFF }); self.faces = [self.frontFace, self.backFace, self.leftFace, self.rightFace, self.topFace, self.bottomFace]; self.faces.forEach(function (face) { self.addChild(face); }); self.speedX = 5; self.speedY = 5; self.speedZ = 5; // Rotate cube around its axes self.rotate3D = function (angleX, angleY, angleZ) { log("cube rotate3D "); self.rotation = angleZ; var zScaleFactor = 1 + self.z / 500; self.faces.forEach(function (face) { face.rotate3D(angleX, angleY, angleZ, zScaleFactor); }); }; }); /***********************************************************************************/ /******************************* FACE CLASS *********************************/ /***********************************************************************************/ var Face = Container.expand(function (options) { var self = Container.call(this); options = options || {}; var points = Math.max(2, Math.min(100, options.points || 4)); // Ensure points are between 2 and 10 self.baseSize = 100; self.w = options.w || self.baseSize; self.h = options.h || self.baseSize; self.d = options.d || self.baseSize; self.dx = options.dx || 0; self.dy = options.dy || 0; self.dz = options.dz || 0; self.rx = options.rx || 0; self.ry = options.ry || 0; self.rz = options.rz || 0; self.tint = options.ti || 0xFFFFFF; // Generate points for the face based on the number of points specified self.baseFaceCoordinates = []; for (var i = 0; i < points; i++) { var angle = 2 * Math.PI * (i / points); self.baseFaceCoordinates.push({ x: self.w / 2 * Math.cos(angle) + self.dx * self.w, y: self.h / 2 * Math.sin(angle) + self.dy * self.h, z: self.dz * self.d }); } self.baseFaceCoordinates.forEach(function (point) { // Update z of each face point coordinates depending on dz and rx, ry point.z += self.dz * Math.cos(self.rx) * Math.cos(self.ry); }); // Create a polygon face using the Shape class self.face = new Shape(self.baseFaceCoordinates, self.tint); // Attach the face to the Face container self.addChild(self.face); // Rotate in 3D: X = roasting chicken / Y = whirling dervish / Z = wheel of Fortune self.rotate3D = function (angleX, angleY, angleZ, scale) { scale = scale || 1; self.faceCoordinates = self.baseFaceCoordinates.map(function (coord) { var x = coord.x - self.dx * self.w, y = coord.y - self.dy * self.h, z = coord.z - self.dz * self.d; // Apply initial rotations (rx, ry, rz) var newY = y * Math.cos(self.rx) - z * Math.sin(self.rx); var newZ = y * Math.sin(self.rx) + z * Math.cos(self.rx); var newX = x * Math.cos(self.ry) + newZ * Math.sin(self.ry); newZ = -x * Math.sin(self.ry) + newZ * Math.cos(self.ry); x = newX * Math.cos(self.rz) - newY * Math.sin(self.rz); y = newX * Math.sin(self.rz) + newY * Math.cos(self.rz); // Apply X-axis rotation newY = y * Math.cos(angleX) - newZ * Math.sin(angleX); newZ = y * Math.sin(angleX) + newZ * Math.cos(angleX); // Apply Y-axis rotation newX = x * Math.cos(angleY) + newZ * Math.sin(angleY); newZ = -x * Math.sin(angleY) + newZ * Math.cos(angleY); // Apply Z-axis rotation x = newX * Math.cos(angleZ) - newY * Math.sin(angleZ); y = newX * Math.sin(angleZ) + newY * Math.cos(angleZ); return { x: (x + self.dx * self.w) * scale, y: (y + self.dy * self.h) * scale, z: (newZ + self.dz * self.d) * scale }; }); self.face.updateCoordinates(self.faceCoordinates); }; // Initialize face in 3D space self.rotate3D(0, 0, 0, 1); }); // Paddle class for player control (Keeping original Paddle class) var Paddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.update = function () { // Paddle movement logic will be handled in game code }; }); /***********************************************************************************/ /********************************** SHAPE CLASS ************************************/ /***********************************************************************************/ var Shape = Container.expand(function (coordinates, tint) { var self = Container.call(this); self.polygon = drawPolygon(coordinates, tint); // Function to create a polygon from a list of coordinates self.tint = tint; self.attachLines = function () { // Iterate through each line in the polygon and attach it to the shape self.polygon.forEach(function (line) { self.addChild(line); }); }; self.attachLines(); self.updateCoordinates = function (newCoordinates) { log("Shape updateCoordinates ", newCoordinates); // Ensure newCoordinates is an array and has the same length as the current polygon if (!Array.isArray(newCoordinates) || newCoordinates.length !== self.polygon.length) { error("Invalid newCoordinates length"); return; } // Update each line in the polygon with new coordinates self.polygon = updatePolygon(self.polygon, newCoordinates); }; }); /***********************************************************************************/ /******************************* SIMPLE FACE CLASS *********************************/ /***********************************************************************************/ var SimpleFace = Container.expand(function (options) { var self = Container.call(this); log("SimpleFAce init options =", options); self.baseSize = 100; options = options || {}; self.w = options.w || self.baseSize; self.h = options.h || self.baseSize; self.d = options.d || self.baseSize; self.dx = options.dx || 0; self.dy = options.dy || 0; self.dz = options.dz || 0; self.rx = options.rx || 0; self.ry = options.ry || 0; self.rz = options.rz || 0; self.tint = options.ti || 0xFFFFFF; // Define faceCoordinates property self.baseFaceCoordinates = [{ x: -self.w + self.dx * self.w, y: -self.h + self.dy * self.h, z: self.dz * self.d }, // Top-left { x: self.w + self.dx * self.w, y: -self.h + self.dy * self.h, z: self.dz * self.d }, // Top-right { x: self.w + self.dx * self.w, y: self.h + self.dy * self.h, z: self.dz * self.d }, // Bottom-right { x: -self.w + self.dx * self.w, y: self.h + self.dy * self.h, z: self.dz * self.d } // Bottom-left ]; log("SimpleFAce ready to init ...", self.baseFaceCoordinates, "DX=" + self.dx); self.baseFaceCoordinates.forEach(function (point) { // Update z of each face point coordinates depending on dz and rx, ry point.z += self.dz * Math.cos(self.rx) * Math.cos(self.ry); }); // Create a square face using the Shape class self.face = new Shape(self.baseFaceCoordinates, self.tint); // Attach the face to the SimpleFace container self.addChild(self.face); // Rotate in 3d : X = roasting chicken / Y = whirling dervish / Z = wheel of Fortune self.rotate3D = function (angleX, angleY, angleZ, scale) { scale = scale || 1; log("SimpleFace rotate3D old coord=", self.faceCoordinates, Date.now()); self.faceCoordinates = self.baseFaceCoordinates.map(function (coord) { return { x: coord.x, y: coord.y, z: coord.z }; }); // Apply rotation around X-axis // Adjust initial rotation parameters before applying new rotations self.faceCoordinates = self.faceCoordinates.map(function (coord) { // Apply initial rotation around Z-axis var xZ = coord.x * Math.cos(self.rz) - coord.y * Math.sin(self.rz); var yZ = coord.x * Math.sin(self.rz) + coord.y * Math.cos(self.rz); // Apply initial rotation around Y-axis var xY = xZ * Math.cos(self.ry) + coord.z * Math.sin(self.ry); var zY = coord.z * Math.cos(self.ry) - xZ * Math.sin(self.ry); // Apply initial rotation around X-axis var yX = yZ * Math.cos(self.rx) - zY * Math.sin(self.rx); var zX = yZ * Math.sin(self.rx) + zY * Math.cos(self.rx); return { x: xY, y: yX, z: zX }; }); // Apply new rotations // Calculate center of the face var centerX = self.faceCoordinates.reduce(function (acc, coord) { return acc + coord.x; }, 0) / self.faceCoordinates.length; var centerY = self.faceCoordinates.reduce(function (acc, coord) { return acc + coord.y; }, 0) / self.faceCoordinates.length; var centerZ = self.faceCoordinates.reduce(function (acc, coord) { return acc + coord.z; }, 0) / self.faceCoordinates.length; self.faceCoordinates = self.faceCoordinates.map(function (coord) { // Translate coordinates to rotate around the center including dy and dz adjustment var translatedY = (coord.y + self.dy * self.h - centerY) * Math.cos(angleX) - (coord.z + self.dz * self.d - centerZ) * Math.sin(angleX); var translatedZ = (coord.y + self.dy * self.h - centerZ) * Math.sin(angleX) + (coord.z + self.dz * self.d - centerZ) * Math.cos(angleX); return { x: coord.x + self.dx * self.w - centerX, // Keep X unchanged but translate to rotate around center y: translatedY + centerY, z: translatedZ + centerZ }; }); self.faceCoordinates = self.faceCoordinates.map(function (coord) { var translatedX = (coord.z - centerZ) * Math.sin(angleY) + (coord.x - centerX) * Math.cos(angleY); var translatedZ = (coord.z - centerZ) * Math.cos(angleY) - (coord.x - centerX) * Math.sin(angleY); return { x: translatedX + centerX, y: coord.y, // Keep Y unchanged z: translatedZ + centerZ }; }); self.faceCoordinates = self.faceCoordinates.map(function (coord) { return { x: coord.x * scale, y: coord.y * scale, z: coord.z * scale }; }); log("SimpleFace rotate3D new coord=", self.faceCoordinates, Date.now()); self.face.updateCoordinates(self.faceCoordinates); }; // initialize face in 3D space self.rotate3D(0, 0, 0, 1); log("SimpleFace end init coord=", self.baseFaceCoordinates, Date.now()); }); /***********************************************************************************/ /********************************** SPHERE CLASS ***********************************/ /***********************************************************************************/ var Sphere = Container.expand(function () { var self = Container.call(this); self.z = 0; self.radius = 50; // Reduced sphere radius to fit better as pong ball // Initialize sphere as a collection of Face instances to simulate a 3D sphere self.faces = []; var segments = 5; // Number of segments to simulate the sphere for (var i = 0; i < segments; i++) { var angle = 2 * Math.PI / segments; // Create a circular segment as a face of the sphere var face = new Face({ points: 33, w: self.radius * 2, h: self.radius * 2, d: self.radius * 2, dx: 0, dy: 0, dz: 0, rx: 0, ry: i * angle, rz: 0, ti: 0xFFFFFF // Tint color }); self.faces.push(face); self.addChild(face); } self.speedX = 5; self.speedY = 5; self.speedZ = 5; // Rotate sphere around its axes self.rotate3D = function (angleX, angleY, angleZ) { log("sphere rotate3D ", angleX, angleY, angleZ); self.rotation = angleZ; var zScaleFactor = 1 + self.z / 500; for (var i = 0; i < self.faces.length; i++) { self.faces[i].rotate3D(angleX, angleY, angleZ, zScaleFactor); } }; self.update = function () { // Basic update for movement, no 3D rotation in pong game loop if (gameStarted) { self.x += self.speedX; self.y += self.speedY; // Ensure ball speed is consistent to prevent shaking if (Math.abs(self.speedX) < 1) { self.speedX = self.speedX < 0 ? -1 : 1; } if (Math.abs(self.speedY) < 1) { self.speedY = self.speedY < 0 ? -1 : 1; } } }; self.rotate3D(0, 0, 0); // Initial rotation }); /**** * Initialize Game ****/ // Utility function to draw a polygon using drawLine (Keep utility functions) var game = new LK.Game({ backgroundColor: 0x000000 // Initialize game with a black background }); /**** * Game Code ****/ // Added line asset // Added debugMarker asset /***********************************************************************************/ /******************************* UTILITY FUNCTIONS *********************************/ /***********************************************************************************/ function drawPolygon(coordinates, tint) { log("drawPolygon ", coordinates); var lines = []; for (var i = 0; i < coordinates.length; i++) { var startPoint = coordinates[i]; var endPoint = coordinates[(i + 1) % coordinates.length]; // Loop back to the first point var line = drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, tint); lines.push(line); } return lines; } function updatePolygon(lines, newCoordinates, scale) { log("updatePolygon ", lines, scale); // Ensure lines and newCoordinates have the same length if (lines.length !== newCoordinates.length) { error("updatePolygon error: lines and newCoordinates length mismatch"); return lines; } // Update each line with new coordinates for (var i = 0; i < lines.length; i++) { var startPoint = newCoordinates[i]; var endPoint = newCoordinates[(i + 1) % newCoordinates.length]; // Loop back to the first point for the last line updateLine(lines[i], startPoint.x, startPoint.y, endPoint.x, endPoint.y, scale); } return lines; } // Utility function to draw lines between two points function drawLine(x1, y1, x2, y2, tint) { log("drawLine ", x1, y1); var line = LK.getAsset('line', { anchorX: 0.0, anchorY: 0.0, x: x1, y: y1, tint: tint }); line.startX = x1; line.startY = y1; line.endX = x2; line.endY = y2; // Calculate the distance between the two points var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); // Set the width of the line to the distance between the points line.width = distance; // Calculate the angle between the two points var angle = Math.atan2(y2 - y1, x2 - x1); // Correct angle calculation for all quadrants line.rotation = angle; return line; } // Utility function to draw lines between two points function updateLine(line, newX1, newY1, newX2, newY2, scale) { log("updateLine ", line); scale = scale === undefined ? 1 : scale; // Calculate midpoint of the original line var midX = (newX1 + newX2) / 2; var midY = (newY1 + newY2) / 2; // Adjust start and end points based on scale newX1 = midX + (newX1 - midX) * scale; newY1 = midY + (newY1 - midY) * scale; newX2 = midX + (newX2 - midX) * scale; newY2 = midY + (newY2 - midY) * scale; // Update line start and end coordinates after scaling line.x = newX1; line.y = newY1; line.startX = newX1; line.startY = newY1; line.endX = newX2; line.endY = newY2; // Recalculate the distance between the new scaled points var distance = Math.sqrt(Math.pow(newX2 - newX1, 2) + Math.pow(newY2 - newY1, 2)); // Update the width of the line to the new distance line.width = distance; // Recalculate the angle between the new points var angle = Math.atan2(newY2 - newY1, newX2 - newX1); // Update the rotation of the line to the new angle line.rotation = angle; return line; } function log() { var isDebug = false; // Set isDebug to false for production, true for debugging logs if (isDebug) { console.log(arguments); } } function error() { // Error logging function var isDebug = true; // Error logs are always shown during debug if (isDebug) { console.error(arguments); } } /***********************************************************************************/ /******************************* GAME VARIABLES*********************************/ /***********************************************************************************/ var centerLine; // Keep centerLine var leftPaddle; // Keep leftPaddle var rightPaddle; // Keep rightPaddle var ball; // Will be Sphere class now var leftScore = 0; // Keep leftScore var rightScore = 0; // Keep rightScore var leftScoreTxt; // Keep leftScoreTxt var rightScoreTxt; // Keep rightScoreTxt var gameStarted = false; // Keep gameStarted /***********************************************************************************/ /***************************** GAME INITIALIZATION *********************************/ /***********************************************************************************/ function gameInitialize() { // Create a dashed line in the center of the screen (Keep center line creation) centerLine = new Container(); var lineHeight = 20; var lineSpacing = 20; for (var y = 0; y < 2732; y += lineHeight + lineSpacing) { var lineSegment = LK.getAsset('paddle', { width: 10, height: lineHeight, color: 0xffffff, anchorX: 0.5, anchorY: 0.5 }); lineSegment.x = 2048 / 2; lineSegment.y = y + lineHeight / 2; centerLine.addChild(lineSegment); } game.addChild(centerLine); // Initialize paddles (Keep paddle initialization) leftPaddle = game.addChild(new Paddle()); rightPaddle = game.addChild(new Paddle()); // Initialize ball as Sphere (Replace 2D Ball with 3D Sphere) ball = game.addChild(new Sphere()); // Position paddles and ball (Keep positioning) leftPaddle.x = 100; leftPaddle.y = 2732 / 2; rightPaddle.x = 2048 - 50; rightPaddle.y = 2732 / 2; ball.x = 2048 / 2; ball.y = 2732 / 2; // Score display (Keep score display) leftScoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF, font: "Teko Regular" // Change font style to Teko Regular }); rightScoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF, font: "Teko Regular" // Change font style to Teko Regular }); leftScoreTxt.anchor.set(0.5, 0); leftScoreTxt.x += 600; rightScoreTxt.anchor.set(0.5, 0); rightScoreTxt.x -= 600; // Decrease the x-axis position by 600 LK.gui.topLeft.addChild(leftScoreTxt); LK.gui.topRight.addChild(rightScoreTxt); } // Update score display (Keep updateScore function) function updateScore() { leftScoreTxt.setText(leftScore); rightScoreTxt.setText(rightScore); // Play 'sayac' sound effect LK.getSound('sayac').play(); } // Reset ball to center (Keep resetBall function) function resetBall() { ball.x = 2048 / 2; ball.y = 2732 / 2; ball.speedX = 5 * (Math.random() > 0.5 ? 1 : -1); ball.speedY = 5 * (Math.random() > 0.5 ? 1 : -1); } /***********************************************************************************/ /******************************** MAIN GAME LOOP ***********************************/ /***********************************************************************************/ game.update = function () { if (!gameStarted) { return; } // Do not update if game not started yet ball.update(); // Use Sphere's update function (basic movement) // Ball collision with top and bottom (Keep collision logic) if (ball.y <= 0 && ball.speedY < 0 || ball.y >= 2732 && ball.speedY > 0) { ball.speedY *= -1; // Play 'carp1' sound effect LK.getSound('carp1').play(); } // Ball collision with paddles (Keep paddle collision logic) if (ball.intersects(leftPaddle)) { if (ball.y < leftPaddle.y) { ball.speedY = -Math.abs(ball.speedY); } else { ball.speedY = Math.abs(ball.speedY); } ball.speedX *= -1.05; // Slight acceleration on paddle hit // Ensure ball speed is consistent to prevent shaking if (Math.abs(ball.speedX) < 1) { ball.speedX = ball.speedX < 0 ? -1 : 1; } if (Math.abs(ball.speedY) < 1) { ball.speedY = ball.speedY < 0 ? -1 : 1; } // Play 'carp1' sound effect LK.getSound('carp1').play(); } if (ball.intersects(rightPaddle)) { if (ball.y < rightPaddle.y) { ball.speedY = -Math.abs(ball.speedY); } else { ball.speedY = Math.abs(ball.speedY); } ball.speedX *= -1.05; // Slight acceleration on paddle hit // Ensure ball speed is consistent to prevent shaking if (Math.abs(ball.speedX) < 1) { ball.speedX = ball.speedX < 0 ? -1 : 1; } if (Math.abs(ball.speedY) < 1) { ball.speedY = ball.speedY < 0 ? -1 : 1; } // Play 'carp1' sound effect LK.getSound('carp1').play(); } // Scoring (Keep scoring logic) if (ball.x <= 0) { rightScore++; updateScore(); if (rightScore >= 10) { LK.showGameOver("Right Player Wins!"); } else { resetBall(); } } else if (ball.x >= 2048) { leftScore++; updateScore(); if (leftScore >= 10) { LK.showGameOver("Left Player Wins!"); } else { resetBall(); } } // Automatic movement for right paddle only when the ball is moving towards it (Keep AI Paddle logic) if (ball.speedX > 0) { if (ball.y > rightPaddle.y) { rightPaddle.y += Math.min(rightPaddle.speed * 1.5, Math.abs(ball.y - rightPaddle.y)); } else if (ball.y < rightPaddle.y) { rightPaddle.y -= Math.min(rightPaddle.speed * 1.5, Math.abs(ball.y - rightPaddle.y)); } } }; // Handle paddle movement (Keep paddle movement handler) game.move = function (x, y, obj) { if (x < 2048 / 2) { leftPaddle.y = y; LK.getSound('cubuk1').play(); } }; // Display 'Pongi' text and start game after delay (Keep start text and delay logic) var startTextBackground = LK.getAsset('paddle', { width: 400, height: 200, color: 0x303030, alpha: 0.5, anchorX: 0.5, anchorY: 0.5 }); startTextBackground.scaleX = 1.5; startTextBackground.x = 2048 / 2; // Center horizontally startTextBackground.y = 100; // Position at top LK.gui.center.addChild(startTextBackground); var startText = new Text2('Pongi', { size: 200, fill: 0xFFFFFF, font: "Teko Regular", shadow: { color: 0x808080, blur: 10, offsetX: 5, offsetY: 5 } }); startText.anchor.set(0.5, 0.5); startText.x = 2048 / 2; // Center horizontally startText.y = 100; // Position at top LK.gui.center.addChild(startText); // Play background music continuously (Keep music) LK.playMusic('fon'); gameStarted = false; // Ensure gameStarted is false initially // Initialize Game (Call gameInitialize to setup paddles, ball, etc.) gameInitialize(); // Remove the start text and background, then begin the game after a delay (Keep timeout logic) LK.setTimeout(function () { LK.gui.center.removeChild(startText); LK.gui.center.removeChild(startTextBackground); gameStarted = true; // Set gameStarted to true to enable game update loop // Game update loop will start automatically as gameStarted is now true and game.update is defined }, 3000); // 3 seconds delay
===================================================================
--- original.js
+++ change.js
@@ -1,81 +1,709 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
* Classes
-****/
-// Ball class
-var Ball = Container.expand(function () {
- var self = Container.call(this);
- var ballGraphics = self.attachAsset('ball', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.speedX = 5;
- self.speedY = 5;
- self.update = function () {
- self.x += self.speedX;
- self.y += self.speedY;
- };
+****/
+// Assuming tween is used in the 3D classes
+/***********************************************************************************/
+/********************************** CUBE CLASS ************************************/
+/***********************************************************************************/
+var Cube = Container.expand(function (wRatio, hRatio, dRatio) {
+ var self = Container.call(this);
+ wRatio = wRatio || 1;
+ hRatio = hRatio || 1;
+ dRatio = dRatio || 1;
+ self.z = 0;
+ self.baseSize = 100;
+ // Initialize cube faces using SimpleFace class
+ self.frontFace = new SimpleFace({
+ w: self.baseSize * wRatio,
+ h: self.baseSize * hRatio,
+ d: self.baseSize,
+ dx: 0,
+ dy: 0,
+ dz: 1 * dRatio,
+ rx: 0,
+ ry: 0,
+ rz: 0,
+ ti: 0xFFFFFF
+ });
+ self.backFace = new SimpleFace({
+ w: self.baseSize * wRatio,
+ h: self.baseSize * hRatio,
+ d: self.baseSize,
+ dx: 0,
+ dy: 0,
+ dz: -1 * dRatio,
+ rx: Math.PI,
+ ry: 0,
+ rz: 0,
+ ti: 0xFFFFFF
+ });
+ self.leftFace = new SimpleFace({
+ w: self.baseSize * dRatio,
+ h: self.baseSize * hRatio,
+ d: self.baseSize,
+ dx: -1 * wRatio / dRatio,
+ dy: 0,
+ dz: 0,
+ rx: 0,
+ ry: Math.PI / 2,
+ rz: 0,
+ ti: 0xFFFFFF
+ });
+ self.rightFace = new SimpleFace({
+ w: self.baseSize * dRatio,
+ h: self.baseSize * hRatio,
+ d: self.baseSize,
+ dx: 1 * wRatio / dRatio,
+ dy: 0,
+ dz: 0,
+ rx: 0,
+ ry: -Math.PI * 0.5,
+ rz: 0,
+ ti: 0xFFFFFF
+ });
+ self.topFace = new SimpleFace({
+ w: self.baseSize * wRatio,
+ h: self.baseSize * dRatio,
+ d: self.baseSize,
+ dx: 0,
+ dy: -1 * hRatio / dRatio,
+ dz: 0,
+ rx: -Math.PI / 2,
+ ry: 0,
+ rz: 0,
+ ti: 0xFFFFFF
+ });
+ self.bottomFace = new SimpleFace({
+ w: self.baseSize * wRatio,
+ h: self.baseSize * dRatio,
+ d: self.baseSize,
+ dx: 0,
+ dy: 1 * hRatio / dRatio,
+ dz: 0,
+ rx: Math.PI / 2,
+ ry: 0,
+ rz: 0,
+ ti: 0xFFFFFF
+ });
+ self.faces = [self.frontFace, self.backFace, self.leftFace, self.rightFace, self.topFace, self.bottomFace];
+ self.faces.forEach(function (face) {
+ self.addChild(face);
+ });
+ self.speedX = 5;
+ self.speedY = 5;
+ self.speedZ = 5;
+ // Rotate cube around its axes
+ self.rotate3D = function (angleX, angleY, angleZ) {
+ log("cube rotate3D ");
+ self.rotation = angleZ;
+ var zScaleFactor = 1 + self.z / 500;
+ self.faces.forEach(function (face) {
+ face.rotate3D(angleX, angleY, angleZ, zScaleFactor);
+ });
+ };
});
-//<Assets used in the game will automatically appear here>
-//<Write imports for supported plugins here>
-// Paddle class
+/***********************************************************************************/
+/******************************* FACE CLASS *********************************/
+/***********************************************************************************/
+var Face = Container.expand(function (options) {
+ var self = Container.call(this);
+ options = options || {};
+ var points = Math.max(2, Math.min(100, options.points || 4)); // Ensure points are between 2 and 10
+ self.baseSize = 100;
+ self.w = options.w || self.baseSize;
+ self.h = options.h || self.baseSize;
+ self.d = options.d || self.baseSize;
+ self.dx = options.dx || 0;
+ self.dy = options.dy || 0;
+ self.dz = options.dz || 0;
+ self.rx = options.rx || 0;
+ self.ry = options.ry || 0;
+ self.rz = options.rz || 0;
+ self.tint = options.ti || 0xFFFFFF;
+ // Generate points for the face based on the number of points specified
+ self.baseFaceCoordinates = [];
+ for (var i = 0; i < points; i++) {
+ var angle = 2 * Math.PI * (i / points);
+ self.baseFaceCoordinates.push({
+ x: self.w / 2 * Math.cos(angle) + self.dx * self.w,
+ y: self.h / 2 * Math.sin(angle) + self.dy * self.h,
+ z: self.dz * self.d
+ });
+ }
+ self.baseFaceCoordinates.forEach(function (point) {
+ // Update z of each face point coordinates depending on dz and rx, ry
+ point.z += self.dz * Math.cos(self.rx) * Math.cos(self.ry);
+ });
+ // Create a polygon face using the Shape class
+ self.face = new Shape(self.baseFaceCoordinates, self.tint);
+ // Attach the face to the Face container
+ self.addChild(self.face);
+ // Rotate in 3D: X = roasting chicken / Y = whirling dervish / Z = wheel of Fortune
+ self.rotate3D = function (angleX, angleY, angleZ, scale) {
+ scale = scale || 1;
+ self.faceCoordinates = self.baseFaceCoordinates.map(function (coord) {
+ var x = coord.x - self.dx * self.w,
+ y = coord.y - self.dy * self.h,
+ z = coord.z - self.dz * self.d;
+ // Apply initial rotations (rx, ry, rz)
+ var newY = y * Math.cos(self.rx) - z * Math.sin(self.rx);
+ var newZ = y * Math.sin(self.rx) + z * Math.cos(self.rx);
+ var newX = x * Math.cos(self.ry) + newZ * Math.sin(self.ry);
+ newZ = -x * Math.sin(self.ry) + newZ * Math.cos(self.ry);
+ x = newX * Math.cos(self.rz) - newY * Math.sin(self.rz);
+ y = newX * Math.sin(self.rz) + newY * Math.cos(self.rz);
+ // Apply X-axis rotation
+ newY = y * Math.cos(angleX) - newZ * Math.sin(angleX);
+ newZ = y * Math.sin(angleX) + newZ * Math.cos(angleX);
+ // Apply Y-axis rotation
+ newX = x * Math.cos(angleY) + newZ * Math.sin(angleY);
+ newZ = -x * Math.sin(angleY) + newZ * Math.cos(angleY);
+ // Apply Z-axis rotation
+ x = newX * Math.cos(angleZ) - newY * Math.sin(angleZ);
+ y = newX * Math.sin(angleZ) + newY * Math.cos(angleZ);
+ return {
+ x: (x + self.dx * self.w) * scale,
+ y: (y + self.dy * self.h) * scale,
+ z: (newZ + self.dz * self.d) * scale
+ };
+ });
+ self.face.updateCoordinates(self.faceCoordinates);
+ };
+ // Initialize face in 3D space
+ self.rotate3D(0, 0, 0, 1);
+});
+// Paddle class for player control (Keeping original Paddle class)
var Paddle = Container.expand(function () {
- var self = Container.call(this);
- var paddleGraphics = self.attachAsset('paddle', {
- anchorX: 0.5,
- anchorY: 0.5
- });
- self.width = 300;
- self.height = 50;
- self.speed = 10;
- self.update = function () {
- // Paddle update logic if needed
- };
+ var self = Container.call(this);
+ var paddleGraphics = self.attachAsset('paddle', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 15;
+ self.update = function () {
+ // Paddle movement logic will be handled in game code
+ };
});
+/***********************************************************************************/
+/********************************** SHAPE CLASS ************************************/
+/***********************************************************************************/
+var Shape = Container.expand(function (coordinates, tint) {
+ var self = Container.call(this);
+ self.polygon = drawPolygon(coordinates, tint); // Function to create a polygon from a list of coordinates
+ self.tint = tint;
+ self.attachLines = function () {
+ // Iterate through each line in the polygon and attach it to the shape
+ self.polygon.forEach(function (line) {
+ self.addChild(line);
+ });
+ };
+ self.attachLines();
+ self.updateCoordinates = function (newCoordinates) {
+ log("Shape updateCoordinates ", newCoordinates);
+ // Ensure newCoordinates is an array and has the same length as the current polygon
+ if (!Array.isArray(newCoordinates) || newCoordinates.length !== self.polygon.length) {
+ error("Invalid newCoordinates length");
+ return;
+ }
+ // Update each line in the polygon with new coordinates
+ self.polygon = updatePolygon(self.polygon, newCoordinates);
+ };
+});
+/***********************************************************************************/
+/******************************* SIMPLE FACE CLASS *********************************/
+/***********************************************************************************/
+var SimpleFace = Container.expand(function (options) {
+ var self = Container.call(this);
+ log("SimpleFAce init options =", options);
+ self.baseSize = 100;
+ options = options || {};
+ self.w = options.w || self.baseSize;
+ self.h = options.h || self.baseSize;
+ self.d = options.d || self.baseSize;
+ self.dx = options.dx || 0;
+ self.dy = options.dy || 0;
+ self.dz = options.dz || 0;
+ self.rx = options.rx || 0;
+ self.ry = options.ry || 0;
+ self.rz = options.rz || 0;
+ self.tint = options.ti || 0xFFFFFF;
+ // Define faceCoordinates property
+ self.baseFaceCoordinates = [{
+ x: -self.w + self.dx * self.w,
+ y: -self.h + self.dy * self.h,
+ z: self.dz * self.d
+ },
+ // Top-left
+ {
+ x: self.w + self.dx * self.w,
+ y: -self.h + self.dy * self.h,
+ z: self.dz * self.d
+ },
+ // Top-right
+ {
+ x: self.w + self.dx * self.w,
+ y: self.h + self.dy * self.h,
+ z: self.dz * self.d
+ },
+ // Bottom-right
+ {
+ x: -self.w + self.dx * self.w,
+ y: self.h + self.dy * self.h,
+ z: self.dz * self.d
+ } // Bottom-left
+ ];
+ log("SimpleFAce ready to init ...", self.baseFaceCoordinates, "DX=" + self.dx);
+ self.baseFaceCoordinates.forEach(function (point) {
+ // Update z of each face point coordinates depending on dz and rx, ry
+ point.z += self.dz * Math.cos(self.rx) * Math.cos(self.ry);
+ });
+ // Create a square face using the Shape class
+ self.face = new Shape(self.baseFaceCoordinates, self.tint);
+ // Attach the face to the SimpleFace container
+ self.addChild(self.face);
+ // Rotate in 3d : X = roasting chicken / Y = whirling dervish / Z = wheel of Fortune
+ self.rotate3D = function (angleX, angleY, angleZ, scale) {
+ scale = scale || 1;
+ log("SimpleFace rotate3D old coord=", self.faceCoordinates, Date.now());
+ self.faceCoordinates = self.baseFaceCoordinates.map(function (coord) {
+ return {
+ x: coord.x,
+ y: coord.y,
+ z: coord.z
+ };
+ });
+ // Apply rotation around X-axis
+ // Adjust initial rotation parameters before applying new rotations
+ self.faceCoordinates = self.faceCoordinates.map(function (coord) {
+ // Apply initial rotation around Z-axis
+ var xZ = coord.x * Math.cos(self.rz) - coord.y * Math.sin(self.rz);
+ var yZ = coord.x * Math.sin(self.rz) + coord.y * Math.cos(self.rz);
+ // Apply initial rotation around Y-axis
+ var xY = xZ * Math.cos(self.ry) + coord.z * Math.sin(self.ry);
+ var zY = coord.z * Math.cos(self.ry) - xZ * Math.sin(self.ry);
+ // Apply initial rotation around X-axis
+ var yX = yZ * Math.cos(self.rx) - zY * Math.sin(self.rx);
+ var zX = yZ * Math.sin(self.rx) + zY * Math.cos(self.rx);
+ return {
+ x: xY,
+ y: yX,
+ z: zX
+ };
+ });
+ // Apply new rotations
+ // Calculate center of the face
+ var centerX = self.faceCoordinates.reduce(function (acc, coord) {
+ return acc + coord.x;
+ }, 0) / self.faceCoordinates.length;
+ var centerY = self.faceCoordinates.reduce(function (acc, coord) {
+ return acc + coord.y;
+ }, 0) / self.faceCoordinates.length;
+ var centerZ = self.faceCoordinates.reduce(function (acc, coord) {
+ return acc + coord.z;
+ }, 0) / self.faceCoordinates.length;
+ self.faceCoordinates = self.faceCoordinates.map(function (coord) {
+ // Translate coordinates to rotate around the center including dy and dz adjustment
+ var translatedY = (coord.y + self.dy * self.h - centerY) * Math.cos(angleX) - (coord.z + self.dz * self.d - centerZ) * Math.sin(angleX);
+ var translatedZ = (coord.y + self.dy * self.h - centerZ) * Math.sin(angleX) + (coord.z + self.dz * self.d - centerZ) * Math.cos(angleX);
+ return {
+ x: coord.x + self.dx * self.w - centerX,
+ // Keep X unchanged but translate to rotate around center
+ y: translatedY + centerY,
+ z: translatedZ + centerZ
+ };
+ });
+ self.faceCoordinates = self.faceCoordinates.map(function (coord) {
+ var translatedX = (coord.z - centerZ) * Math.sin(angleY) + (coord.x - centerX) * Math.cos(angleY);
+ var translatedZ = (coord.z - centerZ) * Math.cos(angleY) - (coord.x - centerX) * Math.sin(angleY);
+ return {
+ x: translatedX + centerX,
+ y: coord.y,
+ // Keep Y unchanged
+ z: translatedZ + centerZ
+ };
+ });
+ self.faceCoordinates = self.faceCoordinates.map(function (coord) {
+ return {
+ x: coord.x * scale,
+ y: coord.y * scale,
+ z: coord.z * scale
+ };
+ });
+ log("SimpleFace rotate3D new coord=", self.faceCoordinates, Date.now());
+ self.face.updateCoordinates(self.faceCoordinates);
+ };
+ // initialize face in 3D space
+ self.rotate3D(0, 0, 0, 1);
+ log("SimpleFace end init coord=", self.baseFaceCoordinates, Date.now());
+});
+/***********************************************************************************/
+/********************************** SPHERE CLASS ***********************************/
+/***********************************************************************************/
+var Sphere = Container.expand(function () {
+ var self = Container.call(this);
+ self.z = 0;
+ self.radius = 50; // Reduced sphere radius to fit better as pong ball
+ // Initialize sphere as a collection of Face instances to simulate a 3D sphere
+ self.faces = [];
+ var segments = 5; // Number of segments to simulate the sphere
+ for (var i = 0; i < segments; i++) {
+ var angle = 2 * Math.PI / segments;
+ // Create a circular segment as a face of the sphere
+ var face = new Face({
+ points: 33,
+ w: self.radius * 2,
+ h: self.radius * 2,
+ d: self.radius * 2,
+ dx: 0,
+ dy: 0,
+ dz: 0,
+ rx: 0,
+ ry: i * angle,
+ rz: 0,
+ ti: 0xFFFFFF // Tint color
+ });
+ self.faces.push(face);
+ self.addChild(face);
+ }
+ self.speedX = 5;
+ self.speedY = 5;
+ self.speedZ = 5;
+ // Rotate sphere around its axes
+ self.rotate3D = function (angleX, angleY, angleZ) {
+ log("sphere rotate3D ", angleX, angleY, angleZ);
+ self.rotation = angleZ;
+ var zScaleFactor = 1 + self.z / 500;
+ for (var i = 0; i < self.faces.length; i++) {
+ self.faces[i].rotate3D(angleX, angleY, angleZ, zScaleFactor);
+ }
+ };
+ self.update = function () {
+ // Basic update for movement, no 3D rotation in pong game loop
+ if (gameStarted) {
+ self.x += self.speedX;
+ self.y += self.speedY;
+ // Ensure ball speed is consistent to prevent shaking
+ if (Math.abs(self.speedX) < 1) {
+ self.speedX = self.speedX < 0 ? -1 : 1;
+ }
+ if (Math.abs(self.speedY) < 1) {
+ self.speedY = self.speedY < 0 ? -1 : 1;
+ }
+ }
+ };
+ self.rotate3D(0, 0, 0); // Initial rotation
+});
-/****
+/****
* Initialize Game
-****/
+****/
+// Utility function to draw a polygon using drawLine (Keep utility functions)
var game = new LK.Game({
- backgroundColor: 0x000000 //Init game with black background
+ backgroundColor: 0x000000 // Initialize game with a black background
});
-/****
+/****
* Game Code
-****/
-// Initialize paddles and ball
-var playerPaddle = game.addChild(new Paddle());
-var aiPaddle = game.addChild(new Paddle());
-var ball = game.addChild(new Ball());
-// Position paddles and ball
-playerPaddle.x = 2048 / 2;
-playerPaddle.y = 2732 - 100;
-aiPaddle.x = 2048 / 2;
-aiPaddle.y = 100;
-ball.x = 2048 / 2;
-ball.y = 2732 / 2;
-// Game update logic
+****/
+// Added line asset
+// Added debugMarker asset
+/***********************************************************************************/
+/******************************* UTILITY FUNCTIONS *********************************/
+/***********************************************************************************/
+function drawPolygon(coordinates, tint) {
+ log("drawPolygon ", coordinates);
+ var lines = [];
+ for (var i = 0; i < coordinates.length; i++) {
+ var startPoint = coordinates[i];
+ var endPoint = coordinates[(i + 1) % coordinates.length]; // Loop back to the first point
+ var line = drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, tint);
+ lines.push(line);
+ }
+ return lines;
+}
+function updatePolygon(lines, newCoordinates, scale) {
+ log("updatePolygon ", lines, scale);
+ // Ensure lines and newCoordinates have the same length
+ if (lines.length !== newCoordinates.length) {
+ error("updatePolygon error: lines and newCoordinates length mismatch");
+ return lines;
+ }
+ // Update each line with new coordinates
+ for (var i = 0; i < lines.length; i++) {
+ var startPoint = newCoordinates[i];
+ var endPoint = newCoordinates[(i + 1) % newCoordinates.length]; // Loop back to the first point for the last line
+ updateLine(lines[i], startPoint.x, startPoint.y, endPoint.x, endPoint.y, scale);
+ }
+ return lines;
+}
+// Utility function to draw lines between two points
+function drawLine(x1, y1, x2, y2, tint) {
+ log("drawLine ", x1, y1);
+ var line = LK.getAsset('line', {
+ anchorX: 0.0,
+ anchorY: 0.0,
+ x: x1,
+ y: y1,
+ tint: tint
+ });
+ line.startX = x1;
+ line.startY = y1;
+ line.endX = x2;
+ line.endY = y2;
+ // Calculate the distance between the two points
+ var distance = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
+ // Set the width of the line to the distance between the points
+ line.width = distance;
+ // Calculate the angle between the two points
+ var angle = Math.atan2(y2 - y1, x2 - x1);
+ // Correct angle calculation for all quadrants
+ line.rotation = angle;
+ return line;
+}
+// Utility function to draw lines between two points
+function updateLine(line, newX1, newY1, newX2, newY2, scale) {
+ log("updateLine ", line);
+ scale = scale === undefined ? 1 : scale;
+ // Calculate midpoint of the original line
+ var midX = (newX1 + newX2) / 2;
+ var midY = (newY1 + newY2) / 2;
+ // Adjust start and end points based on scale
+ newX1 = midX + (newX1 - midX) * scale;
+ newY1 = midY + (newY1 - midY) * scale;
+ newX2 = midX + (newX2 - midX) * scale;
+ newY2 = midY + (newY2 - midY) * scale;
+ // Update line start and end coordinates after scaling
+ line.x = newX1;
+ line.y = newY1;
+ line.startX = newX1;
+ line.startY = newY1;
+ line.endX = newX2;
+ line.endY = newY2;
+ // Recalculate the distance between the new scaled points
+ var distance = Math.sqrt(Math.pow(newX2 - newX1, 2) + Math.pow(newY2 - newY1, 2));
+ // Update the width of the line to the new distance
+ line.width = distance;
+ // Recalculate the angle between the new points
+ var angle = Math.atan2(newY2 - newY1, newX2 - newX1);
+ // Update the rotation of the line to the new angle
+ line.rotation = angle;
+ return line;
+}
+function log() {
+ var isDebug = false; // Set isDebug to false for production, true for debugging logs
+ if (isDebug) {
+ console.log(arguments);
+ }
+}
+function error() {
+ // Error logging function
+ var isDebug = true; // Error logs are always shown during debug
+ if (isDebug) {
+ console.error(arguments);
+ }
+}
+/***********************************************************************************/
+/******************************* GAME VARIABLES*********************************/
+/***********************************************************************************/
+var centerLine; // Keep centerLine
+var leftPaddle; // Keep leftPaddle
+var rightPaddle; // Keep rightPaddle
+var ball; // Will be Sphere class now
+var leftScore = 0; // Keep leftScore
+var rightScore = 0; // Keep rightScore
+var leftScoreTxt; // Keep leftScoreTxt
+var rightScoreTxt; // Keep rightScoreTxt
+var gameStarted = false; // Keep gameStarted
+/***********************************************************************************/
+/***************************** GAME INITIALIZATION *********************************/
+/***********************************************************************************/
+function gameInitialize() {
+ // Create a dashed line in the center of the screen (Keep center line creation)
+ centerLine = new Container();
+ var lineHeight = 20;
+ var lineSpacing = 20;
+ for (var y = 0; y < 2732; y += lineHeight + lineSpacing) {
+ var lineSegment = LK.getAsset('paddle', {
+ width: 10,
+ height: lineHeight,
+ color: 0xffffff,
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ lineSegment.x = 2048 / 2;
+ lineSegment.y = y + lineHeight / 2;
+ centerLine.addChild(lineSegment);
+ }
+ game.addChild(centerLine);
+ // Initialize paddles (Keep paddle initialization)
+ leftPaddle = game.addChild(new Paddle());
+ rightPaddle = game.addChild(new Paddle());
+ // Initialize ball as Sphere (Replace 2D Ball with 3D Sphere)
+ ball = game.addChild(new Sphere());
+ // Position paddles and ball (Keep positioning)
+ leftPaddle.x = 100;
+ leftPaddle.y = 2732 / 2;
+ rightPaddle.x = 2048 - 50;
+ rightPaddle.y = 2732 / 2;
+ ball.x = 2048 / 2;
+ ball.y = 2732 / 2;
+ // Score display (Keep score display)
+ leftScoreTxt = new Text2('0', {
+ size: 100,
+ fill: 0xFFFFFF,
+ font: "Teko Regular" // Change font style to Teko Regular
+ });
+ rightScoreTxt = new Text2('0', {
+ size: 100,
+ fill: 0xFFFFFF,
+ font: "Teko Regular" // Change font style to Teko Regular
+ });
+ leftScoreTxt.anchor.set(0.5, 0);
+ leftScoreTxt.x += 600;
+ rightScoreTxt.anchor.set(0.5, 0);
+ rightScoreTxt.x -= 600; // Decrease the x-axis position by 600
+ LK.gui.topLeft.addChild(leftScoreTxt);
+ LK.gui.topRight.addChild(rightScoreTxt);
+}
+// Update score display (Keep updateScore function)
+function updateScore() {
+ leftScoreTxt.setText(leftScore);
+ rightScoreTxt.setText(rightScore);
+ // Play 'sayac' sound effect
+ LK.getSound('sayac').play();
+}
+// Reset ball to center (Keep resetBall function)
+function resetBall() {
+ ball.x = 2048 / 2;
+ ball.y = 2732 / 2;
+ ball.speedX = 5 * (Math.random() > 0.5 ? 1 : -1);
+ ball.speedY = 5 * (Math.random() > 0.5 ? 1 : -1);
+}
+/***********************************************************************************/
+/******************************** MAIN GAME LOOP ***********************************/
+/***********************************************************************************/
game.update = function () {
- // Ball movement
- ball.update();
- // Ball collision with walls
- if (ball.x <= 0 || ball.x >= 2048) {
- ball.speedX *= -1;
- }
- if (ball.y <= 0 || ball.y >= 2732) {
- ball.speedY *= -1;
- }
- // Ball collision with paddles
- if (ball.intersects(playerPaddle) || ball.intersects(aiPaddle)) {
- ball.speedY *= -1;
- }
- // AI paddle movement
- if (ball.x < aiPaddle.x) {
- aiPaddle.x -= aiPaddle.speed;
- } else if (ball.x > aiPaddle.x) {
- aiPaddle.x += aiPaddle.speed;
- }
+ if (!gameStarted) {
+ return;
+ } // Do not update if game not started yet
+ ball.update(); // Use Sphere's update function (basic movement)
+ // Ball collision with top and bottom (Keep collision logic)
+ if (ball.y <= 0 && ball.speedY < 0 || ball.y >= 2732 && ball.speedY > 0) {
+ ball.speedY *= -1;
+ // Play 'carp1' sound effect
+ LK.getSound('carp1').play();
+ }
+ // Ball collision with paddles (Keep paddle collision logic)
+ if (ball.intersects(leftPaddle)) {
+ if (ball.y < leftPaddle.y) {
+ ball.speedY = -Math.abs(ball.speedY);
+ } else {
+ ball.speedY = Math.abs(ball.speedY);
+ }
+ ball.speedX *= -1.05; // Slight acceleration on paddle hit
+ // Ensure ball speed is consistent to prevent shaking
+ if (Math.abs(ball.speedX) < 1) {
+ ball.speedX = ball.speedX < 0 ? -1 : 1;
+ }
+ if (Math.abs(ball.speedY) < 1) {
+ ball.speedY = ball.speedY < 0 ? -1 : 1;
+ }
+ // Play 'carp1' sound effect
+ LK.getSound('carp1').play();
+ }
+ if (ball.intersects(rightPaddle)) {
+ if (ball.y < rightPaddle.y) {
+ ball.speedY = -Math.abs(ball.speedY);
+ } else {
+ ball.speedY = Math.abs(ball.speedY);
+ }
+ ball.speedX *= -1.05; // Slight acceleration on paddle hit
+ // Ensure ball speed is consistent to prevent shaking
+ if (Math.abs(ball.speedX) < 1) {
+ ball.speedX = ball.speedX < 0 ? -1 : 1;
+ }
+ if (Math.abs(ball.speedY) < 1) {
+ ball.speedY = ball.speedY < 0 ? -1 : 1;
+ }
+ // Play 'carp1' sound effect
+ LK.getSound('carp1').play();
+ }
+ // Scoring (Keep scoring logic)
+ if (ball.x <= 0) {
+ rightScore++;
+ updateScore();
+ if (rightScore >= 10) {
+ LK.showGameOver("Right Player Wins!");
+ } else {
+ resetBall();
+ }
+ } else if (ball.x >= 2048) {
+ leftScore++;
+ updateScore();
+ if (leftScore >= 10) {
+ LK.showGameOver("Left Player Wins!");
+ } else {
+ resetBall();
+ }
+ }
+ // Automatic movement for right paddle only when the ball is moving towards it (Keep AI Paddle logic)
+ if (ball.speedX > 0) {
+ if (ball.y > rightPaddle.y) {
+ rightPaddle.y += Math.min(rightPaddle.speed * 1.5, Math.abs(ball.y - rightPaddle.y));
+ } else if (ball.y < rightPaddle.y) {
+ rightPaddle.y -= Math.min(rightPaddle.speed * 1.5, Math.abs(ball.y - rightPaddle.y));
+ }
+ }
};
-// Player paddle control
+// Handle paddle movement (Keep paddle movement handler)
game.move = function (x, y, obj) {
- playerPaddle.x = x;
-};
\ No newline at end of file
+ if (x < 2048 / 2) {
+ leftPaddle.y = y;
+ LK.getSound('cubuk1').play();
+ }
+};
+// Display 'Pongi' text and start game after delay (Keep start text and delay logic)
+var startTextBackground = LK.getAsset('paddle', {
+ width: 400,
+ height: 200,
+ color: 0x303030,
+ alpha: 0.5,
+ anchorX: 0.5,
+ anchorY: 0.5
+});
+startTextBackground.scaleX = 1.5;
+startTextBackground.x = 2048 / 2; // Center horizontally
+startTextBackground.y = 100; // Position at top
+LK.gui.center.addChild(startTextBackground);
+var startText = new Text2('Pongi', {
+ size: 200,
+ fill: 0xFFFFFF,
+ font: "Teko Regular",
+ shadow: {
+ color: 0x808080,
+ blur: 10,
+ offsetX: 5,
+ offsetY: 5
+ }
+});
+startText.anchor.set(0.5, 0.5);
+startText.x = 2048 / 2; // Center horizontally
+startText.y = 100; // Position at top
+LK.gui.center.addChild(startText);
+// Play background music continuously (Keep music)
+LK.playMusic('fon');
+gameStarted = false; // Ensure gameStarted is false initially
+// Initialize Game (Call gameInitialize to setup paddles, ball, etc.)
+gameInitialize();
+// Remove the start text and background, then begin the game after a delay (Keep timeout logic)
+LK.setTimeout(function () {
+ LK.gui.center.removeChild(startText);
+ LK.gui.center.removeChild(startTextBackground);
+ gameStarted = true; // Set gameStarted to true to enable game update loop
+ // Game update loop will start automatically as gameStarted is now true and game.update is defined
+}, 3000); // 3 seconds delay
\ No newline at end of file