Code edit (1 edits merged)
Please save this source code
User prompt
1. Newspaper should fly in an arch, not a straight line Right now the Newspaper.update() just adds velocity + gravity. That makes it fall but doesn’t give a true arc. We can make it look more natural by: Applying initial velocity from slingshot. Letting gravity curve the path downward. Adding perspective scaling (we already did). Your Newspaper.update already has gravity (self.velocityY += self.gravity). That gives a parabola, but because of the launch angle calculation, it might look flat. 👉 We’ll tweak launch so it always has a negative vertical velocity (so it starts by going “up” and then curves down): function shootNewspaper(power, angle) { var newspaper = new Newspaper(); newspaper.x = 1024; // launch origin newspaper.y = 2200; var radians = angle * Math.PI / 180; newspaper.velocityX = Math.cos(radians) * power; newspaper.velocityY = Math.sin(radians) * power * -1; // invert to go up first newspapers.push(newspaper); game.addChild(newspaper); LK.getSound('paperThrow').play(); } ✅ Now every throw starts by flying upward and then arcs down due to gravity, instead of straight flat throws. 2. Sun arc should stay in the “sky zone” Right now the sun baseline is too low (sunBaseY = 1400), meaning it overlaps the mailbox zone. Let’s move it higher, so it travels above. Mailbox zone ends ~ at y = 1200. We want the sun baseline higher, e.g. ~ y = 600. We also adjust sunArcHeight so it doesn’t clip offscreen.Update in game.update: sun.x = sunStartX + (sunEndX - sunStartX) * timeProgress; sun.y = sunBaseY - Math.sin(timeProgress * Math.PI) * sunArcHeight; 3. Mailboxes layered correctly with house Currently you game.addChild(mailbox) after house, so depending on spawn order, mailboxes may appear behind or on top. We want: Houses in the back. Mailboxes always in front of the house, but still behind the newspaper. 👉 After creating both, explicitly set the mailbox’s index: function createMailbox() { if (!currentHouse) return; var mailbox = new Mailbox(); mailbox.x = 400 + Math.random() * 1200; mailbox.y = mailboxZoneY + (Math.random() * 200 - 100); // Flip horizontally mailbox.scaleX = (Math.random() < 0.5) ? -1 : 1; mailboxes.push(mailbox); game.addChild(mailbox); // Ensure mailbox is drawn in front of house game.setChildIndex(mailbox, game.getChildIndex(currentHouse) + 1); return mailbox; } } ✅ Mailbox always visually sits “in the yard” in front of the house, never hidden or floating above everything. 📌 Summary of fixes Newspaper now always arcs (launch upward, gravity pulls down). Sun travels across the sky zone, never clipping mailbox area or screen edge. Mailboxes always layered in front of the house, never hidden behind or incorrectly layered. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
// Draw sun trajectory arc var sunPath = new Container(); var pathGraphics = sunPath.attachAsset('trajectory', { width: 4, height: 4, color: 0xffff00, anchorX: 0.5, anchorY: 0.5 }); game.addChild(sunPath); function drawSunPath() { for (var t = 0; t <= 1; t += 0.05) { var x = sunStartX + (sunEndX - sunStartX) * t; var y = sunBaseY - Math.sin(t * Math.PI) * sunArcHeight; var dot = game.addChild(LK.getAsset('trajectory', { width: 6, height: 6, color: 0xffff66, // pale yellow anchorX: 0.5, anchorY: 0.5 })); dot.x = x; dot.y = y; dot.alpha = 0.3; // semi-transparent } } drawSunPath(); 3. Replace the old sun movement code in game.update sun.x = sunStartX + (sunEndX - sunStartX) * timeProgress; sun.y = sunBaseY - Math.sin(timeProgress * Math.PI) * sunArcHeight; ✅ With this edit: The sun now follows a realistic parabolic arc. A faint dotted golden trajectory line is visible from sunrise → sunset. Players see how much time is left by watching the sun move across its track. 1. Mailbox random position + flip Right now, createMailbox() positions the mailbox close to the house with only a little randomness. Let’s widen that randomization so it can appear anywhere in the mailbox zone, and add a 50% chance to flip horizontally. function createMailbox() { if (!currentHouse) return; var mailbox = new Mailbox(); // Place randomly within mailbox zone bounds mailbox.x = 400 + Math.random() * 1200; // stays in safe horizontal range mailbox.y = mailboxZoneY + (Math.random() * 200 - 100); // Random horizontal flip if (Math.random() < 0.5) { mailbox.scaleX = -1; } else { mailbox.scaleX = 1; } mailboxes.push(mailbox); game.addChild(mailbox); return mailbox; } 2. Newspaper shrinking as it travels The newspaper is currently a static size. Let’s scale it based on how far it has traveled from its starting Y position — smaller as it rises, then stabilizing. Inside the Newspaper.update function, add: self.startY = self.startY || self.y; // record starting Y once // scale shrinks as it moves upward var travel = self.startY - self.y; // how high it has gone var scaleFactor = Math.max(0.3, 1 - travel / 2000); graphics.scaleX = graphics.scaleY = scaleFactor; ✅ This gives the illusion of depth: the farther “away” the newspaper goes, the smaller it looks. Minimum 30% so it doesn’t disappear. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
1. Define the sun’s arc We’ll treat the sun’s movement as a parametric equation over timeProgress (0 → 1): X moves left → right across the screen. Y follows a smooth arch (using a sine curve). // Sun path parameters var sunStartX = 100; // left side var sunEndX = 1948; // right side var sunBaseY = 1400; // baseline (ground level-ish) var sunArcHeight = 600; // how high the sun climbs ✅ This makes the sun rise in the east, reach peak at noon, and set in the west. 2. Draw the arc line once at game start We’ll create a path with small points and render it as a curve for the sun to “ride.” ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
👉 The simplest fix is to flip deltaX before computing the angle: // In game.up var deltaX = aimStartX - x; // flip X so left/right feels natural var deltaY = aimStartY - y; // keep inverted Y pull aimPower = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1; aimAngle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; And the same adjustment in updateTrajectory: var deltaX = startX - endX; // flip X for preview var deltaY = startY - endY; // inverted Y var power = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1; var angle = Math.atan2(deltaY, deltaX); 2. End turn if the player misses Right now turns only end on a timer if no newspapers are active. We want: one throw per turn → if it misses, turn ends. // Inside game.update, after checking mailbox collisions if (newspaper.active) { // Newspaper went off screen without hitting if (newspaper.x > 2048 || newspaper.y > 2732) { newspaper.active = false; // End the turn if no hit occurred removeHouse(currentHouse, function () { currentHouse = null; // Clear mailboxes for this turn for (var i = mailboxes.length - 1; i >= 0; i--) { mailboxes[i].destroy(); mailboxes.splice(i, 1); } }); } } And after a successful hit, we also end the turn: if (!mailbox.hit && newspaper.intersects(mailbox)) { var distance = Math.sqrt(Math.pow(newspaper.x - mailbox.x, 2) + Math.pow(newspaper.y - mailbox.y, 2)); var score = calculateScore(distance); pennies += score; pennyText.setText('Pennies: ' + pennies); mailbox.hit = true; newspaper.active = false; // Flash + sound LK.effects.flashObject(mailbox, 0x00ff00, 500); LK.getSound('mailboxHit').play(); // End the turn after scoring removeHouse(currentHouse, function () { currentHouse = null; for (var i = mailboxes.length - 1; i >= 0; i--) { mailboxes[i].destroy(); mailboxes.splice(i, 1); } }); break; } 3. Loop summary with your rules Each turn starts with a house sliding in and a new mailbox placed. Player pulls down to aim, directions feel natural. They get one throw per turn. If they hit, they get 1–5 pennies and the turn ends. If they miss, they get 0 and the turn ends. Game continues until: 650 pennies → win Sun finishes arc → lose ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
✅ Fix → remove the auto‐scroll from House.update and instead tween houses in/out as discussed. var House = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('house', { anchorX: 0.5, anchorY: 1.0 }); self.active = true; // Remove scrolling from update, handled by tweens self.update = function () {}; return self; }); ensure house graphic is spawning in front of the mailbox zone ✅ Fix → remove the scrollSpeed from mailbox update, and pin them relative to the house when created: var Mailbox = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('mailbox', { anchorX: 0.5, anchorY: 1.0 }); self.hit = false; self.active = true; self.update = function () {}; // no auto-scrolling return self; }); function createMailbox(house) { var mailbox = new Mailbox(); mailbox.x = house.x + 200; // offset to right of house mailbox.y = mailboxZoneY + 250; // centered in zone mailboxes.push(mailbox); game.addChild(mailbox); return mailbox; } Invert slingshot controls var deltaX = x - aimStartX; var deltaY = aimStartY - y; // invert Y pull aimPower = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1; aimAngle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; And in updateTrajectory: var deltaX = endX - startX; var deltaY = startY - endY; // invert Y var power = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1; var angle = Math.atan2(deltaY, deltaX); ✅ With these edits: Houses will spawn and stay centered in the mailbox zone. Mailboxes will be attached near the house, not flying away. Slingshot now feels like a real slingshot (pull down to launch up). ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
1. Define new zone shapes in the Assets section: LK.init.shape('streetZone', {width: 2048, height: 700, color: 0x228B22, shape:'box'}); // green LK.init.shape('mailboxZone', {width: 2048, height: 500, color: 0xFF8C00, shape:'box'}); // orange 2. Update your zone creation code: // Street zone background var streetZone = game.addChild(LK.getAsset('streetZone', { anchorX: 0.5, anchorY: 0.5 })); streetZone.x = 1024; streetZone.y = streetZoneY; // Mailbox zone background var mailboxZone = game.addChild(LK.getAsset('mailboxZone', { anchorX: 0.5, anchorY: 0.5 })); mailboxZone.x = 1024; mailboxZone.y = mailboxZoneY; This will: Give the street zone its own proper green rectangle. Give the mailbox zone its own proper orange rectangle. Free up the trajectory asset so it only shows up as actual trajectory dots instead of giant background blocks. center sling shot at bottom half of screen in "street zone" sounds more like a turn-based cycle: At the start of a turn → one house slides in from the right edge into the middle of the mailbox zone. During the turn → the house stays centered. Mailbox spawns relative to it (still randomized vertically if you want). At the end of the turn → the house slides out to the left, disappears, and a new house comes in from the right. That means we’ll change createHouse() and add a house cycle manager instead of spawning houses randomly. Step 1 – Update createHouse function createHouse() { var house = new House(); // Start just off-screen to the right house.x = 2200; house.y = mailboxZoneY + 250; // roughly center mailbox zone houses.push(house); game.addChild(house); // Tween it into center of mailbox zone tween.to(house, { x: 1024 }, 1000, "easeOutQuad"); return house; } Step 2 – Add removeHouse for end-of-turn function removeHouse(house, onComplete) { tween.to(house, { x: -200 }, 1000, "easeInQuad", function () { house.destroy(); houses.splice(houses.indexOf(house), 1); if (onComplete) onComplete(); }); } Step 3 – Manage house cycle per turn // End of turn logic if (houses.length > 0) { var currentHouse = houses[0]; removeHouse(currentHouse, function () { // After old house slides out, create a new one createHouse(); }); } else { // No house yet, just spawn one createHouse(); } Step 4 – Remove house spawning from update loop ✅ With these edits: At start of game → one house slides in and centers in mailbox zone. At end of each turn → it slides left off-screen, then the next house slides in from the right. You control exactly one house at a time (no clutter, no overlapping). ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
📰 Newspaper placement & visibility Start newspaper at bottom-center of screen (instead of mothman’s position). Give enough room below for pull-back. Make sure it always attaches its graphics so it’s visible during flight. 👻 Hide Mothman Don’t render the mothman during gameplay. Keep logic intact if needed, but remove/hide his ellipse. 🏠 House duplication fix The extra “street zone” green rectangle was reusing the house shape as a placeholder background — we’ll replace that with a simple colored rectangle so it doesn’t double as a house. Limit houses to spawn only once per turn. /**** * Zones (fixed) ****/ // Street zone (green bar at bottom, no house duplication) var streetZone = new Graphics(); streetZone.beginFill(0x228B22); // green streetZone.drawRect(0, 0, 2048, 700); streetZone.endFill(); streetZone.x = 0; streetZone.y = 1800; game.addChild(streetZone); // Mailbox zone (orange band in middle) var mailboxZone = new Graphics(); mailboxZone.beginFill(0xFF8C00); // orange mailboxZone.drawRect(0, 0, 2048, 500); mailboxZone.endFill(); mailboxZone.x = 0; mailboxZone.y = 1200; game.addChild(mailboxZone); /**** * House & Mailbox Placement ****/ function createHouse() { var house = new House(); house.x = 2100; house.y = 1000; // fixed: only one row of houses houses.push(house); game.addChild(house); } function createMailbox() { var mailbox = new Mailbox(); mailbox.x = 2100; mailbox.y = 1200 + (Math.random() * 200 - 100); // stays in orange band mailboxes.push(mailbox); game.addChild(mailbox); } /**** * Slingshot + Newspaper ****/ // Hide mothman (no sprite during gameplay) mothman.visible = false; // Newspaper starts at bottom center function shootNewspaper(power, angle) { var newspaper = new Newspaper(); newspaper.x = 1024; // center of screen newspaper.y = 2200; // bottom, with room to pull back var radians = angle * Math.PI / 180; newspaper.velocityX = Math.cos(radians) * power; newspaper.velocityY = Math.sin(radians) * power; newspapers.push(newspaper); game.addChild(newspaper); // ensure added after zones so visible LK.getSound('paperThrow').play(); } ✅ Fix Summary Newspaper now launches from bottom center and is always visible. Mothman hidden. Street zone no longer reuses house sprite → prevents duplicate houses. House only spawns once per turn in the correct zone.
User prompt
/**** * Zone Setup ****/ // Define Y positions for zones (adjust as needed to match your reference image) var streetZoneY = 2000; // Green bottom zone where slingshot sits var mailboxZoneY = 1200; // Orange middle zone where mailbox spawns var houseZoneY = 1000; // Houses aligned just above mailbox zone // Ground reference (for houses) var groundY = 2400; /**** * Visual Zone Placeholders ****/ // Street zone background (green) var streetZone = game.addChild(LK.getAsset('house', { width: 2048, height: 700, color: 0x228B22, // green anchorX: 0.5, anchorY: 0.5 })); streetZone.x = 1024; streetZone.y = streetZoneY; // Mailbox zone background (orange) var mailboxZone = game.addChild(LK.getAsset('house', { width: 2048, height: 500, color: 0xFF8C00, // orange anchorX: 0.5, anchorY: 0.5 })); mailboxZone.x = 1024; mailboxZone.y = mailboxZoneY; /**** * House and Mailbox Placement ****/ function createHouse() { var house = new House(); house.x = 2100; house.y = houseZoneY + 200; // align house to top of mailbox zone houses.push(house); game.addChild(house); } function createMailbox() { var mailbox = new Mailbox(); mailbox.x = 2100; // Randomize Y position only within mailbox zone mailbox.y = mailboxZoneY + (Math.random() * 200 - 100); mailboxes.push(mailbox); game.addChild(mailbox); } /**** * Slingshot + Aiming ****/ // Place slingshot in street zone slingshot = game.addChild(new Container()); var slingshotGraphics = slingshot.attachAsset('slingshot', { anchorX: 0.5, anchorY: 0.5 }); slingshot.x = 200; slingshot.y = streetZoneY + 100; // Slingshot bands (for stretch feedback) var bandLeft = new Graphics(); var bandRight = new Graphics(); game.addChild(bandLeft); game.addChild(bandRight); function updateSlingshotBands(endX, endY) { bandLeft.clear(); bandRight.clear(); bandLeft.lineStyle(6, 0x654321); bandRight.lineStyle(6, 0x654321); bandLeft.moveTo(slingshot.x - 20, slingshot.y - 20); bandLeft.lineTo(endX, endY); bandRight.moveTo(slingshot.x + 20, slingshot.y - 20); bandRight.lineTo(endX, endY); } // Shooting logic game.down = function (x, y, obj) { if (y > streetZoneY - 200) { // only allow aiming in street zone isAiming = true; aimStartX = x; aimStartY = y; } }; game.move = function (x, y, obj) { if (isAiming) { updateTrajectory(mothman.x, mothman.y, x, y); updateSlingshotBands(x, y); } }; game.up = function (x, y, obj) { if (isAiming) { var deltaX = x - aimStartX; var deltaY = y - aimStartY; aimPower = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1; aimAngle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; if (aimPower > 2) { shootNewspaper(aimPower, aimAngle); } isAiming = false; // Clear trajectory + bands for (var i = 0; i < trajectoryDots.length; i++) { trajectoryDots[i].destroy(); } trajectoryDots = []; bandLeft.clear(); bandRight.clear(); } }; ✅ What this update does: Creates green street zone and orange mailbox zone like your image. Houses sit above the mailbox zone, and mailboxes spawn randomized within the orange zone. Slingshot is fixed in the street zone. Player can click + drag to stretch (shows rubber bands) and see a trajectory preview, then release to fire.
Code edit (1 edits merged)
Please save this source code
User prompt
Mothman's Pumpkin Spice Paper Route
Initial prompt
Game Concept: A 2D side-scrolling aiming game where the player controls Mothman delivering newspapers. The goal is to earn 650 pennies ($6.50) to buy a Pumpkin Spice Latte. Core Gameplay Loop (Turn Structure): Scene Setup: The game background scrolls from right to left, simulating Mothman moving down a suburban street. A new house appears each turn. A mailbox is randomly placed somewhere on the lawn area in front of the house. Player Action: The player uses a slingshot mechanic located at the bottom half of the screen. The player pulls back to set the power and angle of the newspaper throw, then releases to launch it. Result: If the newspaper hits the mailbox, the player earns 1–5 pennies depending on accuracy (5 pennies for a perfect shot, 1 penny for barely hitting). If the player misses, no pennies are earned, and the turn ends. Progression: The game immediately scrolls to the next house for another turn. This continues until either: The player collects 650 pennies (win condition). Or the time runs out (lose condition). Win / Lose Conditions: Win: Player collects 650 pennies before time runs out. Lose: The in-game day ends (time limit reached) without earning 650 pennies. Time System: The time limit is one full day. At the start of the level, the sun rises on the left side of the screen. As turns progress, the sun moves in an arc across the sky. When the sun sets on the right side of the screen, the day ends and the game is over. Additional Notes: Perspective: Player’s view is from street level, looking toward houses as they pass by. Currency Representation: Each penny is counted individually; total displayed on the screen. Difficulty Scaling (optional): Mailbox positions can become smaller or more randomized as time goes on.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var House = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('house', { anchorX: 0.5, anchorY: 1.0 }); self.active = true; // Remove scrolling from update, handled by tweens self.update = function () {}; return self; }); var Mailbox = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('mailbox', { anchorX: 0.5, anchorY: 1.0 }); self.hit = false; self.active = true; self.update = function () {}; // no auto-scrolling return self; }); var Newspaper = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('newspaper', { anchorX: 0.5, anchorY: 0.5 }); self.velocityX = 0; self.velocityY = 0; self.gravity = 0.3; self.active = true; self.update = function () { if (!self.active) { return; } self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; // Initialize starting Y position for scaling self.startY = self.startY || self.y; // Scale shrinks as it moves upward var travel = self.startY - self.y; // how high it has gone var scaleFactor = Math.max(0.3, 1 - travel / 2000); graphics.scaleX = graphics.scaleY = scaleFactor; // Remove if off screen if (self.x > 2048 + 50 || self.y > 2732 + 50) { self.active = false; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb }); /**** * Game Code ****/ // orange // green game.setBackgroundColor(0x87ceeb); /**** * Sun Path Parameters ****/ // Sun path parameters var sunStartX = 100; // left side var sunEndX = 1948; // right side var sunBaseY = 600; // baseline (sky zone level) var sunArcHeight = 400; // how high the sun climbs /**** * Zone Setup ****/ // Define Y positions for zones (adjust as needed to match your reference image) var streetZoneY = 2000; // Green bottom zone where slingshot sits var mailboxZoneY = 1200; // Orange middle zone where mailbox spawns var houseZoneY = 1000; // Houses aligned just above mailbox zone // Ground reference (for houses) var groundY = 2400; /**** * Visual Zone Placeholders ****/ // Street zone background (green) var streetZone = game.addChild(LK.getAsset('streetZone', { anchorX: 0.5, anchorY: 0.5 })); streetZone.x = 1024; streetZone.y = streetZoneY; // Mailbox zone background (orange) var mailboxZone = game.addChild(LK.getAsset('mailboxZone', { anchorX: 0.5, anchorY: 0.5 })); mailboxZone.x = 1024; mailboxZone.y = mailboxZoneY; // Game variables var mothman; var sun; var slingshot; var newspapers = []; var mailboxes = []; var houses = []; var trajectoryDots = []; var pennies = 0; var targetPennies = 650; var gameTime = 0; var maxGameTime = 18000; // 5 minutes at 60fps var isAiming = false; var aimStartX = 0; var aimStartY = 0; var aimPower = 0; var aimAngle = 0; // Create UI var pennyText = new Text2('Pennies: 0', { size: 40, fill: 0x000000 }); pennyText.anchor.set(0.5, 0); LK.gui.top.addChild(pennyText); var targetText = new Text2('Goal: 650 pennies', { size: 30, fill: 0x000000 }); targetText.anchor.set(0.5, 0); targetText.y = 60; LK.gui.top.addChild(targetText); // Create mothman mothman = game.addChild(new Container()); var mothmanGraphics = mothman.attachAsset('mothman', { anchorX: 0.5, anchorY: 0.5 }); mothman.x = 200; mothman.y = 400; // Hide mothman (no sprite during gameplay) mothman.visible = false; // Create sun sun = game.addChild(new Container()); var sunGraphics = sun.attachAsset('sun', { anchorX: 0.5, anchorY: 0.5 }); sun.x = sunStartX; sun.y = sunBaseY - sunArcHeight; /**** * Draw Sun Arc Path ****/ // Draw sun trajectory arc with dotted path function drawSunPath() { for (var t = 0; t <= 1; t += 0.05) { var x = sunStartX + (sunEndX - sunStartX) * t; var y = sunBaseY - Math.sin(t * Math.PI) * sunArcHeight; var dot = game.addChild(LK.getAsset('trajectory', { width: 6, height: 6, color: 0xffff66, // pale yellow anchorX: 0.5, anchorY: 0.5 })); dot.x = x; dot.y = y; dot.alpha = 0.3; // semi-transparent } } drawSunPath(); // Create slingshot area - positioned in street zone center slingshot = game.addChild(new Container()); var slingshotGraphics = slingshot.attachAsset('slingshot', { anchorX: 0.5, anchorY: 0.5 }); slingshot.x = 1024; // center of screen slingshot.y = streetZoneY + 100; // Slingshot bands (for stretch feedback) var bandLeft = new Container(); var bandRight = new Container(); game.addChild(bandLeft); game.addChild(bandRight); // Ground level var groundY = 2400; // Turn-based house cycle variables var currentHouse = null; var isHouseTransitioning = false; var turnComplete = true; function createHouse() { var house = new House(); // Start just off-screen to the right house.x = 2200; house.y = mailboxZoneY + 250; // roughly center mailbox zone houses.push(house); game.addChild(house); currentHouse = house; isHouseTransitioning = true; turnComplete = false; // Tween it into center of mailbox zone tween(house, { x: 1024 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { isHouseTransitioning = false; } }); return house; } function removeHouse(house, onComplete) { if (!house) { return; } isHouseTransitioning = true; tween(house, { x: -200 }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { house.destroy(); var index = houses.indexOf(house); if (index !== -1) { houses.splice(index, 1); } isHouseTransitioning = false; turnComplete = true; if (onComplete) { onComplete(); } } }); } function createMailbox() { if (!currentHouse) { return; } var mailbox = new Mailbox(); // Place randomly within mailbox zone bounds mailbox.x = 400 + Math.random() * 1200; // stays in safe horizontal range mailbox.y = mailboxZoneY + (Math.random() * 200 - 100); // Random horizontal flip if (Math.random() < 0.5) { mailbox.scaleX = -1; } else { mailbox.scaleX = 1; } mailboxes.push(mailbox); game.addChild(mailbox); // Ensure mailbox is drawn in front of house game.setChildIndex(mailbox, game.getChildIndex(currentHouse) + 1); return mailbox; } function shootNewspaper(power, angle) { var newspaper = new Newspaper(); newspaper.x = 1024; // center of screen newspaper.y = 2200; // bottom, with room to pull back var radians = angle * Math.PI / 180; newspaper.velocityX = Math.cos(radians) * power; newspaper.velocityY = Math.sin(radians) * power * -1; // invert to go up first newspapers.push(newspaper); game.addChild(newspaper); // ensure added after zones so visible LK.getSound('paperThrow').play(); } function updateSlingshotBands(endX, endY) { bandLeft.removeChildren(); bandRight.removeChildren(); var leftBand = bandLeft.attachAsset('trajectory', { width: 6, height: Math.sqrt(Math.pow(endX - (slingshot.x - 20), 2) + Math.pow(endY - (slingshot.y - 20), 2)), color: 0x654321, anchorX: 0.5, anchorY: 0 }); leftBand.rotation = Math.atan2(endY - (slingshot.y - 20), endX - (slingshot.x - 20)) + Math.PI / 2; bandLeft.x = slingshot.x - 20; bandLeft.y = slingshot.y - 20; var rightBand = bandRight.attachAsset('trajectory', { width: 6, height: Math.sqrt(Math.pow(endX - (slingshot.x + 20), 2) + Math.pow(endY - (slingshot.y + 20), 2)), color: 0x654321, anchorX: 0.5, anchorY: 0 }); rightBand.rotation = Math.atan2(endY - (slingshot.y + 20), endX - (slingshot.x + 20)) + Math.PI / 2; bandRight.x = slingshot.x + 20; bandRight.y = slingshot.y + 20; } function calculateScore(distance) { if (distance < 15) { return 5; } // Perfect hit if (distance < 25) { return 4; } // Great hit if (distance < 35) { return 3; } // Good hit if (distance < 45) { return 2; } // OK hit return 1; // Glancing hit } function updateTrajectory(startX, startY, endX, endY) { // Clear existing trajectory dots for (var i = 0; i < trajectoryDots.length; i++) { trajectoryDots[i].destroy(); } trajectoryDots = []; if (!isAiming) { return; } var deltaX = endX - startX; // flip X for preview var deltaY = startY - endY; // inverted Y var power = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1; var angle = Math.atan2(deltaY, deltaX); // Create trajectory preview for (var t = 0; t < 100; t += 10) { var x = startX + Math.cos(angle) * power * t * 0.5; var y = startY + Math.sin(angle) * power * t * 0.5 + 0.3 * t * t * 0.25; if (x > 2048 || y > 2732) { break; } var dot = game.addChild(LK.getAsset('trajectory', { anchorX: 0.5, anchorY: 0.5 })); dot.x = x; dot.y = y; dot.alpha = 0.5; trajectoryDots.push(dot); } } // Game input handlers game.down = function (x, y, obj) { if (y > streetZoneY - 200) { // only allow aiming in street zone isAiming = true; aimStartX = x; aimStartY = y; } }; game.move = function (x, y, obj) { if (isAiming) { updateTrajectory(1024, 2200, x, y); // use newspaper starting position updateSlingshotBands(x, y); } }; game.up = function (x, y, obj) { if (isAiming) { var deltaX = x - aimStartX; // flip X so left/right feels natural var deltaY = aimStartY - y; // keep inverted Y pull aimPower = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1; aimAngle = Math.atan2(deltaY, deltaX) * 180 / Math.PI; if (aimPower > 2) { shootNewspaper(aimPower, aimAngle); } isAiming = false; // Clear trajectory + bands for (var i = 0; i < trajectoryDots.length; i++) { trajectoryDots[i].destroy(); } trajectoryDots = []; bandLeft.removeChildren(); bandRight.removeChildren(); } }; game.update = function () { gameTime++; // Update sun position (moves across sky as timer) var timeProgress = gameTime / maxGameTime; sun.x = sunStartX + (sunEndX - sunStartX) * timeProgress; sun.y = sunBaseY - Math.sin(timeProgress * Math.PI) * sunArcHeight; // Change sky color based on time var skyColor = 0x87ceeb; // Day blue if (timeProgress > 0.8) { skyColor = 0xff6b47; // Sunset orange } else if (timeProgress > 0.6) { skyColor = 0xffa500; // Evening orange } game.setBackgroundColor(skyColor); // Turn-based house cycle management if (turnComplete && !isHouseTransitioning && !currentHouse) { // Start new turn with new house createHouse(); // Create mailbox after house is positioned LK.setTimeout(function () { if (Math.random() < 0.8) { // 80% chance for mailbox createMailbox(); } }, 1100); } // Update newspapers for (var i = newspapers.length - 1; i >= 0; i--) { var newspaper = newspapers[i]; if (!newspaper.active) { newspaper.destroy(); newspapers.splice(i, 1); continue; } // Check if newspaper went off screen without hitting (miss) if (newspaper.active && (newspaper.x > 2048 || newspaper.y > 2732)) { newspaper.active = false; // End the turn if no hit occurred if (currentHouse && !isHouseTransitioning) { removeHouse(currentHouse, function () { currentHouse = null; // Clear mailboxes for this turn for (var k = mailboxes.length - 1; k >= 0; k--) { mailboxes[k].destroy(); mailboxes.splice(k, 1); } }); } continue; } // Check mailbox collisions for (var j = 0; j < mailboxes.length; j++) { var mailbox = mailboxes[j]; if (!mailbox.hit && newspaper.intersects(mailbox)) { var distance = Math.sqrt(Math.pow(newspaper.x - mailbox.x, 2) + Math.pow(newspaper.y - mailbox.y, 2)); var score = calculateScore(distance); pennies += score; pennyText.setText('Pennies: ' + pennies); mailbox.hit = true; newspaper.active = false; // Flash mailbox green LK.effects.flashObject(mailbox, 0x00ff00, 500); LK.getSound('mailboxHit').play(); // End the turn after scoring if (currentHouse && !isHouseTransitioning) { removeHouse(currentHouse, function () { currentHouse = null; for (var k = mailboxes.length - 1; k >= 0; k--) { mailboxes[k].destroy(); mailboxes.splice(k, 1); } }); } break; } } } // Update and clean up mailboxes for (var i = mailboxes.length - 1; i >= 0; i--) { var mailbox = mailboxes[i]; if (!mailbox.active) { mailbox.destroy(); mailboxes.splice(i, 1); } } // Update and clean up houses for (var i = houses.length - 1; i >= 0; i--) { var house = houses[i]; if (!house.active) { house.destroy(); houses.splice(i, 1); } } // Check win condition if (pennies >= targetPennies) { LK.showYouWin(); } // Check lose condition if (gameTime >= maxGameTime) { LK.showGameOver(); } };
===================================================================
--- original.js
+++ change.js
@@ -38,9 +38,11 @@
self.velocityY = 0;
self.gravity = 0.3;
self.active = true;
self.update = function () {
- if (!self.active) return;
+ if (!self.active) {
+ return;
+ }
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
// Initialize starting Y position for scaling
@@ -216,9 +218,11 @@
});
return house;
}
function removeHouse(house, onComplete) {
- if (!house) return;
+ if (!house) {
+ return;
+ }
isHouseTransitioning = true;
tween(house, {
x: -200
}, {
@@ -226,17 +230,23 @@
easing: tween.easeIn,
onFinish: function onFinish() {
house.destroy();
var index = houses.indexOf(house);
- if (index !== -1) houses.splice(index, 1);
+ if (index !== -1) {
+ houses.splice(index, 1);
+ }
isHouseTransitioning = false;
turnComplete = true;
- if (onComplete) onComplete();
+ if (onComplete) {
+ onComplete();
+ }
}
});
}
function createMailbox() {
- if (!currentHouse) return;
+ if (!currentHouse) {
+ return;
+ }
var mailbox = new Mailbox();
// Place randomly within mailbox zone bounds
mailbox.x = 400 + Math.random() * 1200; // stays in safe horizontal range
mailbox.y = mailboxZoneY + (Math.random() * 200 - 100);
@@ -287,30 +297,42 @@
bandRight.x = slingshot.x + 20;
bandRight.y = slingshot.y + 20;
}
function calculateScore(distance) {
- if (distance < 15) return 5; // Perfect hit
- if (distance < 25) return 4; // Great hit
- if (distance < 35) return 3; // Good hit
- if (distance < 45) return 2; // OK hit
+ if (distance < 15) {
+ return 5;
+ } // Perfect hit
+ if (distance < 25) {
+ return 4;
+ } // Great hit
+ if (distance < 35) {
+ return 3;
+ } // Good hit
+ if (distance < 45) {
+ return 2;
+ } // OK hit
return 1; // Glancing hit
}
function updateTrajectory(startX, startY, endX, endY) {
// Clear existing trajectory dots
for (var i = 0; i < trajectoryDots.length; i++) {
trajectoryDots[i].destroy();
}
trajectoryDots = [];
- if (!isAiming) return;
- var deltaX = startX - endX; // flip X for preview
+ if (!isAiming) {
+ return;
+ }
+ var deltaX = endX - startX; // flip X for preview
var deltaY = startY - endY; // inverted Y
var power = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1;
var angle = Math.atan2(deltaY, deltaX);
// Create trajectory preview
for (var t = 0; t < 100; t += 10) {
var x = startX + Math.cos(angle) * power * t * 0.5;
var y = startY + Math.sin(angle) * power * t * 0.5 + 0.3 * t * t * 0.25;
- if (x > 2048 || y > 2732) break;
+ if (x > 2048 || y > 2732) {
+ break;
+ }
var dot = game.addChild(LK.getAsset('trajectory', {
anchorX: 0.5,
anchorY: 0.5
}));
@@ -336,9 +358,9 @@
}
};
game.up = function (x, y, obj) {
if (isAiming) {
- var deltaX = aimStartX - x; // flip X so left/right feels natural
+ var deltaX = x - aimStartX; // flip X so left/right feels natural
var deltaY = aimStartY - y; // keep inverted Y pull
aimPower = Math.sqrt(deltaX * deltaX + deltaY * deltaY) * 0.1;
aimAngle = Math.atan2(deltaY, deltaX) * 180 / Math.PI;
if (aimPower > 2) {