User prompt
Make the speed boost red
User prompt
Locate the speed boost badge in the right side of the screen at the middle
User prompt
Add a badge when reach 500, make it a token the user can activate to slow the road for 30sec. Appear on screen โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Show the badge on the screen when reach 500 points and let the user activate it for slow mode for 30 seconds
User prompt
Add a badge when reach 500, make it a token the user can activate to slow the road for 30sec
User prompt
Remove the girl clapping
User prompt
Change the position of the gir at the end to center down
User prompt
Enhance winning animation and girl positioning
User prompt
Make a reflect in the front of the car that look like faded lights using a gradient
User prompt
Make te car lights yellow โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Relocate victory animation girl to the bottom right corner of the screen
User prompt
Relocate the girl at the end
User prompt
Relocate victory animation girl to the bottom right corner when winning
User prompt
Relocate victory animation girl to bottom right corner when winning
User prompt
Relocate girl clapping at the end
User prompt
Relocate girl clapping when winning
User prompt
Make the trees to be pink in japan and yellow in the beach
User prompt
Make the trees color PINK in japan environment โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Update japan environment and make trees pink
User prompt
In the beach level, please change the trees to palm trees, and in the japan just make them pink
User prompt
Enhance win animation and add effects also position the girl in the bottom right of the screen
User prompt
Enhance win animation add neon confetti and place girl in the bottom of the screen
User prompt
Change the position of the girl clapping to bottom right pf the screen when winning
User prompt
Please fix the bug: 'TypeError: undefined is not an object (evaluating 'self.message.style.fill = 0xFF00FF')' in or related to this line: 'self.message.style.fill = 0xFF00FF; // Pink' Line Number: 1066
User prompt
Please fix the bug: 'TypeError: undefined is not an object (evaluating 'self.message.style.fill = 0xFF00FF')' in or related to this line: 'self.message.style.fill = 0xFF00FF; // Pink' Line Number: 1065
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Building = Container.expand(function () { var self = Container.call(this); var buildingGraphics = self.attachAsset('building', { anchorX: 0.5, anchorY: 0 }); // Randomize building properties var shade = Math.floor(Math.random() * 40) + 40; buildingGraphics.tint = shade << 16 | shade << 8 | shade; buildingGraphics.height = Math.random() * 600 + 400; buildingGraphics.width = Math.random() * 100 + 100; // Add windows to buildings for a city look var windowCount = Math.floor(buildingGraphics.height / 80); var windowsPerRow = Math.floor(buildingGraphics.width / 40); for (var i = 0; i < windowCount; i++) { for (var j = 0; j < windowsPerRow; j++) { var windowLight = self.addChild(new Container()); var windowAsset = windowLight.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 30, tint: 0xFFFF99 }); windowLight.x = j * 40 - buildingGraphics.width / 2 + 25; windowLight.y = i * 80 + 50; windowLight.alpha = Math.random() > 0.3 ? 0.8 : 0; } } self.speed = 10; // Default speed self.update = function () { self.y += self.speed; // Reset building when it goes off screen if (self.y > 2732 + buildingGraphics.height) { self.y = -buildingGraphics.height; // Determine road boundaries to keep buildings off the road var road = null; for (var i = 0; i < game.children.length; i++) { if (game.children[i].asset && game.children[i].asset.id === 'road') { road = game.children[i]; break; } } // Place building only on sidewalks var roadLeftEdge = road ? (2048 - road.width) / 2 : 424; var roadRightEdge = road ? 2048 - (2048 - road.width) / 2 : 1624; // Determine which side to place the building on based on its current side if (self.x < roadLeftEdge) { // Keep on left side self.x = Math.random() * (roadLeftEdge - buildingGraphics.width / 2); } else { // Keep on right side self.x = roadRightEdge + Math.random() * (roadLeftEdge - buildingGraphics.width / 2); } // Check current environment for building appearance if (environment && environment.current === environment.BEACH) { // Beach resort buildings - lighter colors, more variation var r = Math.floor(Math.random() * 40) + 215; // Bright beige/white var g = Math.floor(Math.random() * 40) + 215; var b = Math.floor(Math.random() * 40) + 190; buildingGraphics.tint = r << 16 | g << 8 | b; buildingGraphics.height = Math.random() * 400 + 300; // Beach buildings are shorter buildingGraphics.width = Math.random() * 150 + 100; // But wider } else if (environment && environment.current === environment.JAPAN) { // Traditional Japanese buildings - pagoda style var shade = Math.floor(Math.random() * 40) + 40; // Dark base // Add red tint for some buildings to simulate temples/shrines if (Math.random() > 0.5) { buildingGraphics.tint = shade + 150 << 16 | shade << 8 | shade; buildingGraphics.height = Math.random() * 500 + 300; // Slightly shorter } else { buildingGraphics.tint = shade << 16 | shade << 8 | shade; buildingGraphics.height = Math.random() * 400 + 200; // Low traditional houses } buildingGraphics.width = Math.random() * 120 + 100; } else { // Default city buildings var shade = Math.floor(Math.random() * 40) + 40; buildingGraphics.tint = shade << 16 | shade << 8 | shade; buildingGraphics.height = Math.random() * 600 + 400; buildingGraphics.width = Math.random() * 100 + 100; } // Recreate windows when building resets self.removeChildren(1); // Keep only the main building graphic var windowCount = Math.floor(buildingGraphics.height / 80); var windowsPerRow = Math.floor(buildingGraphics.width / 40); for (var i = 0; i < windowCount; i++) { for (var j = 0; j < windowsPerRow; j++) { var windowLight = self.addChild(new Container()); var windowAsset = windowLight.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 30, tint: 0xFFFF99 }); windowLight.x = j * 40 - buildingGraphics.width / 2 + 25; windowLight.y = i * 80 + 50; // Randomly light windows windowLight.alpha = Math.random() > 0.3 ? 0.8 : 0; } } } }; return self; }); var Car = Container.expand(function () { var self = Container.call(this); // Create car body - using just the car asset without additional square var carGraphics = self.attachAsset('car', { anchorX: 0.5, anchorY: 0.5, tint: 0x3366CC // Blue car color }); // Add headlights var leftHeadlight = self.addChild(new Container()); var leftHeadlightAsset = leftHeadlight.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 40, tint: 0xFFFFAA }); leftHeadlight.x = -60; leftHeadlight.y = -140; var rightHeadlight = self.addChild(new Container()); var rightHeadlightAsset = rightHeadlight.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 40, tint: 0xFFFFAA }); rightHeadlight.x = 60; rightHeadlight.y = -140; self.jumping = false; self.jumpHeight = 100; self.originalY = 0; self.lastY = 0; // Track last Y position for intersection detection self.jump = function () { if (self.jumping) { return; } self.jumping = true; self.originalY = self.y; // Play jump sound LK.getSound('jump').play(); // Enhanced neon effect during jump - random bright color var randomNeonColor = Math.random() > 0.5 ? 0xFFFFFF : 0x00FFFF; // Create a glowing neon effect tween(carGraphics, { tint: randomNeonColor, scaleX: 1.2, scaleY: 1.2 }, { duration: 150, onFinish: function onFinish() { // Return to current neon color after the flash tween(carGraphics, { tint: self.neonColors[self.currentColorIndex], scaleX: 1.0, scaleY: 1.0 }, { duration: 450 }); } }); // Jump animation using tween tween(self, { y: self.y - self.jumpHeight }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Fall back down tween(self, { y: self.originalY }, { duration: 300, easing: tween.easeIn, onFinish: function onFinish() { self.jumping = false; } }); } }); }; self.down = function () { self.jump(); }; // Set up neon color cycling properties self.neonColors = [0x3366CC, // Blue 0xFF00FF, // Magenta 0x00FFFF, // Cyan 0x33CC33, // Green 0xFF6600, // Orange 0xFFFF00, // Yellow 0xFF3366, // Pink 0x9900FF // Purple ]; self.currentColorIndex = 0; self.colorTransitionTime = 0; self.colorTransitionDuration = 60; // About 1 second at 60fps - faster color cycling self.update = function () { self.lastY = self.y; // Create headlight glow effect if (LK.ticks % 5 === 0) { leftHeadlightAsset.alpha = 0.7 + Math.random() * 0.3; rightHeadlightAsset.alpha = 0.7 + Math.random() * 0.3; } // Update neon color effect self.colorTransitionTime++; if (self.colorTransitionTime >= self.colorTransitionDuration) { self.colorTransitionTime = 0; self.currentColorIndex = (self.currentColorIndex + 1) % self.neonColors.length; // Start transition to the next color tween(carGraphics, { tint: self.neonColors[self.currentColorIndex] }, { duration: 1000, easing: tween.easeInOut }); } }; return self; }); var Coin = Container.expand(function () { var self = Container.call(this); // Create the coin graphic var coinGraphic = self.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 40, tint: 0xFFFF00 // Bright yellow color for coins }); // Initialize properties self.active = false; // Animate coin from source to destination self.animate = function (startX, startY, destX, destY) { self.active = true; self.visible = true; self.x = startX + (Math.random() * 120 - 60); self.y = startY + (Math.random() * 120 - 60); self.alpha = 0; self.rotation = Math.random() * Math.PI; self.scale.set(1); // Duration and timing variables var duration = 500 + Math.random() * 200; // First make the coin appear with a quick flash tween(self, { alpha: 1.0, scaleX: 1.2, scaleY: 1.2 }, { duration: 60, onFinish: function onFinish() { // Add a spin to the coins as they move self.rotation = Math.random() * Math.PI * 2; // Small initial burst to create a more dynamic feel tween(self, { y: self.y - 50 - Math.random() * 70, x: self.x + (Math.random() * 100 - 50), alpha: 1.0, rotation: self.rotation + Math.PI * (Math.random() > 0.5 ? 1 : -1) }, { duration: 150, easing: tween.easeOut, onFinish: function onFinish() { // Now move directly to the score with arc path tween(self, { x: destX, y: destY, scaleX: 0.3, scaleY: 0.3, rotation: self.rotation + Math.PI * 2, alpha: 0 }, { duration: duration, easing: tween.easeInOut, onFinish: function onFinish() { // Flash the score text tween(scoreText, { scaleX: 1.2, scaleY: 1.2 }, { duration: 100, onFinish: function onFinish() { tween(scoreText, { scaleX: 1, scaleY: 1 }, { duration: 100 }); } }); // Reset coin self.active = false; self.visible = false; } }); } }); } }); }; return self; }); var Environment = Container.expand(function () { var self = Container.call(this); // Environment types self.CITY = 0; self.BEACH = 1; self.JAPAN = 2; // Current environment self.current = self.CITY; // Assets for each environment self.roadColors = [0x444444, 0xD2B48C, 0x8B4513]; // City, Beach, Japan self.sidewalkColors = [0x999999, 0xF5DEB3, 0x7D8570]; // City, Beach, Japan self.skyColors = [0x87CEEB, 0x87CEEB, 0xE0FFFF]; // City, Beach, Japan // Change environment based on score self.update = function (score) { var newEnvironment = self.current; // Determine environment based on score if (score >= 700) { newEnvironment = self.JAPAN; } else if (score >= 350) { newEnvironment = self.BEACH; } else { newEnvironment = self.CITY; } // Only update if environment changed if (newEnvironment !== self.current) { self.current = newEnvironment; return true; } return false; }; // Apply environment changes self.apply = function (road, leftSidewalk, rightSidewalk, game) { // Update colors based on current environment road.tint = self.roadColors[self.current]; leftSidewalk.tint = self.sidewalkColors[self.current]; rightSidewalk.tint = self.sidewalkColors[self.current]; // Update sky color game.setBackgroundColor(self.skyColors[self.current]); // Apply special transition effect LK.effects.flashScreen(0xFFFFFF, 500); // Return message to display for level change if (self.current === self.BEACH) { return "BEACH LEVEL UNLOCKED!"; } else if (self.current === self.JAPAN) { return "JAPAN LEVEL UNLOCKED!"; } return ""; }; return self; }); var Line = Container.expand(function () { var self = Container.call(this); // Create road line marking var lineGraphics = self.attachAsset('line', { anchorX: 0.5, anchorY: 0.5 }); // Make line vertical lineGraphics.rotation = Math.PI / 2; // Rotate 90 degrees // Road lines have fixed width to better match car size lineGraphics.width = 400; // Line length (now vertical) lineGraphics.height = 60; // Line thickness (more visible) self.lastY = 0; // Track last Y position for intersection detection self.speed = 15; // Default speed self.active = true; // Whether the line is active for scoring self.scored = false; // Whether this line has been scored already // Add visual effect to make lines more prominent var glowEffect = self.addChild(new Container()); var glowAsset = glowEffect.attachAsset('line', { anchorX: 0.5, anchorY: 0.5, width: lineGraphics.width + 20, height: lineGraphics.height + 20, tint: 0xFFFF00, alpha: 0.3 }); glowAsset.rotation = Math.PI / 2; self.update = function () { self.lastY = self.y; // Store last position for collision detection self.y += self.speed; // Pulse glow effect if (LK.ticks % 10 === 0) { glowAsset.alpha = 0.2 + Math.random() * 0.2; } // Remove when off screen if (self.y > 2732 + lineGraphics.width / 2) { self.active = false; } }; return self; }); var ScoreEffect = Container.expand(function () { var self = Container.call(this); var effectGraphics = self.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.show = function (x, y, isPositive) { self.x = x; self.y = y; if (!isPositive) { effectGraphics.tint = 0xFF0000; // Play penalty sound LK.getSound('penalty').play(); } else { effectGraphics.tint = 0x00FF00; // Play point sound LK.getSound('point').play(); } // Animation for the effect tween(self, { alpha: 0, y: y - 100 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { self.alpha = 1; self.visible = false; } }); self.visible = true; }; return self; }); var Store = Container.expand(function () { var self = Container.call(this); // Create store building var storeGraphics = self.attachAsset('building', { anchorX: 0.5, anchorY: 0, width: 200, height: 250, tint: 0xFAE5D3 // Light beige for store }); // Add store sign var storeSign = self.addChild(new Container()); var storeSignAsset = storeSign.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 180, height: 60, tint: 0x3498DB // Blue for store sign }); storeSign.y = 40; // Add store window var storeWindow = self.addChild(new Container()); var storeWindowAsset = storeWindow.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 120, height: 100, tint: 0xD6EAF8 // Light blue for window }); storeWindow.y = 120; // Add store door var storeDoor = self.addChild(new Container()); var storeDoorAsset = storeDoor.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 100, tint: 0x784212 // Brown for door }); storeDoor.y = 180; self.speed = 10; // Default speed self.update = function () { self.y += self.speed; // Reset store when it goes off screen if (self.y > 2732 + storeGraphics.height) { self.y = -storeGraphics.height; // Store types based on environment var storeTypes; if (environment && environment.current === environment.BEACH) { // Beach stores - surf shops, beach bars, cabanas storeTypes = [{ building: 0xF0F8FF, // AliceBlue sign: 0x00BFFF, // DeepSkyBlue window: 0xE0FFFF // LightCyan }, { building: 0xFFEFD5, // PapayaWhip sign: 0xFF6347, // Tomato window: 0xFFDAB9 // PeachPuff }, { building: 0x40E0D0, // Turquoise sign: 0xFFFFFF, // White window: 0xAFEEEE // PaleTurquoise }, { building: 0xF5DEB3, // Wheat sign: 0x1E90FF, // DodgerBlue window: 0xFFF5EE // SeaShell }]; } else if (environment && environment.current === environment.JAPAN) { // Japanese stores - traditional shops, ramen stands, markets storeTypes = [{ building: 0x8B4513, // SaddleBrown (wood) sign: 0xFF0000, // Red window: 0xFFD700 // Gold }, { building: 0xFFF5EE, // SeaShell (white paper walls) sign: 0x000000, // Black window: 0xFFF8DC // Cornsilk }, { building: 0x2F4F4F, // DarkSlateGray sign: 0xDC143C, // Crimson window: 0xF0FFF0 // Honeydew }, { building: 0xCD853F, // Peru (wood) sign: 0x4682B4, // SteelBlue window: 0xF5F5DC // Beige }]; } else { // Default city stores storeTypes = [{ building: 0xFAE5D3, sign: 0x3498DB, window: 0xD6EAF8 }, // Blue store { building: 0xFCF3CF, sign: 0xE74C3C, window: 0xFADBD8 }, // Red store { building: 0xD5F5E3, sign: 0x8E44AD, window: 0xEBDEF0 }, // Purple store { building: 0xEAEDED, sign: 0xF39C12, window: 0xFAE5D3 } // Orange store ]; } var type = storeTypes[Math.floor(Math.random() * storeTypes.length)]; storeGraphics.tint = type.building; storeSignAsset.tint = type.sign; storeWindowAsset.tint = type.window; // Vary store size slightly var sizeVar = 0.8 + Math.random() * 0.4; storeGraphics.width = 200 * sizeVar; storeGraphics.height = 250 * sizeVar; storeSign.scale.set(sizeVar); storeWindow.scale.set(sizeVar); storeDoor.scale.set(sizeVar); // Adjust positions based on new size storeSign.y = 40 * sizeVar; storeWindow.y = 120 * sizeVar; storeDoor.y = 180 * sizeVar; } }; return self; }); var StreetLight = Container.expand(function () { var self = Container.call(this); // Create pole var pole = self.addChild(new Container()); var poleAsset = pole.attachAsset('building', { anchorX: 0.5, anchorY: 1.0, width: 20, height: 200, tint: 0x555555 // Dark gray for pole }); // Create light var light = self.addChild(new Container()); var lightAsset = light.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 40, tint: 0xFFFF99 // Yellow light }); light.y = -200; // Light arm var arm = self.addChild(new Container()); var armAsset = arm.attachAsset('building', { anchorX: 0, anchorY: 0.5, width: 40, height: 10, tint: 0x555555 // Dark gray for arm }); arm.y = -190; self.speed = 10; // Default speed self.isLit = Math.random() > 0.2; // Most lights are on self.update = function () { self.y += self.speed; // Make light flicker occasionally if (self.isLit && LK.ticks % 20 === 0 && Math.random() > 0.7) { lightAsset.alpha = 0.6 + Math.random() * 0.4; } // Reset light when it goes off screen if (self.y > 2732 + 200) { self.y = -200; self.isLit = Math.random() > 0.2; lightAsset.alpha = self.isLit ? 1 : 0.2; } }; return self; }); var TapEffect = Container.expand(function () { var self = Container.call(this); var effectGraphics = self.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 300, height: 300, alpha: 0.6 }); self.show = function (x, y, isPositive) { self.x = x; self.y = y; // Set color based on whether it's a positive or negative tap if (isPositive) { effectGraphics.tint = 0x00FF00; // Green for good taps // Play point sound with lower volume to avoid overwhelming LK.getSound('point').play({ volume: 0.3 }); // Trigger coin effects separately - they're now handled in the game code } else { effectGraphics.tint = 0xFF0000; // Red for bad taps // Play penalty sound with lower volume to avoid overwhelming LK.getSound('penalty').play({ volume: 0.3 }); } // Reset properties before animation self.alpha = 1; effectGraphics.alpha = 0.6; effectGraphics.scale.x = 0.5; effectGraphics.scale.y = 0.5; self.visible = true; // Animate the effect - expand and fade out for a nice ripple effect tween(effectGraphics, { alpha: 0, scaleX: 2.5, scaleY: 2.5 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { self.visible = false; effectGraphics.scale.x = 0.5; effectGraphics.scale.y = 0.5; } }); }; return self; }); var Tree = Container.expand(function () { var self = Container.call(this); // Create tree trunk var trunk = self.addChild(new Container()); var trunkAsset = trunk.attachAsset('building', { anchorX: 0.5, anchorY: 1.0, width: 40, height: 120, tint: 0x8B4513 // Brown color for trunk }); // Create tree foliage (multiple layers for depth) var foliage1 = self.addChild(new Container()); var foliageAsset1 = foliage1.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.8, width: 150, height: 150, tint: 0x228B22 // Forest green }); foliage1.y = -80; var foliage2 = self.addChild(new Container()); var foliageAsset2 = foliage2.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.7, width: 120, height: 120, tint: 0x32CD32 // Lime green for highlight }); foliage2.y = -100; self.speed = 10; // Default speed self.update = function () { self.y += self.speed; // Reset tree when it goes off screen if (self.y > 2732 + 150) { self.y = -150; // Randomize tree appearance when resetting trunkAsset.height = 80 + Math.random() * 80; trunkAsset.width = 30 + Math.random() * 20; var scale = 0.8 + Math.random() * 0.5; foliage1.scale.set(scale); foliage2.scale.set(scale * 0.9); // Check current environment for tree appearance if (environment && environment.current === environment.BEACH) { // Palm trees for beach trunkAsset.tint = 0xA0522D; // Brown trunk for palm trees trunkAsset.height *= 1.5; // Make palm tree trunks much taller trunkAsset.width *= 0.7; // Make palm tree trunks thinner // Change foliage shape and color for palm trees foliageAsset1.width = 200; // Wider palm fronds foliageAsset1.height = 120; // Shorter palm fronds foliageAsset1.tint = 0x2E8B57; // Sea green palms foliageAsset2.width = 220; // Even wider top fronds foliageAsset2.height = 100; // Shorter top fronds foliageAsset2.tint = 0x3CB371; // Medium sea green for highlights // Position foliage to look like palm fronds foliage1.y = -150; // Raise fronds higher for palm tree appearance foliage2.y = -170; // Raise top fronds even higher } else if (environment && environment.current === environment.JAPAN) { // Cherry blossom trees (sakura) trunkAsset.tint = 0x8B4513; // Brown trunk // More vibrant pink cherry blossoms foliageAsset1.width = 170; // Wider, fuller cherry blossom shape foliageAsset1.height = 170; // Rounder for blossom shape // Pure pink color for cherry blossoms foliageAsset1.tint = 0xFFA6C9; // Vibrant pink cherry blossoms // Lighter pink for highlights foliageAsset2.width = 140; // Slightly smaller top layer foliageAsset2.height = 140; // Rounder for blossom shape foliageAsset2.tint = 0xFFB7DD; // Lighter pink highlights // Position foliage to look more like cherry blossom foliage1.y = -100; // Position for traditional cherry blossom tree shape foliage2.y = -120; // Position for traditional cherry blossom tree shape } else { // Default city trees var greenVariation = Math.floor(Math.random() * 40); foliageAsset1.tint = 34 + greenVariation << 16 | 139 + greenVariation << 8 | 34; foliageAsset2.tint = 50 + greenVariation << 16 | 205 + greenVariation << 8 | 50; } } }; return self; }); var Victory = Container.expand(function () { var self = Container.call(this); // Create anime girl character - busty anime style var body = self.addChild(new Container()); var bodyAsset = body.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 180, height: 250, tint: 0xFFD2B0 // Skin tone color }); // Add girl's head var head = self.addChild(new Container()); var headAsset = head.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 120, height: 120, tint: 0xFFD2B0 // Skin tone color }); head.y = -160; // Add girl's hair - anime style with large eyes var hair = self.addChild(new Container()); var hairAsset = hair.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 200, tint: 0xCD7F32 // Golden brown anime hair }); hair.y = -160; // Add girl's outfit - typical anime schoolgirl style var outfit = self.addChild(new Container()); var outfitAsset = outfit.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 220, height: 150, tint: 0x1E90FF // Bright blue outfit }); outfit.y = 10; // Add bust enhancement for anime style var bust = self.addChild(new Container()); var bustAsset = bust.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 160, height: 60, tint: 0x1E90FF // Match outfit color }); bust.y = -70; // Add girl's left arm (will be animated for clapping) var leftArm = self.addChild(new Container()); var leftArmAsset = leftArm.attachAsset('building', { anchorX: 1.0, anchorY: 0.5, width: 100, height: 30, tint: 0xFFD2B0 // Skin tone }); leftArm.x = -50; leftArm.y = -50; leftArm.rotation = -Math.PI / 4; // Angle up // Add girl's right arm (will be animated for clapping) var rightArm = self.addChild(new Container()); var rightArmAsset = rightArm.attachAsset('building', { anchorX: 0.0, anchorY: 0.5, width: 100, height: 30, tint: 0xFFD2B0 // Skin tone }); rightArm.x = 50; rightArm.y = -50; rightArm.rotation = Math.PI / 4; // Angle up // Add girl's face with anime style (larger eyes, small nose) var smile = self.addChild(new Container()); var smileAsset = smile.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 15, tint: 0xFF3366 // Pink anime smile }); smile.y = -140; // Create eyes - large anime style eyes var leftEye = self.addChild(new Container()); var leftEyeAsset = leftEye.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 50, tint: 0x6699FF // Blue anime eyes }); leftEye.x = -30; leftEye.y = -170; var rightEye = self.addChild(new Container()); var rightEyeAsset = rightEye.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 50, tint: 0x6699FF // Blue anime eyes }); rightEye.x = 30; rightEye.y = -170; // Add eye highlights for anime sparkle var leftHighlight = self.addChild(new Container()); var leftHighlightAsset = leftHighlight.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 15, height: 15, tint: 0xFFFFFF }); leftHighlight.x = -25; leftHighlight.y = -175; var rightHighlight = self.addChild(new Container()); var rightHighlightAsset = rightHighlight.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 15, height: 15, tint: 0xFFFFFF }); rightHighlight.x = 35; rightHighlight.y = -175; // Add hair accessories - typical anime bow var bow = self.addChild(new Container()); var bowAsset = bow.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 40, tint: 0xFF3366 // Pink bow }); bow.y = -220; // Starting animation state self.clapping = false; self.animationFrame = 0; // Property to control visibility self.active = false; // Start clapping animation self.startClapping = function () { self.visible = true; self.active = true; self.clapping = true; // Create happy message with anime style text if (!self.message) { self.message = new Text2('Sugoi! You Win!', { size: 120, fill: 0xFF00FF, // Pink stroke: 0x4B0082, strokeThickness: 10, fontWeight: 'bold' }); self.message.anchor.set(0.5, 0.5); self.message.y = -300; self.addChild(self.message); } // Flash confetti effect around the screen with rainbow colors LK.effects.flashScreen(0xFFFFFF, 300); // Create first intense coin shower effect for confetti LK.setTimeout(function () { for (var i = 0; i < 40; i++) { var coin = coins[Math.floor(Math.random() * coins.length)]; if (!coin.active) { // Random position from multiple sides of screen var startX = Math.random() > 0.5 ? Math.random() * 2048 : Math.random() > 0.5 ? -100 : 2148; var startY = Math.random() > 0.7 ? -100 : Math.random() * 2732; // Random position on screen for more scattered effect var destX = Math.random() * 2048; var destY = Math.random() * 2732; // Animate coin as confetti coin.animate(startX, startY, destX, destY); } } }, 200); // Create additional confetti bursts with delays LK.setTimeout(function () { for (var i = 0; i < 30; i++) { var coin = coins[Math.floor(Math.random() * coins.length)]; if (!coin.active) { var startX = Math.random() * 2048; var startY = -100; var destX = Math.random() * 2048; var destY = Math.random() * 2732; coin.animate(startX, startY, destX, destY); } } }, 800); // Final confetti burst LK.setTimeout(function () { for (var i = 0; i < 20; i++) { var coin = coins[Math.floor(Math.random() * coins.length)]; if (!coin.active) { var startX = 2048 / 2 + (Math.random() * 400 - 200); var startY = -100; var destX = Math.random() * 2048; var destY = Math.random() * 2732; coin.animate(startX, startY, destX, destY); } } }, 1500); // Anime-style entrance animation with bounce effect self.alpha = 0; self.scale.set(0.2); tween(self, { alpha: 1.0, scaleX: 1.2, scaleY: 1.2 }, { duration: 500, easing: tween.elasticOut, onFinish: function onFinish() { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeOut }); } }); }; // Stop clapping animation self.stopClapping = function () { self.clapping = false; self.active = false; // Animate exit with spin tween(self, { alpha: 0, scaleX: 0.2, scaleY: 0.2, rotation: Math.PI * 2 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { self.visible = false; self.rotation = 0; } }); }; // Animation update self.update = function () { if (!self.clapping) { return; } self.animationFrame++; // Anime-style clapping animation with exaggerated movements if (self.animationFrame % 30 < 15) { // Hands moving apart with anime exaggeration leftArm.rotation = -Math.PI / 3; rightArm.rotation = Math.PI / 3; // Anime style eye expressions - happy eyes leftEyeAsset.height = 40 + Math.sin(self.animationFrame * 0.2) * 10; rightEyeAsset.height = 40 + Math.sin(self.animationFrame * 0.2) * 10; } else { // Hands clapping together with anime exaggeration leftArm.rotation = -Math.PI / 10; rightArm.rotation = Math.PI / 10; // Only play sound on the exact frame of clap contact if (self.animationFrame % 30 === 15) { // Play clapping sound (using point sound at lower volume) LK.getSound('point').play({ volume: 0.2 }); // Add slight jiggle animation for bust on clap (anime physics) tween(bust, { y: -65, scaleX: 1.1, scaleY: 0.9 }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(bust, { y: -70, scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.elasticOut }); } }); } } // Bouncing animation - more exaggerated for anime style if (self.animationFrame % 60 < 30) { self.y = Math.sin(self.animationFrame * 0.1) * 15; // Anime hair physics - hair moves slightly delayed from body hair.y = -160 + Math.sin((self.animationFrame - 5) * 0.1) * 8; } // Message pulsing animation with anime style glow effect if (self.message && self.message.style && typeof self.message.style.fill !== 'undefined') { self.message.scale.set(1.0 + Math.sin(self.animationFrame * 0.08) * 0.15); // Alternate colors for anime-style rainbow text effect if (self.animationFrame % 180 < 60) { self.message.style.fill = 0xFF00FF; // Pink } else if (self.animationFrame % 180 < 120) { self.message.style.fill = 0x00FFFF; // Cyan } else { self.message.style.fill = 0xFFFF00; // Yellow } } // Anime-style eye blink occasionally if (self.animationFrame % 120 === 0) { tween(leftEyeAsset, { height: 5 }, { duration: 100, onFinish: function onFinish() { tween(leftEyeAsset, { height: 50 }, { duration: 100 }); } }); tween(rightEyeAsset, { height: 5 }, { duration: 100, onFinish: function onFinish() { tween(rightEyeAsset, { height: 50 }, { duration: 100 }); } }); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ // Game variables var car; var lines = []; var buildings = []; var trees = []; var stores = []; var streetLights = []; var score = 0; var scoreText; var speedMultiplier = 1; var lineSpawnRate = 60; // Frames between line spawns var difficulty = 1; var isGameActive = true; var scoreEffects = []; var tapEffects = []; var coins = []; // Pool of coin objects var effectIndex = 0; var tapEffectIndex = 0; var coinIndex = 0; var lastJumpScore = 0; var environment; var levelText; var levelTextTimer = 0; var victory; // Victory animation // Create a sky background game.setBackgroundColor(0x87CEEB); // Light blue sky // Initialize the road var road = game.addChild(LK.getAsset('road', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, width: 1200, // Make the road narrower than the full width tint: 0x444444 // Darker gray for asphalt })); // Add road edges/sidewalks var leftSidewalk = game.addChild(LK.getAsset('building', { anchorX: 0, anchorY: 0.5, width: (2048 - road.width) / 2, height: 2732, x: 0, y: 2732 / 2, tint: 0x999999 // Light gray for sidewalk })); var rightSidewalk = game.addChild(LK.getAsset('building', { anchorX: 1, anchorY: 0.5, width: (2048 - road.width) / 2, height: 2732, x: 2048, y: 2732 / 2, tint: 0x999999 // Light gray for sidewalk })); // Initialize score display scoreText = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 5 }); scoreText.anchor.set(0.5, 0); scoreText.y = 50; // Move down slightly from top LK.gui.top.addChild(scoreText); // Initialize level transition text levelText = new Text2('', { size: 100, fill: 0xFFFFFF, stroke: 0x000000, strokeThickness: 8, fontWeight: 'bold' }); levelText.anchor.set(0.5, 0.5); levelText.visible = false; LK.gui.center.addChild(levelText); // Initialize environment environment = new Environment(); // Add game instructions var instructionsText = new Text2('Tap when no lines\nAvoid tapping on lines\nScore 1000 to win', { size: 70, fill: 0xFFFFFF, stroke: 0x800080, strokeThickness: 10, fontWeight: 'bold', align: 'center' }); instructionsText.anchor.set(0.5, 0); instructionsText.y = 150; LK.gui.top.addChild(instructionsText); // Create buildings for city skyline on both sides of the road (not on the road) for (var i = 0; i < 20; i++) { var building = new Building(); // Position buildings only on the sides, ensuring they stay off the road var roadLeftEdge = (2048 - road.width) / 2; var roadRightEdge = 2048 - roadLeftEdge; if (i % 2 === 0) { // Left side only - ensure buildings stay completely on sidewalk var buildingWidth = building.children[0].width; building.x = Math.random() * (roadLeftEdge - buildingWidth / 2); // Left side only, accounting for building width } else { // Right side only - ensure buildings stay completely on sidewalk var buildingWidth = building.children[0].width; building.x = roadRightEdge + Math.random() * (roadLeftEdge - buildingWidth / 2); // Right side only } building.y = Math.random() * 2732; buildings.push(building); game.addChild(building); } // Add trees along the road var trees = []; for (var i = 0; i < 15; i++) { var tree = new Tree(); // Position trees on the sidewalks if (i % 2 === 0) { // Left side trees - further from road than buildings tree.x = (2048 - road.width) / 2 - 250 - Math.random() * 60; } else { // Right side trees - further from road than buildings tree.x = 2048 - (2048 - road.width) / 2 + 250 + Math.random() * 60; } // Distribute trees along the road tree.y = -150 + i * 350 + Math.random() * 200; trees.push(tree); game.addChild(tree); } // Add stores on the sides var stores = []; for (var i = 0; i < 8; i++) { var store = new Store(); // Position stores on the sidewalks, further from the road than trees if (i % 2 === 0) { // Left side stores store.x = (2048 - road.width) / 4; } else { // Right side stores store.x = 2048 - (2048 - road.width) / 4; } // Distribute stores along the road with some spacing store.y = -300 + i * 650 + Math.random() * 300; stores.push(store); game.addChild(store); } // Add street lights var streetLights = []; for (var i = 0; i < 12; i++) { var light = new StreetLight(); // Position lights on the edge of the road if (i % 2 === 0) { // Left side lights light.x = (2048 - road.width) / 2 - 20; } else { // Right side lights light.x = 2048 - (2048 - road.width) / 2 + 20; } // Distribute lights evenly light.y = -200 + i * 400 + i % 2 * 200; streetLights.push(light); game.addChild(light); } // Create car car = new Car(); car.x = 2048 / 2; car.y = 2732 - 400; game.addChild(car); // Bring car to front to make sure it appears on top of lines game.setChildIndex(car, game.children.length - 1); // Create score effects pool for (var i = 0; i < 5; i++) { var effect = new ScoreEffect(); effect.visible = false; scoreEffects.push(effect); game.addChild(effect); } // Create tap effects pool - increased size to handle multiple effects for (var i = 0; i < 10; i++) { var tapEffect = new TapEffect(); tapEffect.visible = false; tapEffects.push(tapEffect); game.addChild(tapEffect); } // Create coin effects pool for (var i = 0; i < 15; i++) { var coin = new Coin(); coin.visible = false; coin.active = false; coins.push(coin); game.addChild(coin); } // Create victory animation at bottom right corner victory = new Victory(); victory.visible = false; victory.x = 2048 - 300; // Right side of screen with margin victory.y = 2732 - 350; // Bottom of screen with margin victory.scale.set(1.2); // Make the victory animation slightly larger game.addChild(victory); // Game click handler game.down = function (x, y, obj) { if (!isGameActive) { return; } // Check if car is already jumping if (!car.jumping) { car.jump(); // Check if car is over a road line var overLine = false; for (var i = 0; i < lines.length; i++) { // Check if the car intersects with any vertical road line if (lines[i].active && car.intersects(lines[i])) { overLine = true; break; } } // Score or penalty based on jump if (overLine) { // Penalty for jumping over a line score = Math.max(0, score - 10); // Show penalty effect var effect = scoreEffects[effectIndex]; effectIndex = (effectIndex + 1) % scoreEffects.length; effect.show(car.x, car.y - 50, false); // Show tap feedback effect (red for penalty) var tapEffect = tapEffects[tapEffectIndex]; tapEffectIndex = (tapEffectIndex + 1) % tapEffects.length; tapEffect.show(x, y, false); // Add multiple red effects for stronger visual feedback for (var j = 0; j < 2; j++) { var extraEffect = tapEffects[tapEffectIndex]; tapEffectIndex = (tapEffectIndex + 1) % tapEffects.length; extraEffect.show(x + (Math.random() * 100 - 50), y + (Math.random() * 100 - 50), false); } // Flash screen red for bad tap LK.effects.flashScreen(0xff0000, 300); } else { // Points for jumping on empty road var pointsGained = 20 * difficulty; score += pointsGained; lastJumpScore = pointsGained; // Show score effect var effect = scoreEffects[effectIndex]; effectIndex = (effectIndex + 1) % scoreEffects.length; effect.show(car.x, car.y - 50, true); // Show tap feedback effect (green for points) var tapEffect = tapEffects[tapEffectIndex]; tapEffectIndex = (tapEffectIndex + 1) % tapEffects.length; tapEffect.show(x, y, true); // Add multiple green effects for stronger visual feedback for (var j = 0; j < 2; j++) { var extraEffect = tapEffects[tapEffectIndex]; tapEffectIndex = (tapEffectIndex + 1) % tapEffects.length; extraEffect.show(x + (Math.random() * 100 - 50), y + (Math.random() * 100 - 50), true); } // Create coin animation effects var coinCount = 3 + Math.floor(Math.random() * 3); // 3-5 coins for (var i = 0; i < coinCount; i++) { // Get a coin from the pool var coin = coins[coinIndex]; coinIndex = (coinIndex + 1) % coins.length; // Only animate if not currently active if (!coin.active) { // Set destination coordinates (score text position) var destX = 2048 / 2; // Center of screen where the score is var destY = 50; // Near the top where the score is // Animate the coin coin.animate(x, y, destX, destY); } } } // Update score display scoreText.setText(Math.round(score)); LK.setScore(Math.round(score)); } }; // Start background music LK.playMusic('bgmusic', { fade: { start: 0, end: 0.4, duration: 1000 } }); // Game update function game.update = function () { if (!isGameActive) { return; } // Update car car.update(); // Update all lines for (var i = lines.length - 1; i >= 0; i--) { lines[i].update(); // We don't penalize for just passing over a line anymore // Only interactions happen when player taps if (!lines[i].scored && lines[i].lastY < car.y && lines[i].y >= car.y) { lines[i].scored = true; // Mark as scored } // Remove inactive lines if (!lines[i].active) { lines[i].destroy(); lines.splice(i, 1); } } // Update all buildings for (var i = 0; i < buildings.length; i++) { buildings[i].speed = 5 * speedMultiplier; buildings[i].update(); } // Update all trees for (var i = 0; i < trees.length; i++) { trees[i].speed = 5 * speedMultiplier; // Changed from 7 to 5 to match building speed trees[i].update(); } // Update all stores for (var i = 0; i < stores.length; i++) { stores[i].speed = 5 * speedMultiplier; stores[i].update(); } // Update all street lights for (var i = 0; i < streetLights.length; i++) { streetLights[i].speed = 5 * speedMultiplier; // Changed from 7 to 5 to match building speed streetLights[i].update(); } // Create new lines at intervals - always come from center of the screen if (LK.ticks % Math.floor(lineSpawnRate / speedMultiplier) === 0) { var line = new Line(); // Position line at the center of the screen line.x = 2048 / 2; // Center X coordinate line.y = -50; line.speed = 15 * speedMultiplier; lines.push(line); game.addChild(line); // Ensure car is always rendered on top of lines game.setChildIndex(car, game.children.length - 1); } // Increase difficulty over time if (LK.ticks % 600 === 0) { // Every 10 seconds difficulty += 0.1; // Speed up game after 500 points, but not too much, and slow down a bit after 800 if (score > 800) { // Cap the speedMultiplier to prevent game from becoming too fast speedMultiplier = Math.min(1.6, 1 + (difficulty - 1) * 0.6); // Further reduced speed cap lineSpawnRate = Math.max(30, 45 - difficulty * 1.5); // More forgiving line spawn rate } else if (score > 500) { // Cap the speedMultiplier to prevent game from becoming too fast speedMultiplier = Math.min(1.5, 1 + (difficulty - 1) * 0.7); // Lower speed cap lineSpawnRate = Math.max(25, 40 - difficulty * 2); // More moderate increase in line spawn rate } else { speedMultiplier = 1 + (difficulty - 1) * 0.5; lineSpawnRate = Math.max(15, 60 - difficulty * 5); } } // Handle environment transitions based on score if (environment.update(Math.round(score))) { var message = environment.apply(road, leftSidewalk, rightSidewalk, game); // Show level transition message if (message) { levelText.setText(message); levelText.visible = true; levelTextTimer = 120; // Show for 2 seconds (120 frames) // Update car and environment elements based on the theme if (environment.current === environment.BEACH) { // Beach theme colors for buildings and objects for (var i = 0; i < buildings.length; i++) { var building = buildings[i]; if (building.children && building.children[0]) { var shade = Math.floor(Math.random() * 30) + 220; // Lighter buildings for beach building.children[0].tint = shade << 16 | shade << 8 | shade; } } } else if (environment.current === environment.JAPAN) { // Japan theme colors for buildings and objects for (var i = 0; i < buildings.length; i++) { var building = buildings[i]; if (building.children && building.children[0]) { // Reddish pagoda style buildings var red = Math.floor(Math.random() * 55) + 200; var green = Math.floor(red * 0.5); var blue = Math.floor(green * 0.5); building.children[0].tint = red << 16 | green << 8 | blue; } } } } } // Update level transition text timer if (levelTextTimer > 0) { levelTextTimer--; if (levelTextTimer === 0) { levelText.visible = false; } } // Check for game over condition if (score < 0) { isGameActive = false; LK.showGameOver(); } // Check for win condition (1000 points to win) if (score >= 1000) { // Only activate victory animation once if (isGameActive) { isGameActive = false; // Ensure victory animation is at the bottom right corner victory.x = 2048 - 300; // Position at bottom right victory.y = 2732 - 350; // Position at bottom right // Start girl clapping animation victory.startClapping(); // Flash screen with celebration colors LK.effects.flashScreen(0xFFD700, 400); // Gold flash // Set a timer to show the victory screen after animation plays LK.setTimeout(function () { LK.showYouWin(); }, 4000); // Show victory after 4 seconds of clapping (extended time) } // Keep updating the victory animation if (victory.active) { victory.update(); } } };
===================================================================
--- original.js
+++ change.js
@@ -758,13 +758,13 @@
// More vibrant pink cherry blossoms
foliageAsset1.width = 170; // Wider, fuller cherry blossom shape
foliageAsset1.height = 170; // Rounder for blossom shape
// Pure pink color for cherry blossoms
- foliageAsset1.tint = 0xFF9FD5; // Vibrant pink cherry blossoms
+ foliageAsset1.tint = 0xFFA6C9; // Vibrant pink cherry blossoms
// Lighter pink for highlights
foliageAsset2.width = 140; // Slightly smaller top layer
foliageAsset2.height = 140; // Rounder for blossom shape
- foliageAsset2.tint = 0xFFCCE6; // Lighter pink highlights
+ foliageAsset2.tint = 0xFFB7DD; // Lighter pink highlights
// Position foliage to look more like cherry blossom
foliage1.y = -100; // Position for traditional cherry blossom tree shape
foliage2.y = -120; // Position for traditional cherry blossom tree shape
} else {