User prompt
If car button pressed then pop up a 3 selector button under each other to livery selector in that order: grey/yellow, white/yellow, white/red. You should display the colors in diagonal lines but not the color names.
User prompt
Change the way that display digital speedometer to analog by rotating hh asset. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Hh asset is still not rotating by animated to display the speed ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
How could you Replace speedometer text with HH asset and add rotation animation based on speed? Speed 0 is at 8 o'clock and maximum speed is at 4 o'clock. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Animation speedometer HH asset to rotating between 8 o'clock and 4 o'clock to show actual speed. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Change the digital speedometer in the left bottom corner of the screen to HH asset. Ensure the HH asset rotating between 8 o'clock and 4 o'clock to display player's speed. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Improve HH asset rotation synchronization with smoother tween transitions for speedometer display ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Synchronize HH asset rotation to display car speed with 0 speed at 8 o'clock position and maximum speed at 4 o'clock position ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Syncronising the HH TURNING to display speed. 0 speed is at 8 o'clock, maximum speed is at 4 o'clock. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Change the digital speedometer in the left bottom corner of the screen to speedometer asset and HH asset
User prompt
Play NR Sound if the next turn will be right
User prompt
Play NL SOUND if the next turn will be left
User prompt
Avoid LA/RA indicator be on the map at the same time ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
You show the actual LA/RA indicators too short time ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
You pop up LA and RA assets too late ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Pop up RA asset to the top center of the screen before load turning right ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Pop up LA asset to the top center of the screen before load turning left ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add LA and RA assets to the list
User prompt
Play rain sound continous loop without brake in rain gamemode
User prompt
Why dont you play the heavyrain sound again and again One after another without sound loop bugs?
User prompt
Play heavyrain sound after thunder sound
User prompt
Play The Sound of heavyRain not only once at the beginning of the level, but also between lightning effects
User prompt
Play The Sound of Rain not just once at the beginning of the level, but every time there is no lightning.
User prompt
The sound of rain interferes with the other in continuous playback. Fix them so they don't get stuck
User prompt
Play heavyrain sound continous after a previous heavyrainsound
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BlurBackground = Container.expand(function (options) { var self = Container.call(this); self.graphics = new Graphics(); self.addChild(self.graphics); self.options = options || {}; self.options.blur = self.options.blur || 10; self.options.width = self.options.width || 2048; self.options.height = self.options.height || 2732; self.updateGraphics = function () { self.graphics.clear(); self.graphics.beginFill(0x0a0a0a, 0.95); // Very dark background for modern look self.graphics.drawRect(0, 0, self.options.width, self.options.height); self.graphics.endFill(); }; self.applyBlur = function () { var blurFilter = new filters.BlurFilter(); blurFilter.blur = self.options.blur; // Filters not supported in LK engine - commenting out assignment // self.filters = [blurFilter]; }; self.updateGraphics(); self.applyBlur(); return self; }); var Car = Container.expand(function () { var self = Container.call(this); self.projectMovement = function (vector) { var angle = -Math.PI / 4; var cosAngle = Math.cos(angle); var sinAngle = Math.sin(angle); return { x: vector.x * cosAngle - vector.y * sinAngle, y: vector.x * sinAngle + vector.y * cosAngle }; }; var carGraphics = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5 }); // Create headlight beam effect (right beam) self.headlightBeam = self.attachAsset('beamR', { anchorX: 0.5, anchorY: 1.0, width: 1400, height: 1200, alpha: 0.3, tint: 0xFFFF88 }); self.headlightBeam.x = 753; self.headlightBeam.y = -50; // Create second headlight beam next to the first one self.headlightBeam2 = self.attachAsset('beamR', { anchorX: 0.5, anchorY: 1.0, width: 1400, height: 1200, alpha: 0.3, tint: 0xFFFF88 }); self.headlightBeam2.x = 838; self.headlightBeam2.y = -15; // Create left headlight beam effect self.leftBeam = self.attachAsset('beamL', { anchorX: 0.5, anchorY: 1.0, width: 1400, height: 1200, alpha: 0.3, tint: 0xFFFF88 }); self.leftBeam.x = -753; self.leftBeam.y = -50; self.leftBeam.visible = false; // Create second left headlight beam next to the first one self.leftBeam2 = self.attachAsset('beamL', { anchorX: 0.5, anchorY: 1.0, width: 1400, height: 1200, alpha: 0.3, tint: 0xFFFF88 }); self.leftBeam2.x = -838; self.leftBeam2.y = -15; self.leftBeam2.visible = false; self.speed = 5; self.direction = 0; self.momentum = { x: 0, y: 0 }; self._move_migrated = function () { var momentumModifier = 0.1; if (self.direction === 0) { self.momentum.x += self.speed * momentumModifier; } else { self.momentum.y -= self.speed * momentumModifier; } var projectedMovement = self.projectMovement(self.momentum); // Check if car reaches the center of the screen on the X coordinate if (self.lastX <= 2048 / 2 && self.x > 2048 / 2) { console.log("Car reached the center of the screen on the X coordinate"); } self.lastX = self.x; // Predictive turn detection - show indicators before actual turn var momentum = Math.sqrt(self.momentum.x * self.momentum.x + self.momentum.y * self.momentum.y); var turnThreshold = 3.0; // Momentum threshold to predict turn // Predict left turn (direction 0 to 1) - show LA indicator early if (self.direction === 0 && momentum > turnThreshold && self.momentum.y < -2.0) { if (!self.leftTurnPredicted && typeof showLeftTurnIndicator === 'function') { showLeftTurnIndicator(); // Play NL sound when next turn will be left LK.getSound('NL').play(); self.leftTurnPredicted = true; // Reset prediction flag after some time LK.setTimeout(function () { self.leftTurnPredicted = false; }, 2000); } } // Predict right turn (direction 1 to 0) - show RA indicator early if (self.direction === 1 && momentum > turnThreshold && self.momentum.x > 2.0) { if (!self.rightTurnPredicted && typeof showRightTurnIndicator === 'function') { showRightTurnIndicator(); // Play NR sound when next turn will be right LK.getSound('NR').play(); self.rightTurnPredicted = true; // Reset prediction flag after some time LK.setTimeout(function () { self.rightTurnPredicted = false; }, 2000); } } self.x += projectedMovement.x; self.y += projectedMovement.y; // Check if car arrives at a specific X, Y coordinate if (self.lastY <= 1500 && self.y > 1500 && self.lastX <= 1000 && self.x > 1000) { console.log("Car arrived at the specific X, Y coordinate"); } self.lastY = self.y; self.lastX = self.x; // Check if car comes close to the bottom of the screen on the Y coordinate if (self.lastY <= 2732 - 100 && self.y > 2732 - 100) { console.log("Car is close to the bottom of the screen"); } self.lastY = self.y; var nonTravelMomentum; if (self.direction === 0) { self.momentum.x *= 0.98; self.momentum.y *= 0.95; nonTravelMomentum = self.momentum.y; } else { self.momentum.x *= 0.95; self.momentum.y *= 0.98; nonTravelMomentum = self.momentum.x; } self.nonTravelMomentum = nonTravelMomentum; // Show beamR only when car is turned to the right (direction === 0) var shouldShowRightBeam = self.direction === 0; self.headlightBeam.visible = shouldShowRightBeam; self.headlightBeam2.visible = shouldShowRightBeam; // Show beamL only when car is turned to the left (direction === 1) var shouldShowLeftBeam = self.direction === 1; if (self.leftBeam) { self.leftBeam.visible = shouldShowLeftBeam; } if (self.leftBeam2) { self.leftBeam2.visible = shouldShowLeftBeam; } if (shouldShowRightBeam) { // Update headlight beam intensity based on speed var totalSpeed = Math.sqrt(self.momentum.x * self.momentum.x + self.momentum.y * self.momentum.y); var beamIntensity = Math.min(0.6, Math.max(0.2, totalSpeed * 0.05)); // Animate headlight beam flickering tween(self.headlightBeam, { alpha: beamIntensity }, { duration: 100 + Math.random() * 200, easing: tween.easeInOut, onFinish: function onFinish() { // Create slight flickering effect var flickerAlpha = beamIntensity + (Math.random() - 0.5) * 0.1; tween(self.headlightBeam, { alpha: Math.max(0.1, flickerAlpha) }, { duration: 50, easing: tween.linear }); } }); // Animate second beam with slight variation tween(self.headlightBeam2, { alpha: beamIntensity }, { duration: 120 + Math.random() * 180, easing: tween.easeInOut, onFinish: function onFinish() { // Create slight flickering effect var flickerAlpha = beamIntensity + (Math.random() - 0.5) * 0.1; tween(self.headlightBeam2, { alpha: Math.max(0.1, flickerAlpha) }, { duration: 60, easing: tween.linear }); } }); } if (shouldShowLeftBeam && self.leftBeam) { // Update left beam intensity based on speed var totalSpeed = Math.sqrt(self.momentum.x * self.momentum.x + self.momentum.y * self.momentum.y); var beamIntensity = Math.min(0.6, Math.max(0.2, totalSpeed * 0.05)); // Animate left beam flickering tween(self.leftBeam, { alpha: beamIntensity }, { duration: 100 + Math.random() * 200, easing: tween.easeInOut, onFinish: function onFinish() { // Create slight flickering effect var flickerAlpha = beamIntensity + (Math.random() - 0.5) * 0.1; tween(self.leftBeam, { alpha: Math.max(0.1, flickerAlpha) }, { duration: 50, easing: tween.linear }); } }); // Animate second left beam with slight variation if (self.leftBeam2) { tween(self.leftBeam2, { alpha: beamIntensity }, { duration: 120 + Math.random() * 180, easing: tween.easeInOut, onFinish: function onFinish() { // Create slight flickering effect var flickerAlpha = beamIntensity + (Math.random() - 0.5) * 0.1; tween(self.leftBeam2, { alpha: Math.max(0.1, flickerAlpha) }, { duration: 60, easing: tween.linear }); } }); } } // Adjust beam width based on direction and momentum var beamWidth = 1350 + Math.abs(self.nonTravelMomentum) * 20; tween(self.headlightBeam, { width: beamWidth }, { duration: 200, easing: tween.easeOut }); // Update second beam width as well tween(self.headlightBeam2, { width: beamWidth }, { duration: 200, easing: tween.easeOut }); if (self.leftBeam) { tween(self.leftBeam, { width: beamWidth }, { duration: 200, easing: tween.easeOut }); } if (self.leftBeam2) { tween(self.leftBeam2, { width: beamWidth }, { duration: 200, easing: tween.easeOut }); } }; self.changeDirection = function () { var previousDirection = self.direction; self.direction = self.direction === 0 ? 1 : 0; // Indicators are now shown predictively in _move_migrated, not here carGraphics.scale.x *= -1; // Synchronize beam rotation with car direction self.headlightBeam.scale.x *= -1; self.headlightBeam2.scale.x *= -1; if (self.leftBeam) { self.leftBeam.scale.x *= -1; } if (self.leftBeam2) { self.leftBeam2.scale.x *= -1; } }; }); var DriftAndDodge = Container.expand(function () { var self = Container.call(this); }); var Dust = Container.expand(function () { var self = Container.call(this); var dustGraphics = self.attachAsset('dust', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 60; self.velocityY = -2 - Math.random() * 3; self.velocityX = (Math.random() - 0.5) * 2; self.fadeSpeed = 0.02; self.scaleSpeed = 0.02; self.update = function () { self.y += self.velocityY; self.x += self.velocityX; self.alpha -= self.fadeSpeed; self.scaleX += self.scaleSpeed; self.scaleY += self.scaleSpeed; if (self.alpha <= 0 || --self.lifetime <= 0) { self.destroy(); } }; return self; }); var FogOverlay = Container.expand(function () { var self = Container.call(this); var fogGraphics = self.attachAsset('fogOverlay', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Position fog at screen center for fullscreen effect fogGraphics.x = 0; fogGraphics.y = 0; self.isActive = false; self.startFog = function () { self.isActive = true; // Fade in fog effect tween(fogGraphics, { alpha: 0.4 }, { duration: 2000, easing: tween.easeInOut }); // Start continuous fog animation self.animateFog(); }; self.stopFog = function () { self.isActive = false; // Fade out fog effect tween(fogGraphics, { alpha: 0 }, { duration: 2000, easing: tween.easeInOut }); }; self.animateFog = function () { if (!self.isActive) return; // Create subtle fog movement tween(fogGraphics, { alpha: 0.3 + Math.random() * 0.2 }, { duration: 3000 + Math.random() * 2000, easing: tween.easeInOut, onFinish: function onFinish() { if (self.isActive) { self.animateFog(); } } }); }; return self; }); // Add the game logic for 'DriftAndDodge' here var Graphics = Container.expand(function () { var self = Container.call(this); self.clear = function () {}; self.beginFill = function (color, alpha) { self._fillColor = color; self._fillAlpha = alpha; }; self.drawRect = function (x, y, width, height) { var rect = LK.getAsset('beamR', { // Using 'beamR' asset for rectangle drawing x: x, y: y, width: width, height: height, tint: self._fillColor, alpha: self._fillAlpha }); self.addChild(rect); }; self.endFill = function () {}; return self; }); var Lightning = Container.expand(function () { var self = Container.call(this); var lightningGraphics = self.attachAsset('lightning', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); // Position lightning at screen center for fullscreen effect lightningGraphics.x = 0; lightningGraphics.y = 0; self.flashDuration = 150 + Math.random() * 200; self.flickerCount = 2 + Math.floor(Math.random() * 3); self.currentFlicker = 0; self.isActive = false; self.startLightning = function () { self.isActive = true; self.currentFlicker = 0; self.doFlash(); }; self.doFlash = function () { if (self.currentFlicker >= self.flickerCount) { self.endLightning(); return; } // Flash to full brightness tween(lightningGraphics, { alpha: 0.15 + Math.random() * 0.1 }, { duration: 50 + Math.random() * 100, easing: tween.easeOut, onFinish: function onFinish() { // Quick fade out tween(lightningGraphics, { alpha: 0 }, { duration: 30 + Math.random() * 70, easing: tween.easeIn, onFinish: function onFinish() { // Play thunder sound after lightning flash LK.getSound('thunder').play(); // Schedule heavy rain sound to play after thunder sound ends (approximately 2 seconds) LK.setTimeout(function () { if (currentWeather === 'Storm' && !currentWeatherSound) { currentWeatherSound = LK.getSound('Heavyrain'); currentWeatherSound.play(); } }, 2000); self.currentFlicker++; if (self.currentFlicker < self.flickerCount) { // Brief pause before next flicker LK.setTimeout(function () { if (self.isActive) { self.doFlash(); } }, 100 + Math.random() * 200); } else { self.endLightning(); } } }); } }); }; self.endLightning = function () { self.isActive = false; lightningGraphics.alpha = 0; }; return self; }); var Particle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); particleGraphics.rotation = Math.PI / 4; self.lifetime = 100; self.tick = function () { if (--self.lifetime <= 0) { self.destroy(); } }; }); var RainDrop = Container.expand(function () { var self = Container.call(this); // Create raindrop using particle asset with blue tint var dropGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.05, scaleY: 0.8, tint: 0x87CEEB, alpha: 0.6 }); // Rain properties - enhanced for full level coverage self.fallSpeed = 10 + Math.random() * 6; self.windDrift = (Math.random() - 0.5) * 3; self.lifetime = 400 + Math.random() * 300; // Longer lifetime for better coverage self.maxLifetime = self.lifetime; // Add slight rotation for realism dropGraphics.rotation = Math.random() * 0.2 - 0.1; // Removed tween animations for better performance self.update = function () { // Fall down with wind drift self.y += self.fallSpeed; self.x += self.windDrift; // Fade out as lifetime decreases var fadeRatio = self.lifetime / self.maxLifetime; self.alpha = Math.max(0, fadeRatio * 0.6); // Destroy when lifetime expires or when reaching bottom of screen if (--self.lifetime <= 0 || self.y > 2732 + 100) { self.destroy(); } }; return self; }); var Rock = Container.expand(function () { var self = Container.call(this); var rockGraphics = self.attachAsset('rock', { anchorX: 0.5, anchorY: 0.5 }); }); var SnowyEmbankment = Container.expand(function () { var self = Container.call(this); var embankmentGraphics = self.attachAsset('rods', { anchorX: 0.5, anchorY: 0.5 }); }); var Tree = Container.expand(function () { var self = Container.call(this); var treeGraphics = self.attachAsset('tree', { anchorX: 0.5, anchorY: 0.5 }); }); var Tree2 = Container.expand(function () { var self = Container.call(this); var treeGraphics = self.attachAsset('tree2', { anchorX: 0.5, anchorY: 0.5 }); }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xFFFFFF }); /**** * Game Code ****/ var filters = { BlurFilter: function BlurFilter() { this.blur = 0; } }; var driftAndDodge = game.addChild(new DriftAndDodge()); driftAndDodge.on('down', function (x, y, obj) { // Add the event handler for 'down' event here }); driftAndDodge.on('up', function (x, y, obj) { // Add the event handler for 'up' event here }); driftAndDodge.on('move', function (x, y, obj) { // Add the event handler for 'move' event here }); game.calculateDistanceToPoint = function (point, segmentStart, segmentEnd) { var A = point.x - segmentStart.x; var B = point.y - segmentStart.y; var C = segmentEnd.x - segmentStart.x; var D = segmentEnd.y - segmentStart.y; var dot = A * C + B * D; var len_sq = C * C + D * D; var param = -1; if (len_sq != 0) { param = dot / len_sq; } var xx, yy; if (param < 0) { xx = segmentStart.x; yy = segmentStart.y; } else if (param > 1) { xx = segmentEnd.x; yy = segmentEnd.y; } else { xx = segmentStart.x + param * C; yy = segmentStart.y + param * D; } var dx = point.x - xx; var dy = point.y - yy; return Math.sqrt(dx * dx + dy * dy); }; game.addRoadSegment = function () { var lastSegment = roadSegments[roadSegments.length - 1]; zigzag = !zigzag; var segment = roadContainer.attachAsset('roadSegment', { anchorX: 0.5 }); // Adjust segment width based on difficulty var difficultyMultiplier = 1.0; if (currentDifficulty === 'Normal') { difficultyMultiplier = 0.85; // Make track 15% thinner } else if (currentDifficulty === 'Hard') { difficultyMultiplier = 0.5; // Make track 50% thinner for extreme difficulty } segment.width = segmentWidth * difficultyMultiplier; // More controlled width reduction with minimum thresholds to prevent roads becoming too thin var widthReduction = currentDifficulty === 'Hard' ? 8 : 5; var minimumWidth = currentDifficulty === 'Hard' ? 600 : 800; segmentWidth = Math.max(minimumWidth * difficultyMultiplier, segmentWidth - widthReduction); segment.height = (i === 1 ? 3000 : Math.floor(Math.random() * (4000 - 1200 + 1)) + 1200) * 2; segment.rotation = zigzag ? -Math.PI - Math.PI / 4 : -Math.PI + Math.PI / 4; segment.y = currentY; segment.x = currentX; var adjustedHeight = segment.height - segmentWidth / 2; currentY += adjustedHeight * Math.cos(segment.rotation); currentX -= adjustedHeight * Math.sin(segment.rotation); segment.shadow = roadContainer.attachAsset('roadSegmentShadow', { anchorX: 0.5 }); segment.shadow.width = segment.width; segment.shadow.height = segment.height; segment.shadow.rotation = segment.rotation; segment.shadow.x = segment.x; segment.shadow.y = segment.y + 50; segment.shadow.alpha = 1; segment.used = false; roadSegments.push(segment); roadContainer.addChildAt(segment.shadow, 0); roadContainer.addChild(segment); // Add multiple trees to the left and right of the road segment var treeSpacing = 300; // Increase space between trees var numberOfTrees = Math.floor(segment.height / treeSpacing) - 3; // Decrease the number of trees by 3 var numberOfTree2 = Math.floor(segment.height / treeSpacing) - 3; // Decrease the number of tree2 by 3 for (var i = 0; i < numberOfTree2; i++) { var leftTree = new Tree(); // Adjust tree distance based on difficulty - increase distance in hard mode var treeDistance = 100; if (currentDifficulty === 'Hard') { treeDistance = 800; // Much further from road in hard mode to prevent touching } else if (currentDifficulty === 'Normal') { treeDistance = 200; // Moderately further in normal mode } leftTree.x = segment.x - segment.width - treeDistance - i * treeSpacing; leftTree.y = segment.y + i * treeSpacing; roadContainer.addChild(leftTree); var rightTree = new Tree2(); rightTree.x = segment.x + segment.width + treeDistance + i * treeSpacing; rightTree.y = segment.y + i * treeSpacing; roadContainer.addChild(rightTree); } // Add rocks to the left and right of the road segment var leftRock = new Rock(); leftRock.x = segment.x - segment.width - 1000; // Double the distance from the road leftRock.y = segment.y; roadContainer.addChildAt(leftRock, 0); roadContainer.addChildAt(rightRock, 0); var rightRock = new Rock(); rightRock.x = segment.x + segment.width + 1000; // Double the distance from the road rightRock.y = segment.y; // Attach snowy embankments to the left and right of the road segment var leftEmbankment = new SnowyEmbankment(); leftEmbankment.x = segment.x - segment.width / 2 - 50; // Increase distance by 50 units leftEmbankment.y = segment.y; roadContainer.addChild(leftEmbankment); var rightEmbankment = new SnowyEmbankment(); rightEmbankment.x = segment.x + segment.width / 2 + 50; // Increase distance by 50 units rightEmbankment.y = segment.y; roadContainer.addChild(rightEmbankment); }; game.setBackgroundColor(0x000000); // Set background to black var particles = []; var dustParticles = []; var rainDrops = []; var rainIntensity = 3; // Number of raindrops to spawn per tick var lightningContainer = null; var lightningTimer = 0; var nextLightningTime = 0; var fogOverlay = null; var mainContainer = game.addChild(new Container()); var roadContainer = mainContainer.addChild(new Container()); var roadSegments = []; var segmentLength = Math.floor(Math.random() * (1000 - 200 + 1)) + 200; var segmentWidth = 1200; var currentX = 2048 / 2; var currentY = 2732 / 2; var zigzag = true; for (var i = 1; i <= 15; i++) { game.addRoadSegment(); } var turnText = new Text2('Turn:', { size: 50, fill: 0xFFFFFF, weight: '800', dropShadow: true, dropShadowColor: '#373330', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); turnText.anchor.set(1, 0); // Anchor to right edge so it aligns nicely with score turnText.visible = false; // Hide turn text initially LK.gui.topRight.addChild(turnText); var scoreText = new Text2('0', { size: 50, fill: 0xFFFFFF, weight: '800', dropShadow: true, dropShadowColor: '#373330', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); scoreText.anchor.set(0, 0); scoreText.visible = false; // Hide score text initially LK.gui.topRight.addChild(scoreText); // Position turn text to the left of score text turnText.x = scoreText.x - 107; turnText.y = scoreText.y; // Move score text left by 69 units scoreText.x = scoreText.x - 69; // Add HH asset as speedometer needle to the bottom left corner of the map var isMenuShowing = true; var speedometerContainer = new Container(); speedometerContainer.visible = false; // Hide speedometer initially LK.gui.bottomLeft.addChild(speedometerContainer); // Add speedometer background var speedometerBg = speedometerContainer.attachAsset('Speedometer', { anchorX: 0.5, anchorY: 0.5, x: 80, y: -80 }); // Add HH asset as speedometer needle var speedometerNeedle = speedometerContainer.attachAsset('HH', { anchorX: 0.5, anchorY: 1.0, x: 80, y: -80, scaleX: 2.0, scaleY: 2.0 }); // Set initial needle rotation to 8 o'clock position (speed 0) speedometerNeedle.rotation = -Math.PI * 2 / 3; // 8 o'clock position speedometerNeedle.lastRotation = speedometerNeedle.rotation; // Track last rotation for smooth updates var menuContainer = LK.gui.addChild(new Container()); var wallpaper = menuContainer.attachAsset('MW1', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 300, y: 2732 / 2 - 400 }); var wallpaper2 = menuContainer.attachAsset('MW2', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 300, y: 2732 / 2 - 400, alpha: 0 }); var wallpaper3 = menuContainer.attachAsset('MW3', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2 - 300, y: 2732 / 2 - 400, alpha: 0 }); var menuBackground = menuContainer.addChild(new BlurBackground({ width: 2048, height: 2732, blur: 25 })); // Initialize slideshow variables var currentWallpaper = 0; // 0 for MW1, 1 for MW2, 2 for MW3 var slideshowTimer = 0; var slideshowInterval = 4000; // 4 seconds between transitions var transitionDuration = 2000; // 2 seconds for each transition // Start the slideshow gradient transition function startSlideshowTransition() { if (currentWallpaper === 0) { // Fade from MW1 to MW2 tween(wallpaper, { alpha: 0 }, { duration: transitionDuration, easing: tween.easeInOut }); tween(wallpaper2, { alpha: 1 }, { duration: transitionDuration, easing: tween.easeInOut, onFinish: function onFinish() { currentWallpaper = 1; slideshowTimer = 0; } }); } else if (currentWallpaper === 1) { // Fade from MW2 to MW3 tween(wallpaper2, { alpha: 0 }, { duration: transitionDuration, easing: tween.easeInOut }); tween(wallpaper3, { alpha: 1 }, { duration: transitionDuration, easing: tween.easeInOut, onFinish: function onFinish() { currentWallpaper = 2; slideshowTimer = 0; } }); } else { // Fade from MW3 to MW1 tween(wallpaper3, { alpha: 0 }, { duration: transitionDuration, easing: tween.easeInOut }); tween(wallpaper, { alpha: 1 }, { duration: transitionDuration, easing: tween.easeInOut, onFinish: function onFinish() { currentWallpaper = 0; slideshowTimer = 0; } }); } } // Effects removed from menu LK.playMusic('menuMusic', { loop: true }); var difficultyButtonContainer = new Container(); difficultyButtonContainer.x = 200; difficultyButtonContainer.y = 2732 / 2 + 377; var difficultyButtonAsset = difficultyButtonContainer.attachAsset('startbutton', { anchorX: 0.5, anchorY: 0.5 }); var difficultyText = new Text2('Difficulty', { size: 60, fill: 0xFFFFFF, align: 'center' }); difficultyText.anchor.set(0.5, 0.5); difficultyButtonContainer.addChild(difficultyText); menuContainer.addChild(difficultyButtonContainer); var weatherButtonContainer = new Container(); weatherButtonContainer.x = 580; weatherButtonContainer.y = 2732 / 2 + 377; var weatherButtonAsset = weatherButtonContainer.attachAsset('startbutton', { anchorX: 0.5, anchorY: 0.5 }); var weatherText = new Text2('Weather', { size: 60, fill: 0xFFFFFF, align: 'center' }); weatherText.anchor.set(0.5, 0.5); weatherButtonContainer.addChild(weatherText); menuContainer.addChild(weatherButtonContainer); var carButtonContainer = new Container(); carButtonContainer.x = 900; carButtonContainer.y = 2732 / 2 + 377; var carButtonAsset = carButtonContainer.attachAsset('startbutton', { anchorX: 0.5, anchorY: 0.5, width: 250 }); var carText = new Text2('Car', { size: 60, fill: 0xFFFFFF, align: 'center' }); carText.anchor.set(0.5, 0.5); carButtonContainer.addChild(carText); menuContainer.addChild(carButtonContainer); // Difficulty level buttons removed // Add underline graphics for selected difficulty var startButtonContainer = new Container(); startButtonContainer.x = 2048 / 2 - 126 + 333; startButtonContainer.y = 2732 / 2 + 377; var startButtonAsset = startButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 400, height: 100 }); var startButton = new Text2('Start Game', { size: 60, fill: 0xFFFFFF, align: 'center' }); startButton.anchor.set(0.5, 0.5); startButtonContainer.addChild(startButton); function flashStartButton() { // No flashing animation for start button } // Initialize difficulty level text objects with button backgrounds var easyButtonContainer = new Container(); var easyButtonAsset = easyButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); easyText = new Text2('EASY', { size: 60, fill: 0xFFFFFF, align: 'center' }); easyText.anchor.set(0.5, 0.5); easyButtonContainer.addChild(easyText); easyButtonContainer.visible = false; menuContainer.addChild(easyButtonContainer); var normalButtonContainer = new Container(); var normalButtonAsset = normalButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); normalText = new Text2('NORMAL', { size: 60, fill: 0xFFFFFF, align: 'center' }); normalText.anchor.set(0.5, 0.5); normalButtonContainer.addChild(normalText); normalButtonContainer.visible = false; menuContainer.addChild(normalButtonContainer); var hardButtonContainer = new Container(); var hardButtonAsset = hardButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); hardText = new Text2('HARD', { size: 60, fill: 0xFFFFFF, align: 'center' }); hardText.anchor.set(0.5, 0.5); hardButtonContainer.addChild(hardText); hardButtonContainer.visible = false; menuContainer.addChild(hardButtonContainer); // Initialize weather level text objects with button backgrounds var clearButtonContainer = new Container(); var clearButtonAsset = clearButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); clearText = new Text2('CLEAR', { size: 60, fill: 0xFFFFFF, align: 'center' }); clearText.anchor.set(0.5, 0.5); clearButtonContainer.addChild(clearText); clearButtonContainer.visible = false; menuContainer.addChild(clearButtonContainer); var rainButtonContainer = new Container(); var rainButtonAsset = rainButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); rainText = new Text2('RAIN', { size: 60, fill: 0xFFFFFF, align: 'center' }); rainText.anchor.set(0.5, 0.5); rainButtonContainer.addChild(rainText); rainButtonContainer.visible = false; menuContainer.addChild(rainButtonContainer); var stormButtonContainer = new Container(); var stormButtonAsset = stormButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); stormText = new Text2('STORM', { size: 60, fill: 0xFFFFFF, align: 'center' }); stormText.anchor.set(0.5, 0.5); stormButtonContainer.addChild(stormText); stormButtonContainer.visible = false; menuContainer.addChild(stormButtonContainer); var fogButtonContainer = new Container(); var fogButtonAsset = fogButtonContainer.attachAsset('button', { anchorX: 0.5, anchorY: 0.5 }); fogText = new Text2('FOG', { size: 60, fill: 0xFFFFFF, align: 'center' }); fogText.anchor.set(0.5, 0.5); fogButtonContainer.addChild(fogText); fogButtonContainer.visible = false; menuContainer.addChild(fogButtonContainer); // Start the flashing animation menuContainer.addChild(startButtonContainer); difficultyButtonContainer.down = function (x, y, obj) { // Add pulse feedback animation to difficulty button tween(difficultyButtonContainer, { scaleX: 1.2, scaleY: 1.2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(difficultyButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Change difficulty level after pulse feedback difficultyIndex = (difficultyIndex + 1) % difficultyLevels.length; currentDifficulty = difficultyLevels[difficultyIndex]; difficultyText.setText('Difficulty'); // Position and show the difficulty level button containers easyButtonContainer.x = difficultyButtonContainer.x; easyButtonContainer.y = difficultyButtonContainer.y - easyButtonContainer.height - 10; // Above normal text normalButtonContainer.x = difficultyButtonContainer.x; normalButtonContainer.y = difficultyButtonContainer.y - normalButtonContainer.height - 10 - easyButtonContainer.height; // Above hard text hardButtonContainer.x = difficultyButtonContainer.x; hardButtonContainer.y = difficultyButtonContainer.y - hardButtonContainer.height - 10 - easyButtonContainer.height - normalButtonContainer.height; // Above difficulty button hardButtonContainer.visible = true; normalButtonContainer.visible = true; easyButtonContainer.visible = true; } }); } }); }; startButtonContainer.down = function (x, y, obj) { // Check if difficulty has been selected before allowing start if (!difficultySelected) { // Show info text if (!infoText) { infoText = new Text2('Please choose a difficulty level!', { size: 40, fill: 0xFFFFFF, align: 'center' }); infoText.anchor.set(0.5, 0.5); infoText.x = startButtonContainer.x - 512; infoText.y = startButtonContainer.y - 80 + 180; menuContainer.addChild(infoText); } infoText.visible = true; // Hide info text after 3 seconds LK.setTimeout(function () { if (infoText) { infoText.visible = false; } }, 3000); // Pulse animation to indicate difficulty must be selected first tween(startButtonContainer, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(startButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut }); } }); return; // Exit early if no difficulty is selected } // Add pulse feedback animation before loading track tween(startButtonContainer, { scaleX: 1.2, scaleY: 1.2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(startButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Load track after pulse feedback completes isMenuShowing = false; menuContainer.visible = false; mainContainer.visible = true; // Show counters when game starts scoreText.visible = true; speedometerContainer.visible = true; turnText.visible = true; timerText.visible = true; // Initialize game start time gameStartTime = Date.now(); // Properly load and activate the game world // Initialize car's last position tracking for movement detection car.lastX = car.x; car.lastY = car.y; car.lastWasIntersecting = false; // Stop menu music and start the game music LK.stopMusic(); LK.playMusic('Car', { loop: true }); // Reset game state score = 0; LK.setScore(score); scoreText.setText(score.toString()); isGameOver = false; // Initialize lightning system lightningContainer = game.addChild(new Lightning()); // Position lightning at screen center for fullscreen effect lightningContainer.x = 2048 / 2; lightningContainer.y = 2732 / 2; lightningTimer = 0; nextLightningTime = 2000 + Math.random() * 5000; // First lightning in 2-7 seconds // Initialize fog overlay system fogOverlay = game.addChild(new FogOverlay()); // Position fog overlay at screen center for fullscreen effect fogOverlay.x = 2048 / 2; fogOverlay.y = 2732 / 2; // Initialize weather sound management with proper cleanup currentWeatherSound = null; lastWeather = 'Clear'; // Start appropriate weather sound based on selected weather with proper management if (currentWeather === 'Rain') { // Stop any existing weather sounds first if (currentWeatherSound) { currentWeatherSound.stop(); } currentWeatherSound = LK.getSound('rain'); currentWeatherSound.play(); } else if (currentWeather === 'Storm') { // Stop any existing weather sounds first if (currentWeatherSound) { currentWeatherSound.stop(); } currentWeatherSound = LK.getSound('Heavyrain'); currentWeatherSound.play(); } // Ensure all road segments are properly initialized roadSegments.forEach(function (segment) { segment.used = false; }); } }); } }); }; var car = mainContainer.addChild(new Car()); car.x = 2048 / 2; car.y = 2732 / 2; // Add LA asset for left turn indicator var laIndicator = game.addChild(LK.getAsset('LA', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 150, alpha: 0, scaleX: 0.5, scaleY: 0.5 })); // Add RA asset for right turn indicator var raIndicator = game.addChild(LK.getAsset('RA', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 150, alpha: 0, scaleX: 0.5, scaleY: 0.5 })); // Function to show LA indicator before turning left function showLeftTurnIndicator() { // Check if RA indicator is currently active, if so, hide it first if (raIndicator.alpha > 0) { tween.stop(raIndicator); tween(raIndicator, { alpha: 0, scaleX: 0.5, scaleY: 0.5, y: 150 }, { duration: 200, easing: tween.easeIn }); } // Animate LA asset popping up to top center tween(laIndicator, { alpha: 1, scaleX: 1.5, scaleY: 1.5, y: 100 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Keep visible for a longer moment then fade out LK.setTimeout(function () { tween(laIndicator, { alpha: 0, scaleX: 0.5, scaleY: 0.5, y: 150 }, { duration: 800, easing: tween.easeIn }); }, 2500); } }); } // Function to show RA indicator before turning right function showRightTurnIndicator() { // Check if LA indicator is currently active, if so, hide it first if (laIndicator.alpha > 0) { tween.stop(laIndicator); tween(laIndicator, { alpha: 0, scaleX: 0.5, scaleY: 0.5, y: 150 }, { duration: 200, easing: tween.easeIn }); } // Animate RA asset popping up to top center tween(raIndicator, { alpha: 1, scaleX: 1.5, scaleY: 1.5, y: 100 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Keep visible for a longer moment then fade out LK.setTimeout(function () { tween(raIndicator, { alpha: 0, scaleX: 0.5, scaleY: 0.5, y: 150 }, { duration: 800, easing: tween.easeIn }); }, 2500); } }); } // Hide main container when menu is showing mainContainer.visible = false; // Hide difficulty level button containers when menu is hidden easyButtonContainer.visible = false; normalButtonContainer.visible = false; hardButtonContainer.visible = false; // Hide weather option button containers when menu is hidden clearButtonContainer.visible = false; rainButtonContainer.visible = false; stormButtonContainer.visible = false; fogButtonContainer.visible = false; // Add difficulty selector function to easy, normal, hard text easyButtonContainer.down = function (x, y, obj) { // Tint the button orange when touched tween(easyButtonAsset, { tint: 0xff8c00 }, { duration: 150, easing: tween.easeOut }); // Add pulse feedback animation to selected mode button tween(easyButtonContainer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(easyButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { difficultyIndex = 0; currentDifficulty = difficultyLevels[difficultyIndex]; difficultyText.setText('Difficulty'); // Hide difficulty level button containers easyButtonContainer.visible = false; normalButtonContainer.visible = false; hardButtonContainer.visible = false; difficultySelected = true; // Set flag to true when difficulty is selected startButtonContainer.removeChild(startButtonAsset); // Remove old button asset startButtonAsset = startButtonContainer.attachAsset('startbutton', { // Add new startbutton asset anchorX: 0.5, anchorY: 0.5, width: 385, height: 100 }); startButtonContainer.addChildAt(startButtonAsset, 0); // Add it behind the text } }); } }); }; normalButtonContainer.down = function (x, y, obj) { // Tint the button orange when touched tween(normalButtonAsset, { tint: 0xff8c00 }, { duration: 150, easing: tween.easeOut }); // Add pulse feedback animation to selected mode button tween(normalButtonContainer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(normalButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { difficultyIndex = 1; currentDifficulty = difficultyLevels[difficultyIndex]; difficultyText.setText('Difficulty'); // Hide difficulty level button containers easyButtonContainer.visible = false; normalButtonContainer.visible = false; hardButtonContainer.visible = false; difficultySelected = true; // Set flag to true when difficulty is selected startButtonContainer.removeChild(startButtonAsset); // Remove old button asset startButtonAsset = startButtonContainer.attachAsset('startbutton', { // Add new startbutton asset anchorX: 0.5, anchorY: 0.5, width: 385, height: 100 }); startButtonContainer.addChildAt(startButtonAsset, 0); // Add it behind the text } }); } }); }; hardButtonContainer.down = function (x, y, obj) { // Tint the button orange when touched tween(hardButtonAsset, { tint: 0xff8c00 }, { duration: 150, easing: tween.easeOut }); // Add pulse feedback animation to selected mode button tween(hardButtonContainer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(hardButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { difficultyIndex = 2; currentDifficulty = difficultyLevels[difficultyIndex]; difficultyText.setText('Difficulty'); // Hide difficulty level button containers easyButtonContainer.visible = false; normalButtonContainer.visible = false; hardButtonContainer.visible = false; difficultySelected = true; // Set flag to true when difficulty is selected startButtonContainer.removeChild(startButtonAsset); // Remove old button asset startButtonAsset = startButtonContainer.attachAsset('startbutton', { // Add new startbutton asset anchorX: 0.5, anchorY: 0.5, width: 385, height: 100 }); startButtonContainer.addChildAt(startButtonAsset, 0); // Add it behind the text } }); } }); }; weatherButtonContainer.down = function (x, y, obj) { // Add pulse feedback animation to weather button tween(weatherButtonContainer, { scaleX: 1.2, scaleY: 1.2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(weatherButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Show weather option buttons after pulse feedback weatherText.setText('Weather'); // Position and show the weather option button containers clearButtonContainer.x = weatherButtonContainer.x; clearButtonContainer.y = weatherButtonContainer.y - clearButtonContainer.height - 10; // Above rain text rainButtonContainer.x = weatherButtonContainer.x; rainButtonContainer.y = weatherButtonContainer.y - rainButtonContainer.height - 10 - clearButtonContainer.height; // Above storm text stormButtonContainer.x = weatherButtonContainer.x; stormButtonContainer.y = weatherButtonContainer.y - stormButtonContainer.height - 10 - clearButtonContainer.height - rainButtonContainer.height; // Above fog text fogButtonContainer.x = weatherButtonContainer.x; fogButtonContainer.y = weatherButtonContainer.y - fogButtonContainer.height - 10 - clearButtonContainer.height - rainButtonContainer.height - stormButtonContainer.height; // Above weather button fogButtonContainer.visible = true; stormButtonContainer.visible = true; rainButtonContainer.visible = true; clearButtonContainer.visible = true; } }); } }); }; var isGameOver = false; var score = 0; var closestSegment = null; var gameStartTime = 0; var currentDifficulty = 'Easy'; // Track current difficulty level var difficultyLevels = ['Easy', 'Normal', 'Hard']; // Available difficulty levels var difficultyIndex = 0; // Current difficulty index var easyText; var normalText; var hardText; var difficultySelected = false; // Flag to indicate if a difficulty has been selected var infoText = null; // Info text for difficulty selection prompt var currentWeather = 'Clear'; // Track current weather var weatherTypes = ['Clear', 'Rain', 'Storm', 'Fog']; // Available weather types var weatherIndex = 0; // Current weather index var weatherSelected = false; // Flag to indicate if a weather has been selected var currentWeatherSound = null; // Track currently playing weather sound var lastWeather = 'Clear'; // Track last weather to detect changes // Add weather selector function to clear, rain, storm text clearButtonContainer.down = function (x, y, obj) { // Tint the button orange when touched tween(clearButtonAsset, { tint: 0xff8c00 }, { duration: 150, easing: tween.easeOut }); // Add pulse feedback animation to selected mode button tween(clearButtonContainer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(clearButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { weatherIndex = 0; currentWeather = weatherTypes[weatherIndex]; weatherText.setText('Weather'); // Hide weather option button containers clearButtonContainer.visible = false; rainButtonContainer.visible = false; stormButtonContainer.visible = false; fogButtonContainer.visible = false; weatherSelected = true; // Set flag to true when weather is selected } }); } }); }; rainButtonContainer.down = function (x, y, obj) { // Tint the button orange when touched tween(rainButtonAsset, { tint: 0xff8c00 }, { duration: 150, easing: tween.easeOut }); // Add pulse feedback animation to selected mode button tween(rainButtonContainer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(rainButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { weatherIndex = 1; currentWeather = weatherTypes[weatherIndex]; weatherText.setText('Weather'); // Hide weather option button containers clearButtonContainer.visible = false; rainButtonContainer.visible = false; stormButtonContainer.visible = false; fogButtonContainer.visible = false; weatherSelected = true; // Set flag to true when weather is selected } }); } }); }; stormButtonContainer.down = function (x, y, obj) { // Tint the button orange when touched tween(stormButtonAsset, { tint: 0xff8c00 }, { duration: 150, easing: tween.easeOut }); // Add pulse feedback animation to selected mode button tween(stormButtonContainer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(stormButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { weatherIndex = 2; currentWeather = weatherTypes[weatherIndex]; weatherText.setText('Weather'); // Hide weather option button containers clearButtonContainer.visible = false; rainButtonContainer.visible = false; stormButtonContainer.visible = false; fogButtonContainer.visible = false; weatherSelected = true; // Set flag to true when weather is selected } }); } }); }; fogButtonContainer.down = function (x, y, obj) { // Tint the button orange when touched tween(fogButtonAsset, { tint: 0xff8c00 }, { duration: 150, easing: tween.easeOut }); // Add pulse feedback animation to selected mode button tween(fogButtonContainer, { scaleX: 1.3, scaleY: 1.3 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(fogButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { weatherIndex = 3; currentWeather = weatherTypes[weatherIndex]; weatherText.setText('Weather'); // Hide weather option button containers clearButtonContainer.visible = false; rainButtonContainer.visible = false; stormButtonContainer.visible = false; fogButtonContainer.visible = false; weatherSelected = true; // Set flag to true when weather is selected } }); } }); }; // Livery selector containers - create before carButtonContainer.down var liveryContainer1 = new Container(); var liveryContainer2 = new Container(); var liveryContainer3 = new Container(); // Create diagonal pattern assets for grey/yellow var greyYellowPattern = liveryContainer1.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 250, height: 80 }); // Create visual diagonal lines using tinted rectangles var greyRect1 = liveryContainer1.attachAsset('button', { anchorX: 0, anchorY: 0, width: 125, height: 80, x: -125, y: -40, tint: 0x808080 }); var yellowRect1 = liveryContainer1.attachAsset('button', { anchorX: 0, anchorY: 0, width: 125, height: 80, x: 0, y: -40, tint: 0xFFFF00 }); // Create diagonal pattern assets for white/yellow var whiteYellowPattern = liveryContainer2.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 250, height: 80 }); var whiteRect2 = liveryContainer2.attachAsset('button', { anchorX: 0, anchorY: 0, width: 125, height: 80, x: -125, y: -40, tint: 0xFFFFFF }); var yellowRect2 = liveryContainer2.attachAsset('button', { anchorX: 0, anchorY: 0, width: 125, height: 80, x: 0, y: -40, tint: 0xFFFF00 }); // Create diagonal pattern assets for white/red var whiteRedPattern = liveryContainer3.attachAsset('button', { anchorX: 0.5, anchorY: 0.5, width: 250, height: 80 }); var whiteRect3 = liveryContainer3.attachAsset('button', { anchorX: 0, anchorY: 0, width: 125, height: 80, x: -125, y: -40, tint: 0xFFFFFF }); var redRect3 = liveryContainer3.attachAsset('button', { anchorX: 0, anchorY: 0, width: 125, height: 80, x: 0, y: -40, tint: 0xFF0000 }); liveryContainer1.visible = false; liveryContainer2.visible = false; liveryContainer3.visible = false; menuContainer.addChild(liveryContainer1); menuContainer.addChild(liveryContainer2); menuContainer.addChild(liveryContainer3); // Add click handlers for livery selection liveryContainer1.down = function (x, y, obj) { tween(liveryContainer1, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(liveryContainer1, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { // Hide all livery containers liveryContainer1.visible = false; liveryContainer2.visible = false; liveryContainer3.visible = false; // Set selected livery logic here } }); } }); }; liveryContainer2.down = function (x, y, obj) { tween(liveryContainer2, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(liveryContainer2, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { // Hide all livery containers liveryContainer1.visible = false; liveryContainer2.visible = false; liveryContainer3.visible = false; // Set selected livery logic here } }); } }); }; liveryContainer3.down = function (x, y, obj) { tween(liveryContainer3, { scaleX: 1.1, scaleY: 1.1 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(liveryContainer3, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { // Hide all livery containers liveryContainer1.visible = false; liveryContainer2.visible = false; liveryContainer3.visible = false; // Set selected livery logic here } }); } }); }; carButtonContainer.down = function (x, y, obj) { // Add pulse feedback animation to car button tween(carButtonContainer, { scaleX: 1.2, scaleY: 1.2 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { tween(carButtonContainer, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Show livery selector popup carText.setText('Car'); // Position livery containers vertically under each other liveryContainer1.x = carButtonContainer.x; liveryContainer1.y = carButtonContainer.y - 100; liveryContainer2.x = carButtonContainer.x; liveryContainer2.y = carButtonContainer.y - 190; liveryContainer3.x = carButtonContainer.x; liveryContainer3.y = carButtonContainer.y - 280; // Show all livery containers liveryContainer1.visible = true; liveryContainer2.visible = true; liveryContainer3.visible = true; } }); } }); }; var timerText = new Text2('00:00:00:000', { size: 50, fill: 0xFFFFFF, weight: '800', dropShadow: true, dropShadowColor: '#373330', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); timerText.anchor.set(1, 1); // Anchor to bottom right timerText.visible = false; // Hide timer initially LK.gui.bottomRight.addChild(timerText); game.down = function (x, y, obj) { if (isMenuShowing) { return; } car.changeDirection(); }; LK.on('tick', function () { if (isMenuShowing) { // Update slideshow timer when menu is showing slideshowTimer += 16.67; // Approximate milliseconds per tick at 60fps if (slideshowTimer >= slideshowInterval) { startSlideshowTransition(); } return; } car._move_migrated(); var carIsOnRoad = false; var carPosition = { x: car.x, y: car.y }; // Update the speedometer needle rotation based on current speed var currentSpeed = Math.sqrt(car.momentum.x * car.momentum.x + car.momentum.y * car.momentum.y); var maxSpeed = 15; // Maximum expected speed for full rotation - adjusted for better sensitivity var normalizedSpeed = Math.min(currentSpeed / maxSpeed, 1.0); // Normalize speed to 0-1 range // Calculate rotation: 8 o'clock (speed 0) to 4 o'clock (max speed) // 8 o'clock = -2π/3 radians, 4 o'clock = π/3 radians var minRotation = -Math.PI * 2 / 3; // 8 o'clock position (speed 0) var maxRotation = Math.PI / 3; // 4 o'clock position (max speed) var targetRotation = minRotation + normalizedSpeed * (maxRotation - minRotation); // Only update rotation if there's a significant change to avoid excessive tweening var rotationDifference = Math.abs(speedometerNeedle.rotation - targetRotation); if (rotationDifference > 0.05) { // Only animate if change is significant // Stop any existing needle rotation tween before starting new one tween.stop(speedometerNeedle, { rotation: true }); // Animate needle rotation smoothly to display current speed tween(speedometerNeedle, { rotation: targetRotation }, { duration: 150, easing: tween.easeOut }); } // Maintain consistent rain intensity throughout the level with gradual increase var baseRainIntensity = Math.min(16, 6 + Math.floor(score / 10)); // Double the intensity - more gradual increase, higher max intensity // Apply weather-based multiplier if (currentWeather === 'Clear') { rainIntensity = 0; // No rain in clear weather } else if (currentWeather === 'Rain') { rainIntensity = baseRainIntensity; } else if (currentWeather === 'Storm') { rainIntensity = baseRainIntensity * 2; // Double rain density for storm mode // Handle lightning effects in storm mode if (lightningContainer) { lightningTimer += 16.67; // Approximate milliseconds per tick at 60fps if (lightningTimer >= nextLightningTime && !lightningContainer.isActive) { // Trigger lightning flash lightningContainer.startLightning(); // Schedule next lightning strike (5-15 seconds) lightningTimer = 0; nextLightningTime = 4000 + Math.random() * 6000; } } } else if (currentWeather === 'Fog') { rainIntensity = 0; // No rain in fog weather // Apply fog effect by reducing headlight beam intensity, but keep beam distance/placement as in other weather modes if (car.headlightBeam) { car.headlightBeam.alpha = Math.min(car.headlightBeam.alpha, 0.15); } if (car.headlightBeam2) { car.headlightBeam2.alpha = Math.min(car.headlightBeam2.alpha, 0.15); } if (car.leftBeam) { car.leftBeam.alpha = Math.min(car.leftBeam.alpha, 0.15); } if (car.leftBeam2) { car.leftBeam2.alpha = Math.min(car.leftBeam2.alpha, 0.15); } // Activate fog overlay effect if (fogOverlay && !fogOverlay.isActive) { fogOverlay.startFog(); } } else { // Deactivate fog overlay for other weather modes if (fogOverlay && fogOverlay.isActive) { fogOverlay.stopFog(); } } // Handle weather sound changes with proper cleanup if (lastWeather !== currentWeather) { // Stop current weather sound if playing and ensure cleanup if (currentWeatherSound) { currentWeatherSound.stop(); currentWeatherSound = null; } // Small delay to ensure previous sound stops completely before starting new one LK.setTimeout(function () { // Start new weather sound after cleanup delay if (currentWeather === 'Rain') { currentWeatherSound = LK.getSound('rain'); currentWeatherSound.play(); } else if (currentWeather === 'Storm') { currentWeatherSound = LK.getSound('Heavyrain'); currentWeatherSound.play(); } }, 100); lastWeather = currentWeather; } // Manage continuous heavy rain sound with proper loop detection if (currentWeather === 'Storm') { // Check if current sound has ended and restart it if (!currentWeatherSound) { // Start heavy rain sound currentWeatherSound = LK.getSound('Heavyrain'); currentWeatherSound.play(); // Set up automatic restart when sound ends var heavyRainDuration = 3000; // Approximate duration of heavy rain sound LK.setTimeout(function () { if (currentWeather === 'Storm' && currentWeatherSound) { currentWeatherSound = null; // Clear reference to allow restart } }, heavyRainDuration); } } // Manage continuous rain sound with proper loop detection if (currentWeather === 'Rain') { // Check if current sound has ended and restart it if (!currentWeatherSound) { // Start rain sound currentWeatherSound = LK.getSound('rain'); currentWeatherSound.play(); } // Ensure rain sound continues playing by checking every few seconds if (LK.ticks % 240 === 0) { // Check every 4 seconds (240 ticks at 60fps) if (currentWeatherSound) { // Restart rain sound to ensure continuous loop currentWeatherSound.stop(); currentWeatherSound = LK.getSound('rain'); currentWeatherSound.play(); } } } // Update timer display var currentTime = Date.now(); var elapsedTime = currentTime - gameStartTime; var hours = Math.floor(elapsedTime / 3600000); var minutes = Math.floor(elapsedTime % 3600000 / 60000); var seconds = Math.floor(elapsedTime % 60000 / 1000); var milliseconds = elapsedTime % 1000; var formattedTime = (hours < 10 ? '0' + hours : hours) + ':' + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds) + ':' + (milliseconds < 100 ? milliseconds < 10 ? '00' + milliseconds : '0' + milliseconds : milliseconds); timerText.setText(formattedTime); var currentClosestSegment = null; var currentClosestDistance = Infinity; roadSegments.forEach(function (segment) { var segmentStart = { x: segment.x + Math.sin(segment.rotation) * 100, y: segment.y - Math.cos(segment.rotation) * 100 }; var segmentEnd = { x: segment.x - Math.sin(segment.rotation) * (segment.height - segment.width / 2), y: segment.y + Math.cos(segment.rotation) * (segment.height - segment.width / 2) }; var distance = game.calculateDistanceToPoint(carPosition, segmentStart, segmentEnd); if (distance < currentClosestDistance) { currentClosestDistance = distance; currentClosestSegment = segment; } if (distance < segment.width / 2 - 50) { carIsOnRoad = true; } }); if (closestSegment !== currentClosestSegment && !currentClosestSegment.used) { // Check for intersection between car and road segment if (car.lastWasIntersecting === false && car.intersects(currentClosestSegment)) { console.log("Car intersected with a road segment"); } car.lastWasIntersecting = car.intersects(currentClosestSegment); closestSegment = currentClosestSegment; closestSegment.used = true; score++; LK.setScore(score); scoreText.setText(score.toString()); } if (!carIsOnRoad) { LK.showGameOver(); } else {} var particle = new Particle(); particle.alpha = Math.max(0, Math.min(1, Math.abs(car.nonTravelMomentum) / 5 - 0.5)); if (particle.alpha > 0) { var noiseX = (Math.random() - 0.5) * 10; var noiseY = (Math.random() - 0.5) * 10; particle.x = car.x + noiseX; particle.y = car.y + noiseY; mainContainer.addChildAt(particle, 1); particles.push(particle); } // Create brown dust particles under the car if (LK.ticks % 3 === 0) { var dust = new Dust(); dust.x = car.x + (Math.random() - 0.5) * 30; dust.y = car.y + 40; dust.alpha = 0.6 + Math.random() * 0.4; dust.scaleX = 0.5 + Math.random() * 0.5; dust.scaleY = 0.5 + Math.random() * 0.5; // Animate dust with random movement tween(dust, { rotation: (Math.random() - 0.5) * Math.PI }, { duration: 1000 + Math.random() * 1000, easing: tween.easeOut }); mainContainer.addChildAt(dust, 1); dustParticles.push(dust); } // Create additional side dust particles next to the car if (LK.ticks % 2 === 0) { // Left side dust - primary var leftDust = new Dust(); leftDust.x = car.x - 60 + (Math.random() - 0.5) * 40; leftDust.y = car.y + 20 + Math.random() * 30; leftDust.alpha = 0.4 + Math.random() * 0.3; leftDust.scaleX = 0.3 + Math.random() * 0.4; leftDust.scaleY = 0.3 + Math.random() * 0.4; leftDust.velocityX = -1 - Math.random() * 2; // Animate left dust with drift movement tween(leftDust, { rotation: (Math.random() - 0.5) * Math.PI * 1.5, scaleX: leftDust.scaleX + 0.3, scaleY: leftDust.scaleY + 0.3 }, { duration: 800 + Math.random() * 800, easing: tween.easeOut }); mainContainer.addChildAt(leftDust, 1); dustParticles.push(leftDust); // Right side dust - primary var rightDust = new Dust(); rightDust.x = car.x + 60 + (Math.random() - 0.5) * 40; rightDust.y = car.y + 20 + Math.random() * 30; rightDust.alpha = 0.4 + Math.random() * 0.3; rightDust.scaleX = 0.3 + Math.random() * 0.4; rightDust.scaleY = 0.3 + Math.random() * 0.4; rightDust.velocityX = 1 + Math.random() * 2; // Animate right dust with drift movement tween(rightDust, { rotation: (Math.random() - 0.5) * Math.PI * 1.5, scaleX: rightDust.scaleX + 0.3, scaleY: rightDust.scaleY + 0.3 }, { duration: 800 + Math.random() * 800, easing: tween.easeOut }); mainContainer.addChildAt(rightDust, 1); dustParticles.push(rightDust); } // Create additional dense dust clouds on both sides if (LK.ticks % 3 === 0) { // Left side dense dust var leftDenseDust = new Dust(); leftDenseDust.x = car.x - 80 + (Math.random() - 0.5) * 60; leftDenseDust.y = car.y + 10 + Math.random() * 40; leftDenseDust.alpha = 0.5 + Math.random() * 0.4; leftDenseDust.scaleX = 0.6 + Math.random() * 0.6; leftDenseDust.scaleY = 0.6 + Math.random() * 0.6; leftDenseDust.velocityX = -2 - Math.random() * 3; leftDenseDust.velocityY = -1 - Math.random() * 2; // Animate left dense dust with swirl movement tween(leftDenseDust, { rotation: Math.PI + Math.random() * Math.PI, scaleX: leftDenseDust.scaleX + 0.5, scaleY: leftDenseDust.scaleY + 0.5, alpha: 0.1 }, { duration: 1200 + Math.random() * 1000, easing: tween.easeOut }); mainContainer.addChildAt(leftDenseDust, 1); dustParticles.push(leftDenseDust); // Right side dense dust var rightDenseDust = new Dust(); rightDenseDust.x = car.x + 80 + (Math.random() - 0.5) * 60; rightDenseDust.y = car.y + 10 + Math.random() * 40; rightDenseDust.alpha = 0.5 + Math.random() * 0.4; rightDenseDust.scaleX = 0.6 + Math.random() * 0.6; rightDenseDust.scaleY = 0.6 + Math.random() * 0.6; rightDenseDust.velocityX = 2 + Math.random() * 3; rightDenseDust.velocityY = -1 - Math.random() * 2; // Animate right dense dust with swirl movement tween(rightDenseDust, { rotation: -Math.PI - Math.random() * Math.PI, scaleX: rightDenseDust.scaleX + 0.5, scaleY: rightDenseDust.scaleY + 0.5, alpha: 0.1 }, { duration: 1200 + Math.random() * 1000, easing: tween.easeOut }); mainContainer.addChildAt(rightDenseDust, 1); dustParticles.push(rightDenseDust); } // Create smaller wispy dust particles on both sides if (LK.ticks % 5 === 0) { // Left side wispy dust var leftWispyDust = new Dust(); leftWispyDust.x = car.x - 40 + (Math.random() - 0.5) * 20; leftWispyDust.y = car.y + 30 + Math.random() * 20; leftWispyDust.alpha = 0.3 + Math.random() * 0.2; leftWispyDust.scaleX = 0.2 + Math.random() * 0.3; leftWispyDust.scaleY = 0.2 + Math.random() * 0.3; leftWispyDust.velocityX = -0.5 - Math.random(); leftWispyDust.velocityY = -2 - Math.random() * 2; // Animate left wispy dust with gentle float tween(leftWispyDust, { rotation: (Math.random() - 0.5) * Math.PI, scaleX: leftWispyDust.scaleX + 0.2, scaleY: leftWispyDust.scaleY + 0.2 }, { duration: 600 + Math.random() * 600, easing: tween.easeOut }); mainContainer.addChildAt(leftWispyDust, 1); dustParticles.push(leftWispyDust); // Right side wispy dust var rightWispyDust = new Dust(); rightWispyDust.x = car.x + 40 + (Math.random() - 0.5) * 20; rightWispyDust.y = car.y + 30 + Math.random() * 20; rightWispyDust.alpha = 0.3 + Math.random() * 0.2; rightWispyDust.scaleX = 0.2 + Math.random() * 0.3; rightWispyDust.scaleY = 0.2 + Math.random() * 0.3; rightWispyDust.velocityX = 0.5 + Math.random(); rightWispyDust.velocityY = -2 - Math.random() * 2; // Animate right wispy dust with gentle float tween(rightWispyDust, { rotation: (Math.random() - 0.5) * Math.PI, scaleX: rightWispyDust.scaleX + 0.2, scaleY: rightWispyDust.scaleY + 0.2 }, { duration: 600 + Math.random() * 600, easing: tween.easeOut }); mainContainer.addChildAt(rightWispyDust, 1); dustParticles.push(rightWispyDust); } particles.forEach(function (particle, index) { particle.tick(); if (particle.lifetime <= 0) { particles.splice(index, 1); } }); dustParticles.forEach(function (dust, index) { dust.update(); if (dust.alpha <= 0 || dust.lifetime <= 0) { dustParticles.splice(index, 1); } }); // Create rain drops continuously throughout the entire level var rainSpawnRate = Math.max(2, Math.floor(8 / rainIntensity)); // Increased spawn rate for better rain visibility if (LK.ticks % rainSpawnRate === 0) { var spawnCount = Math.min(6, rainIntensity); // Increased max raindrops per spawn for (var r = 0; r < spawnCount; r++) { var rainDrop = new RainDrop(); // Calculate current camera offset to ensure rain covers visible area var cameraOffsetX = -mainContainer.x; var cameraOffsetY = -mainContainer.y; // Spawn rain across much wider area accounting for camera movement var spawnWidth = 4096; // Increased spawn width for better coverage var spawnMargin = 768; // Increased margin rainDrop.x = cameraOffsetX - spawnMargin + Math.random() * (spawnWidth + 2 * spawnMargin); rainDrop.y = cameraOffsetY - 300 - Math.random() * 400; // Add slight opacity variation for realism rainDrop.alpha = 0.4 + Math.random() * 0.4; // Remove tween animation to improve performance mainContainer.addChild(rainDrop); rainDrops.push(rainDrop); } } // Update and clean up rain drops with performance optimization for (var dropIndex = rainDrops.length - 1; dropIndex >= 0; dropIndex--) { var drop = rainDrops[dropIndex]; drop.update(); if (drop.lifetime <= 0 || drop.alpha <= 0 || drop.y > 2732 + 200) { drop.destroy(); rainDrops.splice(dropIndex, 1); } } // Limit total number of raindrops for performance if (rainDrops.length > 120) { var excessDrops = rainDrops.length - 120; for (var excess = 0; excess < excessDrops; excess++) { var oldestDrop = rainDrops.shift(); if (oldestDrop) { oldestDrop.destroy(); } } } var carLocalPosition = game.toLocal(car.position, car.parent); var offsetX = (2048 / 2 - carLocalPosition.x) / 20; var offsetY = (2732 - 450 - carLocalPosition.y) / 20; mainContainer.x += offsetX; mainContainer.y += offsetY; for (var i = roadSegments.length - 1; i >= 0; i--) { var segmentGlobalPosition = game.toLocal(roadSegments[i].position, roadSegments[i].parent); if (segmentGlobalPosition.y - roadSegments[i].height > 2732 * 2) { roadSegments[i].shadow.destroy(); roadSegments[i].destroy(); roadSegments.splice(i, 1); game.addRoadSegment(); } // Destroy embankments which are off screen if (roadSegments[i].leftEmbankment && roadSegments[i].leftEmbankment.y < -50) { roadSegments[i].leftEmbankment.destroy(); } if (roadSegments[i].rightEmbankment && roadSegments[i].rightEmbankment.y < -50) { roadSegments[i].rightEmbankment.destroy(); } } });
===================================================================
--- original.js
+++ change.js
@@ -1622,8 +1622,170 @@
});
}
});
};
+// Livery selector containers - create before carButtonContainer.down
+var liveryContainer1 = new Container();
+var liveryContainer2 = new Container();
+var liveryContainer3 = new Container();
+// Create diagonal pattern assets for grey/yellow
+var greyYellowPattern = liveryContainer1.attachAsset('button', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 250,
+ height: 80
+});
+// Create visual diagonal lines using tinted rectangles
+var greyRect1 = liveryContainer1.attachAsset('button', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 125,
+ height: 80,
+ x: -125,
+ y: -40,
+ tint: 0x808080
+});
+var yellowRect1 = liveryContainer1.attachAsset('button', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 125,
+ height: 80,
+ x: 0,
+ y: -40,
+ tint: 0xFFFF00
+});
+// Create diagonal pattern assets for white/yellow
+var whiteYellowPattern = liveryContainer2.attachAsset('button', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 250,
+ height: 80
+});
+var whiteRect2 = liveryContainer2.attachAsset('button', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 125,
+ height: 80,
+ x: -125,
+ y: -40,
+ tint: 0xFFFFFF
+});
+var yellowRect2 = liveryContainer2.attachAsset('button', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 125,
+ height: 80,
+ x: 0,
+ y: -40,
+ tint: 0xFFFF00
+});
+// Create diagonal pattern assets for white/red
+var whiteRedPattern = liveryContainer3.attachAsset('button', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 250,
+ height: 80
+});
+var whiteRect3 = liveryContainer3.attachAsset('button', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 125,
+ height: 80,
+ x: -125,
+ y: -40,
+ tint: 0xFFFFFF
+});
+var redRect3 = liveryContainer3.attachAsset('button', {
+ anchorX: 0,
+ anchorY: 0,
+ width: 125,
+ height: 80,
+ x: 0,
+ y: -40,
+ tint: 0xFF0000
+});
+liveryContainer1.visible = false;
+liveryContainer2.visible = false;
+liveryContainer3.visible = false;
+menuContainer.addChild(liveryContainer1);
+menuContainer.addChild(liveryContainer2);
+menuContainer.addChild(liveryContainer3);
+// Add click handlers for livery selection
+liveryContainer1.down = function (x, y, obj) {
+ tween(liveryContainer1, {
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(liveryContainer1, {
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ // Hide all livery containers
+ liveryContainer1.visible = false;
+ liveryContainer2.visible = false;
+ liveryContainer3.visible = false;
+ // Set selected livery logic here
+ }
+ });
+ }
+ });
+};
+liveryContainer2.down = function (x, y, obj) {
+ tween(liveryContainer2, {
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(liveryContainer2, {
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ // Hide all livery containers
+ liveryContainer1.visible = false;
+ liveryContainer2.visible = false;
+ liveryContainer3.visible = false;
+ // Set selected livery logic here
+ }
+ });
+ }
+ });
+};
+liveryContainer3.down = function (x, y, obj) {
+ tween(liveryContainer3, {
+ scaleX: 1.1,
+ scaleY: 1.1
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(liveryContainer3, {
+ scaleX: 1.0,
+ scaleY: 1.0
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ // Hide all livery containers
+ liveryContainer1.visible = false;
+ liveryContainer2.visible = false;
+ liveryContainer3.visible = false;
+ // Set selected livery logic here
+ }
+ });
+ }
+ });
+};
carButtonContainer.down = function (x, y, obj) {
// Add pulse feedback animation to car button
tween(carButtonContainer, {
scaleX: 1.2,
@@ -1638,11 +1800,21 @@
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
- // Change car type after pulse feedback
+ // Show livery selector popup
carText.setText('Car');
- // Future car selection logic can be added here
+ // Position livery containers vertically under each other
+ liveryContainer1.x = carButtonContainer.x;
+ liveryContainer1.y = carButtonContainer.y - 100;
+ liveryContainer2.x = carButtonContainer.x;
+ liveryContainer2.y = carButtonContainer.y - 190;
+ liveryContainer3.x = carButtonContainer.x;
+ liveryContainer3.y = carButtonContainer.y - 280;
+ // Show all livery containers
+ liveryContainer1.visible = true;
+ liveryContainer2.visible = true;
+ liveryContainer3.visible = true;
}
});
}
});
Rock at night, drone view
Dirt road at night, topview
Photorealistic dusty rock in desert at night, bird view
photorealistic very dark smoot dirt ground in the night, top view but From a distance
TRANSPARENT RECTANGLE WITH SINGLE LINE ORANGE FRAME, FRONT VIEW
Transparent brawn turning left arrow in a brawn circle, front view
Photorealistic speedometer's orange hourhand, only just the hourhand with black bath. The hourhand shape is a line. front view
Photorealistic Subaru Impreza WRC in nightlight, drone topview from back and 45 degrees angle in top right corner
Photorealistic 1990'S Subaru Impreza WRC Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner
Photorealistic Lancia Delta Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner
Photorealistic Mitsubishi Lancer Evolution Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner
Photorealistic Ford Focus RS WRC 2008 Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner
Photorealistic Seat Cordoba Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner
Photorealistic Suzuki Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner. Replace SUZUKI text to SUZIKA
Photorealistic Lancia Stratos Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner. Replace Lancia to Lacika and Alitalia to All Italia
Photorealistic RENAULT Rallycar in nightlight, drone topview from back and 45 degrees angle in top right corner.
Photorealistic red MINI COOPER Rallycar with something like British flag livery in nightlight, drone topview from back and 45 degrees angle in top right corner. Replace MINI to IMI and Cooper too Qoper.