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
Code edit (1 edits merged)
Please save this source code
User prompt
in Player class , in updatePosition, implement case if (self.isAI && self.moveToTarget)
Code edit (6 edits merged)
Please save this source code
User prompt
instead of moving ai player in aiActing() case MOVE_TO_BALL, just set a target position. use Player's : self.currentTargetPosition = null; self.moveToTarget = false;
Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
in aiActing, implement the case MOVE_TO_BALL
/****
* 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) {
if (self.currentTargetPosition) {
var dx = self.currentTargetPosition.x - self.x;
var dy = self.currentTargetPosition.y - self.y;
self.speedX = dx * 0.15; // Adjust speed factor as needed
self.speedY = dy * 0.15; // Adjust speed factor as needed
// Check if the AI player has reached the target position within a certain threshold
if (Math.abs(dx) < 10 && Math.abs(dy) < 10) {
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;
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: 10,
y: 2000,
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
@@ -425,9 +425,21 @@
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) {}
+ if (self.isAI && self.moveToTarget) {
+ if (self.currentTargetPosition) {
+ var dx = self.currentTargetPosition.x - self.x;
+ var dy = self.currentTargetPosition.y - self.y;
+ self.speedX = dx * 0.15; // Adjust speed factor as needed
+ self.speedY = dy * 0.15; // Adjust speed factor as needed
+ // Check if the AI player has reached the target position within a certain threshold
+ if (Math.abs(dx) < 10 && Math.abs(dy) < 10) {
+ 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));