User prompt
add a smooth sinusoidal vertical movement to coins, it should be relative, that is it doesn't change current y movement and shadow should not be afected by the relavive move
User prompt
add a smooth sinusoidal relative vertical movement to coins
Code edit (1 edits merged)
Please save this source code
User prompt
in Coin update, Update also the y offset of shadow to grow with progress
User prompt
update the y offset of shadow to grow with progress
User prompt
Please fix the bug: 'TypeError: coinGraphics is undefined' in or related to this line: 'coinShadow.y = coinGraphics.height * 0.1; // Offset shadow slightly below the coin' Line Number: 41
User prompt
add and y offset between coin and its shadow
User prompt
in Coin, make Shadow w & h 80% of coin's w & h
User prompt
rename playerShadow to shadow
User prompt
add a shadow under coins graphics
User prompt
add the cent sign to the score when level == 1 and $ sign when level > 1
User prompt
add a global names currentLevel
User prompt
in game.up when killed, wait 1 se before game over
Code edit (2 edits merged)
Please save this source code
User prompt
replace ``` var newCoin = new Coin(); newCoin.reset(); coins.push(newCoin); game.addChild(newCoin); ``` by a loop to create 5 coins at y = roadTop - i * 50
User prompt
now instead of spwning 1 coin, spaw a serie of 5 on the same path at with an y offset of 50
User prompt
update `currentSpeed = currentSpeed * 0.8;` to ensure speed is always between 10 and 20 and is an integer
Code edit (1 edits merged)
Please save this source code
User prompt
add 2 globals lastObstacleHitTime and immunityDelay = 500; then use then in Obstacle update to avoid multiple collision with the same obstacle
Code edit (1 edits merged)
Please save this source code
User prompt
move player/obstacle collision logic relative to Killers from Obstacle class to Killer class
Code edit (7 edits merged)
Please save this source code
User prompt
move player/Obstacle (except Killer) intersection logic in Obstacle class
Code edit (7 edits merged)
Please save this source code
User prompt
move player/coin intersection login in Coin class
/**** 
* Classes
****/ 
// Assets will be automatically created and loaded during gameplay
// Coin class
var Coin = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		//'dollarsBundle'
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 1
	});
	var coinGraphics2 = self.attachAsset('dollarsBundle', {
		//'dollarsBundle'
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: 0
	});
	var speed = 5;
	var startY = roadTop + 50;
	var endY = startY + roadHeight;
	var leftStartX = 1024 - 100;
	var leftEndX = 1024 - 650;
	var rightStartX = 1024 + 100;
	var rightEndX = 1024 + 650;
	var startSize = 2;
	var endSize = 140;
	coinGraphics.width = startSize;
	coinGraphics.height = startSize;
	coinGraphics2.width = startSize;
	coinGraphics2.height = startSize;
	self.pathIndex = 0;
	self.update = function () {
		// Road should animate even if the game hasn't started
		if (!isPlaying || isKilled) {
			return;
		}
		self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property
		coinGraphics.width = startSize + (endSize - startSize) * self.progress;
		coinGraphics.height = startSize + (endSize - startSize) * self.progress;
		coinGraphics2.width = startSize + (endSize - startSize) * self.progress;
		coinGraphics2.height = startSize + (endSize - startSize) * self.progress;
		if (currentCoinType == 0) {
			coinGraphics.alpha = 1;
			coinGraphics2.alpha = 0;
		} else if (currentCoinType == 1) {
			coinGraphics.alpha = 0;
			coinGraphics2.alpha = 1;
		}
		var newSpeed = currentSpeed; // + 10 * self.progress;
		var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3);
		newSpeed = tempSpeed;
		self.y += newSpeed;
		// Move innerLineLeft x progressively to innerLeftLineEndX
		if (self.pathIndex == 0 && self.x != leftEndX) {
			self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
		}
		if (self.pathIndex == 2 && self.x != rightEndX) {
			self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
		}
		if (self.y > endY + endSize / 2) {
			self.reset();
		}
		// Check for collision with player
		if (!player.isJumping && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) {
			score += 1;
			coinsCollected += 1; // Increment coins collected counter
			scoreTxt.setText(score);
			LK.effects.flashObject(player, 0xffd700, 500); // Flash gold for 0.5 seconds
			self.reset();
			// Increase speed every 3 coins collected
			if (coinsCollected % 3 === 0 && currentSpeed < maxSpeed) {
				currentSpeed += 3; // Increase speed by 3
			}
			if (coinsCollected >= nextCoinTypeThreshold) {
				currentCoinType = 1;
			}
		}
	};
	self.reset = function () {
		self.y = startY;
		self.progress = 0; // Initialize progress property
		coinGraphics.width = startSize;
		coinGraphics.height = startSize;
		coinGraphics2.width = startSize;
		coinGraphics2.height = startSize;
		self.pathIndex = Math.floor(Math.random() * 3);
		if (currentCoinType == 0) {
			coinGraphics.alpha = 1;
			coinGraphics2.alpha = 0;
		} else if (currentCoinType == 1) {
			coinGraphics.alpha = 0;
			coinGraphics2.alpha = 1;
		}
		if (self.pathIndex === 0) {
			self.x = leftStartX;
		} else if (self.pathIndex === 2) {
			self.x = rightStartX;
		} else {
			self.x = 1024;
		}
	};
});
// CoinAnimation class
var CoinAnimation = Container.expand(function () {
	var self = Container.call(this);
	var coinGraphics = self.attachAsset('coin', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: currentCoinType == 0 ? 1 : 0
	});
	var coinGraphics2 = self.attachAsset('dollarsBundle', {
		anchorX: 0.5,
		anchorY: 0.5,
		alpha: currentCoinType == 1 ? 1 : 0
	});
	// Initialize velocity and gravity
	self.vx = (Math.random() < 0.5 ? -1 : 1) * 5; // Random horizontal velocity
	self.vy = -15; // Initial vertical velocity
	self.gravity = 0.5; // Gravity effect
	self.update = function () {
		self.vy += self.gravity; // Apply gravity to vertical velocity
		self.x += self.vx; // Update horizontal position
		self.y += self.vy; // Update vertical position
		self.alpha -= 0.0035; // Fade out the coin
		if (currentCoinType == 0) {
			coinGraphics.alpha = 1;
			coinGraphics2.alpha = 0;
		} else if (currentCoinType == 1) {
			coinGraphics.alpha = 0;
			coinGraphics2.alpha = 1;
		}
		if (self.alpha <= 0) {
			self.destroy(); // Remove the coin when it becomes invisible
		}
	};
});
// Decoration class
var Decoration = Container.expand(function () {
	var self = Container.call(this);
	var assets = ['decoration1'];
	var rand = Math.random();
	self.assetIndex = Math.floor(Math.random() * assets.length);
	var randomAsset = assets[self.assetIndex];
	var mainGraphics = self.attachAsset(randomAsset, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var speed = 5;
	var startY = roadTop + 50;
	var endY = startY + roadHeight;
	var xOffset = 2048;
	var baseLeftStartX = 780;
	var leftStartX = baseLeftStartX - rand * xOffset / 2;
	var leftEndX = leftStartX - xOffset * (1 + rand);
	var baseRightStartX = 1280;
	var rightStartX = baseRightStartX + rand * xOffset / 2;
	var rightEndX = rightStartX + xOffset * (1 + rand);
	var assetWidthRatio = 1;
	var startSize, endSize;
	if (self.assetIndex == 0) {
		startSize = 3;
		endSize = 1024;
		assetWidthRatio = 900 / 846;
	} else if (self.assetIndex == 1) {
		startSize = 1;
		endSize = 140;
	} else if (self.assetIndex == 2) {
		startSize = 2;
		endSize = 250;
	}
	mainGraphics.width = startSize;
	mainGraphics.height = startSize;
	self.pathIndex = 0;
	self.update = function () {
		if (isKilled) {
			return;
		}
		var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf;
		mainGraphics.tint = newTint;
		self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property
		mainGraphics.height = startSize + (endSize - startSize) * self.progress;
		mainGraphics.width = mainGraphics.height * assetWidthRatio;
		var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3);
		var newSpeed = currentSpeed; // + 10 * self.progress;
		newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
		self.y += newSpeed;
		// Move innerLineLeft x progressively to innerLeftLineEndX
		if (self.pathIndex == 0 && self.x != leftEndX) {
			self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
		}
		if (self.pathIndex == 1 && self.x != rightEndX) {
			self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
		}
		if (self.y > endY + endSize / 2) {
			//self.y = -startSize; // Move obstacle back to the top
			self.reset();
		}
	};
	self.reset = function () {
		self.y = startY;
		rand = Math.random();
		self.progress = 0; // Initialize progress property
		mainGraphics.width = startSize;
		mainGraphics.height = startSize;
		leftStartX = baseLeftStartX - rand * xOffset / 2;
		leftEndX = leftStartX - xOffset * (1 + rand);
		rightStartX = baseRightStartX + rand * xOffset / 2;
		rightEndX = rightStartX + xOffset * (1 + rand);
		self.pathIndex = Math.floor(rand * 2);
		if (self.pathIndex === 0) {
			self.x = leftStartX;
		} else {
			self.x = rightStartX;
		}
	};
});
var Killer = Container.expand(function () {
	var self = Container.call(this);
	var assets = ['killer3'];
	self.assetIndex = Math.floor(Math.random() * assets.length);
	var randomAsset = assets[self.assetIndex];
	var killerGraphics = self.attachAsset(randomAsset, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var speed = 5;
	var startY = roadTop - 1;
	var endY = startY + roadHeight;
	var leftStartX = 1024 - 100;
	var leftEndX = 1024 - 650;
	var rightStartX = 1024 + 100;
	var rightEndX = 1024 + 650;
	var startSize = 1;
	var endSize = 800;
	var assetHeightRatio = 500 / 400;
	killerGraphics.width = startSize;
	killerGraphics.height = startSize;
	self.pathIndex = 0;
	self.inactive = true;
	self.inactiveStartTime = Date.now();
	self.update = function () {
		if (!isPlaying) {
			return;
		}
		var currentTime = Date.now();
		if (self.inactive) {
			if (currentTime - self.inactiveStartTime >= killerDelay) {
				self.inactive = false;
			}
			return;
		}
		if (!isKilled && player && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) {
			isKilled = true;
			player.visible = false;
			LK.effects.flashScreen(0xff0000, 1000);
			// Spawn MurderShape at player's last position
			var murderShape = new MurderShape();
			murderShape.x = player.x;
			murderShape.y = player.y;
			murderShape.fixPosition();
			game.addChildAt(murderShape, game.getChildIndex(road) + 1);
			return;
		}
		self.progress = Math.max(0, self.y - startY) / (endY - startY);
		killerGraphics.width = startSize + (endSize - startSize) * self.progress;
		debugTxt.setText(self.progress.toFixed(2));
		killerGraphics.height = assetHeightRatio * killerGraphics.width;
		var tempSpeed = currentSpeed * 0.5 + currentSpeed * (self.progress * 5);
		var newSpeed = currentSpeed * 5;
		newSpeed = tempSpeed * 1;
		self.y += newSpeed;
		if (self.pathIndex == 0 && self.x != leftEndX) {
			self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
		}
		if (self.pathIndex == 2 && self.x != rightEndX) {
			self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
		}
		if (self.y > endY + endSize / 2) {
			self.reset();
		}
	};
	self.reset = function () {
		self.y = startY;
		self.progress = 0;
		killerGraphics.width = startSize;
		killerGraphics.height = startSize;
		self.pathIndex = Math.floor(Math.random() * 3);
		if (self.pathIndex === 0) {
			self.x = leftStartX;
		} else if (self.pathIndex === 2) {
			self.x = rightStartX;
		} else {
			self.x = 1024;
		}
		self.inactive = true;
		self.inactiveStartTime = Date.now();
	};
});
var Landscape = Container.expand(function () {
	var self = Container.call(this);
	var landscapeGraphics = self.attachAsset('landscape1', {
		anchorX: 0.5,
		anchorY: 0.0
	});
	var gradientGraphics = self.attachAsset('gradient', {
		anchorX: 0.5,
		anchorY: 0.0,
		scaleY: -1,
		y: 1050,
		blendMode: 2,
		alpha: 0.5,
		tint: 0xFFFFFF,
		height: 10
	});
	self.x = 2048 / 2; // Center horizontally
	self.y = 0; // Position at the top
	self.update = function () {
		// Old 255 -> 128   / New 128-255
		var reverseIntensity = 128 + (255 - intensityHalf);
		reverseIntensity = Math.max(192, reverseIntensity);
		var newTint = reverseIntensity << 16 | reverseIntensity << 8 | reverseIntensity;
		landscapeGraphics.tint = newTint; // Apply reduced tint to the road based on the intensity
		//debugTxt.setText(intensityHalf.toFixed(2));
	};
});
var MurderShape = Container.expand(function () {
	var self = Container.call(this);
	var murderShapeGraphics = self.attachAsset('murderShape', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.update = function () {
		// MurderShape does not need to update its position or behavior
	};
	self.fixPosition = function () {
		if (self.x < 600) {
			self.x += 150;
		} else if (self.x > 1400) {
			self.x -= 150;
		}
	};
});
// Obstacle class
var Obstacle = Container.expand(function () {
	var self = Container.call(this);
	var assets = ['obstacle1', 'obstacle2', 'obstacle3'];
	self.assetIndex = Math.floor(Math.random() * assets.length);
	var randomAsset = assets[self.assetIndex];
	var obstacleGraphics = self.attachAsset(randomAsset, {
		anchorX: 0.5,
		anchorY: 0.5
	});
	var speed = 5;
	var startY = roadTop + 50;
	var endY = startY + roadHeight;
	var leftStartX = 1024 - 100;
	var leftEndX = 1024 - 650;
	var rightStartX = 1024 + 100;
	var rightEndX = 1024 + 650;
	var innerLeftLineStartX = -150;
	var innerLeftLineEndX = -390;
	var startSize, endSize;
	if (self.assetIndex == 0) {
		startSize = 3;
		endSize = 350;
	} else if (self.assetIndex == 1) {
		startSize = 1;
		endSize = 140;
	} else if (self.assetIndex == 2) {
		startSize = 2;
		endSize = 250;
	}
	obstacleGraphics.width = startSize;
	obstacleGraphics.height = startSize;
	self.pathIndex = 0;
	self.update = function () {
		if (!isPlaying || isKilled) {
			return;
		}
		// Check for collision with player
		var currentTime = Date.now();
		if (currentTime - lastObstacleHitTime > immunityDelay && player && !player.isJumping && self.y > 2500 && self.y < 2732 && player.shadow.intersects(self)) {
			lastObstacleHitTime = currentTime; // Update the last hit time
			// Make player flash red for 1 second
			LK.effects.flashObject(player, 0xff0000, 1000);
			// Add coin animation only if score is greater than 0
			if (score > 0) {
				var coinAnimation = new CoinAnimation();
				coinAnimation.x = player.x;
				coinAnimation.y = player.y;
				game.addChild(coinAnimation);
			}
			// Reduce score by 1
			score = Math.max(0, score - 1);
			scoreTxt.setText(score);
			console.log("Obstacle y:", self.y);
			// Reduce currentSpeed by a factor (e.g., 0.8)
			console.log("Old speed :", currentSpeed);
			currentSpeed = Math.max(10, Math.min(20, Math.round(currentSpeed * 0.8)));
			console.log("New speed :", currentSpeed);
		}
		self.progress = Math.max(0, self.y - startY) / (endY - startY); // Update progress property
		obstacleGraphics.width = startSize + (endSize - startSize) * self.progress;
		obstacleGraphics.height = startSize + (endSize - startSize) * self.progress;
		var tempSpeed = currentSpeed * 0.05 + currentSpeed * (self.progress * 3);
		var newSpeed = currentSpeed; // + 10 * self.progress;
		newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
		self.y += newSpeed;
		// Move innerLineLeft x progressively to innerLeftLineEndX
		if (self.pathIndex == 0 && self.x != leftEndX) {
			self.x = leftStartX + (leftEndX - leftStartX) * self.progress;
		}
		if (self.pathIndex == 2 && self.x != rightEndX) {
			self.x = rightStartX + (rightEndX - rightStartX) * self.progress;
		}
		if (self.y > endY + endSize / 2) {
			//self.y = -startSize; // Move obstacle back to the top
			self.reset();
		}
	};
	self.reset = function () {
		self.y = startY;
		self.progress = 0; // Initialize progress property
		obstacleGraphics.width = startSize;
		obstacleGraphics.height = startSize;
		self.pathIndex = Math.floor(Math.random() * 3);
		if (self.pathIndex === 0) {
			self.x = leftStartX;
		} else if (self.pathIndex === 2) {
			self.x = rightStartX;
		} else {
			self.x = 1024;
		}
	};
});
// Player class
var Player = Container.expand(function () {
	var self = Container.call(this);
	self.shadow = self.attachAsset('playerShadow', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.isJumping = false; // Initialize isJumping to false
	self.shadow.alpha = 0.5; // Make the shadow semi-transparent
	self.shadow.y = 270; // Offset the shadow slightly below the player
	var playerGraphics1 = self.attachAsset('player', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: -5
	});
	var playerGraphics2 = self.attachAsset('player2', {
		anchorX: 0.5,
		anchorY: 0.5,
		x: 5
	});
	playerGraphics2.visible = false; // Initially hide player2 asset
	var frame = 0;
	self.update = function () {
		if (!self.isJumping) {
			frame += Math.min(currentSpeed, 20); // Add a max limit to avoid optical effects
			if (frame >= 100) {
				frame = 0;
				// Swap frames every 10 game ticks
				var visible = playerGraphics1.visible;
				playerGraphics1.visible = !visible;
				playerGraphics2.visible = visible;
			}
		}
		self.jump = function () {
			if (!self.isJumping) {
				self.isJumping = true;
				var initialY = self.y;
				var initialShadowY = self.shadow.y;
				var jumpHeight = 300;
				var jumpDuration = 30;
				var jumpStep = jumpHeight / jumpDuration;
				var fallStep = jumpHeight / jumpDuration;
				var jumpStartTime = Date.now();
				var jumpInterval = LK.setInterval(function () {
					var elapsed = Date.now() - jumpStartTime;
					var progress = elapsed / (jumpDuration * 1000 / 60);
					if (progress < 1) {
						var easeProgress = Math.sin(progress * Math.PI / 2);
						self.y = initialY - jumpHeight * easeProgress;
						self.shadow.y = initialShadowY + jumpHeight * easeProgress; // Move shadow inversely
						self.shadow.width = 240 * (1 - 0.5 * easeProgress); // Reduce shadow width
						self.shadow.height = 100 * (1 - 0.5 * easeProgress); // Reduce shadow height
					} else {
						LK.clearInterval(jumpInterval);
						var fallStartTime = Date.now();
						var fallInterval = LK.setInterval(function () {
							var elapsed = Date.now() - fallStartTime;
							var progress = elapsed / (jumpDuration * 1000 / 60);
							if (progress < 1) {
								var easeProgress = Math.sin(progress * Math.PI / 2);
								self.y = initialY - jumpHeight + jumpHeight * easeProgress;
								self.shadow.y = initialShadowY + jumpHeight - jumpHeight * easeProgress; // Move shadow inversely
								self.shadow.width = 120 + 120 * easeProgress; // Reset shadow width
								self.shadow.height = 50 + 50 * easeProgress; // Reset shadow height
							} else {
								self.y = initialY;
								self.shadow.y = initialShadowY; // Reset shadow position
								self.isJumping = false;
								LK.clearInterval(fallInterval);
							}
						}, 1000 / 60);
					}
				}, 1000 / 60);
			}
		};
	};
});
// Road class
var Road = Container.expand(function () {
	var self = Container.call(this);
	var baseY = 750;
	var roadGraphics = self.attachAsset('triangle', {
		tint: 0x555555,
		// Initialize tint to white
		anchorX: 0.5,
		anchorY: 0,
		width: 2048,
		height: roadHeight,
		y: baseY
	});
	var speed = 5;
	var lineOffset = -150;
	// Inner lines
	var innerLineStartY = roadTop;
	var innerLineEndY = roadTop + roadHeight + 200;
	// Left
	var innerLeftLineStartX = -50;
	var innerLeftLineEndX = -412;
	var innerLeftLineStartW = 3;
	var innerLeftLineEndW = 80;
	var innerLeftLineStartH = 3;
	var innerLeftLineEndH = 500;
	var innerLeftLineStartR = 0.22; //0.075;
	var innerLeftLineEndR = 0.275;
	// Right
	var innerRightLineStartX = 50;
	var innerRightLineEndX = 412;
	var innerRightLineStartW = 3;
	var innerRightLineEndW = 80;
	var innerRightLineStartH = 3;
	var innerRightLineEndH = 500;
	var innerRightLineStartR = -0.22;
	var innerRightLineEndR = -0.275;
	// Lamp posts 
	// Left Lamp
	var leftLampStartX = -130;
	var leftLampEndX = -1600;
	var leftLampStartY = roadTop;
	var leftLampEndY = roadTop + roadHeight + 0; // Define leftLampEndY variable
	var leftLampStartH = 2;
	var leftLampEndH = 900;
	var leftLampWRatio = 1 / 3;
	// Right Lamp
	var rightLampStartX = 130;
	var rightLampEndX = 1600;
	var rightLampStartY = roadTop;
	var rightLampEndY = roadTop + roadHeight + 0; // Define leftLampEndY variable
	var rightLampStartH = 2;
	var rightLampEndH = 900;
	var rightLampWRatio = 1 / 3;
	var nbInnerLines = 6;
	var leftLine = self.attachAsset('triangle', {
		anchorX: 0.5,
		anchorY: 0,
		width: 100,
		height: 1950,
		rotation: 0.45
	});
	leftLine.x = lineOffset; // Position the left line on the left side of the road
	leftLine.y = roadTop + 45; // Center the left line vertically
	var rightLine = self.attachAsset('triangle', {
		anchorX: 0.5,
		anchorY: 0,
		width: 100,
		height: 1950,
		rotation: -0.45
	});
	rightLine.x = -lineOffset; // Position the right line on the right side of the road
	rightLine.y = roadTop + 45; // Center the right line vertically
	self.innerLeftLines = [];
	self.innerRightLines = [];
	self.leftLampPosts = [];
	self.rightLampPosts = [];
	for (var i = 0; i < nbInnerLines; i++) {
		var innerLineLeft = self.attachAsset('line', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: innerLeftLineStartW,
			height: innerLeftLineStartH,
			rotation: innerLeftLineStartR,
			alpha: 1
		});
		innerLineLeft.x = innerLeftLineStartX;
		innerLineLeft.y = innerLineStartY - 0.1 * i * roadHeight / nbInnerLines;
		//console.log(i + " : " + innerLineStartY + " + " + i * roadHeight / nbInnerLines + " => " + innerLineLeft.y);
		innerLineLeft.progress = 0; // Initialize progress property
		self.innerLeftLines.push(innerLineLeft);
		var innerLineRight = self.attachAsset('line', {
			anchorX: 0.5,
			anchorY: 0.5,
			width: innerRightLineStartW,
			height: innerRightLineStartH,
			rotation: innerRightLineStartR,
			alpha: 1
		});
		innerLineRight.x = innerRightLineStartX;
		innerLineRight.y = innerLineStartY - 0.1 * i * roadHeight / nbInnerLines;
		innerLineRight.progress = 0; // Initialize progress property
		self.innerRightLines.push(innerLineRight);
		if (i % 2 == 0) {
			continue;
		}
		var leftLampPost = self.attachAsset('lampPost', {
			anchorX: 0.5,
			anchorY: 0.5,
			height: leftLampStartH,
			width: leftLampStartH * leftLampWRatio
		});
		leftLampPost.x = leftLampStartX;
		leftLampPost.y = leftLampStartY - (i - 1) * 40;
		self.addChild(leftLampPost);
		self.leftLampPosts.push(leftLampPost);
		var rightLampPost = self.attachAsset('lampPost', {
			anchorX: 0.5,
			anchorY: 0.5,
			scaleX: -1,
			height: rightLampStartH,
			width: rightLampStartH * rightLampWRatio
		});
		rightLampPost.x = rightLampStartX;
		rightLampPost.y = rightLampStartY - (i - 1) * 40;
		self.addChild(rightLampPost);
		self.rightLampPosts.push(rightLampPost);
	}
	self.update = function () {
		if (isKilled) {
			return;
		}
		var newTint = intensityHalf << 16 | intensityHalf << 8 | intensityHalf;
		//roadGraphics.tint = newTint; // Apply reduced tint to the road based on the intensity
		leftLine.tint = newTint;
		rightLine.tint = newTint;
		// Add any update logic for the road if needed
		for (var i = 0; i < self.innerLeftLines.length; i++) {
			innerLineLeft = self.innerLeftLines[i];
			innerLineLeft.tint = newTint;
			if (innerLineLeft.y > innerLineEndY) {
				self.resetInnerLine(innerLineLeft, true);
			} else {
				innerLineLeft.progress = Math.max(0, innerLineLeft.y - innerLineStartY) / (innerLineEndY - innerLineStartY); // Update progress property
			}
			var tempSpeed = currentSpeed * 0.05 + currentSpeed * (innerLineLeft.progress * 3);
			var newSpeed = currentSpeed; // + 10 * self.progress;
			newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
			innerLineLeft.y += newSpeed;
			// Move innerLineLeft x progressively to innerLeftLineEndX
			if (innerLineLeft.x != innerLeftLineEndX) {
				innerLineLeft.x = innerLeftLineStartX + (innerLeftLineEndX - innerLeftLineStartX) * innerLineLeft.progress;
			}
			// Move innerLineLeft x progressively 
			if (innerLineLeft.rotation != innerLeftLineEndR) {
				//innerLineLeft.rotation = innerLeftLineStartR + (innerLeftLineEndR - innerLeftLineStartR) * innerLineLeft.progress;
			}
			// Move innerLineLeft x progressively 
			if (innerLineLeft.width != innerLeftLineEndW) {
				innerLineLeft.width = innerLeftLineStartW + (innerLeftLineEndW - innerLeftLineStartW) * innerLineLeft.progress;
			}
			// Move innerLineLeft x progressively
			if (innerLineLeft.height != innerLeftLineEndH) {
				innerLineLeft.height = innerLeftLineStartH + (innerLeftLineEndH - innerLeftLineStartH) * innerLineLeft.progress;
			}
		}
		for (var i = 0; i < self.innerRightLines.length; i++) {
			innerLineRight = self.innerRightLines[i];
			innerLineRight.tint = newTint;
			if (innerLineRight.y > innerLineEndY) {
				self.resetInnerLine(innerLineRight, false);
			} else {
				innerLineRight.progress = Math.max(0, innerLineRight.y - innerLineStartY) / (innerLineEndY - innerLineStartY);
			}
			var tempSpeed = currentSpeed * 0.05 + currentSpeed * (innerLineRight.progress * 3);
			var newSpeed = currentSpeed; // + 10 * self.progress;
			newSpeed = tempSpeed * 1; // TEMP DEBUG !!!
			innerLineRight.y += newSpeed;
			// Move innerLineRight x progressively to innerRightLineEndX
			if (innerLineRight.x != innerRightLineEndX) {
				innerLineRight.x = innerRightLineStartX + (innerRightLineEndX - innerRightLineStartX) * innerLineRight.progress;
			}
			// Move innerLineRight x progressively 
			if (innerLineRight.rotation != innerRightLineEndR) {
				//innerLineRight.rotation = innerRightLineStartR + (innerRightLineEndR - innerRightLineStartR) * innerLineRight.progress;
			}
			// Move innerLineRight x progressively 
			if (innerLineRight.width != innerRightLineEndW) {
				innerLineRight.width = innerRightLineStartW + (innerRightLineEndW - innerRightLineStartW) * innerLineRight.progress;
			}
			// Move innerLineRight x progressively 
			if (innerLineRight.height != innerRightLineEndH) {
				innerLineRight.height = innerRightLineStartH + (innerRightLineEndH - innerRightLineStartH) * innerLineRight.progress;
			}
		}
		// Lamp posts
		for (var i = 0; i < self.leftLampPosts.length; i++) {
			var leftLampPost = self.leftLampPosts[i];
			//leftLampPost.tint = newTint;
			var tempProgress = Math.max(0, leftLampPost.y - leftLampStartY) / (leftLampEndY - leftLampStartY);
			var tempSpeed = currentSpeed * 0.05 + currentSpeed * (tempProgress * 3);
			leftLampPost.y += tempSpeed;
			if (leftLampPost.y > leftLampEndY) {
				leftLampPost.y = leftLampStartY;
				leftLampPost.x = leftLampStartX;
				leftLampPost.height = leftLampStartH;
			}
			leftLampPost.progress = Math.max(0, leftLampPost.y - leftLampStartY) / (leftLampEndY - leftLampStartY); // Update progress property
			leftLampPost.alpha = 0.75 + Math.min(0.25, leftLampPost.progress);
			if (i == 0) {
				//debugTxt.setText(leftLampPost.progress.toFixed(2));
			}
			if (leftLampPost.x != leftLampEndX) {
				leftLampPost.x = leftLampStartX + (leftLampEndX - leftLampStartX) * Math.min(1, leftLampPost.progress * 1);
			}
			if (leftLampPost.height != leftLampEndH) {
				leftLampPost.height = Math.min(1, leftLampPost.progress * 2) * leftLampEndH; // leftLampStartH + (leftLampEndH - leftLampStartH) * Math.min(1, leftLampPost.progress * 1);
				leftLampPost.width = leftLampPost.height * leftLampWRatio;
			}
		}
		for (var i = 0; i < self.rightLampPosts.length; i++) {
			var rightLampPost = self.rightLampPosts[i];
			var tempProgress = Math.max(0, rightLampPost.y - rightLampStartY) / (rightLampEndY - rightLampStartY);
			var tempSpeed = currentSpeed * 0.05 + currentSpeed * (tempProgress * 3);
			rightLampPost.y += tempSpeed;
			if (rightLampPost.y > rightLampEndY) {
				rightLampPost.y = rightLampStartY;
				rightLampPost.x = rightLampStartX;
				rightLampPost.height = rightLampStartH;
			}
			rightLampPost.progress = Math.max(0, rightLampPost.y - rightLampStartY) / (rightLampEndY - rightLampStartY);
			rightLampPost.alpha = 0.75 + Math.min(0.25, rightLampPost.progress);
			if (rightLampPost.x != rightLampEndX) {
				rightLampPost.x = rightLampStartX + (rightLampEndX - rightLampStartX) * rightLampPost.progress;
			}
			if (rightLampPost.height != leftLampEndH) {
				rightLampPost.height = rightLampStartH + (rightLampEndH - rightLampStartH) * Math.min(1, rightLampPost.progress * 2);
				rightLampPost.width = rightLampPost.height * rightLampWRatio;
			}
		}
	};
	self.resetInnerLine = function (innerLine, isLeft) {
		if (isLeft) {
			innerLine.x = innerLeftLineStartX;
			innerLine.rotation = innerLeftLineStartR;
			innerLine.width = innerLeftLineStartW;
			innerLine.height = innerLeftLineStartH;
		} else {
			innerLine.x = innerRightLineStartX;
			innerLine.rotation = innerRightLineStartR;
			innerLine.width = innerRightLineStartW;
			innerLine.height = innerRightLineStartH;
		}
		innerLine.y = innerLineStartY - 0.2 * roadHeight / nbInnerLines;
		innerLine.progress = 0; // Reset progress property
	};
});
var StartButton = Container.expand(function () {
	var self = Container.call(this);
	var buttonGraphics = self.attachAsset('startButton', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.interactive = true;
	self.buttonMode = true;
	self.on('down', function () {
		self.visible = false;
		isPlaying = true;
		scoreTxt.visible = true;
	});
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x000000 // Init game with black background
});
/**** 
* Game Code
****/ 
// Initialize arrays and variables
var isPlaying = false;
var isKilled = false;
var killerDelay = 10000; // Delay in milliseconds before updating killer
var lastKillerUpdate = 0; // Timestamp of the last killer update
var currentCoinType = 0;
var nextCoinTypeThreshold = 5;
var isNight = false;
var roadHeight = 2000;
var roadTop = 1000; // ~= road.height/2 - baseY 
var background;
var landscape1;
var coins = [];
var obstacles = [];
var road;
var score = 0;
var scoreTxt;
var startX = 0;
var startY = 0;
var endX = 0;
var endY = 0;
var intensity = 0;
var intensityHalf = 0;
var leftLampPosts = [];
var rightLampPosts = [];
var leftDecorations = [];
var rightDecorationss = [];
var maxSpeed = 50; // Define a maximum speed limit
var currentSpeed = 10; //20; // Initialize currentSpeed
var coinsCollected = 0; // Initialize coins collected counter
var isIntersectingObstacle = false; // Flag to track if the player is currently intersecting an obstacle
var lastObstacleHitTime = 0; // Timestamp of the last obstacle hit
var immunityDelay = 500; // Immunity delay in milliseconds
var playerPositionIndex = 1; // Initialize player position index
// Define the three fixed x positions for the player
var playerPositions = [2048 / 5, 2048 / 2, 4 * 2048 / 5];
// Create player
var player;
var debugMarker;
var debugText;
var debugTxt;
function easeInOutQuad(t) {
	return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}
function updateBackgroundColor() {
	var time = new Date().getTime() * 0.0002;
	intensity = Math.sin(time) * 127 + 128;
	var color = Math.max(32, intensity) << 16 | Math.max(32, intensity) << 8 | Math.max(32, intensity);
	background.tint = color;
	isNight = intensity < 128;
	intensityHalf = 128 + Math.floor(intensity * 0.5);
}
// Handle move events
game.down = function (x, y, obj) {
	if (!isPlaying) {
		return;
	}
	startX = x;
	startY = y;
};
game.up = function (x, y, obj) {
	if (isKilled) {
		LK.showGameOver();
		return;
	}
	if (!isPlaying) {
		return;
	}
	endX = x;
	endY = y;
	var deltaX = endX - startX;
	var deltaY = endY - startY;
	if (Math.abs(deltaX) > Math.abs(deltaY)) {
		if (deltaX > 0) {
			// Swipe right
			if (playerPositionIndex < 2) {
				playerPositionIndex++;
			}
		} else {
			// Swipe left
			if (playerPositionIndex > 0) {
				playerPositionIndex--;
			}
		}
	} else {
		if (deltaY < 0) {
			// Swipe up
			player.jump();
		}
	}
	// Make the player move progressively to the next path
	var targetX = playerPositions[playerPositionIndex];
	var initialX = player.x;
	var moveDuration = 30;
	var moveStartTime = Date.now();
	var moveInterval = LK.setInterval(function () {
		var elapsed = Date.now() - moveStartTime;
		var progress = elapsed / (moveDuration * 1000 / 60);
		if (progress < 1) {
			var easeProgress = easeInOutQuad(progress);
			player.x = initialX + (targetX - initialX) * easeProgress;
		} else {
			player.x = targetX;
			LK.clearInterval(moveInterval);
		}
	}, 1000 / 60);
};
// Update game every tick
game.update = function () {
	updateBackgroundColor();
	if (!isPlaying || isKilled) {
		return;
	}
};
// Initialize game
function gameInitialize() {
	// Initialize arrays and variables
	// Attach the background asset to the game
	background = game.attachAsset('background', {
		anchorX: 0.0,
		anchorY: 0.0
	});
	game.addChild(background);
	// Create and attach a decoration instance to the game
	var newDecoration = new Decoration();
	newDecoration.reset();
	game.addChild(newDecoration);
	// Create and attach the road instance to the game
	road = game.addChild(new Road());
	road.x = 2048 / 2;
	road.y = 0;
	// Create and attach the landscape instance to the game
	var landscape = game.addChild(new Landscape());
	score = 0;
	scoreTxt = new Text2('0', {
		size: 150,
		fill: "#ffffff"
	});
	scoreTxt.anchor.set(0.5, 0);
	scoreTxt.visible = false;
	LK.gui.top.addChild(scoreTxt);
	coins = [];
	for (var i = 0; i < 5; i++) {
		var newCoin = new Coin();
		newCoin.reset();
		newCoin.y = roadTop - i * 50;
		coins.push(newCoin);
		game.addChild(newCoin);
	}
	// Create a variable to store the current player position index
	playerPositionIndex = 1;
	// Create and attach the obstacle instance to the game
	var newObstacle = new Obstacle();
	newObstacle.reset();
	obstacles.push(newObstacle);
	game.addChild(newObstacle);
	// Create and attach the killer instance to the game
	var newKiller = new Killer();
	newKiller.reset();
	obstacles.push(newKiller);
	game.addChild(newKiller);
	// Create player
	player = game.addChild(new Player());
	player.frame = 0;
	player.x = playerPositions[playerPositionIndex]; // Start at the center position
	player.y = 2732 - 300;
	// Attach a debugMarker asset to the game at position (1000, 0)
	debugMarker = game.attachAsset('debugMarker', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	debugMarker.x = 10;
	debugMarker.y = 2500;
	debugTxt = new Text2('Debug Info', {
		size: 50,
		fill: "#ff0000"
	});
	debugTxt.anchor.set(1, 1); // Set anchor to the bottom right corner
	LK.gui.bottomRight.addChild(debugTxt);
	var startButton = game.addChild(new StartButton());
	startButton.x = 2048 / 2;
	startButton.y = 2732 / 4;
	// TEMP DEBUG !!!
	startButton.width = 100;
	startButton.height = 100;
	isPlaying = false;
}
gameInitialize(); ===================================================================
--- original.js
+++ change.js
@@ -905,18 +905,8 @@
 	updateBackgroundColor();
 	if (!isPlaying || isKilled) {
 		return;
 	}
-	// Update coins
-	/*for (var i = coins.length - 1; i >= 0; i--) {
-		coins[i].update();
-	}
-	*/
-	// Update obstacles
-	for (var i = obstacles.length - 1; i >= 0; i--) {
-		//obstacles[i].update();
-	}
-	// Removed continuous speed increase
 };
 // Initialize game
 function gameInitialize() {
 	// Initialize arrays and variables
 Directly overhead, plumb view of a beggar heading top (we see his back).. Zenith view, directly overhead, plumb view. NOT PERSPECTIVE! Fantasy theme. Pixel art
 
 a traffic cone. video game sprite
 
 
 face view of a big start button in the shape of a dollar bill. video game style
 
 
 
 
 a tree. video game style
 a black garbage bag. video game style
 
 
 
 Dollar bill. Perspective. video game sprite
 
 
 
 
 
 perspective of a simple snake rolled up on itself.. video game sprite
 Ball of dry desert bushes. video game sprite
 
 
 
 
 
 
 
 
 tractor. high definition video game sprite
 street ad billboard with 1 or 2 posts with "Get rich!" on it. high definition video game sprite
 
 
 a dog sleeping on a street. video game sprite
 
 desert bush. video game sprite
 
 
 
 profile view of an empty motorcycle helmet. black with a white vertical central band and another thiner orange band on the center. NOT PERSPECTIVE!. Pixel art high definition
 simple red and white magnet. video game style
 gold sign with a "X" and a "2". video game style
 bgMusic
Music
coin_1
Sound effect
hit_1
Sound effect
hit_2
Sound effect
hit_3
Sound effect
levelWin_1
Sound effect
car_1
Sound effect
police_1
Sound effect
ambulance_1
Sound effect
accident_1
Sound effect
killed_1
Sound effect
jump_1
Sound effect
rip_1
Sound effect
bonus_take
Sound effect
bonus_approaching
Sound effect