Code edit (1 edits merged)
Please save this source code
User prompt
center each score txt in its screen half
User prompt
place the scores in the bottom
Code edit (7 edits merged)
Please save this source code
User prompt
add also a new score2Txt
User prompt
create a new global variable score2 for player2 score
Code edit (1 edits merged)
Please save this source code
Code edit (14 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: player1 is not defined' in or related to this line: 'if (!ball.currentPlayer) {' Line Number: 1294
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: currentPosture is not defined' in or related to this line: 'if (!player2.isThrowing) {' Line Number: 1354
Code edit (1 edits merged)
Please save this source code
Code edit (12 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'x')' in or related to this line: 'mesureFlag.x = targetPosition.x; // TEMP DEBUG' Line Number: 1329
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
in aiActing case MOVE_TO_THROW, move to a random courtPositions
Code edit (13 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'height')' in or related to this line: 'courtPositions.push({' Line Number: 670
User prompt
Add 9 points in courtPositions with values x: i * game.width / 4, y: courtTopY + i*3+j * court.height / 4, i and j going from 1 to 3
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of null (reading 'height')' in or related to this line: 'courtPositions.push({' Line Number: 670
User prompt
create a global array of objects, containing 9 positions: from x: 1*game.width / 4, y: courtTopY + 1* court.height / 4 to x: 3*game.width / 4, y: courtTopY + 3* court.height / 4
Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
in if (self.isAI && self.moveToTarget && self.currentTargetPosition) , make the speed constant, not depending on distance
/**** * Classes ****/ /****************************************************************************************** */ /************************************** BALL ********************************************** */ /****************************************************************************************** */ // Ball class for the basketball var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('basketball', { anchorX: 0.5, anchorY: 0.5 }); self.followingSpeed = 1.0; // Increased speed when following target line self.fallingInitialSpeed = 20.0; // Increased speed when following target line self.speedY = 0; self.gravity = 0.5; self.isShot = false; self.isFollowTrajectory = false; self.isFalling = false; self.currentPlayer = null; // New property to track the current player holding the ball self.referenceX = null; self.fallingAngle = null; self.hasBumpedLeft = false; self.hasBumpedRight = false; self.collidedWithBumper = false; self.touchedBumper = null; self.initialXAmplitude = 75; // Amplitude of the sinusoidal movement self.initialXFrequency = 0.15; // Frequency of the sinusoidal movement self.Xamplitude = 0; self.XFrequency = 0; self.YAmplitude = 10; self.YFrequency = 0.05; self.refTicks = 0; self.shootBall = function () { console.log("Executing shootBall ", currentTrajectory); if (!currentTrajectory || currentTrajectory.length === 0) { console.log("No currentTrajectory"); return; } if (self.currentPlayer) { self.currentPlayer.hasBall = false; self.currentPlayer = null; } self.isFollowTrajectory = true; self.isShot = true; }; self.handleFollowing = function () { // Calculate progressive movement towards the next point in the trajectory var nextPoint = currentTrajectory[0]; var dx = nextPoint.x - self.x; var dy = nextPoint.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); //console.log("dx,dy=" + dx, dy, " distance =", distance); if (distance < 5) { //console.log("Close enough..."); // If close enough to the next point, move to the next point and remove it from the trajectory self.x = nextPoint.x; self.y = nextPoint.y; currentTrajectory.shift(); if (currentTrajectory.length === 0) { self.isFollowTrajectory = false; console.log("Trajectory end. Falling...", self.x, self.y, " / hoop :", basket.x, basket.y); // Pause for debug /* LK.setTimeout(function () { self.isFalling = true; }, 1000); */ self.isFalling = true; } } else { // Otherwise, move progressively towards the next point //console.log("following..."); //debugTxt.setText("following"); var speedX = dx * self.followingSpeed; var speedY = dy * self.followingSpeed; self.x += speedX; self.y += speedY; self.speedX = speedX * 0.5; // Store speedX self.speedY = speedY; // Store speedY self.lastSpeedX = speedX; // Store speedX self.lastSpeedY = speedY; // Store speedY } self.referenceX = null; }; self.handleFalling = function () { // Bullet Time effect //if (self.y < 350 && LK.ticks % 2 !== 0) { // return; // Simplify falling behavior // Apply gravity to speedY, increasing it over time to simulate acceleration with increasing factor // if (self.speedY != self.fallingInitialSpeed && self.fallingAngle == null) { // self.speedY = self.fallingInitialSpeed; // self.fallingAngle = 1; // TEMP DEBUG !!! // } self.gravity = 0.5; //self.y > courtTopBoundary ? 0.5 : 0.75; // Reset gravity to a constant value self.speedY += self.gravity; //console.log("handleFalling...", self.speedX, self.speedY, " bumping=" + self.collidedWithBumper); if (!self.collidedWithBumper && (self.intersects(basket.leftHoopBumper) || self.intersects(basket.rightHoopBumper))) { self.collidedWithBumper = true; self.touchedBumper = null; if (self.intersects(basket.leftHoopBumper)) { self.hasBumpedLeft = true; self.touchedBumper = basket.leftHoopBumper; //console.log("Bump left"); } else { self.hasBumpedRight = true; self.touchedBumper = basket.rightHoopBumper; //console.log("Bump right"); } var bumperX = basket.x + self.touchedBumper.x; var bumperY = basket.y + self.touchedBumper.y; var angleToBumper = Math.atan2(bumperY - self.y, bumperX - self.x); /* console.log("Init speed: " + Math.floor(self.speedX) + ", " + Math.floor(self.speedY)); console.log("Bump angle: " + angleToBumper + " => " + (angleToBumper * (180 / Math.PI)).toFixed(0) + "°"); console.log("Ball=" + Math.floor(self.x) + "," + Math.floor(self.y)); console.log("Bump=" + Math.floor(bumperX) + "," + Math.floor(bumperY)); */ // Calculate relative velocity components var relativeSpeedX = self.speedX * Math.cos(angleToBumper) + self.speedY * Math.sin(angleToBumper); var relativeSpeedY = self.speedX * Math.sin(angleToBumper) - self.speedY * Math.cos(angleToBumper); // Adjust speed based on impact relativeSpeedX *= -0.9; // Coefficient of restitution relativeSpeedY *= -0.5; // Reduced vertical rebound // Convert relative velocity components back to global coordinates self.speedX = relativeSpeedX * Math.cos(angleToBumper) - relativeSpeedY * Math.sin(angleToBumper); self.speedY = relativeSpeedX * Math.sin(angleToBumper) + relativeSpeedY * Math.cos(angleToBumper); // Apply dampening effect self.speedX *= 0.95; self.speedY *= 0.95; //console.log("Result speed: " + Math.floor(self.speedX) + ", " + Math.floor(self.speedY)); } else { // Ensure bumper is defined before accessing its properties if (self.collidedWithBumper && self.touchedBumper) { var bumperX = basket.x + self.touchedBumper.x; var bumperY = basket.y + self.touchedBumper.y; var distToBump = Math.sqrt(Math.pow(bumperX - self.x, 2) + Math.pow(bumperY - self.y, 2)); if (distToBump > 75) { //console.log("Stopped bumping. Dist=" + distToBump); self.collidedWithBumper = false; self.touchedBumper = null; } } } // Update the ball's position based on the current speedY and speedX self.x += self.speedX; self.y += self.speedY; // When ball is falling and reaches courtTopBoundary, make its x follow a sinusoidal curve if (self.y > courtTopBoundary) { if (self.referenceX == null) { self.fallingAngle = Math.PI / 4 + (self.lastSpeedX < 0 ? Math.PI / 2 : 0); self.referenceX = self.x; self.Xamplitude = self.initialXAmplitude; self.XFrequency = self.initialXFrequency; self.refTicks = LK.ticks; } self.Xamplitude *= 0.98; // Logarithmic decrease self.XFrequency -= 0.0001; if (self.Xamplitude > 1) { self.x = self.referenceX + (LK.ticks - self.refTicks) * 5 * Math.cos(self.fallingAngle) + self.Xamplitude * Math.abs(Math.sin(LK.ticks * self.XFrequency)); } } // Check boundaries and bounce if a border is reached if (self.y > courtBottomBoundary - self.height / 2) { self.y = courtBottomBoundary - self.height / 2; self.speedY *= -0.5; // Bounce back with reduced speed } if (self.x < courtLeftBoundary + self.width / 2) { self.x = courtLeftBoundary + self.width / 2; self.speedX *= -0.5; // Bounce back with reduced speed } else if (self.x > courtRightBoundary - self.width / 2) { self.x = courtRightBoundary - self.width / 2; self.speedX *= -0.5; // Bounce back with reduced speed } self.speedX *= 0.95; self.speedY *= 0.95; if (self.y > courtTopBoundary && Math.abs(self.speedX) < 1 && Math.abs(self.speedY) < 1) { // Adjust threshold for ending falling console.log("Too slow stop falling", self.speedY); self.isFalling = false; self.fallingAngle = null; self.hasBumpedLeft = false; self.hasBumpedRight = false; self.isShot = false; self.speedY = 0; self.speedX = 0; } }; self.update = function () { if (self.isShot) { if (self.isFollowTrajectory && currentTrajectory && currentTrajectory.length > 0) { self.handleFollowing(); } else if (self.isFalling) { self.handleFalling(); } else { debugTxt.setText("wait"); } } }; self.catched = function () { self.isFalling = false; self.fallingAngle = null; self.hasBumpedLeft = false; self.hasBumpedRight = false; self.collidedWithBumper = false; self.isShot = false; self.speedY = 0; self.speedX = 0; self.scoreCounted = false; }; self.reset = function () { self.x = 300; //1024; // Center X self.y = 2000; // Starting Y 500 -> 2565 self.isShot = false; self.speedY = 0; }; }); /****************************************************************************************** */ /************************************** BASKET ******************************************** */ /****************************************************************************************** */ // Basket class to group backboard, basketBallPost, and hoop var Basket = Container.expand(function () { var self = Container.call(this); self.x = 1024; self.y = 300; self.hoopX = 1024; self.hoopY = 270; self.hoopW = 182; self.hoppBumpW = 10; self.hoopLeftBumpX = 1024 - 182 / 2 + self.hoppBumpW / 2; self.hoopRightBumpX = 1024 + 182 / 2 - self.hoppBumpW / 2; // Create and attach basketBallPost asset self.basketBallPost = self.attachAsset('post', { anchorX: 0.5, anchorY: 1.0, x: 0, y: self.y + 150 // Base of the post aligns with the bottom of the Basket container }); // Create and attach backboard asset self.backboard = self.attachAsset('backBoard', { anchorX: 0.5, anchorY: 0.5, x: 0, y: self.y - 420 }); // Create and attach backboardInner part under backboard self.backboardInner = self.attachAsset('backBoardInner', { anchorX: 0.5, anchorY: 0.5, x: 0, y: self.y - 420 }); // Create and attach hoop asset self.hoop = self.attachAsset('hoop', { anchorX: 0.5, anchorY: 0.5, x: self.x - 1024, // Same as Basket y: self.y - 350 }); // Create and attach leftHoopBumper asset self.leftHoopBumper = self.attachAsset('hoopBumper', { anchorX: 0.5, anchorY: 0.5, x: self.hoopLeftBumpX - self.x, y: self.y - 350 }); // Create and attach rightHoopBumper asset self.rightHoopBumper = self.attachAsset('hoopBumper', { anchorX: 0.5, anchorY: 0.5, x: self.hoopRightBumpX - self.x, y: self.y - 350 }); }); /****************************************************************************************** */ /************************************** PLAYER ******************************************** */ /****************************************************************************************** */ var Player = Container.expand(function (isAI, tint) { var self = Container.call(this); self.isAI = isAI; // New property to indicate if the player is controlled by AI self.tint = tint; // Default tint color for player self.hasBall = false; // New property to indicate if the player has the ball self.currentPosture = ""; // New property to store the name of the current posture self.isChangingPosture = false; // 0 when idle or moving down, 1 when moving up self.nextPosture = null; self.isMovingUp = 0; // 0 when idle or moving down, 1 when moving up self.currentTargetPosition = null; self.moveToTarget = false; self.head = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 1, tint: self.tint }); self.eyes = self.attachAsset('eyes', { anchorX: 0.5, anchorY: 0.75, scaleX: 0.8, scaleY: 1, tint: 0xFFFFFF }); self.rightArm = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 1, scaleX: 0.5, scaleY: 1.5, tint: self.tint }); self.rightHand = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.75, scaleY: 0.5, tint: self.tint }); self.leftArm = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 1, scaleX: 0.5, scaleY: 1.5, tint: self.tint }); self.leftHand = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.75, scaleY: 0.5, tint: self.tint }); self.trunk = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 2.0, tint: self.tint }); self.rightLeg = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 2, tint: self.tint }); self.rightFoot = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.75, scaleY: 0.5, tint: self.tint }); self.leftLeg = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 2, tint: self.tint }); self.leftFoot = self.attachAsset('bodyPart', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.75, scaleY: 0.5, tint: self.tint }); self.updatePosture = function () { var speed = 0.2; //0.1; // Speed of transition if (!this.targetPosture) { return; } // Check if the target posture for hands and legs is reached //console.log("this.targetPosture: " + this.targetPosture.name + " : this.rightHand.x: " + this.rightHand.x, " this.targetPosture.rightHand.x: " + this.targetPosture.rightHand.x); var handsAndLegsReached = Math.abs(this.rightHand.x - this.targetPosture.rightHand.x) < 1 && Math.abs(this.rightHand.y - this.targetPosture.rightHand.y) < 1 && Math.abs(this.leftHand.x - this.targetPosture.leftHand.x) < 1 && Math.abs(this.leftHand.y - this.targetPosture.leftHand.y) < 1 && Math.abs(this.rightLeg.x - this.targetPosture.rightLeg.x) < 1 && Math.abs(this.rightLeg.y - this.targetPosture.rightLeg.y) < 1 && Math.abs(this.leftLeg.x - this.targetPosture.leftLeg.x) < 1 && Math.abs(this.leftLeg.y - this.targetPosture.leftLeg.y) < 1 && Math.abs(this.head.x - this.targetPosture.head.x) < 1 && Math.abs(this.head.y - this.targetPosture.head.y) < 1 && Math.abs(this.eyes.x - this.targetPosture.eyes.x) < 1 && Math.abs(this.eyes.y - this.targetPosture.eyes.y) < 1 && Math.abs(this.rightFoot.x - this.targetPosture.rightFoot.x) < 1 && Math.abs(this.rightFoot.y - this.targetPosture.rightFoot.y) < 1 && Math.abs(this.leftFoot.x - this.targetPosture.leftFoot.x) < 1 && Math.abs(this.leftFoot.y - this.targetPosture.leftFoot.y) < 1; if (handsAndLegsReached) { //console.log("handsAndLegsReached !"); // Update currentPosture to the name of the targetPosture when hands and legs posture is reached this.currentPosture = this.targetPosture.name; this.targetPosture = null; self.isChangingPosture = false; if (self.nextPosture) { self.setPosture(self.nextPosture); } return; } else { self.isChangingPosture = true; } if (this.targetPosture && this.targetPosture.head) { this.head.x += (this.targetPosture.head.x - this.head.x) * speed; } if (this.targetPosture && this.targetPosture.eyes) { this.eyes.x += (this.targetPosture.eyes.x - this.eyes.x) * speed; this.eyes.y += (this.targetPosture.eyes.y - this.eyes.y) * speed; self.updateEyes(); } this.head.y += (this.targetPosture.head.y - this.head.y) * speed; this.rightArm.x += (this.targetPosture.rightArm.x - this.rightArm.x) * speed; this.rightArm.y += (this.targetPosture.rightArm.y - this.rightArm.y) * speed; this.rightHand.x += (this.targetPosture.rightHand.x - this.rightHand.x) * speed; this.rightHand.y += (this.targetPosture.rightHand.y - this.rightHand.y) * speed; this.leftArm.x += (this.targetPosture.leftArm.x - this.leftArm.x) * speed; this.leftArm.y += (this.targetPosture.leftArm.y - this.leftArm.y) * speed; this.leftHand.x += (this.targetPosture.leftHand.x - this.leftHand.x) * speed; this.leftHand.y += (this.targetPosture.leftHand.y - this.leftHand.y) * speed; this.trunk.x += (this.targetPosture.trunk.x - this.trunk.x) * speed; this.trunk.y += (this.targetPosture.trunk.y - this.trunk.y) * speed; this.rightLeg.x += (this.targetPosture.rightLeg.x - this.rightLeg.x) * speed; this.rightLeg.y += (this.targetPosture.rightLeg.y - this.rightLeg.y) * speed; this.rightFoot.x += (this.targetPosture.rightFoot.x - this.rightFoot.x) * speed; this.rightFoot.y += (this.targetPosture.rightFoot.y - this.rightFoot.y) * speed; this.leftLeg.x += (this.targetPosture.leftLeg.x - this.leftLeg.x) * speed; this.leftLeg.y += (this.targetPosture.leftLeg.y - this.leftLeg.y) * speed; this.leftFoot.x += (this.targetPosture.leftFoot.x - this.leftFoot.x) * speed; this.leftFoot.y += (this.targetPosture.leftFoot.y - this.leftFoot.y) * speed; }; self.updatePosition = function () { self.isMoving = false; self.speedX = 0; self.speedY = 0; if (!self.isAI && joystickDrag && !isThrowingMode) { self.isMoving = true; var dx = joystick.x - joystickBasePosition.x; var dy = joystick.y - joystickBasePosition.y; self.speedX = dx * 0.15; // Adjust speed factor as needed self.speedY = dy * 0.15; // Adjust speed factor as needed } if (self.isAI && self.moveToTarget && self.currentTargetPosition) { var dx = self.currentTargetPosition.x - self.x; var dy = self.currentTargetPosition.y - self.y; self.speedX = dx > 50 ? 10 : dx < -50 ? -10 : 0; // Set constant speed regardless of distance self.speedY = dy > 50 ? 10 : dy < -50 ? -10 : 0; // Set constant speed regardless of distance // Check if the AI player has reached the target position within a certain threshold //console.log("dx,dy)", dx, dy, " => speedX,speedY", self.speedX, self.speedY); if (!self.speedX && !self.speedY) { console.warn("Reached target!"); self.moveToTarget = false; // Stop moving towards the target self.currentTargetPosition = null; // Clear the target position } } // Apply speed self.x += self.speedX; self.y += self.speedY; //debugTxt.setText("Player X: " + self.x.toFixed(2) + ", Y: " + self.y.toFixed(2)); //console.log("Player speedY: ", self.speedY); // Log player's vertical speed self.isMovingUp = self.speedY < 0 ? 1 : 0; self.updateEyes(); // Boundary checks if (self.x < courtLeftBoundary + self.width / 2) { self.x = courtLeftBoundary + self.width / 2; } else if (self.x > courtRightBoundary - self.width / 2) { self.x = courtRightBoundary - self.width / 2; } if (self.y < courtTopBoundary - 0) { self.y = courtTopBoundary - 0; } else if (self.y > courtBottomBoundary - 275) { self.y = courtBottomBoundary - 275; } // Posture updates based on movement if (self.isMoving) { var currentTick = LK.ticks; if (currentTick % 20 < 10) { self.setPosture(self.hasBall ? runningUpWithBall1 : runningUp1); } else { self.setPosture(self.hasBall ? runningUpWithBall2 : runningUp2); } } else { if (self.hasBall) { if (isThrowingMode) {} else { self.setPosture(Math.abs(ball.y - self.y) > 150 ? dribblingPosture1 : dribblingPosture2); } } else { //console.log("No ball => idle" + self.hasBall); self.setPosture(idlePosture); } } }; self.updateEyes = function () { self.eyes.visible = enableEye && !self.isMovingUp && (self.isAI || !isThrowingMode); }; self.setPosture = function (newPosture) { //console.log("Entering setPosture " + self.currentPosture + " => " + newPosture.name); if (self.isChangingPosture) { //console.log("Already changing"); // Store next posture for when target one is reached self.nextPosture = newPosture; return; } if (self.nextPosture) { // If a next posture is set, use it as target newPosture = self.nextPosture; self.nextPosture = null; } if (newPosture && self.currentPosture != newPosture.name) { self.targetPosture = newPosture; } else { //console.log("Already in posture"); } }; }); /****************************************************************************************** */ /************************************** TARGET LINE *************************************** */ /****************************************************************************************** */ // Class for the targeting line made of targetDots var TargetingLine = Container.expand(function () { var self = Container.call(this); self.dots = []; self.steps = 20; // Initialize 10 dots for the targeting line for (var i = 0; i < self.steps; i++) { var dot = self.attachAsset('targetDot', { anchorX: 0.5, anchorY: 0.5, visible: false // Initially not visible }); self.dots.push(dot); } // Method to update the targeting line self.updateLine = function (startX, startY, endX, endY) { // Controls only the dots positions, not their visibility if (this.isUpdating) { return; } this.isUpdating = true; // Calculate line direction and distance var dx = endX - startX; var dy = endY - startY; var distance = Math.sqrt(dx * dx + dy * dy); var parabolRatio = Math.min(Math.max(Math.abs(dy / 20), 10), 40); //console.log("dy: " + (dy + game.height * 0.25) + ", ParabolRatio: " + parabolRatio); var stepX = dx / self.steps; var stepY = dy / self.steps; // Update positions of existing dots along the line for (var i = 0; i < self.steps; i++) { if (self.dots[i]) { // Calculate offset to only go up var offset = -parabolRatio * i * Math.sin(Math.PI / self.steps * i); self.dots[i].x = startX + stepX * i; self.dots[i].y = startY + stepY * i + offset; } } this.isUpdating = false; // Store dots coordinates in currentTrajectory currentTrajectory = self.dots.map(function (dot) { return { x: dot.x, y: dot.y }; }); }; // Method to hide the targeting line self.showLine = function () { // Controls only the dots visibility, not their positions self.visible = true; self.dots.forEach(function (dot) { dot.visible = true; }); }; self.hideLine = function () { // Controls only the dots visibility, not their positions self.visible = false; self.dots.forEach(function (dot) { dot.visible = false; }); }; }); /**** * Initialize Game ****/ /******* Retro Basket ******** A retro basketball game. It's a one vs one basketball game. Ball is lanched in the middle. Players must run and catch it, then throw it in the hoop. *****************************/ var game = new LK.Game({ backgroundColor: 0x000000 // Sky blue background }); /**** * Game Code ****/ // Enumeration for AI states var AI_STATE = { IDLE: 'IDLE', MOVE_TO_BALL: 'MOVE_TO_BALL', MOVE_TO_BLOCK: 'MOVE_TO_BLOCK', BLOCKING: 'BLOCKING', MOVE_TO_THROW: 'MOVE_TO_THROW', THROWING: 'THROWING' }; // Enumeration for game states var GAME_STATE = { INIT: 'INIT', MENU: 'MENU', STARTING: 'STARTING', PLAYING: 'PLAYING', SCORE: 'SCORE' }; var gameState = GAME_STATE.INIT; var aiState = AI_STATE.IDLE; var isDebug = true; var player = null; var player2 = null; var ball = null; var basket = null; var court = null; var courtBackground = null; var startButton = null; var mesureFlag = null; var joystick = null; var debugTxt = null; var scoreTxt = null; var score = 0; var joystickBasePosition = null; var joystickDrag = false; var lastTouchDownTime = 0; // Timestamp of the last touch down event var touchTapThreshold = 200; // Milliseconds within which a touch is considered a tap var isTapGesture = false; // Flag to differentiate between tap and drag gestures var isThrowingMode = 0; // 0 = Move mode; 1 = Throw mode var targetingLine = null; var enableEye = true; var courtTopY = 750; var courtCenterY = 1500; // court asset height 2056/2+750 (top) = 1778 ~= 1700 | v2 : 2250/2+750 = 1875 var courtBottomY = 2240; var targetPointXOffsetDirection = 1; var targetPointYOffsetDirection = 1; var targetPointXOffset = 0; var targetPointYOffset = -50; // Offset above hoop for targetting var targetPointXOffsetIncrement = 5; // Increment or decrement offset by 10 var targetPointXOffsetBounds = 220; // Bounds for changing direction var targetPointYOffsetIncrement = 2; // Increment or decrement offset by 10 var targetPointYOffsetBounds = 100; // Bounds for changing direction var currentTrajectory = []; // Define court boundaries as global variables var courtTopBoundary = 750 - 230; var courtBottomBoundary = 2240; var courtLeftBoundary = 0; var courtRightBoundary = 2048; // Global array to store court positions var courtPositions = []; for (var i = 1; i <= 3; i++) { for (var j = 1; j <= 3; j++) { courtPositions.push({ x: i * game.width / 4, y: courtTopY + (i * 3 + j) * court.height / 4 }); } } // Moved courtPositions population to gameInitialize to ensure game object is initialized var distanceImprecisionMin = 1; var distanceImprecisionMax = 20; /****************************************************************************************** */ /************************************** POSTURES ****************************************** */ /****************************************************************************************** */ var idlePosture = { name: "idlePosture", x: 1024, y: 2000, head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 110, y: 50 }, rightHand: { x: 125, y: 30 }, leftArm: { x: -110, y: 50 }, leftHand: { x: -120, y: 30 }, trunk: { x: 0, y: 0 }, rightLeg: { x: 37.5, y: 150 }, rightFoot: { x: 50, y: 250 }, leftLeg: { x: -37.5, y: 150 }, leftFoot: { x: -50, y: 250 } }; var dribblingPosture1 = { name: "dribblingPosture1", x: 1024, // Center X y: 2000, // Player Y position head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 90, y: 50 // Adjusted from -20 to 50 }, rightHand: { x: -90, y: 30 }, leftArm: { x: -90, y: 50 // Adjusted from -20 to 50 }, leftHand: { x: 90, y: 30 }, trunk: { x: 0, y: 0 }, rightLeg: { x: 40, y: 150 }, rightFoot: { x: 50, y: 250 }, leftLeg: { x: -40, y: 150 }, leftFoot: { x: -50, y: 250 } }; var dribblingPosture2 = { name: "dribblingPosture2", x: 1024, // Center X y: 2000, // Player Y position head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 90, y: 50 // Adjusted from -20 to 50 }, rightHand: { x: -90, y: 50 }, leftArm: { x: -90, y: 50 // Adjusted from -20 to 50 }, leftHand: { x: 90, y: 50 }, trunk: { x: 0, y: 0 }, rightLeg: { x: 40, y: 150 }, rightFoot: { x: 50, y: 250 }, leftLeg: { x: -40, y: 150 }, leftFoot: { x: -50, y: 250 } }; var runningUp1 = { name: "runningUp1", x: 1024, // Center X y: 2000, // Player Y position head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 90, y: 50 // Adjusted from -20 to 50 by adding 70 }, rightHand: { x: 105, y: 30 }, leftArm: { x: -90, y: 50 }, leftHand: { x: -105, y: 30 }, trunk: { x: 0, y: 0 }, rightLeg: { x: 40, y: 100 }, rightFoot: { x: 50, y: 200 }, leftLeg: { x: -40, y: 150 }, leftFoot: { x: -50, y: 250 } }; var runningUp2 = { name: "runningUp2", x: 1024, // Center X y: 2000, // Player Y position head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 80, y: 50 // Adjusted from -20 to 50 by adding 70 }, rightHand: { x: 95, y: 30 }, leftArm: { x: -80, y: 50 }, leftHand: { x: -95, y: 30 }, trunk: { x: 0, y: 0 }, rightLeg: { x: 40, y: 150 }, rightFoot: { x: 50, y: 250 }, leftLeg: { x: -40, y: 100 }, leftFoot: { x: -50, y: 200 } }; var runningUpWithBall1 = { name: "runningUpWithBall1", x: 1024, // Center X y: 2000, // Player Y position head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 90, y: 20 // Adjusted from -20 to 50 by adding 70 }, rightHand: { x: -0, y: -20 }, leftArm: { x: -90, y: 20 }, leftHand: { x: 0, y: -20 }, trunk: { x: 0, y: 0 }, rightLeg: { x: 40, y: 100 }, rightFoot: { x: 50, y: 200 }, leftLeg: { x: -40, y: 150 }, leftFoot: { x: -50, y: 250 } }; var runningUpWithBall2 = { name: "runningUpWithBall2", x: 1024, // Center X y: 2000, // Player Y position head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 80, y: -20 // Adjusted from -90 to -20 by adding 70 }, rightHand: { x: 5, y: 15 }, leftArm: { x: -80, y: -20 }, leftHand: { x: 5, y: 15 }, trunk: { x: 0, y: 0 }, rightLeg: { x: 40, y: 150 }, rightFoot: { x: 50, y: 250 }, leftLeg: { x: -40, y: 100 }, leftFoot: { x: -50, y: 200 } }; var throwingPosture = { name: "throwingPosture", x: 1024, y: 2000, head: { x: 0, y: -160 }, eyes: { x: 0, y: -160 }, rightArm: { x: 100, y: -120 }, rightHand: { x: 100, y: -250 // Set the right hand at the top of the right arm }, leftArm: { x: -100, y: -120 }, leftHand: { x: -100, y: -250 // Set the left hand at the top of the left arm }, trunk: { x: 0, y: 0 }, rightLeg: { x: 37.5, y: 150 }, rightFoot: { x: 50, y: 250 }, leftLeg: { x: -37.5, y: 150 }, leftFoot: { x: -50, y: 250 } }; /****************************************************************************************** */ /*********************************** UTILITY FUNCTIONS ************************************ */ /****************************************************************************************** */ function isPointInEllipse(x, y) { console.log("isPointInEllipse:", x, y); // Coordonnées du centre de l'ellipse var x0 = 1024; // Centre du canvas var y0 = 1170; // Centre du canvas var rX = 720; var rY = 600; var dX = Math.abs(x - x0); var dY = Math.abs(y - y0); var d = Math.sqrt(Math.pow(dX, 2) + Math.pow(dY, 2)); // Calcul de l'angle polaire du point par rapport au centre de l'ellipse var angle = Math.atan2(y - y0, x - x0); if (angle < 0) { angle += 2 * Math.PI; // Convertit l'angle en radians positifs } var factor = Math.abs(Math.cos(angle)); // factor will be 1 at 0, PI/2, PI, 3*PI/2 and smaller near PI/4 and 3*PI/4 var xt = x0 + rX * Math.cos(angle) / Math.sqrt(1 / factor); var yt = y0 + rY * Math.sin(angle); var radiusAtAngle = Math.sqrt(Math.pow(xt - x0, 2) + Math.pow(yt - y0, 2)); /* mesureFlag.x = x0; mesureFlag.y = y0; mesureFlag.rotation = angle; mesureFlag.width = d; console.log("Angle : ", angle, "Radius : ", radiusAtAngle, "Dist : ", d, " => inside ", d <= radiusAtAngle); drawElipse(x0, y0, rX, rY); */ return d <= radiusAtAngle; } function drawElipse(x0, y0, rX, rY) { for (var angle = 0; angle < 2 * Math.PI; angle += 0.1) { var factor = Math.abs(Math.cos(angle)); // factor will be 1 at 0, PI/2, PI, 3*PI/2 and smaller near PI/4 and 3*PI/4 var xt = x0 + rX * Math.cos(angle) / Math.sqrt(1 / factor); var yt = y0 + rY * Math.sin(angle); // / Math.sqrt(factor * 1.0); var dot = game.addChild(LK.getAsset('targetDot', { anchorX: 0.5, anchorY: 0.5, x: xt, y: yt, visible: true })); } } /****************************************************************************************** */ /*********************************** INPUT HANDLERS *************************************** */ /****************************************************************************************** */ function onDownPlaying(obj) { lastTouchDownTime = Date.now(); // Capture the current timestamp when touch starts var pos = obj.event.getLocalPosition(game); // Calculate distance between click and joystick center var distance = Math.sqrt(Math.pow(pos.x - joystick.x, 2) + Math.pow(pos.y - joystick.y, 2)); // If click is within joystick radius, start dragging if (distance <= joystick.width / 2) { joystickDrag = true; } } function onMovePlaying(obj) { var pos = obj.event.getLocalPosition(game); if (joystickDrag) { var dx = pos.x - joystickBasePosition.x; var dy = pos.y - joystickBasePosition.y; var distance = Math.sqrt(dx * dx + dy * dy); var maxDistance = joystick.width / 4; // Max distance joystick can move from center if (distance > maxDistance) { var angle = Math.atan2(dy, dx); dx = Math.cos(angle) * maxDistance; dy = Math.sin(angle) * maxDistance; } joystick.x = joystickBasePosition.x + dx; joystick.y = joystickBasePosition.y + dy; if (isThrowingMode) { //console.log("Using joysting in throwing mode..."); var armRotationFactor = 0.05; // Factor to control the rotation sensitivity var armRotation = Math.max(-Math.PI / 1.8, Math.min(Math.PI / 1.8, dx * armRotationFactor)); // Clamp rotation between -100 and 100 degrees converted to radians // Log armRotation in degrees //console.log("Arm rotation: " + (armRotation * (180 / Math.PI)).toFixed(2) + " degrees"); player.rightArm.rotation = armRotation; player.leftArm.rotation = armRotation; // Calculate the top position of the arms and move hands to follow the arms' movement var rightArmTopX = player.rightArm.x + Math.cos(player.rightArm.rotation - Math.PI / 2) * (player.rightArm.height + player.rightHand.height / 1.5); var rightArmTopY = player.rightArm.y + Math.sin(player.rightArm.rotation - Math.PI / 2) * (player.rightArm.height + player.rightHand.height / 1.5); var leftArmTopX = player.leftArm.x + Math.cos(player.leftArm.rotation - Math.PI / 2) * (player.leftArm.height + player.rightHand.height / 1.5); var leftArmTopY = player.leftArm.y + Math.sin(player.leftArm.rotation - Math.PI / 2) * (player.leftArm.height + player.rightHand.height / 1.5); //console.log("rightArmTopX: " + rightArmTopX.toFixed(2) + " y " + rightArmTopY.toFixed(2)); player.rightHand.x = rightArmTopX; player.rightHand.y = rightArmTopY; player.leftHand.x = leftArmTopX; player.leftHand.y = leftArmTopY; } else { //console.log("Using joysting in moving mode..."); } } } function onUpPlaying(obj) { var touchDuration = Date.now() - lastTouchDownTime; // Calculate the duration of the touch isTapGesture = touchDuration <= touchTapThreshold; // Determine if the gesture is a tap based on the duration if (isTapGesture && player.hasBall) { if (isThrowingMode == 1) { var targetPointX = basket.hoop.x; var targetPointY = basket.hoop.y; ball.shootBall(targetPointX, targetPointY); player.hasBall = false; } isThrowingMode = 1 - isThrowingMode; // Toggle isThrowingMode between 0 and 1 console.log("isThrowingMode: " + isThrowingMode); // Log the current joystick mode // Correctly toggle the joystick asset based on isThrowingMode if (isThrowingMode == 1) { joystick.attachAsset('buttonA', { anchorX: 0.5, anchorY: 0.5 }); player.setPosture(throwingPosture); console.log("=> show targeting line"); // Log the current joystick mode LK.setTimeout(function () { targetingLine.showLine(); }, 250); } else { player.rightArm.rotation = 0; player.leftArm.rotation = 0; joystick.attachAsset('joystick', { anchorX: 0.5, anchorY: 0.5 }); targetingLine.hideLine(); // Hide targeting line } joystickDrag = false; } else if (joystickDrag) { joystickDrag = false; joystick.x = joystickBasePosition.x; joystick.y = joystickBasePosition.y; } } game.on('down', function (obj) { switch (gameState) { case GAME_STATE.MENU: // Handle menu logic here break; case GAME_STATE.STARTING: // Handle game starting logic here break; case GAME_STATE.PLAYING: onDownPlaying(obj); break; case GAME_STATE.SCORE: // Handle score display logic here break; } }); game.on('move', function (obj) { switch (gameState) { case GAME_STATE.MENU: // Handle menu logic here break; case GAME_STATE.STARTING: // Handle game starting logic here break; case GAME_STATE.PLAYING: onMovePlaying(obj); break; case GAME_STATE.SCORE: // Handle score display logic here break; } }); game.on('up', function (obj) { switch (gameState) { case GAME_STATE.MENU: // Handle menu logic here break; case GAME_STATE.STARTING: // Handle game starting logic here break; case GAME_STATE.PLAYING: onUpPlaying(obj); break; case GAME_STATE.SCORE: // Handle score display logic here break; } }); // Test postures /* var idle = true; var changePostureTimer = LK.setInterval(function () { if (idle) { player.setPosture(runningUp1); idle = false; } else { player.setPosture(runningUp2); idle = true; } }, 1000); */ /****************************************************************************************** */ /************************************* AI FUNCTIONS **************************************** */ /****************************************************************************************** */ function aiThinking() { if (LK.ticks % 60 !== 0) { return; } var initState = aiState; // Determine AI state based on the ball's situation if (!ball.currentPlayer) { // If the ball is not currently hold, move towards the ball aiState = AI_STATE.MOVE_TO_BALL; } else if (ball.currentPlayer === player2) { // If the ball is being shot and the AI is the current player, prepare to throw aiState = AI_STATE.MOVE_TO_THROW; } else if (ball.currentPlayer && ball.currentPlayer !== player2) { // If the ball is being shot and the AI is not the current player, attempt to block aiState = AI_STATE.MOVE_TO_BLOCK; } // Log the current AI state for debugging purposes console.log("aiThinking... State: " + initState + " -> " + aiState); } function aiActing() { if (LK.ticks % 10 !== 0) { return; } console.log("aiActing... State: " + aiState); switch (aiState) { case AI_STATE.MOVE_TO_BALL: if (!player2.currentTargetPosition) { player2.currentTargetPosition = { x: ball.x, y: ball.y }; player2.moveToTarget = true; } else { console.log("Already have target..."); } break; case AI_STATE.MOVE_TO_THROW: break; case AI_STATE.MOVE_TO_BLOCK: break; default: // IDLE break; } } /****************************************************************************************** */ /************************************* GAME STATES **************************************** */ /****************************************************************************************** */ function gameInitialize() { courtBackground = game.addChild(LK.getAsset('courtBackground', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: courtCenterY })); court = game.addChild(LK.getAsset('Court', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: courtCenterY, scaleX: 1.08, scaleY: 0.90, tint: 0xb27747 })); basket = game.addChild(new Basket()); startButton = game.addChild(LK.getAsset('startButton', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, visible: false, interactive: false })); mesureFlag = game.addChild(LK.getAsset('mesureFlag', { anchorX: 0, anchorY: 0.5, x: 3 * game.width / 4, y: courtTopY + 3 * court.height / 4, width: 20, rotation: 2 * Math.PI / 2, visible: isDebug })); debugTxt = new Text2("Court Top: " + (court.y - court.height / 2), { size: 50, fill: "#ffffff" }); debugTxt.visible = isDebug; debugTxt.x = 20; debugTxt.y = 20; LK.gui.topLeft.addChild(debugTxt); gameInitStateMenu(); } function gameSwitchNextState() { console.log("gameSwitchNextState...from", gameState); switch (gameState) { case GAME_STATE.MENU: gameCleanStateMenu(); gameInitStateStarting(); break; case GAME_STATE.STARTING: gameCleanStateStarting(); gameInitStatePlaying(); break; case GAME_STATE.PLAYING: break; case GAME_STATE.SCORE: // Handle score display logic here break; default: // INIT gameInitStateMenu(); break; } } function gameInitStateMenu() { console.log("gameInitStateMenu..."); gameState = GAME_STATE.MENU; startButton.visible = true; startButton.interactive = true; // Add event listener to startButton to switch game state on press startButton.on('down', function () { var originalWidth = startButton.width; var originalHeight = startButton.height; var shrinkWidth = originalWidth * 0.6; var shrinkHeight = originalHeight * 0.6; var enlargeWidth = originalWidth * 20; var enlargeHeight = originalHeight * 20; var animationSteps = 100; var currentStep = 0; startButton.alpha = 1; var animationInterval = LK.setInterval(function () { if (currentStep < animationSteps / 5) { // Shrink startButton.width -= (originalWidth - shrinkWidth) / (animationSteps / 5); startButton.height -= (originalHeight - shrinkHeight) / (animationSteps / 5); } else if (currentStep < animationSteps) { // Enlarge startButton.width += (enlargeWidth - originalWidth) / (animationSteps / 5); startButton.height += (enlargeHeight - originalHeight) / (animationSteps / 5); startButton.alpha -= 0.01; } else { // Reset to original size and clear interval startButton.width = originalWidth; startButton.height = originalHeight; LK.clearInterval(animationInterval); gameSwitchNextState(); } currentStep++; }, 5); }); debugTxt.setText("MENU"); } function gameCleanStateMenu() { console.log("gameCleanStateMenu..."); startButton.visible = false; startButton.interactive = false; debugTxt.setText("MENU => STARTING"); } function gameInitStateStarting() { console.log("gameInitStateStarting..."); gameState = GAME_STATE.STARTING; debugTxt.setText("STARTING"); // Create and position the joystick joystick = game.addChild(LK.getAsset('joystick', { anchorX: 0.5, anchorY: 0.5, alpha: 0.75, x: 2048 / 2, y: 2732 - 300 })); player = game.addChild(new Player(false, 0x0000FF)); player.x = 800; //2048 / 2; // Center X player.y = 2000; //2732 / 2; // Center Y player.setPosture(idlePosture); player2 = game.addChild(new Player(true, 0xFF0000)); // Instantiate player2 as AI with red tint player2.x = 1248; // Position player2 slightly to the right of player1 player2.y = 2000; // Same Y position as player1 player2.setPosture(idlePosture); ball = game.addChild(new Ball()); ball.reset(); scoreTxt = new Text2(score.toString(), { size: 150, fill: "#ffffff" }); scoreTxt.x = -180; scoreTxt.y = -10; LK.gui.topRight.addChild(scoreTxt); joystickBasePosition = { x: joystick.x, y: joystick.y }; targetingLine = new TargetingLine(); game.addChild(targetingLine); LK.setTimeout(gameSwitchNextState, 1000); } function gameCleanStateStarting() { console.log("gameCleanStateStarting..."); debugTxt.setText("STARTING => PLAYING"); } function gameInitStatePlaying() { console.log("gameInitStatePlaying..."); gameState = GAME_STATE.PLAYING; debugTxt.setText("PLAYING"); } function gamePlaying() { ball.update(); // Check if player's trunk intersects with the ball if (!ball.currentPlayer) { if (player.trunk.intersects(ball) || player.rightLeg.intersects(ball) || player.leftLeg.intersects(ball)) { ball.currentPlayer = player; // Assign the player to the ball's currentPlayer property ball.catched(); player.hasBall = true; // Assign the player to the ball's currentPlayer property } if (player2.trunk.intersects(ball) || player2.rightLeg.intersects(ball) || player2.leftLeg.intersects(ball)) { ball.currentPlayer = player2; // Assign the player to the ball's currentPlayer property ball.catched(); player2.hasBall = true; // Assign the player to the ball's currentPlayer property } } // Make the ball follow the currentPlayer's position with dribble movement if (ball.currentPlayer && !ball.isFollowTrajectory) { ball.x = ball.currentPlayer.x; if (isThrowingMode == 1) { // Dynamically make the ball follow the player's hands position in throwing mode // Calculate the middle position between the two hands var middleHandX = (ball.currentPlayer.rightHand.x + ball.currentPlayer.leftHand.x) / 2 + ball.currentPlayer.x; var middleHandY = (ball.currentPlayer.rightHand.y + ball.currentPlayer.leftHand.y) / 2 + ball.currentPlayer.y; ball.x = middleHandX; ball.y = middleHandY; //Update the targeting line from the ball to the hoop var distanceToHoop = Math.sqrt(Math.pow(basket.x - ball.currentPlayer.x, 2) + Math.pow(basket.y - ball.currentPlayer.y, 2)); // Calculate distanceImprecisionRatio based on distanceToHoop, clamped between 0.5 and 2 var distanceImprecisionRatio = Math.min(Math.max(distanceToHoop / 600, distanceImprecisionMin), distanceImprecisionMax); targetPointXOffset += targetPointXOffsetDirection * targetPointXOffsetIncrement * distanceImprecisionRatio; // Increment or decrement offset if (targetPointXOffset >= targetPointXOffsetBounds || targetPointXOffset <= -targetPointXOffsetBounds) { targetPointXOffsetDirection *= -1; // Change direction } targetPointYOffset += targetPointYOffsetDirection * targetPointYOffsetIncrement * distanceImprecisionRatio; // Increment or decrement offset if (targetPointYOffset >= targetPointYOffsetBounds || targetPointYOffset <= -targetPointYOffsetBounds) { targetPointYOffsetDirection *= -1; } var targetPointX = basket.x + targetPointXOffset + (middleHandX - ball.currentPlayer.x); var targetPointY = basket.y + targetPointYOffset + (middleHandY - ball.currentPlayer.y + 200); targetingLine.updateLine(ball.x, ball.y, targetPointX, targetPointY); // This line is removed to rely on updateLine method for visibility control game.addChild(ball.currentPlayer); // Ensure player is in front by re-adding it to the game } else if (ball.currentPlayer.isMovingUp === 0) { targetingLine.hideLine(); ball.y = ball.currentPlayer.y + 150 + Math.sin(LK.ticks / (ball.currentPlayer.isMoving ? 4 : 7)) * 100; game.addChild(ball); // Ensure ball is in front by re-adding it to the game } else { targetingLine.hideLine(); ball.y = ball.currentPlayer.y - 120 + Math.sin(LK.ticks / (ball.currentPlayer.isMoving ? 4 : 7)) * 50; game.addChild(ball.currentPlayer); // Ensure player is in front by re-adding it to the game } } player.updatePosture(); player.updatePosition(); player2.updatePosture(); player2.updatePosition(); // Re-add joystick to ensure it appears above other elements game.addChild(joystick); // Check if ball intersects with hoop and is moving downwards // Check if ball is passing between the hoop bumpers and moving downwards if (ball.y - ball.height / 2 < basket.hoopY && ball.speedY > 0 && ball.x > basket.hoopLeftBumpX && ball.x < basket.hoopRightBumpX && !ball.scoreCounted) { ball.aboveHoop = true; } else if (ball.aboveHoop && ball.y > basket.hoopY && ball.y < basket.hoopY + ball.height && ball.speedY > 0 && ball.x > basket.hoopLeftBumpX && ball.x < basket.hoopRightBumpX && !ball.scoreCounted) { var refX = player.x; var refY = player.y; refX += player.x > 1024 ? player.leftFoot.x : player.rightFoot.x; refY += player.x > 1024 ? player.leftFoot.y : player.rightFoot.y; console.log("isPointInEllipse:", isPointInEllipse(refX, refY)); var pointsScored = 2; // Default to 2 points if (refY <= 1170) { // Top rectangle area if (refX <= 300 || refX >= 1740) { pointsScored = 3; // Award 3 points for shots from the sides within the specified Y range } } else { // Elipse area pointsScored = isPointInEllipse(refX, refY) ? 2 : 3; } console.log(refX, refY, "=> " + Math.floor(Math.sqrt(Math.pow(refX - 1024, 2) + Math.pow(refY - 1200, 2))) + " => " + pointsScored + "pts"); score += pointsScored; scoreTxt.setText(score.toString()); ball.scoreCounted = true; // Mark score as counted to prevent multiple increments ball.aboveHoop = false; // Reset aboveHoop flag after scoring } // Reset ball if it goes off-screen // Check Y boundaries for the ball if (!ball.isFollowTrajectory && !ball.isFalling) { // when isFollowTrajectory might pass the top of screen if (ball.y < 0 + ball.height / 2) { ball.y = 0 + ball.height / 2; ball.speedY *= -0.5; // Bounce back with reduced speed } if (ball.y > courtBottomBoundary - ball.height / 2) { ball.y = courtBottomBoundary - ball.height / 2; ball.speedY *= -0.5; // Bounce back with reduced speed } } aiThinking(); aiActing(); } LK.on('tick', function () { switch (gameState) { case GAME_STATE.MENU: // Handle menu logic here break; case GAME_STATE.STARTING: // Handle game starting logic here break; case GAME_STATE.PLAYING: gamePlaying(); break; case GAME_STATE.SCORE: // Handle score display logic here break; } }); gameInitialize();
===================================================================
--- original.js
+++ change.js
@@ -640,8 +640,16 @@
var courtLeftBoundary = 0;
var courtRightBoundary = 2048;
// Global array to store court positions
var courtPositions = [];
+for (var i = 1; i <= 3; i++) {
+ for (var j = 1; j <= 3; j++) {
+ courtPositions.push({
+ x: i * game.width / 4,
+ y: courtTopY + (i * 3 + j) * court.height / 4
+ });
+ }
+}
// Moved courtPositions population to gameInitialize to ensure game object is initialized
var distanceImprecisionMin = 1;
var distanceImprecisionMax = 20;
/****************************************************************************************** */