Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 95
Code edit (5 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 95
Code edit (6 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: ticksBeforeNextPosition is not defined' in or related to this line: 'scoreTest = "actualPIx: " + self.actualPositionIndex + " goalPIx: " + self.goalPositionIndex + " assetsToUse: " + self.assetsToUse + " seqIxToUse: " + self.sequenceIndexToUse + "\nticksBeforeNextPosition: " + ticksBeforeNextPosition;' Line Number: 114
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 96
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 96
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 96
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 96
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 94
Code edit (13 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'trajectory')' in or related to this line: 'coconutChoosen.trajectory.isStarted = true;' Line Number: 138
Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'anchorX')' in or related to this line: 'monkeyAsset = self.attachAsset(newAssetId, {' Line Number: 69
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot set properties of undefined (setting 'anchorX')' in or related to this line: 'monkey.monkeyAsset.anchorX = 0.91;' Line Number: 421
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: initialAsset is not defined' in or related to this line: 'self.removeChild(initialAsset);' Line Number: 66
Code edit (1 edits merged)
Please save this source code
Code edit (8 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'x')' in or related to this line: 'monkey.sprite.x = 2048 / 2;' Line Number: 246
/**** 
* Classes
****/ 
// Class for the Coconut
var Coconut = Container.expand(function () {
	var self = Container.call(this);
	var coconutGraphics = self.attachAsset('coconut', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.isFalling = false;
	self.isBouncing = false;
	self.Xintercept = 0; //Abscisse d'interception du coconut avec le parasol
	self.Yintercept = 0; //Ordonnée d'interception du coconut avec le parasol
	self.trajectory = new Trajectory();
	self.update = function () {
		if (self.trajectory.typeTrajectory == -1) {
			self.trajectory.updateStatic();
		}
		if (self.trajectory.typeTrajectory == 0) {
			self.trajectory.updateLinear();
		}
		if (self.trajectory.typeTrajectory == 1) {
			self.trajectory.updateParabol();
		}
		self.y = self.trajectory.y;
		self.x = self.trajectory.x;
		self.isFalling = self.trajectory.isFalling;
		if (self.y > 2732) {
			self.destroy();
		}
	}; //fin update
});
//<Assets used in the game will automatically appear here>
// Class for the Monkey
var Monkey = Container.expand(function () {
	var self = Container.call(this);
	var monkeyAsset = self.attachAsset('monkeyToLeft', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.assetsToRight = ['monkeyToRight', 'monkeyInterRight'];
	self.assetsToLeft = ['monkeyToLeft', 'monkeyInterLeft'];
	self.sequenceIndexToCenter = [0, 1, 0];
	self.sequenceIndexToExtreme = [0, 1, 0, 1, 0];
	self.assetsToUse = [];
	self.sequenceIndexToUse = []; //Séquence des index des assets du monkey a utiliser
	self.sequenceIndex = 0; //Index de la séquence des assets du monkey
	self.actualPositionIndex = 0; //Positions de depart : 0 (XL), 1 (XC), 2 (XR) index du tableau startPoints
	self.goalPositionIndex = 0; //Positions d'arrivée : 0 (XL), 1 (XC), 2 (XR) index du tableau startPoints
	self.ticksToGoToGoalPosition = 0;
	self.ticksBeforeNextPosition = 0; // Initialize ticksBeforeNextPosition
	self.isGoingToRight = false;
	self.isGoingToLeft = false;
	self.isMoving = false;
	self.coconutChoosen = null;
	//Function setMoveToGoalPosition : initialise les paramètres pour se déplacer à la position d'arrivée
	self.setMoveToGoalPosition = function (coconut, ticksToGoToGoalPosition) {
		if (coconut == null) {
			return;
		}
		self.coconutChoosen = coconut;
		self.ticksToGoToGoalPosition = ticksToGoToGoalPosition;
		self.goalPositionIndex = checkIndexPosition(coconut);
		self.actualPositionIndex = checkIndexPosition(self);
		//scoreTest = "actualPositionIndex: " + self.actualPositionIndex + " goalPositionIndex: " + self.goalPositionIndex;
	}; //fin setMoveToGoalPosition
	// Function to change the asset
	self.changeAsset = function (newAssetId, options) {
		// Remove the existing asset
		self.removeChild(monkeyAsset);
		monkeyAsset.destroy();
		// Attach the new asset
		monkeyAsset = self.attachAsset(newAssetId, {
			anchorX: options && options.anchorX !== undefined ? options.anchorX : 0.5,
			anchorY: options && options.anchorY !== undefined ? options.anchorY : 0.5
		});
	};
	self.update = function () {
		//scoreTest = "actualPositionIndex: " + self.actualPositionIndex + " goalPositionIndex: " + self.goalPositionIndex + " isMoving: " + self.isMoving;
		if (!self.isMoving && self.actualPositionIndex != self.goalPositionIndex) {
			if (self.actualPosition < self.goalPosition) {
				self.isGoingToRight = true;
				self.isGoingToLeft = false;
				self.assetsToUse = self.assetsToRight;
			} else {
				self.isGoingToRight = false;
				self.isGoingToLeft = true;
				self.assetsToUse = self.assetsToLeft;
			}
			self.sequenceIndexToUse = Math.abs(self.actualPositionIndex - self.goalPositionIndex) == 1 ? self.sequenceIndexToCenter : self.sequenceIndexToExtreme;
			self.ticksBeforeNextPosition = self.ticksToGoToGoalPosition / self.sequenceIndexToUse.length;
			self.isMoving = true;
			self.ticksBeforeNextPosition = self.ticksToGoToGoalPosition / self.sequenceIndexToUse.length;
			scoreTest = "actualPIx: " + self.actualPositionIndex + " goalPIx: " + self.goalPositionIndex + " assetsToUse: " + self.assetsToUse + " seqIxToUse: " + self.sequenceIndexToUse + "\nticksBeforeNextPosition: " + self.ticksBeforeNextPosition;
		} else if (self.isMoving) {
			if (self.isGoingToRight) {
				if (self.ticksBeforeNextPosition <= 0) {
					self.changeAsset(self.assetsToUse[self.sequenceIndexToUse[self.sequenceIndex]]);
					self.sequenceIndex += 1;
				} else {
					self.ticksBeforeNextPosition -= 1;
				}
			} else if (self.isGoingToLeft) {
				if (self.ticksBeforeNextPosition <= 0) {
					self.changeAsset(self.assetsToUse[self.sequenceIndexToUse[self.sequenceIndex]]);
					self.sequenceIndex += 1;
				} else {
					self.ticksBeforeNextPosition -= 1;
				}
			}
		}
		if (checkIndexPosition(self) == self.goalPositionIndex) {
			//Le monkey est arrivé à la position voulue, on remet les paramètres à zéro
			self.isMoving = false;
			self.actualPositionIndex = self.goalPositionIndex;
			self.isGoingToRight = false;
			self.isGoingToLeft = false;
			self.sequenceIndex = 0;
			self.assetsToUse = [];
			self.sequenceIndexToUse = [];
			if (self.coconutChoosen) {
				self.coconutChoosen.trajectory.isStarted = true; //On lache la coconut
				self.coconutChoosen = null;
			}
		}
	}; //fin update
});
// Class for the Parasol
var Parasol = Container.expand(function () {
	var self = Container.call(this);
	var parasolGraphics = self.attachAsset('parasol', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// Parasol logic can be added here
	};
});
//Class for the trajectory of the coconut
//Gestion d'une trajectoire parabolique de sommet ((X1 + X2)/2, Yh)
//et de point de départ (X1, Y0) et d'arrivée (X2, Y0) avec Y0 > Yh et X1 < X2 et Yh != Y0 != 0 et X1 != X2 != 0
//la fonction de mise à jour calcule la position du point suivant en fonction de speed .
//L'equation de la trajectoire est de la forme y = a(x - X1)(x - X2) + Y0 avec a = 4(Y0 - Yh)/((X1 - X2)(X1 - X2))
//Pour la trajectoire linéaire, le point de départ est (X1, Yh) et le point d'arrivée est (X1, Y0)
//Le temps de parcours est totalTicks que se soit pour la trajectoire linéaire ou parabolique
var Trajectory = Container.expand(function () {
	var self = Container.call(this);
	var trajectoryGraphics = self.attachAsset('trajectory', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.typeTrajectory = 0; //-1: static, 0: linear, 1: parabolic
	self.X1 = 0;
	self.X2 = 0;
	self.Y0 = 0;
	self.Yh = 0;
	self.a = 0;
	self.x = 0;
	self.y = 0;
	self.totalTicks = 0; //Nombre total de ticks pour passer de X1 à X2
	self.distPerTick = 0; //Distance parcourue par tick
	self.isStarted = false; //Indique si la trajectoire a commencé
	self.setParameters = function (typeTrajectory, X1, X2, Y0, Yh, totalTicks) {
		//Initialisation des paramètres de la trajectoire
		self.typeTrajectory = typeTrajectory;
		self.X1 = X1;
		self.X2 = X2;
		self.Y0 = Y0;
		self.Yh = Yh;
		self.totalTicks = totalTicks;
		self.isStarted = false;
		if (self.typeTrajectory == -1) {
			self.x = self.X1;
			self.y = self.Y0;
		}
		if (self.typeTrajectory == 0) {
			self.x = self.X1;
			self.y = self.Yh;
			distPerTick = (self.Y0 - self.Yh) / self.totalTicks;
		}
		if (self.typeTrajectory == 1) {
			self.x = self.X1;
			self.y = self.Y0;
			self.a = 4 * (self.Y0 - self.Yh) / ((self.X1 - self.X2) * (self.X1 - self.X2));
			self.distPerTick = (self.X2 - self.X1) / self.totalTicks;
		}
		//scoreTest = "typeTrajectory: " + typeTrajectory + " X1: " + self.X1 + " X2: " + self.X2 + " Y0: " + self.Y0 + " Yh: " + self.Yh + " totalTicks: " + self.totalTicks;
	}; //fin setParameters
	self.updateStatic = function () {
		var lastY = self.y;
		self.isFalling = lastY < self.y;
	}; //fin updateStatic
	self.updateLinear = function () {
		// Trajectory logic can be added here
		var lastY = self.y;
		if (self.isStarted) {
			if (self.y < self.Y0) {
				self.y += distPerTick;
				//scoreTest = "x= " + self.x + " y= " + self.y + " distPerTick= " + self.distPerTick;
			}
		}
		self.isFalling = lastY < self.y;
	}; //fin updateLinear
	self.updateParabol = function () {
		//scoreTest += 1;
		// Trajectory logic can be added here
		var lastY = self.y;
		if (self.isStarted) {
			self.x += self.distPerTick;
			self.y = self.a * (self.x - self.X1) * (self.x - self.X2) + self.Y0;
			//scoreTest = "x= " + self.x + " y= " + self.y + " a= " + self.a + " distPerTick= " + self.distPerTick;
		}
		self.isFalling = lastY < self.y;
	}; //fin updateParabol
});
/**** 
* Initialize Game
****/ 
//fin class Trajectory
var game = new LK.Game({
	backgroundColor: 0x87CEEB // Sky blue background
});
/**** 
* Game Code
****/ 
/**** 
* Game zones and backgrounds
****/ 
/**** 
* GAME DESCRIPTION:
* Game Principle:
	* NAME: COCO MONKEY V1.0 by Dalhem 2024
	* -There is beach where people are enjoying the sun by the shadow of palm trees.
	* -Above them, three palm trees are growing coconuts.
	* -In the trees, a monkey is throwing coconuts from the top of the trees, thus three points of departure.
	* -The player controls a guy who holding a parasol to protect everyone from the coconuts.
	* -The coconuts are falling at a regular speed, falling in straight lines.
	* -If a coconut touches the parasol, the player earns points.
	* -If a coconut touches the ground, the player loses a life.
	* -The game is over when the player has no more lives.
* Game Areas:
	* The screen is divided into 3 main zones in the following descending order:
		1. Score area: displays the player's score.
		2. The main game area: where the game takes place, it is divided into 3 zones corresponding to the 3 points of departure of the coconuts :
			* The left zone: the coconuts fall from the left tree.
			* The center zone: the coconuts fall from the center tree.
			* The right zone: the coconuts fall from the right tree.
		3. Options area (or advertisement).
* Game Progression:
	* At the beginning of the game, the player has 0 points.
	* The player has 3 lives.
	* The player can move the parasol by dragging it.
	* The monkey throws coconuts at a regular interval randomly from the top of the trees.
	* When a coconut touches the parasol, it bounces up following a parabolic trajectory.
	* The parabolic trajectory depends on the angle of the parasol:
		* The more the parasol is inclined, the more the coconut will bounce back :
			* If the parasol is in the left zone, the coconut may bounce following a parabolic trajectory :
				* to the left, thus outside the screen.
				* to the right, thus towards the center zone.
				* to the extrem right, thus towards the right zone.
			* If the parasol is in the center zone, the coconut may bounce following a parabolic trajectory :
				* to the left, thus towards the left zone.
				* to the extrem left, thus outside the screen.
				* to the right, thus towards the right zone.
				* to the extrem right, thus outside the screen.
			* If the parasol is in the right zone, the coconut may bounce following a parabolic trajectory :
				* to the left, thus towards the center zone.
				* to the extrem left, thus towards the left zone.
				* to the right, thus outside the screen.
	* the parasol has three zones of influence:
		* The left zone: the coconut will bounce to the extrem left.
		* The center zone: the coconut will randomly bounce to the left or to the right.
		* The right zone: the coconut will bounce to the extrem right.
****/ 
var ScoreZone = {
	x: 0,
	y: 0,
	width: game.width,
	height: 200 * game.height / 2732
};
var MainZone = {
	x: 0,
	y: ScoreZone.height,
	width: game.width,
	height: game.height - 2 * ScoreZone.height
};
var OptionsZone = {
	x: 0,
	y: game.height - ScoreZone.height,
	width: game.width,
	height: 200 * game.height / 2732
};
setBackGroundImage('backGroundBeach', 0, 0, game.width, game.height);
/**** 
* Autres
****/ 
var monkeyLevel = 200;
var monkey = game.addChild(new Monkey());
monkey.x = 2048 / 2;
monkey.y = monkeyLevel;
game.addChild(monkey.sprite);
var parasol = game.addChild(new Parasol());
parasol.x = 2048 / 2;
parasol.y = OptionsZone.y - 400;
var coconutsInTree = []; //Tableau des coconuts dans les arbres
var coconuts = []; //Tableau des coconuts en mouvement
var nombreCoconuts = 15; //Nombre de coconuts en mouvement en même temps
var coconutChoosen = null; //Coconut choisie pour tomber
var sommetParaboleHaute = ScoreZone.height + 200;
var sommetParaboleBasse = ScoreZone.height + 400;
var nbTicksToBounceHight = 230; //Nombre de ticks pour effectuer une parabole haute
var nbTicksTobounceLow = 220; //Nombre de ticks pour effectuer une parabole basse
var nbTicksToFall = 200; //Nombre de ticks pour tomber
var nbTicksBeforeThrow = 200;
var nbTicksLeftBeforeNextThrow = 0;
var score = 0;
var scoreTest = 0;
var startPoints = [XL = game.width / 4, XC = game.width / 2, XR = 3 * game.width / 4]; // Define the startPoints array
var parasolLevel = OptionsZone.y - 600;
var groundLevel = OptionsZone.y - 300;
/**** 
* Init game
* ***/
setCocoInTree();
/**** 
* Score
****/ 
var livesLeft = 3; //Nombre de vies restantes
var livesLeftGraphics = []; //Tableau des sprites 'life' représentant les vies restantes
var scoreTestText = new Text2('0', {
	size: 30,
	fill: "#000000",
	anchorX: 0.5,
	anchorY: 0
});
LK.gui.topLeft.addChild(scoreTestText);
var scoreTxt = new Text2('0', {
	size: 150,
	fill: "#ff0000",
	anchorX: 0.5,
	anchorY: 0
});
LK.gui.top.addChild(scoreTxt);
game.down = function (x, y, obj) {
	parasol.x = x;
	parasol.y = parasolLevel;
};
game.move = function (x, y, obj) {
	parasol.x = x;
	parasol.y = parasolLevel;
};
/**** 
* Functions
****/ 
//Fonction setBackGroundImage : permet de définir l'image de fond du jeu
function setBackGroundImage(image, x, y, width, height) {
	backGroundImage = LK.getAsset(image, {
		x: x,
		y: y,
		width: width,
		height: height
	});
	game.addChild(backGroundImage);
} //Fin de la fonction setBackGroundImage
function updateScoreTest(nouveauScore) {
	scoreTestText.setText(nouveauScore);
} //fin updateScoreTest
function updateScore(nouveauScore) {
	scoreTxt.setText(nouveauScore);
} //fin updateScore
function setLivesLeft() {
	//Affiche le nombre de vies restantes (sprite 'life' ) dans le coin supérieur gauche
	//Commence par effacer les vies restantes s'il y en a
	if (livesLeft != livesLeftGraphics.length) {
		for (var i = livesLeftGraphics.length - 1; i >= livesLeft; i--) {
			if (livesLeftGraphics[i]) {
				game.removeChild(livesLeftGraphics[i]);
				livesLeftGraphics[i].destroy();
				livesLeftGraphics.splice(i, 1);
			}
		}
	}
	//Crée des sprites 'life' si nécessaire (si livesLeft > livesLeftGraphics.length)
	if (livesLeft > livesLeftGraphics.length) {
		for (var i = livesLeftGraphics.length; i < livesLeft; i++) {
			var lifeGraphics = LK.getAsset('life', {
				anchorX: 0.5,
				anchorY: 0,
				scaleX: 1,
				scaleY: 1,
				x: ScoreZone.x + 100 + 100 * i,
				y: ScoreZone.y + 100
			});
			livesLeftGraphics.push(lifeGraphics);
		}
	}
	//Affiche les sprites 'life' dans le coin supérieur gauche
	for (var i = 0; i < livesLeft; i++) {
		game.addChild(livesLeftGraphics[i]);
	}
} //fin setLivesLeft
//Fonction setCocoInTree: crée un coconut dans un arbre
//Les coconuts sont créés au nombre de nombreCoconuts 
//puis elles réparties aléatoirement mais équitablement dans les arbres autour des trois points de départ (XL, XC, XR) + ou - 50 pixels
//Elles sont stockées dans le tableau coconutsInTree
function setCocoInTree() {
	for (var i = 0; i < nombreCoconuts; i++) {
		var newCoconut = new Coconut();
		// Choisir aléatoirement un point de départ
		var randomIndex = Math.floor(Math.random() * startPoints.length);
		var randomDeltaX = Math.floor(Math.random() * 100) - 50;
		var randomDeltaY = Math.floor(Math.random() * 100) - 50;
		var typeTrajectory = -1; //Trajectoire statique
		var X1 = startPoints[randomIndex] + randomDeltaX;
		//var X1 = startPoints[1];
		var X2 = X1;
		var Y0 = monkeyLevel + randomDeltaY;
		var Yh = Y0;
		var totalTicks = 0;
		newCoconut.trajectory.setParameters(typeTrajectory, X1, X2, Y0, Yh, totalTicks);
		coconutsInTree.push(newCoconut);
	}
	//Affiche les coconuts dans les arbres
	for (var i = 0; i < coconutsInTree.length; i++) {
		game.addChild(coconutsInTree[i]);
	}
} //fin setCocoInTree
//Fonction chooseNextStartPoint: choisit aléatoirement un point de départ d'un coconut
//Renvoie un objet Coconut
function chooseNextStartPoint() {
	var newCoconut = new Coconut();
	// Choisir aléatoirement un point de départ
	var randomIndex = Math.floor(Math.random() * startPoints.length);
	var typeTrajectory = 0;
	newCoconut.isFalling = true;
	var X1 = startPoints[randomIndex];
	var X2 = X1;
	var Y0 = groundLevel;
	var Yh = monkeyLevel;
	newCoconut.trajectory.setParameters(typeTrajectory, X1, X2, Y0, Yh, nbTicksToFall);
	coconuts.push(newCoconut);
	moveMonkeyToStartPoint(X1, monkeyLevel);
	return newCoconut;
} //fin chooseNextStartPoint
//Fonction chooseNextCoconut: choisit aléatoirement un coconut dans les arbres
//Renvoie un objet Coconut
function chooseNextCoconut() {
	var randomIndex = Math.floor(Math.random() * coconutsInTree.length);
	var newCoconut = coconutsInTree[randomIndex];
	coconutsInTree.splice(randomIndex, 1);
	moveMonkeyToCoconut(newCoconut);
	var typeTrajectory = 0; //Trajectoire linéaire
	var X1 = newCoconut.x;
	var X2 = X1;
	var Y0 = groundLevel;
	var Yh = newCoconut.y;
	newCoconut.trajectory.setParameters(typeTrajectory, X1, X2, Y0, Yh, nbTicksToFall);
	coconuts.push(newCoconut);
	return newCoconut;
} //fin chooseNextCoconut
//Fonction moveMoveMonkeyToCoconut: déplace le monkey au point de depart du coconut
function moveMonkeyToCoconut(coconut) {
	//Efface le monkey de l'écran
	game.removeChild(monkey);
	var deltaIndex = checkIndexPosition(monkey) - checkIndexPosition(coconut);
	if (deltaIndex < 0) {
		//Le monkey est à gauche du coconut
		monkey.changeAsset('monkeyToRight', {
			anchorX: 0.91,
			anchorY: 0.11
		});
		if (deltaIndex > -1) {
			//Le monkey est à gauche du coconut mais pas trop
			monkey.changeAsset('monkeyInterRight', {
				anchorX: 0.5,
				anchorY: 0.5
			});
		}
	} else {
		//Le monkey est à droite du coconut
		monkey.changeAsset('monkeyToLeft', {
			anchorX: 0.09,
			anchorY: 0.11
		});
	}
	monkey.x = coconut.x;
	monkey.y = coconut.y;
	game.addChild(monkey);
	LK.setTimeout(function () {
		//coconut.trajectory.isStarted = true;
	}, 100);
} //fin moveMonkeyToCoconut
//Fonction checkPosition : donne la position XL, XC, ou XR la plus proche de la position x du parasol
function checkPosition(parasol) {
	var deltaX = Math.abs(parasol.x - XL);
	var deltaY = Math.abs(parasol.x - XC);
	var deltaZ = Math.abs(parasol.x - XR);
	var Xreturn = -1;
	if (deltaX <= parasol.width / 2) {
		Xreturn = XL;
	}
	if (deltaY <= parasol.width / 2) {
		Xreturn = XC;
	}
	if (deltaZ <= parasol.width / 2) {
		Xreturn = XR;
	}
	return Xreturn;
} //fin checkPosition
//Fonction checkIndexPosition : donne l'index de la position XL, XC, ou XR la plus proche de la position x d'un objet
function checkIndexPosition(obj) {
	var deltaX = Math.abs(obj.x - XL);
	var deltaY = Math.abs(obj.x - XC);
	var deltaZ = Math.abs(obj.x - XR);
	var Xreturn = -1;
	if (deltaX <= obj.width / 2) {
		Xreturn = 0;
	}
	if (deltaY <= obj.width / 2) {
		Xreturn = 1;
	}
	if (deltaZ <= obj.width / 2) {
		Xreturn = 2;
	}
	return Xreturn;
} //fin checkIndexPosition
//Fonction zoneIntersectParasol: renvoie la zone du parasol qui intersecte le coconut (0 : zone de gauche, 1 : zone centrale de gauche, 2 : zone centrale de droite, 3 : zone de droite)
//Sachant que l'ancrage du parasol est en (0.5, 0.5) et que l'ancrage du coconut est en (0.5, 0.5)
//La zone 0 est la zone de gauche, la zone 1 est la zone centrale, la zone 2 est la zone de droite
function zoneIntersectParasol(coconut) {
	var zone = -1;
	var oneThirdParasol = parasol.width / 3;
	var parasolCenter = parasol.x;
	var coconutCenter = coconut.x;
	var deltaXToCenter = parasolCenter - coconutCenter; //distance du centre du coconut par rapport au centre du parasol (positif si à gauche, négatif si à droite)
	if (deltaXToCenter > oneThirdParasol / 2) {
		//La coco se trouve dans la zone gauche au delà du tiers gauche
		zone = 0;
	}
	if (deltaXToCenter <= oneThirdParasol / 2 && deltaXToCenter >= 0) {
		//La coco se trouve dans la zone gauche entre le tiers gauche et le centre du parasol
		zone = 1;
	}
	if (deltaXToCenter >= -oneThirdParasol / 2 && deltaXToCenter <= 0) {
		//La coco se trouve dans la zone droite entre le centre du parasol et le tiers droit
		zone = 2;
	}
	if (deltaXToCenter < -oneThirdParasol / 2) {
		//La coco se trouve dans la zone droite au delà du tiers droit
		zone = 3;
	}
	return zone;
} //fin zoneIntersectParasol
//Fonction changeTrajectory: change la trajectoire d'un coconut en fonction de la position du parasol en XL, XC ou XR (position de startPoints)
//Si la position du parasol est en XL le coconut rebondit aléatoirement :
//	- vers la gauche, donc vers l'extérieur de l'écran
//	- vers la droite, donc vers la zone centrale avec une parabole de somment sommetParaboleHaute
//	- vers l'extrême droite, donc vers la zone de droite avec une parabole de somment sommetParaboleBasse
//Si la position du parasol est en XC le coconut rebondit aléatoirement :
//	- vers la gauche, donc vers la zone de gauche avec une parabole de somment sommetParaboleHaute
//	- vers l'extrême gauche, donc vers l'extérieur de l'écran
//	- vers la droite, donc vers la zone de droite avec une parabole de somment sommetParaboleHaute
//	- vers l'extrême droite, donc vers l'extérieur de l'écran
//Si la position du parasol est en XR le coconut rebondit aléatoirement :
//	- vers la droite, donc vers l'extérieur de l'écran
//	- vers la gauche, donc vers la zone centrale avec une parabole de somment sommetParaboleHaute
//	- vers l'extrême gauche, donc vers la zone de gauche avec une parabole de somment sommetParaboleBasse
function changeTrajectory(coconut, randomIndex) {
	if (randomIndex != 0 && randomIndex != 1 && randomIndex != 2 && randomIndex != 3) {
		randomIndex = Math.floor(Math.random() * 4);
	}
	var Xposition = checkPosition(parasol);
	var deltaX = Math.abs(coconut.x - Xposition);
	if (Xposition == XL) {
		if (randomIndex == 0) {
			//vers la gauche, sortie de l'écran
			coconut.trajectory.setParameters(1, coconut.x, -XL - deltaX, coconut.y, sommetParaboleBasse, nbTicksToBounceHight);
		}
		if (randomIndex == 1) {
			//vers la gauche, sortie de l'écran
			coconut.trajectory.setParameters(1, coconut.x, -XL - deltaX, coconut.y, sommetParaboleHaute, nbTicksToBounceHight);
		}
		if (randomIndex == 2) {
			//vers le centre, parabole haute
			coconut.trajectory.setParameters(1, coconut.x, XC - deltaX, coconut.y, sommetParaboleHaute, nbTicksToBounceHight);
		}
		if (randomIndex == 3) {
			//vers l'extrême droite, parabole basse
			coconut.trajectory.setParameters(1, coconut.x, XR - deltaX, coconut.y, sommetParaboleBasse, nbTicksTobounceLow);
		}
	} else if (Xposition == XC) {
		if (randomIndex == 0) {
			//vers la gauche, sortie d'ecran
			coconut.trajectory.setParameters(1, coconut.x, -XL + deltaX, coconut.y, sommetParaboleBasse, nbTicksTobounceLow);
		}
		if (randomIndex == 1) {
			//vers la gauche, parabole haute
			coconut.trajectory.setParameters(1, coconut.x, XL + deltaX, coconut.y, sommetParaboleHaute, nbTicksToBounceHight);
		}
		if (randomIndex == 2) {
			//Vers la droite, parabole haute
			coconut.trajectory.setParameters(1, coconut.x, XR - deltaX, coconut.y, sommetParaboleHaute, nbTicksToBounceHight);
		}
		if (randomIndex == 3) {
			//Vers la droite, sortie d'ecran
			coconut.trajectory.setParameters(1, coconut.x, XR + 2 * XL - deltaX, coconut.y, sommetParaboleBasse, nbTicksTobounceLow);
		}
	} else if (Xposition == XR) {
		if (randomIndex == 0) {
			//vers l'extrême gauche, parabole basse
			coconut.trajectory.setParameters(1, coconut.x, XL + deltaX, coconut.y, sommetParaboleBasse, nbTicksTobounceLow);
		}
		if (randomIndex == 1) {
			//vers le centre, parabole haute
			coconut.trajectory.setParameters(1, coconut.x, XC + deltaX, coconut.y, sommetParaboleHaute, nbTicksToBounceHight);
		}
		if (randomIndex == 2) {
			//vers la droite, sortie de l'écran
			coconut.trajectory.setParameters(1, coconut.x, XR + 2 * XL - deltaX, coconut.y, sommetParaboleHaute, nbTicksToBounceHight);
		}
		if (randomIndex == 3) {
			//vers l'extrême gauche, parabole haute
			coconut.trajectory.setParameters(1, coconut.x, XR + 2 * XL - deltaX, coconut.y, sommetParaboleBasse, nbTicksTobounceLow);
		}
	}
} //fin changeTrajectory
/**** 
* Main loop
****/ 
game.update = function () {
	//Mise à jour score
	updateScoreTest(scoreTest);
	updateScore(score);
	//Vérifier si un coco a touché le sol
	for (var i = coconuts.length - 1; i >= 0; i--) {
		if (coconuts[i].y >= groundLevel / 2 && (coconuts[i].x < 0 || coconuts[i].x > game.width)) {
			//Si le coco est sorti de l'écran sur les côtés
			coconuts[i].destroy();
			coconuts.splice(i, 1);
		} else if (coconuts[i].y >= groundLevel) {
			//Si le coco est tombé au sol
			if (coconuts[i].x == XC) {
				LK.getSound('sheOuch').play();
			} else {
				LK.effects.flashScreen(0xff0000, 1000);
			}
			coconuts[i].destroy();
			coconuts.splice(i, 1);
			livesLeft -= 1;
			if (livesLeft == 0) {
				setLivesLeft();
				LK.showGameOver();
			}
		}
	}
	//Check if a coconut has touched the parasol et changement de trajectoire
	for (var i = coconuts.length - 1; i >= 0; i--) {
		var deltaX = Math.abs(coconuts[i].x - parasol.x);
		var deltaY = parasol.y - coconuts[i].y;
		var isCloseEnough = deltaY > 0 && deltaY < 150;
		if (coconuts[i].intersects(parasol) && coconuts[i].isFalling && deltaX < parasol.width / 2 && isCloseEnough) {
			coconuts[i].Xintercept = parasol.x;
			coconuts[i].Yintercept = coconuts[i].y;
			score += 10;
			coconuts[i].isFalling = false;
			var bouncingSoundList = ['bouncing1', 'bouncing2', 'bouncing3'];
			var bouncingSound = bouncingSoundList[Math.floor(Math.random() * bouncingSoundList.length)];
			LK.getSound(bouncingSound).play();
			changeTrajectory(coconuts[i], zoneIntersectParasol(coconuts[i]));
			coconuts[i].trajectory.isStarted = true;
			coconuts[i].isBouncing = true;
		}
	}
	//Autres actions à effectuer sans urgence
	if (LK.ticks % 60 == 0) {
		//Afficher les coeurs
		setLivesLeft();
		// Récupérer un coconut dans les arbres et le faire tomber si l'heure est venue
		if (coconutsInTree.length > 0 && nbTicksLeftBeforeNextThrow <= 0) {
			if (coconutChoosen == null) {
				coconutChoosen = chooseNextCoconut();
				coconutChoosen.trajectory.isStarted = true;
				game.addChild(coconutChoosen);
				//monkey.setMoveToGoalPosition(coconutChoosen, nbTicksBeforeThrow);
			} else {
				nbTicksLeftBeforeNextThrow = nbTicksBeforeThrow;
				coconutChoosen = null;
			}
		} else {
			nbTicksLeftBeforeNextThrow -= 60;
		}
	}
}; ===================================================================
--- original.js
+++ change.js
@@ -34,10 +34,9 @@
 //<Assets used in the game will automatically appear here>
 // Class for the Monkey
 var Monkey = Container.expand(function () {
 	var self = Container.call(this);
-	var monkeyAsset;
-	monkeyAsset = self.attachAsset('monkeyToLeft', {
+	var monkeyAsset = self.attachAsset('monkeyToLeft', {
 		anchorX: 0.5,
 		anchorY: 0.5
 	});
 	self.assetsToRight = ['monkeyToRight', 'monkeyInterRight'];
@@ -71,14 +70,12 @@
 		// Remove the existing asset
 		self.removeChild(monkeyAsset);
 		monkeyAsset.destroy();
 		// Attach the new asset
-		if (self.assetsToUse.length > 0) {
-			monkeyAsset = self.attachAsset(newAssetId, {
-				anchorX: options && options.anchorX !== undefined ? options.anchorX : 0.5,
-				anchorY: options && options.anchorY !== undefined ? options.anchorY : 0.5
-			});
-		}
+		monkeyAsset = self.attachAsset(newAssetId, {
+			anchorX: options && options.anchorX !== undefined ? options.anchorX : 0.5,
+			anchorY: options && options.anchorY !== undefined ? options.anchorY : 0.5
+		});
 	};
 	self.update = function () {
 		//scoreTest = "actualPositionIndex: " + self.actualPositionIndex + " goalPositionIndex: " + self.goalPositionIndex + " isMoving: " + self.isMoving;
 		if (!self.isMoving && self.actualPositionIndex != self.goalPositionIndex) {
@@ -98,24 +95,16 @@
 			scoreTest = "actualPIx: " + self.actualPositionIndex + " goalPIx: " + self.goalPositionIndex + " assetsToUse: " + self.assetsToUse + " seqIxToUse: " + self.sequenceIndexToUse + "\nticksBeforeNextPosition: " + self.ticksBeforeNextPosition;
 		} else if (self.isMoving) {
 			if (self.isGoingToRight) {
 				if (self.ticksBeforeNextPosition <= 0) {
-					//self.changeAsset(self.assetsToUse[self.sequenceIndexToUse[self.sequenceIndex]]);
-					self.changeAsset('monkeyToRight', {
-						anchorX: 0.91,
-						anchorY: 0.11
-					});
+					self.changeAsset(self.assetsToUse[self.sequenceIndexToUse[self.sequenceIndex]]);
 					self.sequenceIndex += 1;
 				} else {
 					self.ticksBeforeNextPosition -= 1;
 				}
 			} else if (self.isGoingToLeft) {
 				if (self.ticksBeforeNextPosition <= 0) {
-					//self.changeAsset(self.assetsToUse[self.sequenceIndexToUse[self.sequenceIndex]]);
-					self.changeAsset('monkeyToLeft', {
-						anchorX: 0.09,
-						anchorY: 0.11
-					});
+					self.changeAsset(self.assetsToUse[self.sequenceIndexToUse[self.sequenceIndex]]);
 					self.sequenceIndex += 1;
 				} else {
 					self.ticksBeforeNextPosition -= 1;
 				}
@@ -461,9 +450,9 @@
 function chooseNextCoconut() {
 	var randomIndex = Math.floor(Math.random() * coconutsInTree.length);
 	var newCoconut = coconutsInTree[randomIndex];
 	coconutsInTree.splice(randomIndex, 1);
-	//moveMonkeyToCoconut(newCoconut);
+	moveMonkeyToCoconut(newCoconut);
 	var typeTrajectory = 0; //Trajectoire linéaire
 	var X1 = newCoconut.x;
 	var X2 = X1;
 	var Y0 = groundLevel;
@@ -475,14 +464,22 @@
 //Fonction moveMoveMonkeyToCoconut: déplace le monkey au point de depart du coconut
 function moveMonkeyToCoconut(coconut) {
 	//Efface le monkey de l'écran
 	game.removeChild(monkey);
-	if (monkey.x < coconut.x) {
+	var deltaIndex = checkIndexPosition(monkey) - checkIndexPosition(coconut);
+	if (deltaIndex < 0) {
 		//Le monkey est à gauche du coconut
 		monkey.changeAsset('monkeyToRight', {
 			anchorX: 0.91,
 			anchorY: 0.11
 		});
+		if (deltaIndex > -1) {
+			//Le monkey est à gauche du coconut mais pas trop
+			monkey.changeAsset('monkeyInterRight', {
+				anchorX: 0.5,
+				anchorY: 0.5
+			});
+		}
 	} else {
 		//Le monkey est à droite du coconut
 		monkey.changeAsset('monkeyToLeft', {
 			anchorX: 0.09,
@@ -490,10 +487,12 @@
 		});
 	}
 	monkey.x = coconut.x;
 	monkey.y = coconut.y;
-	coconut.trajectory.isStarted = true;
 	game.addChild(monkey);
+	LK.setTimeout(function () {
+		//coconut.trajectory.isStarted = true;
+	}, 100);
 } //fin moveMonkeyToCoconut
 //Fonction checkPosition : donne la position XL, XC, ou XR la plus proche de la position x du parasol
 function checkPosition(parasol) {
 	var deltaX = Math.abs(parasol.x - XL);
@@ -682,11 +681,11 @@
 		// Récupérer un coconut dans les arbres et le faire tomber si l'heure est venue
 		if (coconutsInTree.length > 0 && nbTicksLeftBeforeNextThrow <= 0) {
 			if (coconutChoosen == null) {
 				coconutChoosen = chooseNextCoconut();
-				//coconutChoosen.trajectory.isStarted = true;
-				//game.addChild(coconutChoosen);
-				monkey.setMoveToGoalPosition(coconutChoosen, nbTicksBeforeThrow);
+				coconutChoosen.trajectory.isStarted = true;
+				game.addChild(coconutChoosen);
+				//monkey.setMoveToGoalPosition(coconutChoosen, nbTicksBeforeThrow);
 			} else {
 				nbTicksLeftBeforeNextThrow = nbTicksBeforeThrow;
 				coconutChoosen = null;
 			}