User prompt
the cars speed value cant be lower than zero
User prompt
audience heads will change in size and go back to its org size for a jumping look from above when shifting and the same effect in long period and more intensity for finish effect. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
do not change the size of audience or audheads, just audience heads will change in size for short time for a jumping look from above when shifting and the same effect in long period and more intensity for finish effect. the audience wont be affected just the heads ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make audience get exited with each gear shift and get crazy whens somebodyt passes the finish line ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add an audience over and under the track to watch the race
User prompt
layer the bad zone to the bottom
User prompt
put the bad shift area iside the perceft zone
User prompt
add a wider bad shift zone and an if player bad shifts car gets a slight speed decreasemnet
User prompt
fabolous shift adds a slight speed boost
User prompt
add a sound effect when fabolous shift
User prompt
add a smaller fabulous shiting zone inside the perceft zone, when player shited in this position, the car gets a small speed bost with blue nos effect ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
reduce the diffuculty of 6th race slightly so player can only win by perceft shifting each gear and must rev from start
User prompt
start the 6th race just for nuw to playtest it
User prompt
Reduce the number of races from 3-3-3 to 2-2-2
User prompt
make the medium text yellow and hard text red
User prompt
add outline to the text
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'difficultyText.style.fill = 0x4CAF50; // Green' Line Number: 599
User prompt
add outline to the text and make the font a lot bigger
User prompt
Write the difficulty of the race the player is in on the top right: easy-green medium-yellow hard-red
User prompt
slightly reduce speedometer display value to make it appear slower without changing actual car speed
User prompt
refresh speedometers display more often
User prompt
Increase the value on the speedometer less quickly, do not increase suddenly when changing gear. Do it without changing the speed of the car and using tween plugin. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Increase the value on the speedometer less quickly, do not increase suddenly when changing gear. Do it without changing the speed of the car. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
do not increase the speed of the car but increase the values on the speedometer so that the player thinks the car is going faster
User prompt
move the gear bg a little down
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Car = Container.expand(function (carType) { var self = Container.call(this); var carBody = self.attachAsset(carType, { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0; self.maxSpeed = 200; self.acceleration = 0; self.rpm = 1000; self.gear = 1; self.maxGear = 6; self.perfectShiftZone = { min: 6000, max: 6500 }; self.redline = 7000; self.isRevving = false; self.raceStarted = false; self.raceFinished = false; self.startRevving = function () { self.isRevving = true; }; self.stopRevving = function () { self.isRevving = false; }; self.shift = function () { if (self.gear < self.maxGear && self.raceStarted && !self.raceFinished) { var perfect = self.rpm >= self.perfectShiftZone.min && self.rpm <= self.perfectShiftZone.max; var fabulous = self.rpm >= 6200 && self.rpm <= 6300; // Smaller zone within perfect zone if (fabulous) { self.gear++; self.rpm = 2000; self.acceleration = 1.2; // Higher acceleration for fabulous shift self.speed += 15; // Direct speed boost for fabulous shift LK.getSound('fabulousShift').play(); LK.effects.flashScreen(0x00BFFF, 300); // Blue flash for fabulous shift // Blue NOS effect on car tween(self, { tint: 0x00BFFF }, { duration: 500, onFinish: function onFinish() { tween(self, { tint: 0xFFFFFF }, { duration: 300 }); } }); } else if (perfect) { self.gear++; self.rpm = 2000; self.acceleration = 0.8; LK.getSound('perfectShift').play(); LK.effects.flashScreen(0x4CAF50, 200); } else { var badShift = self.rpm <= 5000 || self.rpm >= 7000; // Wider bad zone if (badShift) { self.gear++; self.rpm = 2000; self.acceleration = 0.2; // Lower acceleration for bad shift self.speed -= 10; // Speed penalty for bad shift LK.getSound('badShift').play(); LK.effects.flashScreen(0xF44336, 200); } else { // Regular shift (not perfect, not fabulous, not bad) self.gear++; self.rpm = 2000; self.acceleration = 0.3; LK.getSound('badShift').play(); LK.effects.flashScreen(0xF44336, 200); } } } }; self.update = function () { if (self.isRevving && !self.raceStarted) { self.rpm += 160; if (self.rpm > self.redline) { self.rpm = self.redline; } } else if (!self.isRevving && !self.raceStarted) { self.rpm -= 40; if (self.rpm < 1000) { self.rpm = 1000; } } if (self.raceStarted) { var rpmIncrease = 120 / self.gear; // RPM increases slower in higher gears self.rpm += rpmIncrease; if (self.rpm > self.redline) { self.rpm = self.redline; self.acceleration = 0.1; } // Calculate target speed based on RPM and gear var rpmRatio = (self.rpm - 1000) / (self.redline - 1000); // Normalize RPM to 0-1 var gearMaxSpeed = self.maxSpeed * (self.gear / self.maxGear); // Max speed for current gear var targetSpeed = rpmRatio * gearMaxSpeed; // Rev limiter: when at redline, speed is capped at gear's max speed if (self.rpm >= self.redline) { targetSpeed = gearMaxSpeed; } // Gradually adjust speed towards target speed if (targetSpeed > self.speed) { self.speed += self.acceleration; } else { self.speed = targetSpeed; } if (self.speed > self.maxSpeed) { self.speed = self.maxSpeed; } self.x += self.speed * 0.15; self.acceleration *= 0.95; } }; return self; }); var OpponentCar = Car.expand(function () { var self = Car.call(this, 'opponentCar'); self.aiShiftTimer = 0; self.aiShiftDelay = 90 + Math.random() * 30; self.difficultyLevel = 'easy'; // Will be updated based on current race self.baseLaunchAcceleration = 0.5; // Base launch performance self.baseShiftAcceleration = 0.4; // Base shift performance self.update = function () { // Call parent update manually since we're using expand() if (self.isRevving && !self.raceStarted) { self.rpm += 160; if (self.rpm > self.redline) { self.rpm = self.redline; } } else if (!self.isRevving && !self.raceStarted) { self.rpm -= 40; if (self.rpm < 1000) { self.rpm = 1000; } } if (self.raceStarted) { var rpmIncrease = 120 / self.gear; // RPM increases slower in higher gears self.rpm += rpmIncrease; if (self.rpm > self.redline) { self.rpm = self.redline; self.acceleration = 0.1; } // Calculate target speed based on RPM and gear var rpmRatio = (self.rpm - 1000) / (self.redline - 1000); // Normalize RPM to 0-1 var gearMaxSpeed = self.maxSpeed * (self.gear / self.maxGear); // Max speed for current gear var targetSpeed = rpmRatio * gearMaxSpeed; // Rev limiter: when at redline, speed is capped at gear's max speed if (self.rpm >= self.redline) { targetSpeed = gearMaxSpeed; } // Gradually adjust speed towards target speed if (targetSpeed > self.speed) { self.speed += self.acceleration; } else { self.speed = targetSpeed; } if (self.speed > self.maxSpeed) { self.speed = self.maxSpeed; } self.x += self.speed * 0.15; self.acceleration *= 0.95; } if (self.raceStarted && !self.raceFinished) { self.aiShiftTimer++; // Difficulty-based shift timing and performance var shiftDelay, minAcceleration, maxAcceleration; if (self.difficultyLevel === 'easy') { shiftDelay = 100 + Math.random() * 60; // Slower shifts: 100-160 frames minAcceleration = 0.4; maxAcceleration = 0.6; } else if (self.difficultyLevel === 'medium') { shiftDelay = 80 + Math.random() * 40; // Medium shifts: 80-120 frames minAcceleration = 0.6; maxAcceleration = 0.75; } else if (currentRace === 5) { // hard (race 5) shiftDelay = 60 + Math.random() * 20; // Fast shifts: 60-80 frames minAcceleration = 0.75; maxAcceleration = 0.9; } else { // race 6 - slightly slower but more consistent for perfect requirement shiftDelay = 65 + Math.random() * 15; // Slightly slower shifts: 65-80 frames minAcceleration = 0.72; maxAcceleration = 0.87; } if (self.aiShiftTimer >= self.aiShiftDelay && self.gear < self.maxGear) { // Opponent car shifts automatically with difficulty-based performance self.gear++; self.rpm = 2000; self.acceleration = minAcceleration + Math.random() * (maxAcceleration - minAcceleration); self.aiShiftTimer = 0; self.aiShiftDelay = shiftDelay; } } }; return self; }); var WinPopup = Container.expand(function () { var self = Container.call(this); // Semi-transparent background overlay var overlay = self.attachAsset('rpmGauge', { anchorX: 0.5, anchorY: 0.5, scaleX: 10, scaleY: 15, alpha: 0.95, x: 1024, y: 1366 }); overlay.tint = 0x000000; // Win text var winText = new Text2('YOU WON!', { size: 120, fill: 0xFFD700 }); winText.anchor.set(0.5, 0.5); winText.x = 1024; winText.y = 1200; self.addChild(winText); // Next race button background var buttonBg = self.attachAsset('rpmGauge', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 0.8, x: 1024, y: 1500 }); buttonBg.tint = 0x4CAF50; // Next race button text var buttonText = new Text2('NEXT RACE', { size: 60, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); buttonText.x = 1024; buttonText.y = 1500; self.addChild(buttonText); self.down = function (x, y, obj) { // Check if click is on button area if (x > 824 && x < 1224 && y > 1420 && y < 1580) { self.onNextRace(); } }; self.onNextRace = function () { // This will be set from outside }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var background = game.attachAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); var currentRace = 1; var maxRaces = 6; var raceState = 'countdown'; var countdownTimer = 0; var startLightTimer = 0; var perfectStartWindow = false; var lightSequenceStep = 0; var lightSequenceTimer = 0; var currentGearSound = null; var revSound = null; var lastGear = 1; var isCurrentlyRevving = false; var track = game.attachAsset('track', { anchorX: 0, anchorY: 0.5, x: 0, y: 1366 }); // Create audience above track var upperAudience = []; for (var i = 0; i < 10; i++) { var audienceGroup = new Container(); var audienceBody = audienceGroup.attachAsset('audience', { anchorX: 0.5, anchorY: 1 }); // Add multiple heads on each audience section for (var j = 0; j < 8; j++) { var head = audienceGroup.attachAsset('audienceHead', { anchorX: 0.5, anchorY: 0.5, x: -75 + j * 20 + (Math.random() * 10 - 5), y: -60 + (Math.random() * 20 - 10) }); // Randomize head colors var headColors = [0xFFDBB3, 0xF1C27D, 0xE0AC69, 0xC68642]; head.tint = headColors[Math.floor(Math.random() * headColors.length)]; } audienceGroup.x = 200 + i * 180; audienceGroup.y = 1216; game.addChild(audienceGroup); upperAudience.push(audienceGroup); } // Create audience below track var lowerAudience = []; for (var i = 0; i < 10; i++) { var audienceGroup = new Container(); var audienceBody = audienceGroup.attachAsset('audience', { anchorX: 0.5, anchorY: 0 }); // Add multiple heads on each audience section for (var j = 0; j < 8; j++) { var head = audienceGroup.attachAsset('audienceHead', { anchorX: 0.5, anchorY: 0.5, x: -75 + j * 20 + (Math.random() * 10 - 5), y: 60 + (Math.random() * 20 - 10) }); // Randomize head colors var headColors = [0xFFDBB3, 0xF1C27D, 0xE0AC69, 0xC68642]; head.tint = headColors[Math.floor(Math.random() * headColors.length)]; } audienceGroup.x = 200 + i * 180; audienceGroup.y = 1516; game.addChild(audienceGroup); lowerAudience.push(audienceGroup); } var startLine = game.attachAsset('startLine', { anchorX: 0.5, anchorY: 0.5, x: 100, y: 1366 }); var finishLine = game.attachAsset('finishLine', { anchorX: 0.5, anchorY: 0.5, x: 1948, y: 1366 }); var playerCar = game.addChild(new Car('playerCar')); playerCar.x = 50; playerCar.y = 1320; var opponentCar = game.addChild(new OpponentCar()); opponentCar.x = 50; opponentCar.y = 1420; var rpmGauge = game.attachAsset('rpmGauge', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1600 }); var badZone = game.attachAsset('badZone', { anchorX: 0.5, anchorY: 0.5, x: 1180, y: 1600 }); var perfectZone = game.attachAsset('perfectZone', { anchorX: 0.5, anchorY: 0.5, x: 1180, y: 1600 }); var fabulousZone = game.attachAsset('fabulousZone', { anchorX: 0.5, anchorY: 0.5, x: 1180, y: 1600 }); var rpmNeedle = game.attachAsset('rpmNeedle', { anchorX: 0.5, anchorY: 0.5, x: 824, y: 1600 }); var redLight1 = game.attachAsset('redLight1', { anchorX: 0.5, anchorY: 0.5, x: 824, y: 600, alpha: 0.3 }); var redLight2 = game.attachAsset('redLight2', { anchorX: 0.5, anchorY: 0.5, x: 924, y: 600, alpha: 0.3 }); var redLight3 = game.attachAsset('redLight3', { anchorX: 0.5, anchorY: 0.5, x: 1124, y: 600, alpha: 0.3 }); var redLight4 = game.attachAsset('redLight4', { anchorX: 0.5, anchorY: 0.5, x: 1224, y: 600, alpha: 0.3 }); var redLight = game.attachAsset('redLight', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 600 }); var greenLight = game.attachAsset('greenLight', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 600, alpha: 0 }); var speedText = new Text2('0 MPH', { size: 80, fill: 0x000000 }); speedText.anchor.set(0.5, 0); speedText.x = 1024; speedText.y = 1700; game.addChild(speedText); var gearBackground = game.attachAsset('gearBackground', { anchorX: 0.5, anchorY: 0.5, x: 1400, y: 1620 }); var gearText = new Text2('1', { size: 120, fill: 0xFFFFFF }); gearText.anchor.set(0.5, 0); gearText.x = 1400; gearText.y = 1550; game.addChild(gearText); var raceText = new Text2('RACE ' + currentRace, { size: 100, fill: 0x000000 }); raceText.anchor.set(0.5, 0.5); raceText.x = 1024; raceText.y = 300; game.addChild(raceText); var instructionText = new Text2('HOLD TO REV', { size: 80, fill: 0x000000 }); instructionText.anchor.set(0.5, 0.5); instructionText.x = 1024; instructionText.y = 800; game.addChild(instructionText); var difficultyText = new Text2('EASY', { size: 120, fill: 0x4CAF50, stroke: 0x000000, strokeThickness: 8 }); difficultyText.anchor.set(1, 0); difficultyText.x = 1948; difficultyText.y = 150; game.addChild(difficultyText); var winPopup = null; var displayedSpeed = 0; // Current displayed speed value var targetSpeed = 0; // Target speed value for smooth transition // Play background music LK.playMusic('back'); function showWinPopup() { // Stop all sounds when popup appears if (currentGearSound) { currentGearSound.stop(); currentGearSound = null; } if (revSound) { revSound.stop(); revSound = null; } isCurrentlyRevving = false; if (!winPopup) { winPopup = new WinPopup(); winPopup.onNextRace = function () { hideWinPopup(); currentRace++; if (currentRace > maxRaces) { currentRace = 1; } resetRace(); }; game.addChild(winPopup); } } function hideWinPopup() { if (winPopup) { game.removeChild(winPopup); winPopup = null; } } function startCountdown() { raceState = 'countdown'; countdownTimer = 0; startLightTimer = 0; lightSequenceStep = 0; lightSequenceTimer = 0; // Reset all lights to dim state redLight1.alpha = 0.3; redLight2.alpha = 0.3; redLight3.alpha = 0.3; redLight4.alpha = 0.3; redLight.alpha = 0; greenLight.alpha = 0; // Start light sequence after 1 second LK.setTimeout(function () { // Light 1 turns on tween(redLight1, { alpha: 1 }, { duration: 200 }); LK.setTimeout(function () { // Light 2 turns on tween(redLight2, { alpha: 1 }, { duration: 200 }); LK.setTimeout(function () { // Light 3 turns on tween(redLight3, { alpha: 1 }, { duration: 200 }); LK.setTimeout(function () { // Light 4 turns on tween(redLight4, { alpha: 1 }, { duration: 200 }); LK.setTimeout(function () { // All red lights turn off and green lights turn on tween(redLight1, { alpha: 0.3 }, { duration: 100 }); tween(redLight2, { alpha: 0.3 }, { duration: 100 }); tween(redLight3, { alpha: 0.3 }, { duration: 100 }); tween(redLight4, { alpha: 0.3 }, { duration: 100 }); tween(greenLight, { alpha: 1 }, { duration: 200 }); perfectStartWindow = true; instructionText.setText('TAP TO SHIFT IN GREEN ZONE'); LK.getSound('raceStart').play(); LK.setTimeout(function () { raceState = 'racing'; playerCar.raceStarted = true; opponentCar.raceStarted = true; var launchQuality = 0.5; if (playerCar.rpm >= 4000 && playerCar.rpm <= 5000) { launchQuality = 1.0; } else if (playerCar.rpm >= 3000 && playerCar.rpm <= 6000) { launchQuality = 0.8; } playerCar.acceleration = launchQuality; // Use difficulty-based launch acceleration with some randomness var launchVariation = Math.random() * 0.15; // ±0.15 variation opponentCar.acceleration = opponentCar.baseLaunchAcceleration + launchVariation; perfectStartWindow = false; // Reset RPM needle position to starting position playerCar.rpm = 1000; opponentCar.rpm = 1000; }, 500); }, 800); }, 800); }, 800); }, 800); }, 1000); } function updateOpponentDifficulty() { if (currentRace >= 1 && currentRace <= 2) { opponentCar.difficultyLevel = 'easy'; opponentCar.baseLaunchAcceleration = 0.5; opponentCar.baseShiftAcceleration = 0.4; } else if (currentRace >= 3 && currentRace <= 4) { opponentCar.difficultyLevel = 'medium'; opponentCar.baseLaunchAcceleration = 0.7; opponentCar.baseShiftAcceleration = 0.6; } else if (currentRace === 5) { // race 5 - hard opponentCar.difficultyLevel = 'hard'; opponentCar.baseLaunchAcceleration = 0.85; opponentCar.baseShiftAcceleration = 0.75; } else { // race 6 - slightly reduced difficulty to require perfect play opponentCar.difficultyLevel = 'hard'; opponentCar.baseLaunchAcceleration = 0.82; opponentCar.baseShiftAcceleration = 0.72; } } function resetRace() { raceState = 'countdown'; playerCar.x = 50; playerCar.y = 1320; playerCar.speed = 0; playerCar.rpm = 1000; playerCar.gear = 1; playerCar.acceleration = 0; playerCar.raceStarted = false; playerCar.raceFinished = false; playerCar.isRevving = false; opponentCar.x = 50; opponentCar.y = 1420; opponentCar.speed = 0; opponentCar.rpm = 1000; opponentCar.gear = 1; opponentCar.acceleration = 0; opponentCar.raceStarted = false; opponentCar.raceFinished = false; opponentCar.aiShiftTimer = 0; updateOpponentDifficulty(); // Update difficulty based on current race lightSequenceStep = 0; lightSequenceTimer = 0; // Reset all lights to dim state redLight1.alpha = 0.3; redLight2.alpha = 0.3; redLight3.alpha = 0.3; redLight4.alpha = 0.3; greenLight.alpha = 0; raceText.setText('RACE ' + currentRace); instructionText.setText('HOLD TO REV'); // Update difficulty text based on current race if (currentRace >= 1 && currentRace <= 2) { difficultyText.setText('EASY'); difficultyText.fill = 0x4CAF50; // Green } else if (currentRace >= 3 && currentRace <= 4) { difficultyText.setText('MEDIUM'); difficultyText.fill = 0xFFFF00; // Yellow } else if (currentRace === 5) { difficultyText.setText('HARD'); difficultyText.fill = 0xFF0000; // Red } else { difficultyText.setText('EXPERT'); difficultyText.fill = 0xFF0000; // Red } // Stop any existing gear sound if (currentGearSound) { currentGearSound.stop(); currentGearSound = null; } // Stop revving sound if (revSound) { revSound.stop(); revSound = null; } isCurrentlyRevving = false; displayedSpeed = 0; targetSpeed = 0; // Create loading screen var loadingText = new Text2('LOADING...', { size: 120, fill: 0x000000 }); loadingText.anchor.set(0.5, 0.5); loadingText.x = 1024; loadingText.y = 1366; game.addChild(loadingText); // Wait for assets to load then start countdown LK.setTimeout(function () { // Remove loading text game.removeChild(loadingText); // Start the game startCountdown(); }, 1000); } game.down = function (x, y, obj) { if (raceState === 'countdown') { playerCar.startRevving(); LK.getSound('engineRev').play(); } else if (raceState === 'racing') { // Only player car shifting is controlled by player input playerCar.shift(); } }; game.up = function (x, y, obj) { if (raceState === 'countdown') { playerCar.stopRevving(); } }; // Function to animate audience excitement for gear shifts function animateAudienceForShift() { // Animate upper audience heads for (var i = 0; i < upperAudience.length; i++) { var audienceGroup = upperAudience[i]; // Animate each head in the group for (var j = 1; j < audienceGroup.children.length; j++) { var head = audienceGroup.children[j]; // Scale up heads for jumping effect tween(head, { scaleX: 1.3 + Math.random() * 0.2, scaleY: 1.3 + Math.random() * 0.2 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.bounceOut }); } }); } } // Animate lower audience heads for (var i = 0; i < lowerAudience.length; i++) { var audienceGroup = lowerAudience[i]; // Animate each head in the group for (var j = 1; j < audienceGroup.children.length; j++) { var head = audienceGroup.children[j]; // Scale up heads for jumping effect tween(head, { scaleX: 1.3 + Math.random() * 0.2, scaleY: 1.3 + Math.random() * 0.2 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(this, { scaleX: 1, scaleY: 1 }, { duration: 150, easing: tween.bounceOut }); } }); } } } // Function to animate audience going crazy at finish line function animateAudienceFinishLine() { // More intense animation for finish line - animate heads only for (var i = 0; i < upperAudience.length; i++) { var audienceGroup = upperAudience[i]; // Animate each head in the group with crazy effects for (var j = 1; j < audienceGroup.children.length; j++) { var head = audienceGroup.children[j]; // Crazy scaling animation for heads tween(head, { scaleX: 1.8 + Math.random() * 0.4, scaleY: 1.8 + Math.random() * 0.4 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { var currentHead = this; tween(currentHead, { scaleX: 1, scaleY: 1 }, { duration: 400, easing: tween.bounceOut, onFinish: function onFinish() { // Continue bouncing for a while tween(currentHead, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(currentHead, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeInOut }); } }); } }); } }); } } // Animate lower audience heads with crazy effects for (var i = 0; i < lowerAudience.length; i++) { var audienceGroup = lowerAudience[i]; // Animate each head in the group with crazy effects for (var j = 1; j < audienceGroup.children.length; j++) { var head = audienceGroup.children[j]; // Crazy scaling animation for heads tween(head, { scaleX: 1.8 + Math.random() * 0.4, scaleY: 1.8 + Math.random() * 0.4 }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { var currentHead = this; tween(currentHead, { scaleX: 1, scaleY: 1 }, { duration: 400, easing: tween.bounceOut, onFinish: function onFinish() { // Continue bouncing for a while tween(currentHead, { scaleX: 1.3, scaleY: 1.3 }, { duration: 300, easing: tween.easeInOut, onFinish: function onFinish() { tween(currentHead, { scaleX: 1, scaleY: 1 }, { duration: 300, easing: tween.easeInOut }); } }); } }); } }); } } } game.update = function () { var needlePosition = 824 + (playerCar.rpm - 1000) / 6000 * 400; if (needlePosition > 1224) needlePosition = 1224; if (needlePosition < 824) needlePosition = 824; rpmNeedle.x = needlePosition; // Calculate new target speed for display (multiply by 3 for speedometer effect) var newTargetSpeed = Math.floor(playerCar.speed * 3); // Only start tween if target speed has changed significantly if (Math.abs(newTargetSpeed - targetSpeed) > 1) { targetSpeed = newTargetSpeed; // Stop any existing speed tween tween.stop({ speed: displayedSpeed }, { speed: true }); // Smoothly tween to new target speed over 200ms for faster updates tween({ speed: displayedSpeed }, { speed: targetSpeed }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { displayedSpeed = targetSpeed; } }); } // Update displayed speed during tween speedText.setText(Math.floor(displayedSpeed) + ' MPH'); gearText.setText(playerCar.gear); // Sound control - play individual gear sounds or revving sound if (playerCar.isRevving && !playerCar.raceStarted) { // Handle revving before race starts if (!isCurrentlyRevving) { // Stop any current gear sound if (currentGearSound) { currentGearSound.stop(); currentGearSound = null; } // Start revving sound revSound = LK.getSound('revSound'); revSound.play(); isCurrentlyRevving = true; } } else if (playerCar.raceStarted) { // Handle gear sounds during racing if (isCurrentlyRevving) { // Stop revving sound if (revSound) { revSound.stop(); revSound = null; } isCurrentlyRevving = false; } // Check if gear changed if (playerCar.gear !== lastGear) { // Stop current gear sound if (currentGearSound) { currentGearSound.stop(); currentGearSound = null; } // Start new gear sound var gearSoundId = 'gear' + playerCar.gear + 'Sound'; currentGearSound = LK.getSound(gearSoundId); currentGearSound.play(); lastGear = playerCar.gear; // Animate audience excitement for gear shift animateAudienceForShift(); } } else { // Stop all sounds when not racing or revving if (currentGearSound) { currentGearSound.stop(); currentGearSound = null; } if (revSound) { revSound.stop(); revSound = null; } isCurrentlyRevving = false; } if (raceState === 'racing') { if (playerCar.x >= 1900 && !playerCar.raceFinished) { playerCar.raceFinished = true; opponentCar.raceFinished = true; // Animate audience going crazy at finish line animateAudienceFinishLine(); LK.setTimeout(function () { showWinPopup(); }, 1000); } else if (opponentCar.x >= 1900 && !opponentCar.raceFinished) { playerCar.raceFinished = true; opponentCar.raceFinished = true; // Animate audience going crazy even when opponent wins animateAudienceFinishLine(); LK.showGameOver(); } } }; startCountdown();
===================================================================
--- original.js
+++ change.js
@@ -723,130 +723,150 @@
}
};
// Function to animate audience excitement for gear shifts
function animateAudienceForShift() {
- // Animate upper audience
+ // Animate upper audience heads
for (var i = 0; i < upperAudience.length; i++) {
var audienceGroup = upperAudience[i];
- // Random bounce effect
- tween(audienceGroup, {
- y: audienceGroup.y - (20 + Math.random() * 15)
- }, {
- duration: 150,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- tween(this, {
- y: 1216
- }, {
- duration: 200,
- easing: tween.bounceOut
- });
- }
- });
+ // Animate each head in the group
+ for (var j = 1; j < audienceGroup.children.length; j++) {
+ var head = audienceGroup.children[j];
+ // Scale up heads for jumping effect
+ tween(head, {
+ scaleX: 1.3 + Math.random() * 0.2,
+ scaleY: 1.3 + Math.random() * 0.2
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(this, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 150,
+ easing: tween.bounceOut
+ });
+ }
+ });
+ }
}
- // Animate lower audience
+ // Animate lower audience heads
for (var i = 0; i < lowerAudience.length; i++) {
var audienceGroup = lowerAudience[i];
- // Random bounce effect
- tween(audienceGroup, {
- y: audienceGroup.y + (20 + Math.random() * 15)
- }, {
- duration: 150,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- tween(this, {
- y: 1516
- }, {
- duration: 200,
- easing: tween.bounceOut
- });
- }
- });
+ // Animate each head in the group
+ for (var j = 1; j < audienceGroup.children.length; j++) {
+ var head = audienceGroup.children[j];
+ // Scale up heads for jumping effect
+ tween(head, {
+ scaleX: 1.3 + Math.random() * 0.2,
+ scaleY: 1.3 + Math.random() * 0.2
+ }, {
+ duration: 100,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(this, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 150,
+ easing: tween.bounceOut
+ });
+ }
+ });
+ }
}
}
// Function to animate audience going crazy at finish line
function animateAudienceFinishLine() {
- // More intense animation for finish line
+ // More intense animation for finish line - animate heads only
for (var i = 0; i < upperAudience.length; i++) {
var audienceGroup = upperAudience[i];
- // Crazy jumping animation
- tween(audienceGroup, {
- y: audienceGroup.y - (40 + Math.random() * 30),
- scaleX: 1.1 + Math.random() * 0.2,
- scaleY: 1.1 + Math.random() * 0.2
- }, {
- duration: 100,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- var currentGroup = this;
- tween(currentGroup, {
- y: 1216,
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 300,
- easing: tween.bounceOut,
- onFinish: function onFinish() {
- // Continue bouncing for a while
- tween(currentGroup, {
- y: 1196
- }, {
- duration: 200,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(currentGroup, {
- y: 1216
- }, {
- duration: 200,
- easing: tween.easeInOut
- });
- }
- });
- }
- });
- }
- });
+ // Animate each head in the group with crazy effects
+ for (var j = 1; j < audienceGroup.children.length; j++) {
+ var head = audienceGroup.children[j];
+ // Crazy scaling animation for heads
+ tween(head, {
+ scaleX: 1.8 + Math.random() * 0.4,
+ scaleY: 1.8 + Math.random() * 0.4
+ }, {
+ duration: 150,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ var currentHead = this;
+ tween(currentHead, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 400,
+ easing: tween.bounceOut,
+ onFinish: function onFinish() {
+ // Continue bouncing for a while
+ tween(currentHead, {
+ scaleX: 1.3,
+ scaleY: 1.3
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(currentHead, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 300,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
}
- // Animate lower audience with crazy effects
+ // Animate lower audience heads with crazy effects
for (var i = 0; i < lowerAudience.length; i++) {
var audienceGroup = lowerAudience[i];
- // Crazy jumping animation
- tween(audienceGroup, {
- y: audienceGroup.y + (40 + Math.random() * 30),
- scaleX: 1.1 + Math.random() * 0.2,
- scaleY: 1.1 + Math.random() * 0.2
- }, {
- duration: 100,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- var currentGroup = this;
- tween(currentGroup, {
- y: 1516,
- scaleX: 1,
- scaleY: 1
- }, {
- duration: 300,
- easing: tween.bounceOut,
- onFinish: function onFinish() {
- // Continue bouncing for a while
- tween(currentGroup, {
- y: 1536
- }, {
- duration: 200,
- easing: tween.easeInOut,
- onFinish: function onFinish() {
- tween(currentGroup, {
- y: 1516
- }, {
- duration: 200,
- easing: tween.easeInOut
- });
- }
- });
- }
- });
- }
- });
+ // Animate each head in the group with crazy effects
+ for (var j = 1; j < audienceGroup.children.length; j++) {
+ var head = audienceGroup.children[j];
+ // Crazy scaling animation for heads
+ tween(head, {
+ scaleX: 1.8 + Math.random() * 0.4,
+ scaleY: 1.8 + Math.random() * 0.4
+ }, {
+ duration: 150,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ var currentHead = this;
+ tween(currentHead, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 400,
+ easing: tween.bounceOut,
+ onFinish: function onFinish() {
+ // Continue bouncing for a while
+ tween(currentHead, {
+ scaleX: 1.3,
+ scaleY: 1.3
+ }, {
+ duration: 300,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ tween(currentHead, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 300,
+ easing: tween.easeInOut
+ });
+ }
+ });
+ }
+ });
+ }
+ });
+ }
}
}
game.update = function () {
var needlePosition = 824 + (playerCar.rpm - 1000) / 6000 * 400;
engineSound
Sound effect
gear1Sound
Sound effect
gear2Sound
Sound effect
gear3Sound
Sound effect
gear4Sound
Sound effect
gear5Sound
Sound effect
gear6Sound
Sound effect
revSound
Sound effect
perfectShift
Sound effect
badShift
Sound effect
raceStart
Sound effect
back
Music
fabulousShift
Sound effect