User prompt
Enhance win condition with a girl clapping at the end
User prompt
Add a anime character girl busty clapping at the end when you win โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Enhance win animation add a girl clapping at the end โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Enhance win animation and add a girl clapping for you at the end โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make a better animation for when you win, bring a girl that claps when you win
User prompt
Remove levels from instructions, just show the main goal
User prompt
Do not show levels in instructions, just final goal
User prompt
Add 2 more leves after this same points goal but the enviroment chamge to beach side and then japan
User prompt
Limit the speed after 500 is now imposible when it gets too fast
User prompt
Please make the car to change colors during the game as a neon effect โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make the coins yellow
User prompt
Enhance the coin effect separate it from the main tap effect
User prompt
Please enhance the coins effect
User prompt
Please enhance the coins effect making them dissapear after tap and to be a new yellow coins asset
User prompt
Score effect only when tapping, then dissapear
User prompt
Maje the coins yellow and make them dissapear after tap as well
User prompt
For the tap effect can you make coins going into the counter direction each time that we win points โช๐ก Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please make the trees and the buildings not to overlap
User prompt
Can you make the trees and buildings move at the same speed
Remix started
Copy Line Jump: Road Rhythm
/**** * 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 foliageAsset1.tint = 0x2E8B57; // Sea green palms foliageAsset2.tint = 0x3CB371; // Medium sea green for highlights // Make palm trees slightly taller trunkAsset.height *= 1.2; trunkAsset.width *= 0.8; } else if (environment && environment.current === environment.JAPAN) { // Cherry blossom or Japanese maple trees trunkAsset.tint = 0x8B4513; // Brown trunk var pinkVariation = Math.floor(Math.random() * 30); foliageAsset1.tint = 240 - pinkVariation << 16 | 150 << 8 | 170 + pinkVariation; // Pink cherry blossoms foliageAsset2.tint = 255 << 16 | 182 + Math.floor(Math.random() * 20) << 8 | 193; // Lighter pink highlights } 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 girl character var girl = self.addChild(new Container()); var girlAsset = girl.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 150, height: 300, 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: 150, height: 150, tint: 0xFFD2B0 // Skin tone color }); head.y = -140; // Add girl's hair var hair = self.addChild(new Container()); var hairAsset = hair.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 180, height: 180, tint: 0x8B4513 // Brown hair }); hair.y = -150; // Add girl's dress var dress = self.addChild(new Container()); var dressAsset = dress.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 200, height: 250, tint: 0xFF69B4 // Pink dress }); dress.y = 50; // 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 = -20; leftArm.y = -70; 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 = 20; rightArm.y = -70; rightArm.rotation = Math.PI / 4; // Angle up // Add girl's face (simple smile) var smile = self.addChild(new Container()); var smileAsset = smile.attachAsset('building', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 20, tint: 0xFF5555 // Red smile }); smile.y = -120; // Create eyes var leftEye = self.addChild(new Container()); var leftEyeAsset = leftEye.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 20, tint: 0x000000 // Black eyes }); leftEye.x = -30; leftEye.y = -150; var rightEye = self.addChild(new Container()); var rightEyeAsset = rightEye.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 20, height: 20, tint: 0x000000 // Black eyes }); rightEye.x = 30; rightEye.y = -150; // Add sparkle effects around the girl var sparkles = []; for (var i = 0; i < 8; i++) { var sparkle = self.addChild(new Container()); var sparkleAsset = sparkle.attachAsset('scoreEffect', { anchorX: 0.5, anchorY: 0.5, width: 30, height: 30, tint: 0xFFFFFF, alpha: 0 }); // Position sparkles in a circle around the girl var angle = i / 8 * Math.PI * 2; var radius = 200; sparkle.x = Math.cos(angle) * radius; sparkle.y = Math.sin(angle) * radius; sparkles.push(sparkle); } // 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 if (!self.message) { self.message = new Text2('Congratulations!', { size: 100, fill: 0xFFFF00, stroke: 0x800080, strokeThickness: 8, fontWeight: 'bold' }); self.message.anchor.set(0.5, 0.5); self.message.y = -300; self.addChild(self.message); // Add second congratulation message self.subMessage = new Text2('You Win!', { size: 80, fill: 0xFFFFFF, stroke: 0x800080, strokeThickness: 6, fontWeight: 'bold' }); self.subMessage.anchor.set(0.5, 0.5); self.subMessage.y = -220; self.addChild(self.subMessage); } // Flash confetti effect around the screen LK.effects.flashScreen(0xFFFFFF, 300); // Animate sparkles using tween for (var i = 0; i < sparkles.length; i++) { var delay = i * 200; // Stagger the sparkle animations LK.setTimeout(function (sparkle) { return function () { // Animate sparkle to fade in, grow, and fade out tween(sparkle, { alpha: 0.8, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(sparkle, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 700, easing: tween.easeIn }); } }); }; }(sparkles[i]), delay); } // Create coin shower effect for confetti LK.setTimeout(function () { for (var i = 0; i < 20; i++) { var coin = coins[Math.floor(Math.random() * coins.length)]; if (!coin.active) { // Random position at top of screen var startX = Math.random() * 2048; var startY = -100; // Random position on screen var destX = Math.random() * 2048; var destY = Math.random() * 2732; // Animate coin as confetti coin.animate(startX, startY, destX, destY); } } }, 300); // Create more confetti effects with delay LK.setTimeout(function () { for (var i = 0; i < 20; 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); } } }, 1000); // Third wave of confetti for even more celebration LK.setTimeout(function () { for (var i = 0; i < 20; 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); } } }, 1800); // Animate entry with bounce effect self.alpha = 0; self.scale.set(0.2); tween(self, { alpha: 1.0, scaleX: 1.1, scaleY: 1.1 }, { duration: 400, easing: tween.easeOut, onFinish: function onFinish() { // Bounce back to normal size tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200, easing: tween.easeInOut }); } }); }; // Stop clapping animation self.stopClapping = function () { self.clapping = false; self.active = false; // Animate exit tween(self, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { self.visible = false; } }); }; // Animation update self.update = function () { if (!self.clapping) { return; } self.animationFrame++; // Enhanced clapping animation if (self.animationFrame % 30 < 15) { // Hands moving apart leftArm.rotation = -Math.PI / 4; rightArm.rotation = Math.PI / 4; // Rotate slightly side to side for more natural movement self.rotation = Math.sin(self.animationFrame * 0.1) * 0.05; } else { // Hands clapping together leftArm.rotation = -Math.PI / 8; rightArm.rotation = Math.PI / 8; // 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 }); // Create a quick flash effect when hands meet LK.setTimeout(function () { LK.effects.flashObject(leftArm, 0xFFFFFF, 200); LK.effects.flashObject(rightArm, 0xFFFFFF, 200); }, 0); } } // Improved bouncing animation - more natural up and down movement self.y = 2732 / 2 + Math.sin(self.animationFrame * 0.05) * 20; // Animate head nodding slightly head.rotation = Math.sin(self.animationFrame * 0.08) * 0.1; hair.rotation = Math.sin(self.animationFrame * 0.08 + 0.5) * 0.12; // Slightly delayed to look more natural // Animate sparkles to twinkle periodically for (var i = 0; i < sparkles.length; i++) { if (self.animationFrame % 120 === i * 15) { var sparkle = sparkles[i]; tween(sparkle, { alpha: 0.8, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(sparkle, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 700, easing: tween.easeIn }); } }); } } // Message pulsing animation - improved to look more celebratory if (self.message) { self.message.scale.set(1.0 + Math.sin(self.animationFrame * 0.05) * 0.1); // Add color cycling to message text for more festive look if (self.animationFrame % 10 === 0) { // Cycle through festive colors var hue = self.animationFrame * 2 % 360; var color = self.hslToRgb(hue / 360, 1, 0.5); self.message.style.fill = color; } } // Make sub-message pulse out of phase with main message if (self.subMessage) { self.subMessage.scale.set(1.0 + Math.sin(self.animationFrame * 0.05 + Math.PI) * 0.1); } }; // Helper function to convert HSL to RGB for color cycling self.hslToRgb = function (h, s, l) { var r, g, b; if (s === 0) { r = g = b = l; // achromatic } else { var hue2rgb = function hue2rgb(p, q, t) { if (t < 0) { t += 1; } if (t > 1) { t -= 1; } if (t < 1 / 6) { return p + (q - p) * 6 * t; } if (t < 1 / 2) { return q; } if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; } return p; }; var q = l < 0.5 ? l * (1 + s) : l + s - l * s; var p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255); }; 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 victory = new Victory(); victory.visible = false; victory.x = 2048 / 2; victory.y = 2732 / 2; 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; // Start girl clapping animation victory.startClapping(); // Set a timer to show the victory screen after animation plays LK.setTimeout(function () { LK.showYouWin(); }, 5000); // Show victory after 5 seconds of clapping for longer celebration } // Keep updating the victory animation if (victory.active) { victory.update(); // Create occasional coin burst effects during victory celebration if (LK.ticks % 60 === 0) { // Random position around the girl var burstX = 2048 / 2 + (Math.random() * 400 - 200); var burstY = 2732 / 2 + (Math.random() * 400 - 200); // Create small burst of coins for (var i = 0; i < 5; i++) { var coin = coins[Math.floor(Math.random() * coins.length)]; if (!coin.active) { coin.animate(burstX, burstY, burstX + (Math.random() * 200 - 100), burstY - Math.random() * 300); } } } } } };
===================================================================
--- original.js
+++ change.js
@@ -762,57 +762,47 @@
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', {
+ // Create girl character
+ var girl = self.addChild(new Container());
+ var girlAsset = girl.attachAsset('building', {
anchorX: 0.5,
anchorY: 0.5,
- width: 180,
- height: 250,
+ width: 150,
+ height: 300,
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,
+ width: 150,
+ height: 150,
tint: 0xFFD2B0 // Skin tone color
});
- head.y = -160;
- // Add girl's hair - anime style with large eyes
+ head.y = -140;
+ // Add girl's hair
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
+ width: 180,
+ height: 180,
+ tint: 0x8B4513 // Brown hair
});
- hair.y = -160;
- // Add girl's outfit - typical anime schoolgirl style
- var outfit = self.addChild(new Container());
- var outfitAsset = outfit.attachAsset('building', {
+ hair.y = -150;
+ // Add girl's dress
+ var dress = self.addChild(new Container());
+ var dressAsset = dress.attachAsset('building', {
anchorX: 0.5,
anchorY: 0.5,
- width: 220,
- height: 150,
- tint: 0x1E90FF // Bright blue outfit
+ width: 200,
+ height: 250,
+ tint: 0xFF69B4 // Pink dress
});
- 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;
+ dress.y = 50;
// Add girl's left arm (will be animated for clapping)
var leftArm = self.addChild(new Container());
var leftArmAsset = leftArm.attachAsset('building', {
anchorX: 1.0,
@@ -820,10 +810,10 @@
width: 100,
height: 30,
tint: 0xFFD2B0 // Skin tone
});
- leftArm.x = -50;
- leftArm.y = -50;
+ leftArm.x = -20;
+ leftArm.y = -70;
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', {
@@ -832,73 +822,61 @@
width: 100,
height: 30,
tint: 0xFFD2B0 // Skin tone
});
- rightArm.x = 50;
- rightArm.y = -50;
+ rightArm.x = 20;
+ rightArm.y = -70;
rightArm.rotation = Math.PI / 4; // Angle up
- // Add girl's face with anime style (larger eyes, small nose)
+ // Add girl's face (simple smile)
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
+ width: 80,
+ height: 20,
+ tint: 0xFF5555 // Red smile
});
- smile.y = -140;
- // Create eyes - large anime style eyes
+ smile.y = -120;
+ // Create 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
+ width: 20,
+ height: 20,
+ tint: 0x000000 // Black eyes
});
leftEye.x = -30;
- leftEye.y = -170;
+ leftEye.y = -150;
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
+ width: 20,
+ height: 20,
+ tint: 0x000000 // Black 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;
+ rightEye.y = -150;
+ // Add sparkle effects around the girl
+ var sparkles = [];
+ for (var i = 0; i < 8; i++) {
+ var sparkle = self.addChild(new Container());
+ var sparkleAsset = sparkle.attachAsset('scoreEffect', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 30,
+ height: 30,
+ tint: 0xFFFFFF,
+ alpha: 0
+ });
+ // Position sparkles in a circle around the girl
+ var angle = i / 8 * Math.PI * 2;
+ var radius = 200;
+ sparkle.x = Math.cos(angle) * radius;
+ sparkle.y = Math.sin(angle) * radius;
+ sparkles.push(sparkle);
+ }
// Starting animation state
self.clapping = false;
self.animationFrame = 0;
// Property to control visibility
@@ -907,23 +885,61 @@
self.startClapping = function () {
self.visible = true;
self.active = true;
self.clapping = true;
- // Create happy message with anime style text
+ // Create happy message
if (!self.message) {
- self.message = new Text2('Sugoi! You Win!', {
+ self.message = new Text2('Congratulations!', {
size: 100,
- fill: 0xFF00FF,
- stroke: 0x4B0082,
+ fill: 0xFFFF00,
+ stroke: 0x800080,
strokeThickness: 8,
fontWeight: 'bold'
});
self.message.anchor.set(0.5, 0.5);
self.message.y = -300;
self.addChild(self.message);
+ // Add second congratulation message
+ self.subMessage = new Text2('You Win!', {
+ size: 80,
+ fill: 0xFFFFFF,
+ stroke: 0x800080,
+ strokeThickness: 6,
+ fontWeight: 'bold'
+ });
+ self.subMessage.anchor.set(0.5, 0.5);
+ self.subMessage.y = -220;
+ self.addChild(self.subMessage);
}
// Flash confetti effect around the screen
LK.effects.flashScreen(0xFFFFFF, 300);
+ // Animate sparkles using tween
+ for (var i = 0; i < sparkles.length; i++) {
+ var delay = i * 200; // Stagger the sparkle animations
+ LK.setTimeout(function (sparkle) {
+ return function () {
+ // Animate sparkle to fade in, grow, and fade out
+ tween(sparkle, {
+ alpha: 0.8,
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ tween(sparkle, {
+ alpha: 0,
+ scaleX: 0.5,
+ scaleY: 0.5
+ }, {
+ duration: 700,
+ easing: tween.easeIn
+ });
+ }
+ });
+ };
+ }(sparkles[i]), delay);
+ }
// Create coin shower effect for confetti
LK.setTimeout(function () {
for (var i = 0; i < 20; i++) {
var coin = coins[Math.floor(Math.random() * coins.length)];
@@ -951,45 +967,57 @@
coin.animate(startX, startY, destX, destY);
}
}
}, 1000);
- // Anime-style entrance animation with bounce effect
+ // Third wave of confetti for even more celebration
+ LK.setTimeout(function () {
+ for (var i = 0; i < 20; 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);
+ }
+ }
+ }, 1800);
+ // Animate entry with bounce effect
self.alpha = 0;
self.scale.set(0.2);
tween(self, {
alpha: 1.0,
- scaleX: 1.2,
- scaleY: 1.2
+ scaleX: 1.1,
+ scaleY: 1.1
}, {
duration: 400,
- easing: tween.elasticOut,
+ easing: tween.easeOut,
onFinish: function onFinish() {
+ // Bounce back to normal size
tween(self, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 200,
- easing: tween.easeOut
+ easing: tween.easeInOut
});
}
});
};
// Stop clapping animation
self.stopClapping = function () {
self.clapping = false;
self.active = false;
- // Animate exit with spin
+ // Animate exit
tween(self, {
alpha: 0,
- scaleX: 0.2,
- scaleY: 0.2,
- rotation: Math.PI * 2
+ scaleX: 0.5,
+ scaleY: 0.5
}, {
duration: 500,
easing: tween.easeIn,
onFinish: function onFinish() {
self.visible = false;
- self.rotation = 0;
}
});
};
// Animation update
@@ -997,92 +1025,108 @@
if (!self.clapping) {
return;
}
self.animationFrame++;
- // Anime-style clapping animation with exaggerated movements
+ // Enhanced clapping animation
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;
+ // Hands moving apart
+ leftArm.rotation = -Math.PI / 4;
+ rightArm.rotation = Math.PI / 4;
+ // Rotate slightly side to side for more natural movement
+ self.rotation = Math.sin(self.animationFrame * 0.1) * 0.05;
} else {
- // Hands clapping together with anime exaggeration
- leftArm.rotation = -Math.PI / 10;
- rightArm.rotation = Math.PI / 10;
+ // Hands clapping together
+ leftArm.rotation = -Math.PI / 8;
+ rightArm.rotation = Math.PI / 8;
// 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
+ // Create a quick flash effect when hands meet
+ LK.setTimeout(function () {
+ LK.effects.flashObject(leftArm, 0xFFFFFF, 200);
+ LK.effects.flashObject(rightArm, 0xFFFFFF, 200);
+ }, 0);
+ }
+ }
+ // Improved bouncing animation - more natural up and down movement
+ self.y = 2732 / 2 + Math.sin(self.animationFrame * 0.05) * 20;
+ // Animate head nodding slightly
+ head.rotation = Math.sin(self.animationFrame * 0.08) * 0.1;
+ hair.rotation = Math.sin(self.animationFrame * 0.08 + 0.5) * 0.12; // Slightly delayed to look more natural
+ // Animate sparkles to twinkle periodically
+ for (var i = 0; i < sparkles.length; i++) {
+ if (self.animationFrame % 120 === i * 15) {
+ var sparkle = sparkles[i];
+ tween(sparkle, {
+ alpha: 0.8,
+ scaleX: 1.5,
+ scaleY: 1.5
}, {
- duration: 100,
+ duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
- tween(bust, {
- y: -70,
- scaleX: 1.0,
- scaleY: 1.0
+ tween(sparkle, {
+ alpha: 0,
+ scaleX: 0.5,
+ scaleY: 0.5
}, {
- duration: 200,
- easing: tween.elasticOut
+ duration: 700,
+ easing: tween.easeIn
});
}
});
}
}
- // 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
+ // Message pulsing animation - improved to look more celebratory
if (self.message) {
- 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
+ self.message.scale.set(1.0 + Math.sin(self.animationFrame * 0.05) * 0.1);
+ // Add color cycling to message text for more festive look
+ if (self.animationFrame % 10 === 0) {
+ // Cycle through festive colors
+ var hue = self.animationFrame * 2 % 360;
+ var color = self.hslToRgb(hue / 360, 1, 0.5);
+ self.message.style.fill = color;
}
}
- // 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
- });
+ // Make sub-message pulse out of phase with main message
+ if (self.subMessage) {
+ self.subMessage.scale.set(1.0 + Math.sin(self.animationFrame * 0.05 + Math.PI) * 0.1);
+ }
+ };
+ // Helper function to convert HSL to RGB for color cycling
+ self.hslToRgb = function (h, s, l) {
+ var r, g, b;
+ if (s === 0) {
+ r = g = b = l; // achromatic
+ } else {
+ var hue2rgb = function hue2rgb(p, q, t) {
+ if (t < 0) {
+ t += 1;
}
- });
- tween(rightEyeAsset, {
- height: 5
- }, {
- duration: 100,
- onFinish: function onFinish() {
- tween(rightEyeAsset, {
- height: 50
- }, {
- duration: 100
- });
+ if (t > 1) {
+ t -= 1;
}
- });
+ if (t < 1 / 6) {
+ return p + (q - p) * 6 * t;
+ }
+ if (t < 1 / 2) {
+ return q;
+ }
+ if (t < 2 / 3) {
+ return p + (q - p) * (2 / 3 - t) * 6;
+ }
+ return p;
+ };
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
+ var p = 2 * l - q;
+ r = hue2rgb(p, q, h + 1 / 3);
+ g = hue2rgb(p, q, h);
+ b = hue2rgb(p, q, h - 1 / 3);
}
+ return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255);
};
return self;
});
@@ -1501,12 +1545,25 @@
victory.startClapping();
// Set a timer to show the victory screen after animation plays
LK.setTimeout(function () {
LK.showYouWin();
- }, 3000); // Show victory after 3 seconds of clapping
+ }, 5000); // Show victory after 5 seconds of clapping for longer celebration
}
// Keep updating the victory animation
if (victory.active) {
victory.update();
+ // Create occasional coin burst effects during victory celebration
+ if (LK.ticks % 60 === 0) {
+ // Random position around the girl
+ var burstX = 2048 / 2 + (Math.random() * 400 - 200);
+ var burstY = 2732 / 2 + (Math.random() * 400 - 200);
+ // Create small burst of coins
+ for (var i = 0; i < 5; i++) {
+ var coin = coins[Math.floor(Math.random() * coins.length)];
+ if (!coin.active) {
+ coin.animate(burstX, burstY, burstX + (Math.random() * 200 - 100), burstY - Math.random() * 300);
+ }
+ }
+ }
}
}
};
\ No newline at end of file