User prompt
Add anmated roadtrack line under the car, but above the roads. line only disappear if reach the edge of the screen ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
ensure the roadtrack line is upeer then roads in display
User prompt
Add a roadtrack line behind the car
User prompt
Add a roadtrack line on the area what the car is taken
User prompt
Add a par of roadtrack line on the area what the car is taken
User prompt
also add second beam next to the previous one if the car turned left
User prompt
Move the second headlight beam up by 15 units
User prompt
Move the second headlight beam left by 15 units
User prompt
move the second beam down by 50 units
User prompt
rename smoke to dust
User prompt
add a second beam next to the previous one
User prompt
Add menuwallpaper asset to the asset list
User prompt
Move all trees a little bit closer to roads
User prompt
Avoid road segment cover the other road segment
User prompt
Add overlap prevention logic to road segments positioning
User prompt
Avoid roads overlaping each other
User prompt
Add more smoke effect next to the car both sides ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add more smoke effect next to the car ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Take much more place between trees
User prompt
Change speedometer color to gold
User prompt
Ensure smoke effect upper then road in display
User prompt
Add brown animated smoke under the car ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add brown animated particles smoke under the car ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add brown animated particles smoke behind the car ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add s2 asset next to difficulty text on the left side
/**** * 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 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; 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; 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; // 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 (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 }); } }); } 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 }); } }); } // 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 }); if (self.leftBeam) { tween(self.leftBeam, { width: beamWidth }, { duration: 200, easing: tween.easeOut }); } }; self.changeDirection = function () { self.direction = self.direction === 0 ? 1 : 0; carGraphics.scale.x *= -1; // Synchronize beam rotation with car direction self.headlightBeam.scale.x *= -1; if (self.leftBeam) { self.leftBeam.scale.x *= -1; } }; }); var DiagonalStripe = Container.expand(function (options) { var self = Container.call(this); self.options = options || {}; self.options.width = self.options.width || 100; self.options.height = self.options.height || 3000; self.options.color = self.options.color || 0x1a237e; self.options.alpha = self.options.alpha || 0.3; var stripe = self.attachAsset('beamR', { anchorX: 0.5, anchorY: 0.5, width: self.options.width, height: self.options.height, tint: self.options.color, alpha: self.options.alpha }); self.rotation = Math.PI / 4; // 45 degree angle for diagonal return self; }); var DriftAndDodge = Container.expand(function () { var self = Container.call(this); }); // 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 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 Rock = Container.expand(function () { var self = Container.call(this); var rockGraphics = self.attachAsset('rock', { anchorX: 0.5, anchorY: 0.5 }); }); var SmokeParticle = Container.expand(function () { var self = Container.call(this); var smokeGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5, tint: 0x8B4513, alpha: 0.6 }); self.lifetime = 60 + Math.random() * 40; self.maxLifetime = self.lifetime; self.velocityX = (Math.random() - 0.5) * 3; self.velocityY = -Math.random() * 2 - 1; self.initialScale = 0.3 + Math.random() * 0.4; self.targetScale = self.initialScale * (2 + Math.random()); smokeGraphics.scale.x = self.initialScale; smokeGraphics.scale.y = self.initialScale; self.update = function () { self.lifetime--; // Move particle self.x += self.velocityX; self.y += self.velocityY; // Calculate life progress (1 = start, 0 = end) var lifeProgress = self.lifetime / self.maxLifetime; // Fade out and scale up over time var newAlpha = lifeProgress * 0.6; var newScale = self.initialScale + (self.targetScale - self.initialScale) * (1 - lifeProgress); smokeGraphics.alpha = newAlpha; smokeGraphics.scale.x = newScale; smokeGraphics.scale.y = newScale; // Add some rotation smokeGraphics.rotation += 0.02; if (self.lifetime <= 0) { self.destroy(); } }; return self; }); 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 aggressive width reduction for hard mode var widthReduction = currentDifficulty === 'Hard' ? 25 : 15; segmentWidth = Math.max(350 * 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 = 150; // 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(); leftTree.x = segment.x - segment.width - 200 - i * treeSpacing; // Decrease the distance from the road by 100 units leftTree.y = segment.y + i * treeSpacing; roadContainer.addChild(leftTree); var rightTree = new Tree2(); rightTree.x = segment.x + segment.width + 200 + i * treeSpacing; // Decrease the distance from the road by 100 units 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); }; var wallpaper = game.attachAsset('wallpaper', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); var particles = []; var smokeParticles = []; 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 a neon blue-colored speedometer to the bottom left corner of the map var isMenuShowing = true; var speedometer = new Text2('Speed: 0', { size: 50, fill: 0x00FFFF, // Neon blue color weight: '800', dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); speedometer.anchor.set(0, 1); // Anchor to bottom left speedometer.visible = false; // Hide speedometer initially LK.gui.bottomLeft.addChild(speedometer); var menuContainer = LK.gui.addChild(new Container()); var menuBackground = menuContainer.addChild(new BlurBackground({ width: 2048, height: 2732, blur: 25 })); // Add diagonal stripes for modern look var stripeContainer = menuContainer.addChild(new Container()); var stripes = []; for (var i = 0; i < 12; i++) { var stripe = stripeContainer.addChild(new DiagonalStripe({ width: 80, height: 3500, color: 0x1565c0, alpha: 0.2 })); stripe.x = -200 + i * 200; stripe.y = 1366; stripes.push(stripe); } // Add secondary stripe layer with different color var stripes2 = []; for (var j = 0; j < 10; j++) { var stripe2 = stripeContainer.addChild(new DiagonalStripe({ width: 60, height: 3200, color: 0x0d47a1, alpha: 0.15 })); stripe2.x = -100 + j * 230; stripe2.y = 1366; stripes2.push(stripe2); } // Animate stripes horizontally and with flashing function animateStripes() { // Animate first stripe layer stripes.forEach(function (stripe, index) { // Create continuous horizontal movement animation function animateStripeMovement() { tween(stripe, { x: stripe.x + 400 }, { duration: 3000 + index * 100, easing: tween.linear, onFinish: function onFinish() { stripe.x = -400; animateStripeMovement(); // Direct recursive call for looping } }); } animateStripeMovement(); // Flashing animation var flashDelay = index * 200; LK.setTimeout(function () { function flashLoop() { tween(stripe, { alpha: 0.05 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { tween(stripe, { alpha: 0.2 }, { duration: 1500, easing: tween.easeInOut, onFinish: function onFinish() { LK.setTimeout(flashLoop, 50); } }); } }); } flashLoop(); }, flashDelay); }); // Animate second stripe layer stripes2.forEach(function (stripe2, index) { // Create continuous horizontal movement animation function animateStripe2Movement() { tween(stripe2, { x: stripe2.x + 350 }, { duration: 3500 + index * 120, easing: tween.linear, onFinish: function onFinish() { stripe2.x = -350; // Use setTimeout to restart animation without recursion LK.setTimeout(animateStripe2Movement, 50); } }); } animateStripe2Movement(); // Flashing animation with different timing var flashDelay2 = index * 180 + 500; LK.setTimeout(function () { function flashLoop2() { tween(stripe2, { alpha: 0.08 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { tween(stripe2, { alpha: 0.15 }, { duration: 2000, easing: tween.easeInOut, onFinish: function onFinish() { LK.setTimeout(flashLoop2, 50); } }); } }); } flashLoop2(); }, flashDelay2); }); } // Start stripe animations animateStripes(); // Start menu music LK.playMusic('menuMusic', { loop: true }); var menuTitle = new Text2('DIRT R4LLY', { size: 100, fill: 0xFFFFFF, align: 'center' }); menuTitle.anchor.set(0.5, 0); menuTitle.x = 2048 / 2 - 300; menuTitle.y = 200; menuContainer.addChild(menuTitle); var difficultyText = new Text2('Difficulty:', { size: 87.5, fill: 0xFFFFFF, align: 'center' }); difficultyText.anchor.set(0.5, 0.5); difficultyText.x = 2048 / 2 - 313; difficultyText.y = 2732 / 2 + 200; menuContainer.addChild(difficultyText); // Add difficulty level buttons var easyButton = new Text2('Easy', { size: 100, fill: 0x00ff00, // Green for Easy align: 'center' }); easyButton.anchor.set(0.5, 0.5); easyButton.x = 200; easyButton.y = 2732 / 2 + 380; menuContainer.addChild(easyButton); var normalButton = new Text2('Normal', { size: 100, fill: 0xFFFFFF, // White for Normal align: 'center' }); normalButton.anchor.set(0.5, 0.5); normalButton.x = 2048 / 2 - 313; normalButton.y = 2732 / 2 + 380; menuContainer.addChild(normalButton); var hardButton = new Text2('Hard', { size: 100, fill: 0xff0000, // Red for Hard align: 'center' }); hardButton.anchor.set(0.5, 0.5); hardButton.x = 2048 / 2 - 126 + 333; hardButton.y = 2732 / 2 + 380; menuContainer.addChild(hardButton); // Highlight current difficulty (Easy by default) easyButton.alpha = 1.0; normalButton.alpha = 0.6; hardButton.alpha = 0.6; // Add underline graphics for selected difficulty var easyUnderline = menuContainer.attachAsset('underline', { anchorX: 0.5, anchorY: 0.5, x: easyButton.x, y: easyButton.y + 70, width: 120 }); var normalUnderline = menuContainer.attachAsset('underline', { anchorX: 0.5, anchorY: 0.5, x: normalButton.x, y: normalButton.y + 70, width: 240, visible: false }); var hardUnderline = menuContainer.attachAsset('underline', { anchorX: 0.5, anchorY: 0.5, x: hardButton.x, y: hardButton.y + 70, width: 120, visible: false }); // Add dark car shadow with slow flashing animation var carShadow = menuContainer.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, tint: 0x000000, alpha: 0.6, scaleX: 5, scaleY: 5 }); carShadow.x = 2048 / 2 - 123; carShadow.y = 2732 / 2 - 300 + 300 - 100; // Add second shadow asset for checkered effect var carShadow2 = menuContainer.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, tint: 0x333333, alpha: 0.4, scaleX: 5, scaleY: 5 }); carShadow2.x = 2048 / 2 - 123 + 30; carShadow2.y = 2732 / 2 - 300 + 300 - 100 + 20; // Create alternating flashing animation for car shadows function flashCarShadow() { // First shadow animation function animateShadow1() { tween(carShadow, { alpha: 0.6 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(carShadow, { alpha: 0.2 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { LK.setTimeout(animateShadow1, 2000); } }); } }); } // Second shadow animation - starts when first shadow fades out function animateShadow2() { tween(carShadow2, { alpha: 0.1 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(carShadow2, { alpha: 0.4 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { LK.setTimeout(animateShadow2, 2000); } }); } }); } // Start first shadow immediately animateShadow1(); // Start second shadow after 1 second delay to create alternating effect LK.setTimeout(animateShadow2, 1000); } // Start the flashing animation flashCarShadow(); var startButton = new Text2('Start Game', { size: 60, fill: 0x00ffff, align: 'center' }); startButton.anchor.set(0.5, 0.5); startButton.x = 2048 / 2 - 321; startButton.y = 2732 / 2 + 50 - 500; var startButtonGraphic = menuContainer.attachAsset('startButtonGraphic', { anchorX: 0.5, anchorY: 0.5, x: startButton.x, y: startButton.y, tint: 0x00ffff }); // Create flashing animation for start button function flashStartButton() { tween(startButtonGraphic, { alpha: 0.3 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(startButtonGraphic, { alpha: 1.0 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { LK.setTimeout(flashStartButton, 100); } }); } }); } // Start the flashing animation flashStartButton(); menuContainer.addChild(startButtonGraphic); menuContainer.addChild(startButton); // Add click handlers for difficulty buttons easyButton.down = function (x, y, obj) { currentDifficulty = 'Easy'; difficultyIndex = 0; easyButton.alpha = 1.0; normalButton.alpha = 0.6; hardButton.alpha = 0.6; easyUnderline.visible = true; normalUnderline.visible = false; hardUnderline.visible = false; }; normalButton.down = function (x, y, obj) { currentDifficulty = 'Normal'; difficultyIndex = 1; easyButton.alpha = 0.6; normalButton.alpha = 1.0; hardButton.alpha = 0.6; easyUnderline.visible = false; normalUnderline.visible = true; hardUnderline.visible = false; }; hardButton.down = function (x, y, obj) { currentDifficulty = 'Hard'; difficultyIndex = 2; easyButton.alpha = 0.6; normalButton.alpha = 0.6; hardButton.alpha = 1.0; easyUnderline.visible = false; normalUnderline.visible = false; hardUnderline.visible = true; }; startButton.down = function (x, y, obj) { isMenuShowing = false; menuContainer.visible = false; mainContainer.visible = true; // Show counters when game starts scoreText.visible = true; speedometer.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; // 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; // Hide main container when menu is showing mainContainer.visible = false; 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 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.on('down', function (x, y, obj) { if (isMenuShowing) { return; } car.changeDirection(); }); LK.on('tick', function () { if (isMenuShowing) { return; } car._move_migrated(); LK.playMusic('Car', { loop: true }); var carIsOnRoad = false; var carPosition = { x: car.x, y: car.y }; // Update the speedometer with the current speed speedometer.setText('Speed: ' + Math.round(Math.sqrt(car.momentum.x * car.momentum.x + car.momentum.y * car.momentum.y) * 5) + ' km/h'); // 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); } // Emit brown smoke particles behind car var carSpeed = Math.sqrt(car.momentum.x * car.momentum.x + car.momentum.y * car.momentum.y); if (carSpeed > 1) { // Emit smoke particles every few frames based on speed if (LK.ticks % Math.max(1, Math.floor(8 - carSpeed)) === 0) { var smokeParticle = new SmokeParticle(); // Position behind the car var behindCarX = car.x - Math.sin(car.rotation || 0) * 40; var behindCarY = car.y + Math.cos(car.rotation || 0) * 40; smokeParticle.x = behindCarX + (Math.random() - 0.5) * 30; smokeParticle.y = behindCarY + (Math.random() - 0.5) * 15; mainContainer.addChildAt(smokeParticle, 0); smokeParticles.push(smokeParticle); } } particles.forEach(function (particle, index) { particle.tick(); if (particle.lifetime <= 0) { particles.splice(index, 1); } }); // Update smoke particles smokeParticles.forEach(function (smoke, index) { if (smoke.lifetime <= 0) { smokeParticles.splice(index, 1); } }); 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
@@ -254,8 +254,45 @@
anchorX: 0.5,
anchorY: 0.5
});
});
+var SmokeParticle = Container.expand(function () {
+ var self = Container.call(this);
+ var smokeGraphics = self.attachAsset('particle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ tint: 0x8B4513,
+ alpha: 0.6
+ });
+ self.lifetime = 60 + Math.random() * 40;
+ self.maxLifetime = self.lifetime;
+ self.velocityX = (Math.random() - 0.5) * 3;
+ self.velocityY = -Math.random() * 2 - 1;
+ self.initialScale = 0.3 + Math.random() * 0.4;
+ self.targetScale = self.initialScale * (2 + Math.random());
+ smokeGraphics.scale.x = self.initialScale;
+ smokeGraphics.scale.y = self.initialScale;
+ self.update = function () {
+ self.lifetime--;
+ // Move particle
+ self.x += self.velocityX;
+ self.y += self.velocityY;
+ // Calculate life progress (1 = start, 0 = end)
+ var lifeProgress = self.lifetime / self.maxLifetime;
+ // Fade out and scale up over time
+ var newAlpha = lifeProgress * 0.6;
+ var newScale = self.initialScale + (self.targetScale - self.initialScale) * (1 - lifeProgress);
+ smokeGraphics.alpha = newAlpha;
+ smokeGraphics.scale.x = newScale;
+ smokeGraphics.scale.y = newScale;
+ // Add some rotation
+ smokeGraphics.rotation += 0.02;
+ if (self.lifetime <= 0) {
+ self.destroy();
+ }
+ };
+ return self;
+});
var SnowyEmbankment = Container.expand(function () {
var self = Container.call(this);
var embankmentGraphics = self.attachAsset('rods', {
anchorX: 0.5,
@@ -404,8 +441,9 @@
x: 2048 / 2,
y: 2732 / 2
});
var particles = [];
+var smokeParticles = [];
var mainContainer = game.addChild(new Container());
var roadContainer = mainContainer.addChild(new Container());
var roadSegments = [];
var segmentLength = Math.floor(Math.random() * (1000 - 200 + 1)) + 200;
@@ -605,15 +643,8 @@
difficultyText.anchor.set(0.5, 0.5);
difficultyText.x = 2048 / 2 - 313;
difficultyText.y = 2732 / 2 + 200;
menuContainer.addChild(difficultyText);
-// Add s2 asset next to difficulty text on the left side
-var s2Asset = menuContainer.attachAsset('s2', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: difficultyText.x - 200,
- y: difficultyText.y
-});
// Add difficulty level buttons
var easyButton = new Text2('Easy', {
size: 100,
fill: 0x00ff00,
@@ -943,14 +974,35 @@
particle.y = car.y + noiseY;
mainContainer.addChildAt(particle, 1);
particles.push(particle);
}
+ // Emit brown smoke particles behind car
+ var carSpeed = Math.sqrt(car.momentum.x * car.momentum.x + car.momentum.y * car.momentum.y);
+ if (carSpeed > 1) {
+ // Emit smoke particles every few frames based on speed
+ if (LK.ticks % Math.max(1, Math.floor(8 - carSpeed)) === 0) {
+ var smokeParticle = new SmokeParticle();
+ // Position behind the car
+ var behindCarX = car.x - Math.sin(car.rotation || 0) * 40;
+ var behindCarY = car.y + Math.cos(car.rotation || 0) * 40;
+ smokeParticle.x = behindCarX + (Math.random() - 0.5) * 30;
+ smokeParticle.y = behindCarY + (Math.random() - 0.5) * 15;
+ mainContainer.addChildAt(smokeParticle, 0);
+ smokeParticles.push(smokeParticle);
+ }
+ }
particles.forEach(function (particle, index) {
particle.tick();
if (particle.lifetime <= 0) {
particles.splice(index, 1);
}
});
+ // Update smoke particles
+ smokeParticles.forEach(function (smoke, index) {
+ if (smoke.lifetime <= 0) {
+ smokeParticles.splice(index, 1);
+ }
+ });
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;
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.