Code edit (1 edits merged)
Please save this source code
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
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 basΜ§lamadan oΜnce ekranda goΜrenmedik istersen rengi degΜisΜ§tir
User prompt
oyun basΜ§lama ekranΔ±n da Pongi yazsΔ±n arka plan saydam gir olsun ve tam olarak ortada olsun ve yazΔ± ve arka plan uyumu cΜ§ok oΜ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