User prompt
No ball can pass the table edges!
User prompt
Add collision to all balls so they can't pass their edges images when get hited
User prompt
minimumpowershot = 50
User prompt
Don't let the balls out from the screen edges!
Code edit (2 edits merged)
Please save this source code
User prompt
add minimumshot = 100
User prompt
Don't let any ball out from boundaries
User prompt
let the cue follow the cursor
User prompt
Start charge power from the close distance from cueball
Code edit (1 edits merged)
Please save this source code
User prompt
maxshot power = 1000
User prompt
let the cueball can touch the other balls at anytime get hit by cuestick
Code edit (1 edits merged)
Please save this source code
User prompt
Make the cuestick so close to the cueball
User prompt
reduce distance between cuestick head and the whiteball so i can get power by dragging from close distance
Code edit (1 edits merged)
Please save this source code
User prompt
fit the background2 to screen
User prompt
Replace table ground by background2 or place it front of it
User prompt
Add background2 as table of billiard
User prompt
Let the cue can hit the ball from small distance like close to whiteball.
User prompt
Add collision by edges of the balls not from senter
User prompt
make the distance between cuestick and the whiteball smaller
User prompt
add collision to all new balls
User prompt
add when i release the cuestick after hold and drag hit the whiteball from the first time.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var ColoredBall = Container.expand(function (assetId) { var self = Container.call(this); var ballGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.speedX = 0; self.speedY = 0; self.friction = 0.99; // Friction to slow down the ball self.update = function () { self.x += self.speedX; self.y += self.speedY; // Apply friction self.speedX *= self.friction; self.speedY *= self.friction; // Stop the ball if speed is very low if (Math.abs(self.speedX) < 0.1 && Math.abs(self.speedY) < 0.1) { self.speedX = 0; self.speedY = 0; } }; return self; }); var Cue = Container.expand(function () { var self = Container.call(this); // You'll need to define a shape or image asset for the cue stick // Assuming you have a 'cueStickAsset' defined in Assets var cueGraphics = self.attachAsset('cueStickAsset', { anchorX: 0.5, anchorY: 1.0 // Anchor at the bottom edge (handle on opposite side) }); self.update = function () { // The cue will likely be positioned and rotated based on the drag input // in the game.move and game.up handlers. }; return self; }); //Storage library which should be used for persistent game data //var storage = LK.import('@upit/storage.v1'); //Library for using the camera (the background becomes the user's camera video feed) and the microphone. It can access face coordinates for interactive play, as well detect microphone volume / voice interactions //var facekit = LK.import('@upit/facekit.v1'); //Classes can only be defined here. You cannot create inline classes in the games code. var CueBall = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('cueBall', { anchorX: 0.5, anchorY: 0.5 }); self.speedX = 0; self.speedY = 0; self.friction = 0.99; // Friction to slow down the ball self.update = function () { self.x += self.speedX; self.y += self.speedY; // Apply friction self.speedX *= self.friction; self.speedY *= self.friction; // Stop the ball if speed is very low if (Math.abs(self.speedX) < 0.1 && Math.abs(self.speedY) < 0.1) { self.speedX = 0; self.speedY = 0; } }; return self; }); var Pocket = Container.expand(function () { var self = Container.call(this); self.attachAsset('pocket', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var TableEdge = Container.expand(function (width, height) { var self = Container.call(this); self.attachAsset('tableEdge', { width: width, height: height, anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x228B22 // Init game with forest green background }); /**** * Game Code ****/ // Assuming striped balls are the same size as solid balls //Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property. //Only include the plugins you need to create the game. // Create the shooting line visualization // Note: We can't draw lines directly. We'll simulate with a long thin box asset if needed. // For now, we'll just handle the logic and power calculation. // Create and position the cue // cue = new Cue(); // This is created in game.down // game.addChild(cue); // This is added in game.down // cue.x = cueBall.x; // This is set in game.down and game.move // cue.y = cueBall.y; // This is set in game.down and game.move // If you have a line drawing asset: /* Supported Types: 1. Shape: 2. Image: 3. Sound: 4. Music: */ //Note game dimensions are 2048x2732 var background = LK.getAsset('background2', { anchorX: 0, anchorY: 0, width: 2048, height: 2732, x: 0, y: 0 }); game.addChild(background); // Game elements var cueBall = null; // Initialize cueBall here var coloredBalls = []; var pockets = []; var tableEdges = []; // Game state // var draggingCueBall = false; // This logic is replaced by draggingCue // var dragStartX = 0; // No longer used for this cue mechanic // var dragStartY = 0; // No longer used for this cue mechanic var shotPower = 0; // Represents the power of the shot, calculated on release var maxShotPower = 200; // Adjust as needed for desired power var shootingLine = null; // Placeholder for the shooting line, currently unused // Note: The following declarations are duplicates from lines {1i} to {1s} // var cueBall = null; // var coloredBalls = []; // var pockets = []; // var tableEdges = []; // Game state // var draggingCueBall = false; // var dragStartX = 0; // var dragStartY = 0; // var shotPower = 0; // var maxShotPower = 200; // var shootingLine = null; var cue = null; // Initialize cue variable var shotTaken = false; // Track if a shot has been taken this turn // var cueVerticalOffset = 200; // No longer used var CUE_TIP_TO_BALL_SURFACE_OFFSET = 5; // Make cue stick very close to the cue ball var draggingCue = false; // True if player is dragging the cue stick // Create pockets // Create pockets // Create pockets function createPockets() { var pocketSize = 200; var edgeOffset = 50; // Adjust to align with the new edge positions // Top pockets var topLeftPocket = new Pocket(); topLeftPocket.x = edgeOffset; topLeftPocket.y = edgeOffset; game.addChild(topLeftPocket); pockets.push(topLeftPocket); var topMiddlePocket = new Pocket(); topMiddlePocket.x = 2048 / 2; topMiddlePocket.y = edgeOffset; game.addChild(topMiddlePocket); pockets.push(topMiddlePocket); var topRightPocket = new Pocket(); topRightPocket.x = 2048 - edgeOffset; topRightPocket.y = edgeOffset; game.addChild(topRightPocket); pockets.push(topRightPocket); // Bottom pockets var bottomLeftPocket = new Pocket(); bottomLeftPocket.x = edgeOffset; bottomLeftPocket.y = 2732 - edgeOffset; game.addChild(bottomLeftPocket); pockets.push(bottomLeftPocket); var bottomMiddlePocket = new Pocket(); bottomMiddlePocket.x = 2048 / 2; bottomMiddlePocket.y = 2732 - edgeOffset; game.addChild(bottomMiddlePocket); pockets.push(bottomMiddlePocket); var bottomRightPocket = new Pocket(); bottomRightPocket.x = 2048 - edgeOffset; bottomRightPocket.y = 2732 - edgeOffset; game.addChild(bottomRightPocket); pockets.push(bottomRightPocket); } // Create table edges function createTableEdges() { var edgeThickness = 20; var pocketOffset = 100; // Should align with pocket edge // Top edges var topLeftEdge = new TableEdge(2048 / 2 - pocketOffset, edgeThickness); topLeftEdge.x = pocketOffset + (2048 / 2 - pocketOffset) / 2; topLeftEdge.y = edgeThickness / 2; // Position at the top edge game.addChild(topLeftEdge); tableEdges.push(topLeftEdge); var topRightEdge = new TableEdge(2048 / 2 - pocketOffset, edgeThickness); topRightEdge.x = 2048 - pocketOffset - (2048 / 2 - pocketOffset) / 2; topRightEdge.y = edgeThickness / 2; // Position at the top edge game.addChild(topRightEdge); tableEdges.push(topRightEdge); // Bottom edges var bottomLeftEdge = new TableEdge(2048 / 2 - pocketOffset, edgeThickness); bottomLeftEdge.x = pocketOffset + (2048 / 2 - pocketOffset) / 2; bottomLeftEdge.y = 2732 - edgeThickness / 2; // Position at the bottom edge game.addChild(bottomLeftEdge); tableEdges.push(bottomLeftEdge); var bottomRightEdge = new TableEdge(2048 / 2 - pocketOffset, edgeThickness); bottomRightEdge.x = 2048 - pocketOffset - (2048 / 2 - pocketOffset) / 2; bottomRightEdge.y = 2732 - edgeThickness / 2; // Position at the bottom edge game.addChild(bottomRightEdge); tableEdges.push(bottomRightEdge); // Left edges var leftTopEdge = new TableEdge(edgeThickness, 2732 / 2 - pocketOffset); leftTopEdge.x = edgeThickness / 2; // Position at the left edge leftTopEdge.y = pocketOffset + (2732 / 2 - pocketOffset) / 2; // Position aligned with pockets game.addChild(leftTopEdge); tableEdges.push(leftTopEdge); var leftBottomEdge = new TableEdge(edgeThickness, 2732 / 2 - pocketOffset); leftBottomEdge.x = edgeThickness / 2; // Position at the left edge leftBottomEdge.y = 2732 - pocketOffset - (2732 / 2 - pocketOffset) / 2; // Position aligned with pockets game.addChild(leftBottomEdge); tableEdges.push(leftBottomEdge); var rightTopEdge = new TableEdge(edgeThickness, 2732 / 2 - pocketOffset); rightTopEdge.x = 2048 - edgeThickness / 2; // Position at the right edge rightTopEdge.y = pocketOffset + (2732 / 2 - pocketOffset) / 2; // Position aligned with pockets game.addChild(rightTopEdge); tableEdges.push(rightTopEdge); var rightBottomEdge = new TableEdge(edgeThickness, 2732 / 2 - pocketOffset); rightBottomEdge.x = 2048 - edgeThickness / 2; // Position at the right edge rightBottomEdge.y = 2732 - pocketOffset - (2732 / 2 - pocketOffset) / 2; // Position aligned with pockets game.addChild(rightBottomEdge); tableEdges.push(rightBottomEdge); } // Create balls function createBalls() { cueBall = new CueBall(); cueBall.x = 2048 / 2; cueBall.y = 2732 * 0.75; // Position cue ball at the bottom game.addChild(cueBall); // Create the cue stick cue = new Cue(); game.addChild(cue); //{1K} // Cue is added once // Initial position and orientation for the cue // Position cue handle "behind" (larger Y coordinate) the cueBall if (cueBall && cue) { var handle_distance_from_ball_center = cue.height + cueBall.width / 2 + CUE_TIP_TO_BALL_SURFACE_OFFSET; // Use reduced offset for closer cue cue.x = cueBall.x; cue.y = cueBall.y + handle_distance_from_ball_center; var initialAngle = Math.atan2(cueBall.y - cue.y, cueBall.x - cue.x); // Assuming cue asset's tip is along its positive local Y-axis (anchorY=0.0 means handle is at top of image) cue.rotation = initialAngle - Math.PI / 2; } cue.visible = true; // Ensure cue is visible at the start // Create some colored balls in a triangle formation var startX = 2048 / 2; var startY = 2732 * 0.25; // Position colored balls at the top var ballSpacing = cueBall.width * 1.2; // Spacing between balls var numRows = 5; // Define the order of balls for the rack (standard 8-ball setup) var ballOrder = ['solidYellow', // Row 1 'solidBlue', 'solidRed', // Row 2 'stripedOrange', 'stripedGreen', 'solidBrown', // Row 3 'stripedBlue', 'stripedRed', 'solidBlack', 'solidPurple', // Row 4 (solid black ball in the middle) 'solidGreen', 'stripedYellow', 'stripedBrown', 'stripedPurple', 'solidOrange' // Row 5 ]; // stripedBlack has been removed from the ballOrder array var ballIndex = 0; for (var row = 0; row < numRows; row++) { for (var col = 0; col <= row; col++) { var assetId = ballOrder[ballIndex]; var ball = new ColoredBall(assetId); // Calculate x and y positions for the flipped triangle ball.x = startX + col * ballSpacing - row * ballSpacing / 2; ball.y = startY + (numRows - 1 - row) * ballSpacing; // Flip the row calculation game.addChild(ball); coloredBalls.push(ball); ball.lastIntersectingBall = false; // Initialize collision tracking ballIndex++; } } } createPockets(); createTableEdges(); createBalls(); // Handle ball collisions with table edges function handleEdgeCollisions(ball) { // Store last position for transition detection if (ball.lastX === undefined) { ball.lastX = ball.x; } if (ball.lastY === undefined) { ball.lastY = ball.y; } var ballRadius = ball.width / 2; var hitEdge = false; // Define table boundaries with a small margin to ensure balls never escape var leftBound = ballRadius; var rightBound = 2048 - ballRadius; var topBound = ballRadius; var bottomBound = 2732 - ballRadius; // Check collision with table edges and enforce boundaries // Check collision with vertical edges (left and right table bounds) if (ball.x <= leftBound) { ball.x = leftBound; // Force ball to stay within boundary ball.speedX = Math.abs(ball.speedX); // Force positive X velocity (rightward) hitEdge = true; } else if (ball.x >= rightBound) { ball.x = rightBound; // Force ball to stay within boundary ball.speedX = -Math.abs(ball.speedX); // Force negative X velocity (leftward) hitEdge = true; } // Check collision with horizontal edges (top and bottom table bounds) if (ball.y <= topBound) { ball.y = topBound; // Force ball to stay within boundary ball.speedY = Math.abs(ball.speedY); // Force positive Y velocity (downward) hitEdge = true; } else if (ball.y >= bottomBound) { ball.y = bottomBound; // Force ball to stay within boundary ball.speedY = -Math.abs(ball.speedY); // Force negative Y velocity (upward) hitEdge = true; } // Play collision sound if we hit an edge if (hitEdge) { LK.getSound('collision').play(); } // Double-check clamping to absolutely ensure ball stays within table boundaries ball.x = Math.max(leftBound, Math.min(rightBound, ball.x)); ball.y = Math.max(topBound, Math.min(bottomBound, ball.y)); // Update last position with the now clamped values ball.lastX = ball.x; ball.lastY = ball.y; } // Handle collisions between balls function handleBallCollisions() { var allBalls = [cueBall].concat(coloredBalls); // Initialize collidedThisTick flags and ensure lastIntersectingBall is defined for (var k = 0; k < allBalls.length; k++) { if (allBalls[k].lastIntersectingBall === undefined) { allBalls[k].lastIntersectingBall = false; } allBalls[k].collidedThisTick = false; } for (var i = 0; i < allBalls.length; i++) { var ball1 = allBalls[i]; for (var j = i + 1; j < allBalls.length; j++) { var ball2 = allBalls[j]; var dx = ball2.x - ball1.x; var dy = ball2.y - ball1.y; var distance = Math.sqrt(dx * dx + dy * dy); var minDistance = ball1.width / 2 + ball2.width / 2; // Check for overlap based on distance between centers and sum of radii var currentPairwiseIntersecting = distance < minDistance; if (currentPairwiseIntersecting) { ball1.collidedThisTick = true; ball2.collidedThisTick = true; // Process collision physics if balls are intersecting. // This allows for continuous interaction and ensures collisions register // even if balls were previously touching. // Simple collision response (based on elastic collision) var angle = Math.atan2(dy, dx); var sin = Math.sin(angle); var cos = Math.cos(angle); // Rotate ball1 velocity var vel1X = ball1.speedX * cos + ball1.speedY * sin; var vel1Y = ball1.speedY * cos - ball1.speedX * sin; // Rotate ball2 velocity var vel2X = ball2.speedX * cos + ball2.speedY * sin; var vel2Y = ball2.speedY * cos - ball2.speedX * sin; // Perform 1D collision (balls exchange velocities along the collision axis) var finalVel1X = vel2X; var finalVel2X = vel1X; // Rotate velocities back ball1.speedX = finalVel1X * cos - vel1Y * sin; ball1.speedY = vel1Y * cos + finalVel1X * sin; ball2.speedX = finalVel2X * cos - vel2Y * sin; ball2.speedY = vel2Y * cos + finalVel2X * sin; // Move balls apart to prevent sticking if they are overlapping var overlap = minDistance - distance; if (overlap > 0) { // Ensure distance is not zero to prevent division by zero var separationAmount = overlap / (distance > 0 ? distance : 1); var sepX = dx * separationAmount; var sepY = dy * separationAmount; // Move ball1 away from ball2 by half the overlap ball1.x -= sepX / 2; ball1.y -= sepY / 2; // Move ball2 away from ball1 by half the overlap ball2.x += sepX / 2; ball2.y += sepY / 2; // Make sure balls don't end up outside the table after separation var ballRadius = ball1.width / 2; ball1.x = Math.max(ballRadius, Math.min(2048 - ballRadius, ball1.x)); ball1.y = Math.max(ballRadius, Math.min(2732 - ballRadius, ball1.y)); ballRadius = ball2.width / 2; ball2.x = Math.max(ballRadius, Math.min(2048 - ballRadius, ball2.x)); ball2.y = Math.max(ballRadius, Math.min(2732 - ballRadius, ball2.y)); } LK.getSound('collision').play(); } } } // After all pairs are checked, update lastIntersectingBall for the next game tick for (var k = 0; k < allBalls.length; k++) { allBalls[k].lastIntersectingBall = allBalls[k].collidedThisTick; } } // Handle ball potting function handlePotting() { var allBalls = [cueBall].concat(coloredBalls); for (var i = allBalls.length - 1; i >= 0; i--) { var ball = allBalls[i]; for (var j = 0; j < pockets.length; j++) { var pocket = pockets[j]; var currentIntersecting = ball.intersects(pocket); if (!ball.lastIntersectingPocket && currentIntersecting) { // Ball is potted if (ball === cueBall) { // Cue ball potted - handle as a foul or reset console.log("Cue ball potted!"); // For a simple game, let's just reset the cue ball cueBall.x = 2048 / 2; cueBall.y = 2732 * 0.75; cueBall.speedX = 0; cueBall.speedY = 0; LK.getSound('pot').play(); } else { // Colored ball potted console.log("Colored ball potted!"); ball.destroy(); coloredBalls.splice(i, 1); LK.getSound('pot').play(); // Check for win condition if (coloredBalls.length === 0) { LK.showYouWin(); } } break; // Ball can only be potted in one pocket at a time } ball.lastIntersectingPocket = currentIntersecting; // Update last state } } } // Mouse or touch down on game object game.down = function (x, y, obj) { // Only allow cue interaction if a shot is not currently in progress and cue/cueBall exist if (!shotTaken && cue && cueBall) { draggingCue = true; // Snap cue's handle (anchor 0.5, 0.0) to the mouse cursor position // Calculate the angle from the drag point to the cue ball center var angleToWhiteBall = Math.atan2(cueBall.y - y, cueBall.x - x); // Place the cue handle at the closest possible distance from the cue ball center, along the drag direction var handle_distance_from_ball_center = cue.height + cueBall.width / 2 + CUE_TIP_TO_BALL_SURFACE_OFFSET; cue.x = cueBall.x - handle_distance_from_ball_center * Math.cos(angleToWhiteBall); cue.y = cueBall.y - handle_distance_from_ball_center * Math.sin(angleToWhiteBall); // Aim cue's tip towards the white ball cue.rotation = angleToWhiteBall - Math.PI / 2; // Assumes cue asset's positive Y is "down" its length cue.visible = true; // Ensure cue is visible when interaction starts } }; // Mouse or touch move on game object game.move = function (x, y, obj) { if (draggingCue && cue && cueBall) { // Calculate the angle from the cursor to the cue ball center var angleToWhiteBall = Math.atan2(cueBall.y - y, cueBall.x - x); // Place the cue handle at the cursor position, but keep the cue tip always pointing at the cue ball cue.x = x; cue.y = y; cue.rotation = angleToWhiteBall - Math.PI / 2; } }; // Mouse or touch up on game object game.up = function (x, y, obj) { if (draggingCue && cue && cueBall) { // Ensure cue and cueBall exist draggingCue = false; // Calculate vector from cue handle (current mouse position) to cueBall center var dx_shot = cueBall.x - cue.x; var dy_shot = cueBall.y - cue.y; var dist_cue_handle_to_ball_center = Math.sqrt(dx_shot * dx_shot + dy_shot * dy_shot); // Power is based on how far the cue handle is pulled back from the white ball, // beyond the cue's own length (where cue tip would be at ball's center). var minimumShotPower = 50; var powerFactor = Math.max(0, dist_cue_handle_to_ball_center - cue.height); shotPower = Math.max(minimumShotPower, Math.min(powerFactor * 0.2, maxShotPower)); // Sensitivity 0.2, adjust as needed if (shotPower > 0) { var shootAngle = Math.atan2(dy_shot, dx_shot); // Angle from cue handle to white ball // Calculate target position for cue handle for the tween animation. // The cue's tip should visually end up CUE_TIP_TO_BALL_SURFACE_OFFSET from the cueBall's surface. // The handle is cue.height from the tip. The ball's radius is cueBall.width / 2. var distanceFromBallCenterToHandleTarget = cue.height + cueBall.width / 2 + CUE_TIP_TO_BALL_SURFACE_OFFSET; var targetHandleX = cueBall.x - distanceFromBallCenterToHandleTarget * Math.cos(shootAngle); var targetHandleY = cueBall.y - distanceFromBallCenterToHandleTarget * Math.sin(shootAngle); // Animate the cue hitting the ball tween(cue, { x: targetHandleX, y: targetHandleY }, { duration: 100, // Duration of the hit animation in ms easing: tween.easeOut, // Apply an easing function for smoother animation onFinish: function onFinish() { // Apply force to the cue ball after the animation completes cueBall.speedX = Math.cos(shootAngle) * shotPower; cueBall.speedY = Math.sin(shootAngle) * shotPower; shotTaken = true; // Mark that a shot has been taken cue.visible = false; // Hide cue during the shot } }); } else { // If shotPower is 0, no tween or shot, cue might be reset by game.update if balls are stopped. // Ensure shotTaken remains false if no actual shot is made. shotTaken = false; } } }; // Ask LK engine to update game every game tick game.update = function () { // Update ball positions cueBall.update(); for (var i = 0; i < coloredBalls.length; i++) { coloredBalls[i].update(); } // Handle collisions handleEdgeCollisions(cueBall); // Clamping for cueBall is now handled within handleEdgeCollisions for (var i = 0; i < coloredBalls.length; i++) { handleEdgeCollisions(coloredBalls[i]); // Clamping for coloredBalls is now handled within handleEdgeCollisions } handleBallCollisions(); // Handle potting handlePotting(); // You can add a check here to see if all balls have stopped moving // before allowing another shot. var allStopped = true; if (Math.abs(cueBall.speedX) > 0.1 || Math.abs(cueBall.speedY) > 0.1) { allStopped = false; } for (var i = 0; i < coloredBalls.length; i++) { if (Math.abs(coloredBalls[i].speedX) > 0.1 || Math.abs(coloredBalls[i].speedY) > 0.1) { allStopped = false; break; } } // Example: if all balls stopped and not dragging, you could enable a "next turn" or allow another shot if (allStopped && shotTaken && cue && cueBall) { // Check if cue and cueBall also exist shotTaken = false; // Reset for the next turn/aiming phase // Make the cue visible again and position it for the next shot cue.visible = true; var handle_distance_from_ball_center = cue.height + cueBall.width / 2 + CUE_TIP_TO_BALL_SURFACE_OFFSET; // Use reduced offset for closer cue cue.x = cueBall.x; cue.y = cueBall.y + handle_distance_from_ball_center; var angleToWhiteBall = Math.atan2(cueBall.y - cue.y, cueBall.x - cue.x); cue.rotation = angleToWhiteBall - Math.PI / 2; // Aim at cueBall } };
===================================================================
--- original.js
+++ change.js
@@ -99,28 +99,28 @@
/****
* Game Code
****/
-//Note game dimensions are 2048x2732
+// Assuming striped balls are the same size as solid balls
+//Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property.
+//Only include the plugins you need to create the game.
+// Create the shooting line visualization
+// Note: We can't draw lines directly. We'll simulate with a long thin box asset if needed.
+// For now, we'll just handle the logic and power calculation.
+// Create and position the cue
+// cue = new Cue(); // This is created in game.down
+// game.addChild(cue); // This is added in game.down
+// cue.x = cueBall.x; // This is set in game.down and game.move
+// cue.y = cueBall.y; // This is set in game.down and game.move
+// If you have a line drawing asset:
/*
Supported Types:
1. Shape:
2. Image:
3. Sound:
4. Music:
*/
-// If you have a line drawing asset:
-// cue.y = cueBall.y; // This is set in game.down and game.move
-// cue.x = cueBall.x; // This is set in game.down and game.move
-// game.addChild(cue); // This is added in game.down
-// cue = new Cue(); // This is created in game.down
-// Create and position the cue
-// For now, we'll just handle the logic and power calculation.
-// Note: We can't draw lines directly. We'll simulate with a long thin box asset if needed.
-// Create the shooting line visualization
-//Only include the plugins you need to create the game.
-//Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property.
-// Assuming striped balls are the same size as solid balls
+//Note game dimensions are 2048x2732
var background = LK.getAsset('background2', {
anchorX: 0,
anchorY: 0,
width: 2048,
@@ -310,32 +310,41 @@
ball.lastY = ball.y;
}
var ballRadius = ball.width / 2;
var hitEdge = false;
- // Check collision with table edges
+ // Define table boundaries with a small margin to ensure balls never escape
+ var leftBound = ballRadius;
+ var rightBound = 2048 - ballRadius;
+ var topBound = ballRadius;
+ var bottomBound = 2732 - ballRadius;
+ // Check collision with table edges and enforce boundaries
// Check collision with vertical edges (left and right table bounds)
- if (ball.x - ballRadius < 0) {
+ if (ball.x <= leftBound) {
+ ball.x = leftBound; // Force ball to stay within boundary
ball.speedX = Math.abs(ball.speedX); // Force positive X velocity (rightward)
hitEdge = true;
- } else if (ball.x + ballRadius > 2048) {
+ } else if (ball.x >= rightBound) {
+ ball.x = rightBound; // Force ball to stay within boundary
ball.speedX = -Math.abs(ball.speedX); // Force negative X velocity (leftward)
hitEdge = true;
}
// Check collision with horizontal edges (top and bottom table bounds)
- if (ball.y - ballRadius < 0) {
+ if (ball.y <= topBound) {
+ ball.y = topBound; // Force ball to stay within boundary
ball.speedY = Math.abs(ball.speedY); // Force positive Y velocity (downward)
hitEdge = true;
- } else if (ball.y + ballRadius > 2732) {
+ } else if (ball.y >= bottomBound) {
+ ball.y = bottomBound; // Force ball to stay within boundary
ball.speedY = -Math.abs(ball.speedY); // Force negative Y velocity (upward)
hitEdge = true;
}
// Play collision sound if we hit an edge
if (hitEdge) {
LK.getSound('collision').play();
}
- // Clamp ball position to stay within table boundaries
- ball.x = Math.max(ballRadius, Math.min(2048 - ballRadius, ball.x));
- ball.y = Math.max(ballRadius, Math.min(2732 - ballRadius, ball.y));
+ // Double-check clamping to absolutely ensure ball stays within table boundaries
+ ball.x = Math.max(leftBound, Math.min(rightBound, ball.x));
+ ball.y = Math.max(topBound, Math.min(bottomBound, ball.y));
// Update last position with the now clamped values
ball.lastX = ball.x;
ball.lastY = ball.y;
}
3D Billiard circle pocket web from top. In-Game asset. High contrast. No shadows. 3D
Modern App Store icon, high definition, square with rounded corners, transparent glass neon balls of billiard, high definition, HD colors, for a game named it "Chorizora Billiard". with text on the middle of the icon with many colors "Chorizora Billiard" !