Code edit (3 edits merged)
Please save this source code
User prompt
update with: function initObjectPools() { for (var i = 0; i < POOL_SIZE_FIREBALLS; i++) { var fireball = new Fireball(); fireball.visible = false; fireball.active = false; // Add this line game.addChild(fireball); fireballPool.push(fireball); } // ... }
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: currentEnemy.deactivate is not a function. (In 'currentEnemy.deactivate()', 'currentEnemy.deactivate' is undefined)' in or related to this line: 'currentEnemy.deactivate();' Line Number: 587
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: if (currentEnemy.toDestroy) { currentEnemy.destroy(); enemies.splice(k, 1); continue; }
User prompt
Update with: LK.setTimeout(function () { if (fireballs.indexOf(fireball) !== -1) { fireball.deactivate(); } }, 100);
User prompt
Update with: if (fireball.y < -100) { fireball.deactivate(); continue; }
User prompt
Update with: function createFireParticle(x, y) { var particle = particlePool.find(function(p) { return !p.visible; }); if (particle) { particle.activate(x, y); fireParticles.push(particle); } }
User prompt
Update with: function spawnFireball() { if (!gameActive || firepower < 10) { return; } var now = Date.now(); if (now - lastFireTime < fireRate) { return; } lastFireTime = now; // Find available fireball from pool var fireball = fireballPool.find(function(fb) { return !fb.visible; }); if (fireball) { fireball.activate(dragon.x, dragon.y + 50); fireballs.push(fireball); // Use firepower firepower -= firepowerUseRate; powerBar.setPower(firepower / maxFirepower); // Play sound LK.getSound('firebreathSound').play(); } }
User prompt
Update with: self.update = function() { self.x += self.vx; self.y += self.vy; self.age++; particle.alpha = 1 - self.age / self.lifespan; if (self.age >= self.lifespan) { self.deactivate(); // Use deactivate instead of destroy } };
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: var FlyingBackground = Container.expand(function () { var self = Container.call(this); // Create sky background (top half) var sky = self.attachAsset('skyBackground', { anchorX: 0.5, anchorY: 1.0, // Anchor to bottom x: 2048/2, y: 2732/2 // Place at middle of screen (horizon line) }); // Create field background (bottom half) var field = self.attachAsset('fieldBackground', { anchorX: 0.5, anchorY: 0, // Anchor to top x: 2048/2, y: 2732/2 // Place at middle of screen (horizon line) }); // Horizon line is at y = 2732/2 self.horizonY = 2732/2; // Create clouds self.clouds = []; for (var i = 0; i < 8; i++) { // Start clouds with larger scale farther from horizon var startY = self.horizonY - 400 - Math.random() * 600; var distanceFromHorizon = Math.abs(startY - self.horizonY); var startScale = 0.5 + (distanceFromHorizon / 800); var cloud = self.attachAsset('cloudShape', { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: startY, alpha: 0.8, scaleX: startScale, scaleY: startScale * 0.8 }); // Store with motion properties self.clouds.push({ sprite: cloud, speedY: 1 + Math.random() * 2, speedX: (Math.random() - 0.5) * 1.5, // Slight side-to-side drift targetY: self.horizonY }); } // Create field elements self.fieldElements = []; for (var j = 0; j < 12; j++) { // Start field elements with larger scale farther from horizon var fieldStartY = self.horizonY + 400 + Math.random() * 800; var fieldDistanceFromHorizon = Math.abs(fieldStartY - self.horizonY); var fieldStartScale = 0.5 + (fieldDistanceFromHorizon / 1000); var fieldElement = self.attachAsset('fieldElement', { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: fieldStartY, scaleX: fieldStartScale, scaleY: fieldStartScale * 0.8 }); // Store with motion properties self.fieldElements.push({ sprite: fieldElement, speedY: 2 + Math.random() * 3, speedX: (Math.random() - 0.5) * 3, // More side-to-side movement for field elements targetY: self.horizonY }); } self.update = function() { // Update clouds for (var i = 0; i < self.clouds.length; i++) { var cloud = self.clouds[i]; // Move cloud toward horizon cloud.sprite.y += cloud.speedY; cloud.sprite.x += cloud.speedX; // Calculate scale based on distance from horizon var distanceFactor = Math.max(0.05, (cloud.sprite.y - self.horizonY) / -500); cloud.sprite.scaleX = distanceFactor; cloud.sprite.scaleY = distanceFactor * 0.8; // Adjust alpha for fade effect near horizon cloud.sprite.alpha = Math.min(0.9, distanceFactor); // Reset cloud if it reaches horizon or gets too small if (cloud.sprite.y >= self.horizonY - 10 || cloud.sprite.scaleX < 0.1) { cloud.sprite.y = self.horizonY - 800 - Math.random() * 400; cloud.sprite.x = Math.random() * 2048; var newDistanceFactor = (cloud.sprite.y - self.horizonY) / -500; cloud.sprite.scaleX = newDistanceFactor; cloud.sprite.scaleY = newDistanceFactor * 0.8; cloud.sprite.alpha = 0.8; } } // Update field elements for (var j = 0; j < self.fieldElements.length; j++) { var element = self.fieldElements[j]; // Move field element toward horizon element.sprite.y -= element.speedY; element.sprite.x += element.speedX; // Calculate scale based on distance from horizon var fieldDistanceFactor = Math.max(0.05, (element.sprite.y - self.horizonY) / 500); element.sprite.scaleX = fieldDistanceFactor; element.sprite.scaleY = fieldDistanceFactor * 0.8; // Adjust alpha for fade effect near horizon element.sprite.alpha = Math.min(0.9, fieldDistanceFactor); // Reset field element if it reaches horizon or goes off screen if (element.sprite.y <= self.horizonY + 10 || element.sprite.scaleX < 0.1 || element.sprite.x < -50 || element.sprite.x > 2048 + 50) { element.sprite.y = self.horizonY + 800 + Math.random() * 400; element.sprite.x = Math.random() * 2048; var newFieldDistanceFactor = (element.sprite.y - self.horizonY) / 500; element.sprite.scaleX = newFieldDistanceFactor; element.sprite.scaleY = newFieldDistanceFactor * 0.8; element.sprite.alpha = 0.9; } } }; return self; });
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: self.update = function () { self.y -= self.speed; // Enemies move up the screen toward the player // Calculate scale based on y position (smaller as they approach dragon) var maxDistance = 2732; // Screen height var minScale = 0.3; // Smallest size var maxScale = 2.0; // Largest size var distancePercent = (self.y) / maxDistance; var newScale = minScale + (distancePercent * (maxScale - minScale)); // Apply scaling self.scaleX = newScale; self.scaleY = newScale; // Also adjust speed based on proximity (slower as they get closer) var baseSpeed = self.type; self.speed = baseSpeed * (0.5 + (distancePercent * 0.5)); };
Code edit (1 edits merged)
Please save this source code
User prompt
Update with: var GroundScroller = Container.expand(function () { var self = Container.call(this); // Set up ground configuration self.scrollSpeed = -5; // NEGATIVE to scroll upward self.horizonY = 2732 * 0.7; // Horizon at 70% down the screen self.groundWidth = 2048; // Width at bottom self.groundWidthFar = 2048; // Make horizon line full width self.segmentHeight = 300; // Add a thinner horizon line that spans full width var horizon = self.attachAsset('groundFar', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); horizon.x = 2048 / 2; horizon.y = self.horizonY; horizon.width = 2048; // Full width horizon.height = 10; // Make it thinner horizon.tint = 0x555555; // Darker color // Calculate how many segments we need to fill screen self.segmentCount = Math.ceil((2732 - self.horizonY) / self.segmentHeight) + 2; self.segments = []; // Create segments by using boxes with varying widths for (var i = 0; i < self.segmentCount; i++) { var segmentContainer = new Container(); self.addChild(segmentContainer); // Position from horizon down segmentContainer.y = self.horizonY + i * self.segmentHeight; segmentContainer.x = 2048 / 2; // Center horizontally // Calculate widths based on distance from horizon var distFromHorizon = segmentContainer.y - self.horizonY; var totalDist = 2732 - self.horizonY; var perspectiveFactor = Math.min(1, distFromHorizon / totalDist); var segmentWidth = self.groundWidthFar * (0.7 + 0.3 * perspectiveFactor); // Create main segment var segment = segmentContainer.attachAsset('ground', { anchorX: 0.5, anchorY: 0 }); segment.width = segmentWidth; segment.height = self.segmentHeight; // Store for scrolling self.segments.push({ container: segmentContainer, segment: segment, origY: segmentContainer.y }); } self.update = function() { // Scroll all segments upward (negative direction) for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; seg.container.y += self.scrollSpeed; // If segment has moved completely above horizon, move it to the bottom if (seg.container.y < self.horizonY - self.segmentHeight) { // Find the segment that's currently lowest var lowestY = -Infinity; for (var j = 0; j < self.segments.length; j++) { if (j !== i && self.segments[j].container.y > lowestY) { lowestY = self.segments[j].container.y; } } // Place this segment below the lowest one seg.container.y = lowestY + self.segmentHeight; } // Update width based on perspective for a smoother effect var distFromHorizon = seg.container.y - self.horizonY; var totalDist = 2732 - self.horizonY; var perspectiveFactor = Math.min(1, distFromHorizon / totalDist); // Calculate width - wider at bottom, narrower at horizon var segmentWidth = 2048 * (0.7 + 0.3 * perspectiveFactor); seg.segment.width = segmentWidth; } }; return self; });
User prompt
Update with: var GroundScroller = Container.expand(function () { var self = Container.call(this); // Set up ground configuration self.scrollSpeed = 5; self.horizonY = 2732 * 0.7; // Horizon at 70% down the screen self.groundWidth = 2048; // Width at bottom self.groundWidthFar = 1200; // Width at horizon self.segmentHeight = 300; // Add a horizon line var horizon = self.attachAsset('groundFar', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); horizon.x = 2048 / 2; horizon.y = self.horizonY; horizon.width = self.groundWidthFar; // Calculate how many segments we need to fill screen self.segmentCount = Math.ceil((2732 - self.horizonY) / self.segmentHeight) + 2; self.segments = []; // Create segments by using multiple boxes side by side for (var i = 0; i < self.segmentCount; i++) { var segmentContainer = new Container(); self.addChild(segmentContainer); // Position from horizon down segmentContainer.y = self.horizonY + i * self.segmentHeight; segmentContainer.x = 2048 / 2; // Center horizontally // Calculate widths based on distance from horizon var distFromHorizon = segmentContainer.y - self.horizonY; var totalDist = 2732 - self.horizonY; var perspectiveFactor = Math.min(1, distFromHorizon / totalDist); var topWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor; var bottomWidth = topWidth + (self.scrollSpeed * 2); // Make bottom slightly wider // Create main segment var segment = segmentContainer.attachAsset('ground', { anchorX: 0.5, anchorY: 0 }); segment.width = topWidth; segment.height = self.segmentHeight; // Store for scrolling self.segments.push({ container: segmentContainer, segment: segment, topWidth: topWidth, bottomWidth: bottomWidth }); } self.update = function() { // Scroll all segments downward for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; seg.container.y += self.scrollSpeed; // If segment has moved completely below screen, move it to the top if (seg.container.y > 2732 + self.segmentHeight) { // Find the segment that's currently highest var highestY = Infinity; for (var j = 0; j < self.segments.length; j++) { if (j !== i && self.segments[j].container.y < highestY) { highestY = self.segments[j].container.y; } } // Place this segment above the highest one seg.container.y = highestY - self.segmentHeight; // Recalculate width based on new position var distFromHorizon = seg.container.y - self.horizonY; var totalDist = 2732 - self.horizonY; var perspectiveFactor = Math.min(1, distFromHorizon / totalDist); var newWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor; seg.segment.width = newWidth; } // Update width based on perspective for a smoother effect var distFromHorizon = seg.container.y - self.horizonY; var totalDist = 2732 - self.horizonY; var perspectiveFactor = Math.min(1, distFromHorizon / totalDist); var newWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor; seg.segment.width = newWidth; } }; return self; });
User prompt
Please fix the bug: 'undefined is not a constructor (evaluating 'new Graphics()')' in or related to this line: 'var trapezoid = new Graphics();' Line Number: 251
User prompt
Please fix the bug: 'undefined is not a constructor (evaluating 'new LK.Graphics()')' in or related to this line: 'var trapezoid = new LK.Graphics();' Line Number: 251
User prompt
Update with: var GroundScroller = Container.expand(function () { var self = Container.call(this); // Set up ground configuration self.scrollSpeed = 5; // Now this will be positive to scroll downward self.horizonY = 2732 * 0.7; // Horizon at 70% down the screen self.groundWidth = 2048; // Width at bottom self.groundWidthFar = 1200; // Width at horizon self.segmentHeight = 300; // Calculate how many segments we need to fill screen self.segmentCount = Math.ceil((2732 - self.horizonY) / self.segmentHeight) + 2; // +2 for overlap self.segments = []; // Create trapezoid-shaped ground segments using multiple ground pieces for (var i = 0; i < self.segmentCount; i++) { // Create a container for this segment var segmentContainer = new Container(); self.addChild(segmentContainer); segmentContainer.x = 2048 / 2; // Center horizontally // Position segment from horizon and down var yPos = self.horizonY + i * self.segmentHeight; segmentContainer.y = yPos; // Calculate top and bottom widths for this segment var distFromHorizonTop = yPos - self.horizonY; var distFromHorizonBottom = yPos + self.segmentHeight - self.horizonY; var totalDist = 2732 - self.horizonY; var topWidthFactor = Math.min(1, distFromHorizonTop / totalDist); var bottomWidthFactor = Math.min(1, distFromHorizonBottom / totalDist); var topWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * topWidthFactor; var bottomWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * bottomWidthFactor; // Instead of one rectangle, create a trapezoid using custom graphics var trapezoid = new LK.Graphics(); segmentContainer.addChild(trapezoid); // Set color and draw trapezoid trapezoid.beginFill(0x8B4513); trapezoid.moveTo(-topWidth/2, 0); trapezoid.lineTo(topWidth/2, 0); trapezoid.lineTo(bottomWidth/2, self.segmentHeight); trapezoid.lineTo(-bottomWidth/2, self.segmentHeight); trapezoid.lineTo(-topWidth/2, 0); trapezoid.endFill(); // Store in our array for scrolling self.segments.push({ container: segmentContainer, trapezoid: trapezoid, topWidth: topWidth, bottomWidth: bottomWidth }); } // Add a horizon line var horizon = self.attachAsset('groundFar', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); horizon.x = 2048 / 2; horizon.y = self.horizonY; horizon.width = self.groundWidthFar; self.update = function() { // Scroll all segments downward (positive direction) for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; seg.container.y += self.scrollSpeed; // If segment has moved completely below screen, move it to the top if (seg.container.y > 2732 + self.segmentHeight) { // Find the segment that's currently highest var highestY = Infinity; for (var j = 0; j < self.segments.length; j++) { if (j !== i && self.segments[j].container.y < highestY) { highestY = self.segments[j].container.y; } } // Place this segment above the highest one seg.container.y = highestY - self.segmentHeight; // Recalculate trapezoid dimensions based on new position var yPos = seg.container.y; var distFromHorizonTop = yPos - self.horizonY; var distFromHorizonBottom = yPos + self.segmentHeight - self.horizonY; var totalDist = 2732 - self.horizonY; var topWidthFactor = Math.min(1, distFromHorizonTop / totalDist); var bottomWidthFactor = Math.min(1, distFromHorizonBottom / totalDist); var topWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * topWidthFactor; var bottomWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * bottomWidthFactor; // Update trapezoid seg.trapezoid.clear(); seg.trapezoid.beginFill(0x8B4513); seg.trapezoid.moveTo(-topWidth/2, 0); seg.trapezoid.lineTo(topWidth/2, 0); seg.trapezoid.lineTo(bottomWidth/2, self.segmentHeight); seg.trapezoid.lineTo(-bottomWidth/2, self.segmentHeight); seg.trapezoid.lineTo(-topWidth/2, 0); seg.trapezoid.endFill(); } } }; return self; });
User prompt
Reverse the direction of the ground scroll.
User prompt
Update with: var GroundScroller = Container.expand(function () { var self = Container.call(this); // Set up ground configuration self.scrollSpeed = 5; self.horizonY = 2732 * 0.7; // Move horizon lower (70% down the screen) self.groundWidth = 2048; self.groundWidthFar = 1200; // Width at horizon self.segmentHeight = 300; // Calculate how many segments we need to fill screen self.segmentCount = Math.ceil((2732 - self.horizonY) / self.segmentHeight) + 1; self.segments = []; // Create trapezoid-shaped ground segments for (var i = 0; i < self.segmentCount; i++) { // Create a container for this segment (to handle the trapezoid shape) var segmentContainer = new Container(); self.addChild(segmentContainer); // Create the actual ground piece var segment = segmentContainer.attachAsset('ground', { anchorX: 0.5, anchorY: 0 // Anchor at top }); // Position the segment segmentContainer.y = self.horizonY + i * self.segmentHeight; segmentContainer.x = 2048 / 2; // Center horizontally // Store in our array for scrolling self.segments.push({ container: segmentContainer, segment: segment, index: i }); } // Add a horizon line var horizon = self.attachAsset('groundFar', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); horizon.x = 2048 / 2; // Center horizontally horizon.y = self.horizonY; horizon.width = self.groundWidthFar; // Update trapezoid shapes based on their position self.updateSegmentShapes = function() { for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; var distFromHorizon = seg.container.y - self.horizonY; // Calculate width based on distance from horizon // Segments closer to horizon are narrower var perspectiveFactor = Math.min(1, distFromHorizon / (2732 - self.horizonY)); var segmentWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor; // Update the segment shape seg.segment.width = segmentWidth; seg.segment.x = 0; // Center within container // Make closer segments taller for better perspective seg.segment.height = self.segmentHeight * (0.7 + 0.3 * perspectiveFactor); } }; self.update = function() { // Scroll all segments downward for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; seg.container.y += self.scrollSpeed; // If segment has moved completely below screen, move it to the top if (seg.container.y > 2732 + self.segmentHeight) { // Find the segment that's currently highest var highestY = Infinity; for (var j = 0; j < self.segments.length; j++) { if (j !== i && self.segments[j].container.y < highestY) { highestY = self.segments[j].container.y; } } // Place this segment above the highest one seg.container.y = highestY - self.segmentHeight; } } // Update shapes each frame to maintain perspective self.updateSegmentShapes(); }; // Initialize shapes self.updateSegmentShapes(); return self; });
User prompt
Update with: var GroundScroller = Container.expand(function () { var self = Container.call(this); // Set up ground configuration self.scrollSpeed = 5; self.horizonY = 2732 * 0.7; // Move horizon lower (70% down the screen) self.groundWidth = 2048; self.groundWidthFar = 1200; // Width at horizon self.segmentHeight = 300; // Calculate how many segments we need to fill screen self.segmentCount = Math.ceil((2732 - self.horizonY) / self.segmentHeight) + 1; self.segments = []; // Create trapezoid-shaped ground segments for (var i = 0; i < self.segmentCount; i++) { // Create a container for this segment (to handle the trapezoid shape) var segmentContainer = new Container(); self.addChild(segmentContainer); // Create the actual ground piece var segment = segmentContainer.attachAsset('ground', { anchorX: 0.5, anchorY: 0 // Anchor at top }); // Position the segment segmentContainer.y = self.horizonY + i * self.segmentHeight; segmentContainer.x = 2048 / 2; // Center horizontally // Store in our array for scrolling self.segments.push({ container: segmentContainer, segment: segment, index: i }); } // Add a horizon line var horizon = self.attachAsset('groundFar', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); horizon.x = 2048 / 2; // Center horizontally horizon.y = self.horizonY; horizon.width = self.groundWidthFar; // Update trapezoid shapes based on their position self.updateSegmentShapes = function() { for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; var distFromHorizon = seg.container.y - self.horizonY; // Calculate width based on distance from horizon // Segments closer to horizon are narrower var perspectiveFactor = Math.min(1, distFromHorizon / (2732 - self.horizonY)); var segmentWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor; // Update the segment shape seg.segment.width = segmentWidth; seg.segment.x = 0; // Center within container // Make closer segments taller for better perspective seg.segment.height = self.segmentHeight * (0.7 + 0.3 * perspectiveFactor); } }; self.update = function() { // Scroll all segments downward for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; seg.container.y += self.scrollSpeed; // If segment has moved completely below screen, move it to the top if (seg.container.y > 2732 + self.segmentHeight) { // Find the segment that's currently highest var highestY = Infinity; for (var j = 0; j < self.segments.length; j++) { if (j !== i && self.segments[j].container.y < highestY) { highestY = self.segments[j].container.y; } } // Place this segment above the highest one seg.container.y = highestY - self.segmentHeight; } } // Update shapes each frame to maintain perspective self.updateSegmentShapes(); }; // Initialize shapes self.updateSegmentShapes(); return self; });
User prompt
Update with: var GroundScroller = Container.expand(function () { var self = Container.call(this); // Set up ground configuration self.scrollSpeed = 5; self.horizonY = 2732 * 0.5; // Horizon at middle of screen self.groundWidth = 2048; self.groundWidthFar = 1200; // Width at horizon self.segmentHeight = 300; // Calculate how many segments we need to fill screen self.segmentCount = Math.ceil(2732 / self.segmentHeight) + 1; self.segments = []; // Create trapezoid-shaped ground segments for (var i = 0; i < self.segmentCount; i++) { // Create a container for this segment (to handle the trapezoid shape) var segmentContainer = new Container(); self.addChild(segmentContainer); // Create the actual ground piece var segment = segmentContainer.attachAsset('ground', { anchorX: 0.5, anchorY: 0 // Anchor at top }); // Position the segment segmentContainer.y = self.horizonY + i * self.segmentHeight; // Store in our array for scrolling self.segments.push({ container: segmentContainer, segment: segment, index: i }); } // Add a horizon line var horizon = self.attachAsset('groundFar', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); horizon.x = self.groundWidth / 2; horizon.y = self.horizonY; horizon.width = self.groundWidthFar; // Update trapezoid shapes based on their position self.updateSegmentShapes = function() { for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; var distFromHorizon = seg.container.y - self.horizonY; // Calculate width based on distance from horizon // Segments closer to horizon are narrower var perspectiveFactor = Math.min(1, distFromHorizon / (2732 - self.horizonY)); var segmentWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor; // Update the segment shape seg.segment.width = segmentWidth; seg.segment.x = segmentWidth / 2; // Center within container // Make closer segments taller for better perspective seg.segment.height = self.segmentHeight * (0.7 + 0.3 * perspectiveFactor); } }; self.update = function() { // Scroll all segments downward for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; seg.container.y += self.scrollSpeed; // If segment has moved completely below screen, move it to the top if (seg.container.y > 2732 + self.segmentHeight) { // Find the segment that's currently highest var highestY = Infinity; for (var j = 0; j < self.segments.length; j++) { if (j !== i && self.segments[j].container.y < highestY) { highestY = self.segments[j].container.y; } } // Place this segment above the highest one seg.container.y = highestY - self.segmentHeight; } } // Update shapes each frame to maintain perspective self.updateSegmentShapes(); }; // Initialize shapes self.updateSegmentShapes(); return self; });
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); var facekit = LK.import("@upit/facekit.v1"); /**** * Classes ****/ var DragonHead = Container.expand(function () { var self = Container.call(this); var head = self.attachAsset('dragonHead', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); var headOpen = self.attachAsset('dragonHeadOpen', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, alpha: 0 }); // Position smoothing variables self.targetX = 2048 / 2; self.targetY = 2732 * 0.2; self.smoothingFactor = 0.15; // Simplified rotation variables self.currentRotation = 0; self.targetRotation = 0; self.rotationSmoothing = 0.1; self.update = function () { // Position tracking if (facekit.noseTip) { self.targetX = facekit.noseTip.x; self.targetY = facekit.noseTip.y; } // Apply position smoothing self.x += (self.targetX - self.x) * self.smoothingFactor; self.y += (self.targetY - self.y) * self.smoothingFactor; // Simplified rotation calculation directly from eye positions if (facekit.leftEye && facekit.rightEye) { // Calculate angle between eyes (simpler approach) var dx = facekit.rightEye.x - facekit.leftEye.x; var dy = facekit.rightEye.y - facekit.leftEye.y; // Get the raw angle in radians and negate it to reverse the direction var rawAngle = -Math.atan2(dy, dx); // Limit the rotation to prevent extreme angles (±0.3 radians ≈ ±17 degrees) self.targetRotation = Math.max(-0.3, Math.min(0.3, rawAngle)); // Apply rotation smoothing self.rotation += (self.targetRotation - self.rotation) * self.rotationSmoothing; // Debug output - uncomment if you have console logging // console.log("Eyes dx/dy:", dx, dy, "Target rotation:", self.targetRotation, "Current rotation:", self.rotation); } // Toggle dragon head assets based on mouth open state if (facekit && facekit.mouthOpen) { head.alpha = 0; headOpen.alpha = 1; } else { head.alpha = 1; headOpen.alpha = 0; } }; return self; }); var Enemy = Container.expand(function (type) { var self = Container.call(this); var assetId = 'enemy1'; if (type === 2) { assetId = 'enemy2'; } if (type === 3) { assetId = 'enemy3'; } self.type = type || 1; var enemyGraphic = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); // Different enemy types have different speeds and health switch (self.type) { case 1: self.speed = 2; self.health = 1; break; case 2: self.speed = 1.5; self.health = 2; break; case 3: self.speed = 3; self.health = 1; break; } self.update = function () { // Calculate perspective factor (0 at bottom, 1 at top) var screenHeight = 2732; var perspectiveFactor = (screenHeight - self.y) / screenHeight; // Move slower as they get "farther" away var adjustedSpeed = self.speed * (1 - 0.7 * perspectiveFactor); self.y -= adjustedSpeed; // Scale down as they move "farther" away var scale = 1 - 0.6 * perspectiveFactor; self.scaleX = scale; self.scaleY = scale; }; self.hit = function () { self.health--; // Visual feedback when hit LK.effects.flashObject(enemyGraphic, 0xff0000, 200); // Different death animations based on enemy type if (self.health <= 0) { if (self.type === 1) { // Type 1 enemy burns to ash tween(enemyGraphic, { alpha: 0, scaleX: 0.5, scaleY: 0.5 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { self.toDestroy = true; } }); } else if (self.type === 2) { // Type 2 enemy spins away tween(enemyGraphic, { rotation: Math.PI * 4, y: self.y + 300 }, { duration: 700, easing: tween.easeIn, onFinish: function onFinish() { self.toDestroy = true; } }); } else if (self.type === 3) { // Type 3 enemy explodes outward tween(enemyGraphic, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { self.toDestroy = true; } }); } return true; } return false; }; return self; }); var FireParticle = Container.expand(function () { var self = Container.call(this); var particle = self.attachAsset('fireParticle', { anchorX: 0.5, anchorY: 0.5 }); self.vx = Math.random() * 4 - 2; self.vy = Math.random() * 2 + 1; self.lifespan = 20 + Math.random() * 20; self.age = 0; self.update = function () { self.x += self.vx; self.y += self.vy; self.age++; particle.alpha = 1 - self.age / self.lifespan; if (self.age >= self.lifespan) { self.destroy(); } }; return self; }); var Fireball = Container.expand(function () { var self = Container.call(this); var fireballGraphic = self.attachAsset('fireball', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.active = true; self.update = function () { if (!self.active) { return; } self.y += self.speed; // Create fire trail particles if (Math.random() < 0.3) { createFireParticle(self.x + (Math.random() * 40 - 20), self.y + 20); } }; return self; }); var GroundScroller = Container.expand(function () { var self = Container.call(this); // Set up ground configuration self.scrollSpeed = 5; self.horizonY = 2732 * 0.5; // Horizon at middle of screen self.groundWidth = 2048; self.groundWidthFar = 1200; // Width at horizon self.segmentHeight = 300; // Calculate how many segments we need to fill screen self.segmentCount = Math.ceil(2732 / self.segmentHeight) + 1; self.segments = []; // Create trapezoid-shaped ground segments for (var i = 0; i < self.segmentCount; i++) { // Create a container for this segment (to handle the trapezoid shape) var segmentContainer = new Container(); self.addChild(segmentContainer); // Create the actual ground piece var segment = segmentContainer.attachAsset('ground', { anchorX: 0.5, anchorY: 0 // Anchor at top }); // Position the segment segmentContainer.y = self.horizonY + i * self.segmentHeight; // Store in our array for scrolling self.segments.push({ container: segmentContainer, segment: segment, index: i }); } // Add a horizon line var horizon = self.attachAsset('groundFar', { anchorX: 0.5, anchorY: 1 // Anchor at bottom }); horizon.x = self.groundWidth / 2; horizon.y = self.horizonY; horizon.width = self.groundWidthFar; // Update trapezoid shapes based on their position self.updateSegmentShapes = function () { for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; var distFromHorizon = seg.container.y - self.horizonY; // Calculate width based on distance from horizon // Segments closer to horizon are narrower var perspectiveFactor = Math.min(1, distFromHorizon / (2732 - self.horizonY)); var segmentWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor; // Update the segment shape seg.segment.width = segmentWidth; seg.segment.x = segmentWidth / 2; // Center within container // Make closer segments taller for better perspective seg.segment.height = self.segmentHeight * (0.7 + 0.3 * perspectiveFactor); } }; self.update = function () { // Scroll all segments downward for (var i = 0; i < self.segments.length; i++) { var seg = self.segments[i]; seg.container.y += self.scrollSpeed; // If segment has moved completely below screen, move it to the top if (seg.container.y > 2732 + self.segmentHeight) { // Find the segment that's currently highest var highestY = Infinity; for (var j = 0; j < self.segments.length; j++) { if (j !== i && self.segments[j].container.y < highestY) { highestY = self.segments[j].container.y; } } // Place this segment above the highest one seg.container.y = highestY - self.segmentHeight; } } // Update shapes each frame to maintain perspective self.updateSegmentShapes(); }; // Initialize shapes self.updateSegmentShapes(); return self; }); var PowerBar = Container.expand(function () { var self = Container.call(this); // Background bar var background = self.attachAsset('powerBarBg', { anchorX: 0.5, anchorY: 0.5 }); // Foreground bar (showing power level) var bar = self.attachAsset('powerBar', { anchorX: 0, anchorY: 0.5, x: -250 }); self.maxWidth = 500; self.setPower = function (percent) { var newWidth = self.maxWidth * percent; bar.width = Math.max(0, Math.min(newWidth, self.maxWidth)); // Change color based on power level if (percent < 0.3) { bar.tint = 0xe74c3c; // Red when low } else if (percent < 0.6) { bar.tint = 0xf39c12; // Orange when medium } else { bar.tint = 0x2ecc71; // Green when high } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Set dark blue background for sky effect game.setBackgroundColor(0x2c3e50); // Game state variables var score = 0; var firepower = 100; var maxFirepower = 100; var firepowerRechargeRate = 0.5; var firepowerUseRate = 2; var gameActive = true; var fireballs = []; var enemies = []; var fireParticles = []; var isFiring = false; var lastFireTime = 0; var fireRate = 150; // ms between fireballs var enemySpawnRate = 60; // Frames between enemy spawns var difficultyScaling = 0; var groundScroller = new GroundScroller(); game.addChild(groundScroller); // Create dragon head (player character) var dragon = game.addChild(new DragonHead()); dragon.x = 2048 / 2; dragon.y = 2732 * 0.2; // Place dragon at top fifth of screen // Create power bar var powerBar = new PowerBar(); powerBar.x = 2048 / 2; powerBar.y = 150; LK.gui.top.addChild(powerBar); // Score display var scoreTxt = new Text2('0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.y = 50; LK.gui.top.addChild(scoreTxt); // Create a function to add fire particles function createFireParticle(x, y) { var particle = new FireParticle(); particle.x = x; particle.y = y; game.addChild(particle); fireParticles.push(particle); } // Function to spawn a fireball function spawnFireball() { if (!gameActive || firepower < 10) { return; } var now = Date.now(); if (now - lastFireTime < fireRate) { return; } lastFireTime = now; // Create new fireball var fireball = new Fireball(); fireball.x = dragon.x; fireball.y = dragon.y + 50; // Spawn below dragon's mouth game.addChild(fireball); fireballs.push(fireball); // Use firepower firepower -= firepowerUseRate; powerBar.setPower(firepower / maxFirepower); // Play sound LK.getSound('firebreathSound').play(); } // Function to spawn enemies function spawnEnemy() { if (!gameActive) { return; } // Create enemy of random type var type = Math.floor(Math.random() * 3) + 1; var enemy = new Enemy(type); // Position randomly along bottom of screen enemy.x = Math.random() * (2048 - 200) + 100; enemy.y = 2732 + 100; // Start below screen game.addChild(enemy); enemies.push(enemy); } // Game update logic game.update = function () { if (!gameActive) { return; } // Check if mouth is open for fire breathing if (facekit && facekit.mouthOpen) { isFiring = true; spawnFireball(); } else { isFiring = false; } // Recharge firepower when not firing if (!isFiring && firepower < maxFirepower) { firepower += firepowerRechargeRate; powerBar.setPower(firepower / maxFirepower); } // Warn player when power is low if (firepower < 20 && Math.floor(LK.ticks) % 60 === 0) { LK.getSound('powerLow').play(); } // Spawn enemies if (LK.ticks % Math.max(10, enemySpawnRate - difficultyScaling) === 0) { spawnEnemy(); } // Increase difficulty over time if (LK.ticks % 300 === 0 && difficultyScaling < 40) { difficultyScaling += 1; } // Update fireballs and check for collisions for (var i = fireballs.length - 1; i >= 0; i--) { var fireball = fireballs[i]; // Remove fireballs that go off screen if (fireball.y < -100) { fireball.destroy(); fireballs.splice(i, 1); continue; } // Check for collisions with enemies for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (fireball.active && fireball.intersects(enemy)) { // Hit the enemy var killed = enemy.hit(); if (killed) { score += enemy.type * 10; scoreTxt.setText(score); LK.setScore(score); LK.getSound('enemyDefeat').play(); } // Deactivate the fireball fireball.active = false; // Destroy it after a slight delay (for visual effect) LK.setTimeout(function () { if (fireballs.indexOf(fireball) !== -1) { fireball.destroy(); fireballs.splice(fireballs.indexOf(fireball), 1); } }, 100); break; } } } // Update enemies for (var k = enemies.length - 1; k >= 0; k--) { var currentEnemy = enemies[k]; // Remove enemies marked for destruction if (currentEnemy.toDestroy) { currentEnemy.destroy(); enemies.splice(k, 1); continue; } // Check if enemy reaches player if (currentEnemy.y < 300) { // Game over gameActive = false; LK.getSound('gameOverSound').play(); LK.showGameOver(); } } // Update fire particles for (var m = fireParticles.length - 1; m >= 0; m--) { if (!fireParticles[m].parent) { fireParticles.splice(m, 1); } } }; // Start background music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.3, duration: 1000 } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
var facekit = LK.import("@upit/facekit.v1");
/****
* Classes
****/
var DragonHead = Container.expand(function () {
var self = Container.call(this);
var head = self.attachAsset('dragonHead', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
var headOpen = self.attachAsset('dragonHeadOpen', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
alpha: 0
});
// Position smoothing variables
self.targetX = 2048 / 2;
self.targetY = 2732 * 0.2;
self.smoothingFactor = 0.15;
// Simplified rotation variables
self.currentRotation = 0;
self.targetRotation = 0;
self.rotationSmoothing = 0.1;
self.update = function () {
// Position tracking
if (facekit.noseTip) {
self.targetX = facekit.noseTip.x;
self.targetY = facekit.noseTip.y;
}
// Apply position smoothing
self.x += (self.targetX - self.x) * self.smoothingFactor;
self.y += (self.targetY - self.y) * self.smoothingFactor;
// Simplified rotation calculation directly from eye positions
if (facekit.leftEye && facekit.rightEye) {
// Calculate angle between eyes (simpler approach)
var dx = facekit.rightEye.x - facekit.leftEye.x;
var dy = facekit.rightEye.y - facekit.leftEye.y;
// Get the raw angle in radians and negate it to reverse the direction
var rawAngle = -Math.atan2(dy, dx);
// Limit the rotation to prevent extreme angles (±0.3 radians ≈ ±17 degrees)
self.targetRotation = Math.max(-0.3, Math.min(0.3, rawAngle));
// Apply rotation smoothing
self.rotation += (self.targetRotation - self.rotation) * self.rotationSmoothing;
// Debug output - uncomment if you have console logging
// console.log("Eyes dx/dy:", dx, dy, "Target rotation:", self.targetRotation, "Current rotation:", self.rotation);
}
// Toggle dragon head assets based on mouth open state
if (facekit && facekit.mouthOpen) {
head.alpha = 0;
headOpen.alpha = 1;
} else {
head.alpha = 1;
headOpen.alpha = 0;
}
};
return self;
});
var Enemy = Container.expand(function (type) {
var self = Container.call(this);
var assetId = 'enemy1';
if (type === 2) {
assetId = 'enemy2';
}
if (type === 3) {
assetId = 'enemy3';
}
self.type = type || 1;
var enemyGraphic = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Different enemy types have different speeds and health
switch (self.type) {
case 1:
self.speed = 2;
self.health = 1;
break;
case 2:
self.speed = 1.5;
self.health = 2;
break;
case 3:
self.speed = 3;
self.health = 1;
break;
}
self.update = function () {
// Calculate perspective factor (0 at bottom, 1 at top)
var screenHeight = 2732;
var perspectiveFactor = (screenHeight - self.y) / screenHeight;
// Move slower as they get "farther" away
var adjustedSpeed = self.speed * (1 - 0.7 * perspectiveFactor);
self.y -= adjustedSpeed;
// Scale down as they move "farther" away
var scale = 1 - 0.6 * perspectiveFactor;
self.scaleX = scale;
self.scaleY = scale;
};
self.hit = function () {
self.health--;
// Visual feedback when hit
LK.effects.flashObject(enemyGraphic, 0xff0000, 200);
// Different death animations based on enemy type
if (self.health <= 0) {
if (self.type === 1) {
// Type 1 enemy burns to ash
tween(enemyGraphic, {
alpha: 0,
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
self.toDestroy = true;
}
});
} else if (self.type === 2) {
// Type 2 enemy spins away
tween(enemyGraphic, {
rotation: Math.PI * 4,
y: self.y + 300
}, {
duration: 700,
easing: tween.easeIn,
onFinish: function onFinish() {
self.toDestroy = true;
}
});
} else if (self.type === 3) {
// Type 3 enemy explodes outward
tween(enemyGraphic, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
self.toDestroy = true;
}
});
}
return true;
}
return false;
};
return self;
});
var FireParticle = Container.expand(function () {
var self = Container.call(this);
var particle = self.attachAsset('fireParticle', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = Math.random() * 4 - 2;
self.vy = Math.random() * 2 + 1;
self.lifespan = 20 + Math.random() * 20;
self.age = 0;
self.update = function () {
self.x += self.vx;
self.y += self.vy;
self.age++;
particle.alpha = 1 - self.age / self.lifespan;
if (self.age >= self.lifespan) {
self.destroy();
}
};
return self;
});
var Fireball = Container.expand(function () {
var self = Container.call(this);
var fireballGraphic = self.attachAsset('fireball', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.active = true;
self.update = function () {
if (!self.active) {
return;
}
self.y += self.speed;
// Create fire trail particles
if (Math.random() < 0.3) {
createFireParticle(self.x + (Math.random() * 40 - 20), self.y + 20);
}
};
return self;
});
var GroundScroller = Container.expand(function () {
var self = Container.call(this);
// Set up ground configuration
self.scrollSpeed = 5;
self.horizonY = 2732 * 0.5; // Horizon at middle of screen
self.groundWidth = 2048;
self.groundWidthFar = 1200; // Width at horizon
self.segmentHeight = 300;
// Calculate how many segments we need to fill screen
self.segmentCount = Math.ceil(2732 / self.segmentHeight) + 1;
self.segments = [];
// Create trapezoid-shaped ground segments
for (var i = 0; i < self.segmentCount; i++) {
// Create a container for this segment (to handle the trapezoid shape)
var segmentContainer = new Container();
self.addChild(segmentContainer);
// Create the actual ground piece
var segment = segmentContainer.attachAsset('ground', {
anchorX: 0.5,
anchorY: 0 // Anchor at top
});
// Position the segment
segmentContainer.y = self.horizonY + i * self.segmentHeight;
// Store in our array for scrolling
self.segments.push({
container: segmentContainer,
segment: segment,
index: i
});
}
// Add a horizon line
var horizon = self.attachAsset('groundFar', {
anchorX: 0.5,
anchorY: 1 // Anchor at bottom
});
horizon.x = self.groundWidth / 2;
horizon.y = self.horizonY;
horizon.width = self.groundWidthFar;
// Update trapezoid shapes based on their position
self.updateSegmentShapes = function () {
for (var i = 0; i < self.segments.length; i++) {
var seg = self.segments[i];
var distFromHorizon = seg.container.y - self.horizonY;
// Calculate width based on distance from horizon
// Segments closer to horizon are narrower
var perspectiveFactor = Math.min(1, distFromHorizon / (2732 - self.horizonY));
var segmentWidth = self.groundWidthFar + (self.groundWidth - self.groundWidthFar) * perspectiveFactor;
// Update the segment shape
seg.segment.width = segmentWidth;
seg.segment.x = segmentWidth / 2; // Center within container
// Make closer segments taller for better perspective
seg.segment.height = self.segmentHeight * (0.7 + 0.3 * perspectiveFactor);
}
};
self.update = function () {
// Scroll all segments downward
for (var i = 0; i < self.segments.length; i++) {
var seg = self.segments[i];
seg.container.y += self.scrollSpeed;
// If segment has moved completely below screen, move it to the top
if (seg.container.y > 2732 + self.segmentHeight) {
// Find the segment that's currently highest
var highestY = Infinity;
for (var j = 0; j < self.segments.length; j++) {
if (j !== i && self.segments[j].container.y < highestY) {
highestY = self.segments[j].container.y;
}
}
// Place this segment above the highest one
seg.container.y = highestY - self.segmentHeight;
}
}
// Update shapes each frame to maintain perspective
self.updateSegmentShapes();
};
// Initialize shapes
self.updateSegmentShapes();
return self;
});
var PowerBar = Container.expand(function () {
var self = Container.call(this);
// Background bar
var background = self.attachAsset('powerBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
// Foreground bar (showing power level)
var bar = self.attachAsset('powerBar', {
anchorX: 0,
anchorY: 0.5,
x: -250
});
self.maxWidth = 500;
self.setPower = function (percent) {
var newWidth = self.maxWidth * percent;
bar.width = Math.max(0, Math.min(newWidth, self.maxWidth));
// Change color based on power level
if (percent < 0.3) {
bar.tint = 0xe74c3c; // Red when low
} else if (percent < 0.6) {
bar.tint = 0xf39c12; // Orange when medium
} else {
bar.tint = 0x2ecc71; // Green when high
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Set dark blue background for sky effect
game.setBackgroundColor(0x2c3e50);
// Game state variables
var score = 0;
var firepower = 100;
var maxFirepower = 100;
var firepowerRechargeRate = 0.5;
var firepowerUseRate = 2;
var gameActive = true;
var fireballs = [];
var enemies = [];
var fireParticles = [];
var isFiring = false;
var lastFireTime = 0;
var fireRate = 150; // ms between fireballs
var enemySpawnRate = 60; // Frames between enemy spawns
var difficultyScaling = 0;
var groundScroller = new GroundScroller();
game.addChild(groundScroller);
// Create dragon head (player character)
var dragon = game.addChild(new DragonHead());
dragon.x = 2048 / 2;
dragon.y = 2732 * 0.2; // Place dragon at top fifth of screen
// Create power bar
var powerBar = new PowerBar();
powerBar.x = 2048 / 2;
powerBar.y = 150;
LK.gui.top.addChild(powerBar);
// Score display
var scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.y = 50;
LK.gui.top.addChild(scoreTxt);
// Create a function to add fire particles
function createFireParticle(x, y) {
var particle = new FireParticle();
particle.x = x;
particle.y = y;
game.addChild(particle);
fireParticles.push(particle);
}
// Function to spawn a fireball
function spawnFireball() {
if (!gameActive || firepower < 10) {
return;
}
var now = Date.now();
if (now - lastFireTime < fireRate) {
return;
}
lastFireTime = now;
// Create new fireball
var fireball = new Fireball();
fireball.x = dragon.x;
fireball.y = dragon.y + 50; // Spawn below dragon's mouth
game.addChild(fireball);
fireballs.push(fireball);
// Use firepower
firepower -= firepowerUseRate;
powerBar.setPower(firepower / maxFirepower);
// Play sound
LK.getSound('firebreathSound').play();
}
// Function to spawn enemies
function spawnEnemy() {
if (!gameActive) {
return;
}
// Create enemy of random type
var type = Math.floor(Math.random() * 3) + 1;
var enemy = new Enemy(type);
// Position randomly along bottom of screen
enemy.x = Math.random() * (2048 - 200) + 100;
enemy.y = 2732 + 100; // Start below screen
game.addChild(enemy);
enemies.push(enemy);
}
// Game update logic
game.update = function () {
if (!gameActive) {
return;
}
// Check if mouth is open for fire breathing
if (facekit && facekit.mouthOpen) {
isFiring = true;
spawnFireball();
} else {
isFiring = false;
}
// Recharge firepower when not firing
if (!isFiring && firepower < maxFirepower) {
firepower += firepowerRechargeRate;
powerBar.setPower(firepower / maxFirepower);
}
// Warn player when power is low
if (firepower < 20 && Math.floor(LK.ticks) % 60 === 0) {
LK.getSound('powerLow').play();
}
// Spawn enemies
if (LK.ticks % Math.max(10, enemySpawnRate - difficultyScaling) === 0) {
spawnEnemy();
}
// Increase difficulty over time
if (LK.ticks % 300 === 0 && difficultyScaling < 40) {
difficultyScaling += 1;
}
// Update fireballs and check for collisions
for (var i = fireballs.length - 1; i >= 0; i--) {
var fireball = fireballs[i];
// Remove fireballs that go off screen
if (fireball.y < -100) {
fireball.destroy();
fireballs.splice(i, 1);
continue;
}
// Check for collisions with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (fireball.active && fireball.intersects(enemy)) {
// Hit the enemy
var killed = enemy.hit();
if (killed) {
score += enemy.type * 10;
scoreTxt.setText(score);
LK.setScore(score);
LK.getSound('enemyDefeat').play();
}
// Deactivate the fireball
fireball.active = false;
// Destroy it after a slight delay (for visual effect)
LK.setTimeout(function () {
if (fireballs.indexOf(fireball) !== -1) {
fireball.destroy();
fireballs.splice(fireballs.indexOf(fireball), 1);
}
}, 100);
break;
}
}
}
// Update enemies
for (var k = enemies.length - 1; k >= 0; k--) {
var currentEnemy = enemies[k];
// Remove enemies marked for destruction
if (currentEnemy.toDestroy) {
currentEnemy.destroy();
enemies.splice(k, 1);
continue;
}
// Check if enemy reaches player
if (currentEnemy.y < 300) {
// Game over
gameActive = false;
LK.getSound('gameOverSound').play();
LK.showGameOver();
}
}
// Update fire particles
for (var m = fireParticles.length - 1; m >= 0; m--) {
if (!fireParticles[m].parent) {
fireParticles.splice(m, 1);
}
}
};
// Start background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.3,
duration: 1000
}
});
A clear blue sky background with no clouds.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a small bush. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a wooden arrow with red feathers and a metal arrow head. Completely vertical orientation. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A small vertical flame. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a black scorch mark on the ground left by a meteor impact. cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A bright spark. Cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a red heart. cartoon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An SVG of the word **BOSS** in sharp red font.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An SVG of the word “Start” written in fire. Cartoon.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows