Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Timeout.tick error: clearInterval is not a function' in or related to this line: 'clearInterval(animationInterval);' Line Number: 1342
Code edit (3 edits merged)
Please save this source code
User prompt
in gameInitStateMenu, animate the startButton push by progressively reducing then enlarging its width and height
Code edit (1 edits merged)
Please save this source code
User prompt
n gameInitStateMenu, animate the startButton push by downsizing then enlarging it
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: setInterval is not a function' in or related to this line: 'var scaleDownInterval = setInterval(function () {' Line Number: 1334
User prompt
in gameInitStateMenu, animate the startButton push by animating its scale
User prompt
LK.effects.flashObject(startButton, 0xffffff, 100, function () { gameSwitchNextState(); }); Doesn't work
Code edit (1 edits merged)
Please save this source code
User prompt
in gameInitStateMenu, animate the startButton push
Code edit (3 edits merged)
Please save this source code
User prompt
in gameCleanStateMenu, hide and disable the startButton
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'x')' in or related to this line: 'var distance = Math.sqrt(Math.pow(pos.x - joystick.x, 2) + Math.pow(pos.y - joystick.y, 2));' Line Number: 1101
User prompt
in gameInitStateMenu, add a startButton that calls function gameSwitchNextState() on press
Code edit (5 edits merged)
Please save this source code
User prompt
add a switch on gameState in tick event function
Code edit (1 edits merged)
Please save this source code
User prompt
move game initialisation code in a new function gameInitialize()
Code edit (2 edits merged)
Please save this source code
User prompt
move current code of LK.on('tick', function in a new global function gamePlaying()
User prompt
add a gameState global variable, defaulting to GAME_STATE.MENU
User prompt
add a GAME_STATE enumeration with values : MENU, STARTING, PLAYING, SCORE
/**** 
* Classes
****/ 
// Assets will be automatically created based on usage in the code.
// 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 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 - 400
	});
	// Create and attach backboardInner part under backboard
	self.backboardInner = self.attachAsset('backBoardInner', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 0,
		y: self.y - 400
	});
	// 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 - 330
	});
	// Create and attach leftHoopBumper asset
	self.leftHoopBumper = self.attachAsset('hoopBumper', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: self.hoopLeftBumpX - self.x,
		y: self.y - 330
	});
	// Create and attach rightHoopBumper asset
	self.rightHoopBumper = self.attachAsset('hoopBumper', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: self.hoopRightBumpX - self.x,
		y: self.y - 330
	});
});
// Hoop class for the basketball hoop
// var Hoop = Container.expand(function () {
// 	var self = Container.call(this);
// 	var hoopGraphics = self.attachAsset('hoop', {
// 		anchorX: 0.5,
// 		anchorY: 0.5
// 	});
// 	self.setPosition = function () {
// 		self.x = 1024; // Center X
// 		self.y = 200; // Hoop Y position
// 	};
// });
// Player class for the 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.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;
			this.eyes.visible = enableEye && !self.isMovingUp && !isThrowingMode;
		}
		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 (joystickDrag) {
			if (isThrowingMode) {} else {
				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
			}
		}
		// 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.eyes.visible = enableEye && !self.isMovingUp && !isThrowingMode;
		// 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.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");
		}
	};
});
// 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
****/ 
// Player positions
var game = new LK.Game({
	backgroundColor: 0x000000 // Sky blue background
});
/**** 
* Game Code
****/ 
// Enumeration for game states
var GAME_STATE = {
	MENU: 'MENU',
	STARTING: 'STARTING',
	PLAYING: 'PLAYING',
	SCORE: 'SCORE'
};
// Initialize gameState to MENU
var gameState = GAME_STATE.MENU;
// Create and position the court
var isDebug = true;
var courtTopY = 750;
var courtCenterY = 1500; //1525; // court asset height 2056/2+750 (top) = 1778 ~= 1700 | v2 : 2250/2+750 = 1875
var courtBottomY = 2240;
var courtBackground = game.addChild(LK.getAsset('courtBackground', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 2048 / 2,
	y: courtCenterY
}));
var 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 //AE4E00 // Brown tint
}));
// Create and position the Basket instance containing backboard, basketBallPost, and hoop
var basket = game.addChild(new Basket());
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;
var mesureFlag = game.addChild(LK.getAsset('mesureFlag', {
	anchorX: 0,
	anchorY: 0.5,
	x: 10,
	y: 2000,
	width: 20,
	rotation: 2 * Math.PI / 2,
	visible: isDebug
}));
// Create and position the joystick
var joystick = game.addChild(LK.getAsset('joystick', {
	anchorX: 0.5,
	anchorY: 0.5,
	alpha: 0.75,
	x: 2048 / 2,
	// Center X
	y: 2732 - 300
}));
/******* 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 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
	}
};
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 player = game.addChild(new Player(false, 0x0000FF));
player.x = 800; //2048 / 2; // Center X
player.y = 2000; //2732 / 2; // Center Y
player.setPosture(idlePosture);
var 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);
var ball = game.addChild(new Ball());
ball.reset();
var score = 0;
var 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);
var scoreTxt = new Text2(score.toString(), {
	size: 150,
	fill: "#ffffff"
});
scoreTxt.x = -180;
scoreTxt.y = -10;
var enableEye = true;
LK.gui.topRight.addChild(scoreTxt);
var joystickBasePosition = {
	x: joystick.x,
	y: joystick.y
};
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
		}));
	}
}
game.on('down', function (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;
	}
});
game.on('move', function (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...");
		}
	}
});
game.on('up', function (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;
	}
});
var idle = true;
// Test postures
/* 
var changePostureTimer = LK.setInterval(function () {
	if (idle) {
		player.setPosture(runningUp1);
		idle = false;
	} else {
		player.setPosture(runningUp2);
		idle = true;
	}
}, 1000);
*/ 
function gameInitialize() {
	targetingLine = new TargetingLine();
	game.addChild(targetingLine);
}
function gamePlaying() {
	ball.update();
	// Check if player's trunk intersects with the ball
	if (!player.hasBall && (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
	}
	// 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 - player.x, 2) + Math.pow(basket.y - player.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 - player.x);
			var targetPointY = basket.y + targetPointYOffset + (middleHandY - player.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
		}
	}
}
LK.on('tick', function () {
	gamePlaying();
});
gameInitialize(); ===================================================================
--- original.js
+++ change.js
@@ -562,11 +562,8 @@
 
 /**** 
 * Game Code
 ****/ 
-// Player positions
-function gameInitialize() {}
-gameInitialize();
 // Enumeration for game states
 var GAME_STATE = {
 	MENU: 'MENU',
 	STARTING: 'STARTING',
@@ -1040,8 +1037,14 @@
 		x: -50,
 		y: 250
 	}
 };
+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 player = game.addChild(new Player(false, 0x0000FF));
 player.x = 800; //2048 / 2; // Center X
 player.y = 2000; //2732 / 2; // Center Y
 player.setPosture(idlePosture);
@@ -1114,15 +1117,8 @@
 			visible: true
 		}));
 	}
 }
-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 = new TargetingLine();
-game.addChild(targetingLine);
 game.on('down', function (obj) {
 	lastTouchDownTime = Date.now(); // Capture the current timestamp when touch starts
 	var pos = obj.event.getLocalPosition(game);
 	// Calculate distance between click and joystick center
@@ -1220,8 +1216,12 @@
 		idle = true;
 	}
 }, 1000);
 */ 
+function gameInitialize() {
+	targetingLine = new TargetingLine();
+	game.addChild(targetingLine);
+}
 function gamePlaying() {
 	ball.update();
 	// Check if player's trunk intersects with the ball
 	if (!player.hasBall && (player.trunk.intersects(ball) || player.rightLeg.intersects(ball) || player.leftLeg.intersects(ball))) {
@@ -1313,5 +1313,6 @@
 	}
 }
 LK.on('tick', function () {
 	gamePlaying();
-});
\ No newline at end of file
+});
+gameInitialize();
\ No newline at end of file