Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught ReferenceError: easingFunctions is not defined' in or related to this line: 'var behaviour = (_behaviours$enemyType = behaviours[enemyType]) !== null && _behaviours$enemyType !== void 0 ? _behaviours$enemyType : easingFunctions[Math.floor(Math.random() * easingFunctions.length)]; // Assign random easing function;' Line Number: 947
User prompt
Please fix the bug: 'Uncaught ReferenceError: easingFunctions is not defined' in or related to this line: 'var behaviour = (_behaviours$enemyType = behaviours[enemyType]) !== null && _behaviours$enemyType !== void 0 ? _behaviours$enemyType : easingFunctions[Math.floor(Math.random() * easingFunctions.length)]; // Assign random easing function;' Line Number: 947
Code edit (1 edits merged)
Please save this source code
User prompt
Every time you change the level, please call to addFloors(). Also, at the start the dragon does not appear on top of the ground floor now, please fix
Code edit (3 edits merged)
Please save this source code
User prompt
When I start a new game, the left, right and ground floors are not there1
Code edit (12 edits merged)
Please save this source code
User prompt
This is ok, but only works for level 1. I need it for the rest of the levels as well // BLOCKS // Add a floor to the bottom of the screen - create 1 floor out of 5 var floors = []; var floor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 - 30, width: 2048 }); game.addChild(floor); floors.push(floor); // Add continuous floor on the left margin of the screen - only every 5th floor var leftFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 50, y: 15 * 100, height: 3000 }); game.addChild(leftFloor); floors.push(leftFloor); var rightFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 40, y: 15 * 100, height: 3000 });
Code edit (1 edits merged)
Please save this source code
Code edit (2 edits merged)
Please save this source code
User prompt
You need to do the same with platformYPositions on the distinct heights!
User prompt
You need to do the same with the platforms
User prompt
You need to do the same with the platforms.
User prompt
Ok there are tooooo many floors and they are too small, which makes a lot of floors and the intersection checks very heavy. Make 1 floor out of 5 that we have right now, that hsould reduce the floors in 1/5
User prompt
No, still does not work if mirrored.
User prompt
Careful! the width becomes negative (-300) if mirrored, you need to take that into account! // Check if click is anywhere near the dragon - use more generous hit testing // Create a larger hit area rectangle for the dragon with 1.5x the size var dragonBounds = new Rectangle(dragon.x - dragon.width * 0.75, // Wider hit area left dragon.y - dragon.height * 0.75, // Taller hit area top dragon.width * 1.5, // 50% wider hit area dragon.height * 1.5 // 50% taller hit area ); console.log(dragonBounds); console.log(x, y); // Check if click point is within the dragon's bounds if (dragonBounds.contains(x, y)) { // Only shoot a bubble when clicking on or near the dragon if (now - lastShot > 200) { dragon.shootBubble(); lastShot = now; } }
Code edit (2 edits merged)
Please save this source code
User prompt
var dragonBounds = new Rectangle(dragon.x - dragon.width / 2, dragon.y - dragon.height / 2, dragon.width, dragon.height); This is very strict, please be much more acceptant
User prompt
if (Math.abs(x - dragon.x) < dragon.width / 2 && Math.abs(y - dragon.y) < dragon.height / 2) { is not working. Find another way
User prompt
var point = new Container(); point.x = x; point.y = y; console.log(point.x, point.y); console.log(dragon.x, dragon.y); if (point.intersects(dragon)) { // Only shoot a bubble when clicking directly on the dragon if (now - lastClick > 200) { dragon.shootBubble(); lastShot = now; } } THis is not shooting a bubble although these are the console logs? VM28:602 1713.1916666666668 2529.9458333333337 VM28:603 1720.631107349702 2552 VM28:602 1676.1958333333334 2555.558333333334 VM28:603 1696.9027755909174 2552 VM28:602 1562.3625000000002 2584.016666666667 VM28:603 1628.9430217245933 2552 VM28:602 1548.1333333333334 2592.554166666667 VM28:603 1569.6840460502608 2552 VM28:602 1548.1333333333334 2592.554166666667 VM28:603 1548.9555370396877 2552
Code edit (2 edits merged)
Please save this source code
User prompt
This is not reliable and it's not working. Use intersect or something else? if (Math.abs(x - dragon.x) < dragon.width && Math.abs(y - dragon.y) < dragon.height) {
Code edit (1 edits merged)
Please save this source code
User prompt
There are some serious issues. After I jump to platforms I click on the dragon and bubbles are not shot.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Class for Bubbles var Bubble = Container.expand(function () { var self = Container.call(this); var bubbleGraphics = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -5; self.update = function () { self.x += self.speed; // Check for intersection with any floor for (var i = 0; i < floors.length; i++) { if (self.intersects(floors[i])) { // Create a PoppedBubble at the bubble's position var pop = game.addChild(new PoppedBubble()); pop.x = self.x; pop.y = self.y; // Destroy the bubble self.destroy(); bubbles.splice(bubbles.indexOf(self), 1); // Destroy the PoppedBubble after 0.5 seconds LK.setTimeout(function () { pop.destroy(); }, 500); break; } } // Update last known positions self.lastX = self.x; self.lastY = self.y; }; }); var CapturingBubble = Container.expand(function () { var self = Container.call(this); var bubbleGraphics = self.attachAsset('bubble', { anchorX: 0.5, anchorY: 0.5 }); self.alpha = 0.5; self.scaleX = 2; self.scaleY = 2; self.update = function () {}; }); //<Assets used in the game will automatically appear here> // Class for the Dragon character var Dragon = Container.expand(function () { var self = Container.call(this); self.dragonGraphics = self.attachAsset('dragon', { anchorX: 0.5, anchorY: 0.5 }); self.isIntersectingBubble = false; // Add a variable to track if the dragon is intersecting a bubble self.shootBubble = function () { var bubble = new Bubble(); bubble.x = self.x + 200 * self.scaleX; bubble.y = self.y - 5; // If the dragon is looking right, the bubble should move to the right if (self.scale.x == 1) { bubble.speed = 25; } else { // If the dragon is looking left, the bubble should move to the left bubble.speed = -25; } game.addChild(bubble); bubbles.push(bubble); // Play bubble sound when a bubble is shot LK.getSound('bubble').play(); }; }); // Class for Pop var PoppedBubble = Container.expand(function () { var self = Container.call(this); var popGraphics = self.attachAsset('poppedBubble', { anchorX: 0.5, anchorY: 0.5 }); }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x09899d }); /**** * Game Code ****/ function tweenDragonContainer() { tween(dragonOnContainer, { y: dragonOnContainer.y + 300 }, { duration: 1000, onFinish: function onFinish() { tween(dragonOnContainer, { y: dragonOnContainer.y - 300 }, { duration: 1000 }); } }); } var started = false; // Initialize started flag var intervalId = LK.setInterval(function () { if (!started) { tweenDragonContainer(); } else { LK.clearInterval(intervalId); // Clear interval if started is true } }, 4000); var controlPanel = new Container(); var panelBackground = LK.getAsset('game_background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.8 }); controlPanel.addChild(panelBackground); var instructionsText = new Text2('INSTRUCTIONS', { size: 100, fill: 0xffffff, align: "center", font: "Comic Sans MS", fontWeight: "bold" }); instructionsText.anchor.set(0.5, 0.5); instructionsText.x = 2048 / 2; instructionsText.y = 75; controlPanel.addChild(instructionsText); // Rainbow color array var rainbowColors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x8B00FF]; var colorIndex = 0; // Function to cycle through rainbow colors function cycleRainbowColors() { instructionsText.tint = rainbowColors[colorIndex]; colorIndex = (colorIndex + 1) % rainbowColors.length; } // Set interval to change color every 500ms LK.setInterval(cycleRainbowColors, 500); var controlText = new Text2('- Click on 🐲 to shoot 🫧\n- Click above the 🐲 to jump ⬆️.\n- The higher you click, the bigger the jump ⬆️⬆️!', { size: 85, // Increased size for better visibility fill: 0x000000, align: "center", font: "Comic Sans MS" // Adding a cool font and bold style }); controlText.anchor.set(0.5, 0.5); controlText.x = 2048 / 2; controlText.y = 400; controlPanel.addChild(controlText); var understoodButtonBackgroundBg = LK.getAsset('understoodBg', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 800, width: 2000, alpha: 0.5 }); controlPanel.addChild(understoodButtonBackgroundBg); var dragonOnContainer = LK.getAsset('dragon', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 1200, scaleX: 2, scaleY: 2 }); controlPanel.addChild(dragonOnContainer); var bubbleOnContainer = LK.getAsset('bubble', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2, alpha: 0.35 }); dragonOnContainer.addChild(bubbleOnContainer); var understoodButton = new Text2('Click anywhere to start', { size: 150, fill: 0x1570e0, align: "center" }); understoodButton.anchor.set(0.5, 0.5); understoodButton.x = 2048 / 2; understoodButton.y = 800; controlPanel.addChild(understoodButton); game.addChild(controlPanel); // Add event listener to the 'Understood' button understoodButton.interactive = true; understoodButton.buttonMode = true; game.down = function (x, y, obj) { controlPanel.destroy(); startGame(); }; var bubbles = []; // Initialize bubbles array to store bubble instances var floors = []; // Initialize floors array to store floor instances var behaviours = {}; // Initialize behaviours object var enemies = []; var capturingBubbles = []; function startGame() { started = true; var level = 1; function restartGame() { // Clear existing platforms and enemies floors.forEach(function (floor) { floor.destroy(); }); floors = []; enemies.forEach(function (enemy) { enemy.destroy(); }); enemies = []; // Recreate floors at the bottom, left, and right margins for (var i = 0; i < 21; i++) { var floor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: i * 100, y: 2732 - 30 }); game.addChild(floor); floors.push(floor); } for (var j = 0; j < 27; j++) { var leftFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 0, y: j * 100 }); game.addChild(leftFloor); floors.push(leftFloor); } for (var k = 0; k < 27; k++) { var rightFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 50, y: k * 100 }); game.addChild(rightFloor); floors.push(rightFloor); } // Destroy the existing dragon dragon.destroy(); // Recreate the dragon and add it to the game dragon = game.addChild(new Dragon()); // Reposition dragon at the bottom dragon.x = 1024; // Center horizontally dragon.y = 2532; // Position the dragon on top of the floor // Add new platforms and enemies for the new level for (var j = 0; j < platformYPositions.length; j++) { var platformLength = Math.floor(Math.random() * (maxPlatformLength - minPlatformLength + 1)) + minPlatformLength; var startX = Math.floor(Math.random() * (2048 - platformLength * 100)); var startY = platformYPositions[j]; var randomTint = Math.floor(Math.random() * 16777215); for (var i = 0; i < platformLength; i++) { var newX = startX + i * 100; if (newX > 1900 || newX < 120) { continue; } var platform = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: startX + i * 100, y: platformYPositions[j] }); platform.tint = randomTint; game.addChild(platform); floors.push(platform); } var enemyType = 'enemy' + (i % 5 + 1); var behaviour = behaviours[enemyType] || easingFunctions[Math.floor(Math.random() * easingFunctions.length)]; behaviours[enemyType] = behaviour; var enemy = LK.getAsset(enemyType, { anchorX: 0.5, anchorY: 0.5, x: startX + 100, y: platformYPositions[j] - 100, type: enemyType }); if (enemyType === 'enemy5' || enemyType === 'enemy2') { enemy.tint = Math.floor(Math.random() * 0x7FFFFF) + 0x808080; } enemy.captured = false; game.addChild(enemy); enemies.push(enemy); } } var background = LK.getAsset('pixel_background_' + level.toString(), { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2, alpha: 0.95 }); game.addChild(background); function _toConsumableArray2(r) { return _arrayWithoutHoles2(r) || _iterableToArray2(r) || _unsupportedIterableToArray3(r) || _nonIterableSpread2(); } function _nonIterableSpread2() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray3(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray3(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray3(r, a) : void 0; } } function _iterableToArray2(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) { return Array.from(r); } } function _arrayWithoutHoles2(r) { if (Array.isArray(r)) { return _arrayLikeToArray3(r); } } function _arrayLikeToArray3(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray2(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) { throw o; } } } }; } function _unsupportedIterableToArray2(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray2(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray2(r, a) : void 0; } } function _arrayLikeToArray2(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) { return Array.from(r); } } function _arrayWithoutHoles(r) { if (Array.isArray(r)) { return _arrayLikeToArray(r); } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } var jumpStartTime; // Declare jumpStartTime to track the start of the jump var easingFunctions = [tween.linear, tween.easeIn, tween.easeOut, tween.easeInOut, tween.bounceIn, tween.bounceOut, tween.bounceInOut, tween.elasticIn, tween.elasticOut, tween.elasticInOut, tween.cubicIn, tween.cubicOut, tween.cubitInOut, tween.expoIn, tween.expoOut, tween.expoInOut, tween.sineIn, tween.sineOut, tween.sineInOut]; LK.playMusic('music'); function isStandingOnFloor() { for (var i = 0; i < floors.length; i++) { if (dragon.intersects(floors[i])) { return true; } } return false; } function updateFall() { if (isFalling) { dragon.y += 85; // Move dragon downwards faster // Use a more efficient loop to check for intersection with any floor var _iterator = _createForOfIteratorHelper(floors), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var floor = _step.value; // Check if dragon is landing on a floor if (!dragon.lastWasIntersecting && dragon.intersects(floor)) { isJumping = false; // Stop jumping isFalling = false; // Stop falling when colliding with a floor canJump = true; // Allow jumping again when the dragon hits a floor dragon.y = floor.y - floor.height * 1.5; // Align dragon to the top of the floor break; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } // Update last known intersection state dragon.lastWasIntersecting = floors.some(function (floor) { return dragon.intersects(floor); }); } //<Assets used in the game will automatically appear here> // Handle mouse move events to move the dragon game.move = function (x, y, obj) { // Ignore the event if the target is outside the screen or close to its margins if (x > 150 && x < 2048 - 200) { // Set the target x position for the dragon dragon.targetX = x; } }; var isFalling = false; // Initialize isFalling to track dragon's fall state var dragon = game.addChild(new Dragon()); dragon.lastY = dragon.y; // Initialize lastY position dragon.x = 1024; // Center horizontally dragon.y = 2532; // Position the dragon on top of the floor // Handle game updates game.update = function () { // Move dragon incrementally towards target x if (dragon.targetX !== undefined) { var increment = (dragon.targetX - dragon.x) / 10; // Move in 0.5 seconds assuming 60 FPS if (dragon.targetX !== undefined && (increment > 0 && dragon.x < dragon.targetX || increment < 0 && dragon.x > dragon.targetX)) { dragon.x += increment; } // Update last known position dragon.lastX = dragon.x; dragon.lastY = dragon.y; // Track lastY position // Adjust dragon's scale based on targetX position if (dragon.targetX < dragon.x) { dragon.scale.x = -1; } else { dragon.scale.x = 1; } } var standingOnFloor = isStandingOnFloor(); if (!standingOnFloor && !isJumping) { isFalling = true; } /*if (standingOnFloor && dragon.wings) { dragon.wings = false; dragon.removeChild(dragon.dragonGraphics); // Remove the current dragon graphics dragon.dragonGraphics = dragon.attachAsset('dragon', { anchorX: 0.5, anchorY: 0.5 }); dragon.addChild(dragon.dragonGraphics); }*/ if (LK.ticks % 2 === 0) { updateJump(); } if (LK.ticks % 2 === 0) { updateFall(); } if (LK.ticks % 1 === 0) { updateBubbles(); } if (LK.ticks % 15 === 0) { updateEnemiesMovement(); } }; // Handle touch events for shooting bubbles var lastShot = 0; var lastClick = 0; var isJumping = false; // Add a variable to track if the dragon is jumping var canJump = true; // Initialize canJump flag to allow jumping game.down = function (x, y, obj) { var now = Date.now(); if (y < dragon.y - dragon.height && canJump && !isJumping) { isJumping = true; // Set isJumping to true when the dragon starts jumping // Play jump sound when the dragon starts jumping LK.getSound('jump').play(); jumpStartY = y; // Capture the Y position of the mouse click jumpStartTime = Date.now(); // Initialize jump start time } else if (Math.abs(x - dragon.x) < dragon.width && Math.abs(y - dragon.y) < dragon.height) { // Only shoot a bubble when clicking directly on the dragon // Using full width/height instead of half for better touch detection if (now - lastClick > 200) { dragon.shootBubble(); lastShot = now; } } lastClick = now; }; function updateEnemiesMovement() { enemies.forEach(function (enemy) { if (enemy.captured) { if (enemy.isMoving) { tween.stop(enemy); enemy.isMoving = false; enemy.floating = true; } else if (enemy.floating) { tween(enemy, { y: 100 }, { duration: 5000, easing: tween.linear, onFinish: function onFinish() { console.log(enemy.children[1].tint); enemy.children[1].tint = 0xbf5555; if (enemies.length === 0) { if (level < 5) { level++; background.destroy(); // Remove the previous background background = LK.getAsset('pixel_background_' + level.toString(), { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 - background.height / 2, // Position at the bottom of the screen alpha: 0.95 }); game.addChild(background); // Add the new background var levelTextBackground = new Text2('LEVEL ' + level.toString(), { size: 210, fill: 0x000000 }); levelTextBackground.anchor.set(0.5, 0.5); levelTextBackground.x = 2048 / 2; levelTextBackground.y = 2732 / 2; game.addChild(levelTextBackground); LK.setTimeout(function () { levelTextBackground.destroy(); }, 2000); var levelText = new Text2('LEVEL ' + level.toString(), { size: 200, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.x = 2048 / 2; levelText.y = 2732 / 2; game.addChild(levelText); LK.setTimeout(function () { levelText.destroy(); }, 2000); // Restart game with new platforms and enemies restartGame(); } else { LK.showYouWin(); } } } }); } } else if (!enemy.isMoving) { enemy.isMoving = true; var platformFloors = floors.filter(function (floor) { return floor.y === enemy.y + 100 && floor.x > 0 && floor.x < 2048 - 50; }); var startX = Math.min.apply(Math, _toConsumableArray2(platformFloors.map(function (floor) { return floor.x; }))); var endX = Math.max.apply(Math, _toConsumableArray2(platformFloors.map(function (floor) { return floor.x; }))); enemy.alpha = 0.75; // Apply alpha when starting to move tween(enemy, { x: endX }, { duration: Math.random() * 10000, easing: behaviours[enemy.type], onFinish: function onFinish() { tween(enemy, { x: startX }, { duration: 2000, easing: tween.linear, onFinish: function onFinish() { enemy.isMoving = false; enemy.alpha = 1; // Restore alpha on finish } }); } }); } enemy.scale.x = enemy.lastX < enemy.x ? 1 : -1; if (!enemy.captured && dragon.intersects(enemy)) { // Play game over sound when the dragon dies LK.getSound('gameover').play(); // Rotate the dragon 90 degrees left dragon.rotation = -3 * Math.PI * dragon.scale.x; // Animate the dragon falling down tween(dragon, { y: 2732 + dragon.height, // Move dragon off the screen tint: 0xFF0000 }, { duration: 500, // Duration of the fall easing: tween.linear, onFinish: function onFinish() { // Show game over after the dragon has fallen LK.showGameOver(); } }); } enemy.lastX = enemy.x; enemy.lastY = enemy.y; }); } function updateBubbles() { // Update bubbles for (var i = bubbles.length - 1; i >= 0; i--) { var bubble = bubbles[i]; if (!bubble) { continue; } // Check for bubble-bubble intersections for (var j = i - 1; j >= 0; j--) { var otherBubble = bubbles[j]; if (!otherBubble) { continue; } if (bubble.intersects(otherBubble)) { // Create a PoppedBubble for each intersecting bubble var pop1 = game.addChild(new PoppedBubble()); pop1.x = bubble.x; pop1.y = bubble.y; var pop2 = game.addChild(new PoppedBubble()); pop2.x = otherBubble.x; pop2.y = otherBubble.y; // Destroy both bubbles bubble.destroy(); otherBubble.destroy(); bubbles.splice(i, 1); bubbles.splice(j, 1); // Play pop sound when a bubble is popped LK.getSound('pop').play(); // Destroy the PoppedBubbles after 0.5 seconds LK.setTimeout(function () { pop1.destroy(); pop2.destroy(); }, 500); break; } } if (!bubble) { return; } if (bubble.y < -50) { bubble.destroy(); bubbles.splice(i, 1); } } // Check for bubble-enemy collisions for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; for (var j = bubbles.length - 1; j >= 0; j--) { var bubble = bubbles[j]; if (bubble.intersects(enemy)) { // Destroy the original bubble bubble.destroy(); bubbles.splice(j, 1); // Create a new bubble as a child of the enemy var newBubble = new CapturingBubble(); newBubble.x = 0; // Position relative to the enemy newBubble.y = 0; // Position relative to the enemy enemy.addChild(newBubble); enemy.captured = true; capturingBubbles.push(newBubble); break; } } } // Check if the dragon is intersecting a bubble for (var i = 0; i < bubbles.length; i++) { if (dragon.intersects(bubbles[i])) { // Create a PoppedBubble at the bubble's position var pop = game.addChild(new PoppedBubble()); pop.x = bubbles[i].x; pop.y = bubbles[i].y; // Destroy the bubble bubbles[i].destroy(); bubbles.splice(i, 1); // Play pop sound when a bubble is popped LK.getSound('pop').play(); // Destroy the PoppedBubble after 0.5 seconds LK.setTimeout(function () { pop.destroy(); }, 500); break; } } // Check if the dragon is intersecting a CapturingBubble for (var i = capturingBubbles.length - 1; i >= 0; i--) { var capturingBubble = capturingBubbles[i]; if (dragon.intersects(capturingBubble)) { // Find and destroy the enemy that is the parent of the CapturingBubble for (var j = enemies.length - 1; j >= 0; j--) { var enemy = enemies[j]; if (enemy.children.includes(capturingBubble)) { // Create a PoppedBubble at the capturingBubble's position var pop = game.addChild(new PoppedBubble()); pop.x = enemy.x; pop.y = enemy.y; // Destroy the enemy and capturingBubble enemy.destroy(); enemies.splice(j, 1); // Play pop sound when a capturing bubble is popped LK.getSound('pop').play(); // Destroy the PoppedBubble after 2 seconds LK.setTimeout(function () { pop.destroy(); }, 1000); break; } } } } capturingBubbles.forEach(function (capturingBubble) { var enemy = capturingBubble.parent; if (enemy && !enemy.captured) { enemy.y -= 150; // Make the enemy jump with the dragon } }); } function updateJump() { if (isJumping) { // Calculate how far into the jump we are (0 to 1) var jumpElapsed = Date.now() - jumpStartTime; var jumpDuration = 200; // 200ms jump duration var jumpProgress = Math.min(jumpElapsed / jumpDuration, 1); // Calculate the position based on jumpStartY and current progress var initialY = dragon.y; // Starting position // Calculate maximum jump height based on click position // The higher the click, the smaller the jump (limited by dragon's current position) var maxJumpHeight = Math.min(dragon.y - jumpStartY, 500); // Cap maximum jump at 500px var targetY = dragon.y - maxJumpHeight; // Target position based on click var jumpDistance = initialY - targetY; // Total distance to cover // Calculate new Y position dragon.y = initialY - jumpDistance * jumpProgress; // Check for intersection with any floor var intersectingFloor = floors.find(function (floor) { return !dragon.lastWasIntersecting && dragon.intersects(floor); }); if (intersectingFloor) { isJumping = false; // Stop jumping isFalling = true; // Start falling when colliding with a floor canJump = false; // Disallow jumping again until the dragon hits a floor dragon.y = intersectingFloor.y - intersectingFloor.height * 1.5; // Align dragon to the top of the floor } // Check if jump duration has exceeded jump time if (jumpProgress >= 1) { isJumping = false; isFalling = true; } } // Update last known intersection state dragon.lastWasIntersecting = floors.some(function (floor) { return dragon.intersects(floor); }); } // BLOCKS // Add a floor to the bottom of the screen var floors = []; for (var i = 0; i < 21; i++) { var floor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: i * 100, y: 2732 - 30 }); game.addChild(floor); floors.push(floor); } // Add continuous floor on the left margin of the screen for (var j = 0; j < 27; j++) { var leftFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 0, y: j * 100 }); game.addChild(leftFloor); floors.push(leftFloor); } // Add continuous floor on the right margin of the screen for (var k = 0; k < 27; k++) { var rightFloor = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: 2048 - 50, y: k * 100 }); game.addChild(rightFloor); floors.push(rightFloor); } // Add random platforms with irregular heights and positions var platformYPositions = []; var distinctHeights = [2300, 1900, 1500, 1100, 700]; // Define 4-5 distinct heights var minPlatformLength = 5; var maxPlatformLength = 14; distinctHeights.forEach(function (height) { platformYPositions.push(height); }); // Add random platforms with irregular heights and positions for (var j = 0; j < platformYPositions.length; j++) { var _behaviours$enemyType; var platformLength = Math.floor(Math.random() * (maxPlatformLength - minPlatformLength + 1)) + minPlatformLength; var startX = Math.floor(Math.random() * (2048 - platformLength * 100)); // Random start position var startY = platformYPositions[j]; // Generate a random tint color for the platforms var randomTint = Math.floor(Math.random() * 16777215); for (var i = 0; i < platformLength; i++) { var newX = startX + i * 100; if (newX > 1900 || newX < 120) { continue; } var platform = LK.getAsset('floor', { anchorX: 0.5, anchorY: 0.5, x: startX + i * 100, y: platformYPositions[j] }); platform.tint = randomTint; // Apply the random tint to the platform game.addChild(platform); floors.push(platform); } // Spawn an enemy on top of each platform var enemyType = 'enemy' + (i % 5 + 1); // Cycle through enemy1 to enemy5 var behaviour = (_behaviours$enemyType = behaviours[enemyType]) !== null && _behaviours$enemyType !== void 0 ? _behaviours$enemyType : easingFunctions[Math.floor(Math.random() * easingFunctions.length)]; // Assign random easing function; behaviours[enemyType] = behaviour; var enemy = LK.getAsset(enemyType, { anchorX: 0.5, anchorY: 0.5, x: startX + 100, y: platformYPositions[j] - 100, type: enemyType }); if (enemyType === 'enemy5' || enemyType === 'enemy2') { enemy.tint = Math.floor(Math.random() * 0x7FFFFF) + 0x808080; // Ensure light tint } enemy.captured = false; game.addChild(enemy); enemies.push(enemy); } /* LEVEL MANAGEMENT 1 */ var levelTextBackground = new Text2('LEVEL ' + level.toString(), { size: 210, fill: 0x000000 }); levelTextBackground.anchor.set(0.5, 0.5); levelTextBackground.x = 2048 / 2; levelTextBackground.y = 2732 / 2; game.addChild(levelTextBackground); LK.setTimeout(function () { levelTextBackground.destroy(); }, 2000); var levelText = new Text2('LEVEL ' + level.toString(), { size: 200, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.x = 2048 / 2; levelText.y = 2732 / 2; game.addChild(levelText); LK.setTimeout(function () { levelText.destroy(); }, 2000); }
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Class for Bubbles
var Bubble = Container.expand(function () {
var self = Container.call(this);
var bubbleGraphics = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -5;
self.update = function () {
self.x += self.speed;
// Check for intersection with any floor
for (var i = 0; i < floors.length; i++) {
if (self.intersects(floors[i])) {
// Create a PoppedBubble at the bubble's position
var pop = game.addChild(new PoppedBubble());
pop.x = self.x;
pop.y = self.y;
// Destroy the bubble
self.destroy();
bubbles.splice(bubbles.indexOf(self), 1);
// Destroy the PoppedBubble after 0.5 seconds
LK.setTimeout(function () {
pop.destroy();
}, 500);
break;
}
}
// Update last known positions
self.lastX = self.x;
self.lastY = self.y;
};
});
var CapturingBubble = Container.expand(function () {
var self = Container.call(this);
var bubbleGraphics = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5
});
self.alpha = 0.5;
self.scaleX = 2;
self.scaleY = 2;
self.update = function () {};
});
//<Assets used in the game will automatically appear here>
// Class for the Dragon character
var Dragon = Container.expand(function () {
var self = Container.call(this);
self.dragonGraphics = self.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
self.isIntersectingBubble = false; // Add a variable to track if the dragon is intersecting a bubble
self.shootBubble = function () {
var bubble = new Bubble();
bubble.x = self.x + 200 * self.scaleX;
bubble.y = self.y - 5;
// If the dragon is looking right, the bubble should move to the right
if (self.scale.x == 1) {
bubble.speed = 25;
} else {
// If the dragon is looking left, the bubble should move to the left
bubble.speed = -25;
}
game.addChild(bubble);
bubbles.push(bubble);
// Play bubble sound when a bubble is shot
LK.getSound('bubble').play();
};
});
// Class for Pop
var PoppedBubble = Container.expand(function () {
var self = Container.call(this);
var popGraphics = self.attachAsset('poppedBubble', {
anchorX: 0.5,
anchorY: 0.5
});
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x09899d
});
/****
* Game Code
****/
function tweenDragonContainer() {
tween(dragonOnContainer, {
y: dragonOnContainer.y + 300
}, {
duration: 1000,
onFinish: function onFinish() {
tween(dragonOnContainer, {
y: dragonOnContainer.y - 300
}, {
duration: 1000
});
}
});
}
var started = false; // Initialize started flag
var intervalId = LK.setInterval(function () {
if (!started) {
tweenDragonContainer();
} else {
LK.clearInterval(intervalId); // Clear interval if started is true
}
}, 4000);
var controlPanel = new Container();
var panelBackground = LK.getAsset('game_background', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.8
});
controlPanel.addChild(panelBackground);
var instructionsText = new Text2('INSTRUCTIONS', {
size: 100,
fill: 0xffffff,
align: "center",
font: "Comic Sans MS",
fontWeight: "bold"
});
instructionsText.anchor.set(0.5, 0.5);
instructionsText.x = 2048 / 2;
instructionsText.y = 75;
controlPanel.addChild(instructionsText);
// Rainbow color array
var rainbowColors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x8B00FF];
var colorIndex = 0;
// Function to cycle through rainbow colors
function cycleRainbowColors() {
instructionsText.tint = rainbowColors[colorIndex];
colorIndex = (colorIndex + 1) % rainbowColors.length;
}
// Set interval to change color every 500ms
LK.setInterval(cycleRainbowColors, 500);
var controlText = new Text2('- Click on 🐲 to shoot 🫧\n- Click above the 🐲 to jump ⬆️.\n- The higher you click, the bigger the jump ⬆️⬆️!', {
size: 85,
// Increased size for better visibility
fill: 0x000000,
align: "center",
font: "Comic Sans MS" // Adding a cool font and bold style
});
controlText.anchor.set(0.5, 0.5);
controlText.x = 2048 / 2;
controlText.y = 400;
controlPanel.addChild(controlText);
var understoodButtonBackgroundBg = LK.getAsset('understoodBg', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 800,
width: 2000,
alpha: 0.5
});
controlPanel.addChild(understoodButtonBackgroundBg);
var dragonOnContainer = LK.getAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 1200,
scaleX: 2,
scaleY: 2
});
controlPanel.addChild(dragonOnContainer);
var bubbleOnContainer = LK.getAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2,
alpha: 0.35
});
dragonOnContainer.addChild(bubbleOnContainer);
var understoodButton = new Text2('Click anywhere to start', {
size: 150,
fill: 0x1570e0,
align: "center"
});
understoodButton.anchor.set(0.5, 0.5);
understoodButton.x = 2048 / 2;
understoodButton.y = 800;
controlPanel.addChild(understoodButton);
game.addChild(controlPanel);
// Add event listener to the 'Understood' button
understoodButton.interactive = true;
understoodButton.buttonMode = true;
game.down = function (x, y, obj) {
controlPanel.destroy();
startGame();
};
var bubbles = []; // Initialize bubbles array to store bubble instances
var floors = []; // Initialize floors array to store floor instances
var behaviours = {}; // Initialize behaviours object
var enemies = [];
var capturingBubbles = [];
function startGame() {
started = true;
var level = 1;
function restartGame() {
// Clear existing platforms and enemies
floors.forEach(function (floor) {
floor.destroy();
});
floors = [];
enemies.forEach(function (enemy) {
enemy.destroy();
});
enemies = [];
// Recreate floors at the bottom, left, and right margins
for (var i = 0; i < 21; i++) {
var floor = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: i * 100,
y: 2732 - 30
});
game.addChild(floor);
floors.push(floor);
}
for (var j = 0; j < 27; j++) {
var leftFloor = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: j * 100
});
game.addChild(leftFloor);
floors.push(leftFloor);
}
for (var k = 0; k < 27; k++) {
var rightFloor = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 50,
y: k * 100
});
game.addChild(rightFloor);
floors.push(rightFloor);
}
// Destroy the existing dragon
dragon.destroy();
// Recreate the dragon and add it to the game
dragon = game.addChild(new Dragon());
// Reposition dragon at the bottom
dragon.x = 1024; // Center horizontally
dragon.y = 2532; // Position the dragon on top of the floor
// Add new platforms and enemies for the new level
for (var j = 0; j < platformYPositions.length; j++) {
var platformLength = Math.floor(Math.random() * (maxPlatformLength - minPlatformLength + 1)) + minPlatformLength;
var startX = Math.floor(Math.random() * (2048 - platformLength * 100));
var startY = platformYPositions[j];
var randomTint = Math.floor(Math.random() * 16777215);
for (var i = 0; i < platformLength; i++) {
var newX = startX + i * 100;
if (newX > 1900 || newX < 120) {
continue;
}
var platform = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: startX + i * 100,
y: platformYPositions[j]
});
platform.tint = randomTint;
game.addChild(platform);
floors.push(platform);
}
var enemyType = 'enemy' + (i % 5 + 1);
var behaviour = behaviours[enemyType] || easingFunctions[Math.floor(Math.random() * easingFunctions.length)];
behaviours[enemyType] = behaviour;
var enemy = LK.getAsset(enemyType, {
anchorX: 0.5,
anchorY: 0.5,
x: startX + 100,
y: platformYPositions[j] - 100,
type: enemyType
});
if (enemyType === 'enemy5' || enemyType === 'enemy2') {
enemy.tint = Math.floor(Math.random() * 0x7FFFFF) + 0x808080;
}
enemy.captured = false;
game.addChild(enemy);
enemies.push(enemy);
}
}
var background = LK.getAsset('pixel_background_' + level.toString(), {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.95
});
game.addChild(background);
function _toConsumableArray2(r) {
return _arrayWithoutHoles2(r) || _iterableToArray2(r) || _unsupportedIterableToArray3(r) || _nonIterableSpread2();
}
function _nonIterableSpread2() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray3(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray3(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray3(r, a) : void 0;
}
}
function _iterableToArray2(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles2(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray3(r);
}
}
function _arrayLikeToArray3(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _createForOfIteratorHelper(r, e) {
var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
if (!t) {
if (Array.isArray(r) || (t = _unsupportedIterableToArray2(r)) || e && r && "number" == typeof r.length) {
t && (r = t);
var _n = 0,
F = function F() {};
return {
s: F,
n: function n() {
return _n >= r.length ? {
done: !0
} : {
done: !1,
value: r[_n++]
};
},
e: function e(r) {
throw r;
},
f: F
};
}
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
var o,
a = !0,
u = !1;
return {
s: function s() {
t = t.call(r);
},
n: function n() {
var r = t.next();
return a = r.done, r;
},
e: function e(r) {
u = !0, o = r;
},
f: function f() {
try {
a || null == t["return"] || t["return"]();
} finally {
if (u) {
throw o;
}
}
}
};
}
function _unsupportedIterableToArray2(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray2(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray2(r, a) : void 0;
}
}
function _arrayLikeToArray2(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
function _toConsumableArray(r) {
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
}
function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _unsupportedIterableToArray(r, a) {
if (r) {
if ("string" == typeof r) {
return _arrayLikeToArray(r, a);
}
var t = {}.toString.call(r).slice(8, -1);
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
}
}
function _iterableToArray(r) {
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) {
return Array.from(r);
}
}
function _arrayWithoutHoles(r) {
if (Array.isArray(r)) {
return _arrayLikeToArray(r);
}
}
function _arrayLikeToArray(r, a) {
(null == a || a > r.length) && (a = r.length);
for (var e = 0, n = Array(a); e < a; e++) {
n[e] = r[e];
}
return n;
}
var jumpStartTime; // Declare jumpStartTime to track the start of the jump
var easingFunctions = [tween.linear, tween.easeIn, tween.easeOut, tween.easeInOut, tween.bounceIn, tween.bounceOut, tween.bounceInOut, tween.elasticIn, tween.elasticOut, tween.elasticInOut, tween.cubicIn, tween.cubicOut, tween.cubitInOut, tween.expoIn, tween.expoOut, tween.expoInOut, tween.sineIn, tween.sineOut, tween.sineInOut];
LK.playMusic('music');
function isStandingOnFloor() {
for (var i = 0; i < floors.length; i++) {
if (dragon.intersects(floors[i])) {
return true;
}
}
return false;
}
function updateFall() {
if (isFalling) {
dragon.y += 85; // Move dragon downwards faster
// Use a more efficient loop to check for intersection with any floor
var _iterator = _createForOfIteratorHelper(floors),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var floor = _step.value;
// Check if dragon is landing on a floor
if (!dragon.lastWasIntersecting && dragon.intersects(floor)) {
isJumping = false; // Stop jumping
isFalling = false; // Stop falling when colliding with a floor
canJump = true; // Allow jumping again when the dragon hits a floor
dragon.y = floor.y - floor.height * 1.5; // Align dragon to the top of the floor
break;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
// Update last known intersection state
dragon.lastWasIntersecting = floors.some(function (floor) {
return dragon.intersects(floor);
});
}
//<Assets used in the game will automatically appear here>
// Handle mouse move events to move the dragon
game.move = function (x, y, obj) {
// Ignore the event if the target is outside the screen or close to its margins
if (x > 150 && x < 2048 - 200) {
// Set the target x position for the dragon
dragon.targetX = x;
}
};
var isFalling = false; // Initialize isFalling to track dragon's fall state
var dragon = game.addChild(new Dragon());
dragon.lastY = dragon.y; // Initialize lastY position
dragon.x = 1024; // Center horizontally
dragon.y = 2532; // Position the dragon on top of the floor
// Handle game updates
game.update = function () {
// Move dragon incrementally towards target x
if (dragon.targetX !== undefined) {
var increment = (dragon.targetX - dragon.x) / 10; // Move in 0.5 seconds assuming 60 FPS
if (dragon.targetX !== undefined && (increment > 0 && dragon.x < dragon.targetX || increment < 0 && dragon.x > dragon.targetX)) {
dragon.x += increment;
}
// Update last known position
dragon.lastX = dragon.x;
dragon.lastY = dragon.y; // Track lastY position
// Adjust dragon's scale based on targetX position
if (dragon.targetX < dragon.x) {
dragon.scale.x = -1;
} else {
dragon.scale.x = 1;
}
}
var standingOnFloor = isStandingOnFloor();
if (!standingOnFloor && !isJumping) {
isFalling = true;
}
/*if (standingOnFloor && dragon.wings) {
dragon.wings = false;
dragon.removeChild(dragon.dragonGraphics); // Remove the current dragon graphics
dragon.dragonGraphics = dragon.attachAsset('dragon', {
anchorX: 0.5,
anchorY: 0.5
});
dragon.addChild(dragon.dragonGraphics);
}*/
if (LK.ticks % 2 === 0) {
updateJump();
}
if (LK.ticks % 2 === 0) {
updateFall();
}
if (LK.ticks % 1 === 0) {
updateBubbles();
}
if (LK.ticks % 15 === 0) {
updateEnemiesMovement();
}
};
// Handle touch events for shooting bubbles
var lastShot = 0;
var lastClick = 0;
var isJumping = false; // Add a variable to track if the dragon is jumping
var canJump = true; // Initialize canJump flag to allow jumping
game.down = function (x, y, obj) {
var now = Date.now();
if (y < dragon.y - dragon.height && canJump && !isJumping) {
isJumping = true; // Set isJumping to true when the dragon starts jumping
// Play jump sound when the dragon starts jumping
LK.getSound('jump').play();
jumpStartY = y; // Capture the Y position of the mouse click
jumpStartTime = Date.now(); // Initialize jump start time
} else if (Math.abs(x - dragon.x) < dragon.width && Math.abs(y - dragon.y) < dragon.height) {
// Only shoot a bubble when clicking directly on the dragon
// Using full width/height instead of half for better touch detection
if (now - lastClick > 200) {
dragon.shootBubble();
lastShot = now;
}
}
lastClick = now;
};
function updateEnemiesMovement() {
enemies.forEach(function (enemy) {
if (enemy.captured) {
if (enemy.isMoving) {
tween.stop(enemy);
enemy.isMoving = false;
enemy.floating = true;
} else if (enemy.floating) {
tween(enemy, {
y: 100
}, {
duration: 5000,
easing: tween.linear,
onFinish: function onFinish() {
console.log(enemy.children[1].tint);
enemy.children[1].tint = 0xbf5555;
if (enemies.length === 0) {
if (level < 5) {
level++;
background.destroy(); // Remove the previous background
background = LK.getAsset('pixel_background_' + level.toString(), {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - background.height / 2,
// Position at the bottom of the screen
alpha: 0.95
});
game.addChild(background); // Add the new background
var levelTextBackground = new Text2('LEVEL ' + level.toString(), {
size: 210,
fill: 0x000000
});
levelTextBackground.anchor.set(0.5, 0.5);
levelTextBackground.x = 2048 / 2;
levelTextBackground.y = 2732 / 2;
game.addChild(levelTextBackground);
LK.setTimeout(function () {
levelTextBackground.destroy();
}, 2000);
var levelText = new Text2('LEVEL ' + level.toString(), {
size: 200,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
levelText.x = 2048 / 2;
levelText.y = 2732 / 2;
game.addChild(levelText);
LK.setTimeout(function () {
levelText.destroy();
}, 2000);
// Restart game with new platforms and enemies
restartGame();
} else {
LK.showYouWin();
}
}
}
});
}
} else if (!enemy.isMoving) {
enemy.isMoving = true;
var platformFloors = floors.filter(function (floor) {
return floor.y === enemy.y + 100 && floor.x > 0 && floor.x < 2048 - 50;
});
var startX = Math.min.apply(Math, _toConsumableArray2(platformFloors.map(function (floor) {
return floor.x;
})));
var endX = Math.max.apply(Math, _toConsumableArray2(platformFloors.map(function (floor) {
return floor.x;
})));
enemy.alpha = 0.75; // Apply alpha when starting to move
tween(enemy, {
x: endX
}, {
duration: Math.random() * 10000,
easing: behaviours[enemy.type],
onFinish: function onFinish() {
tween(enemy, {
x: startX
}, {
duration: 2000,
easing: tween.linear,
onFinish: function onFinish() {
enemy.isMoving = false;
enemy.alpha = 1; // Restore alpha on finish
}
});
}
});
}
enemy.scale.x = enemy.lastX < enemy.x ? 1 : -1;
if (!enemy.captured && dragon.intersects(enemy)) {
// Play game over sound when the dragon dies
LK.getSound('gameover').play();
// Rotate the dragon 90 degrees left
dragon.rotation = -3 * Math.PI * dragon.scale.x;
// Animate the dragon falling down
tween(dragon, {
y: 2732 + dragon.height,
// Move dragon off the screen
tint: 0xFF0000
}, {
duration: 500,
// Duration of the fall
easing: tween.linear,
onFinish: function onFinish() {
// Show game over after the dragon has fallen
LK.showGameOver();
}
});
}
enemy.lastX = enemy.x;
enemy.lastY = enemy.y;
});
}
function updateBubbles() {
// Update bubbles
for (var i = bubbles.length - 1; i >= 0; i--) {
var bubble = bubbles[i];
if (!bubble) {
continue;
}
// Check for bubble-bubble intersections
for (var j = i - 1; j >= 0; j--) {
var otherBubble = bubbles[j];
if (!otherBubble) {
continue;
}
if (bubble.intersects(otherBubble)) {
// Create a PoppedBubble for each intersecting bubble
var pop1 = game.addChild(new PoppedBubble());
pop1.x = bubble.x;
pop1.y = bubble.y;
var pop2 = game.addChild(new PoppedBubble());
pop2.x = otherBubble.x;
pop2.y = otherBubble.y;
// Destroy both bubbles
bubble.destroy();
otherBubble.destroy();
bubbles.splice(i, 1);
bubbles.splice(j, 1);
// Play pop sound when a bubble is popped
LK.getSound('pop').play();
// Destroy the PoppedBubbles after 0.5 seconds
LK.setTimeout(function () {
pop1.destroy();
pop2.destroy();
}, 500);
break;
}
}
if (!bubble) {
return;
}
if (bubble.y < -50) {
bubble.destroy();
bubbles.splice(i, 1);
}
}
// Check for bubble-enemy collisions
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
for (var j = bubbles.length - 1; j >= 0; j--) {
var bubble = bubbles[j];
if (bubble.intersects(enemy)) {
// Destroy the original bubble
bubble.destroy();
bubbles.splice(j, 1);
// Create a new bubble as a child of the enemy
var newBubble = new CapturingBubble();
newBubble.x = 0; // Position relative to the enemy
newBubble.y = 0; // Position relative to the enemy
enemy.addChild(newBubble);
enemy.captured = true;
capturingBubbles.push(newBubble);
break;
}
}
}
// Check if the dragon is intersecting a bubble
for (var i = 0; i < bubbles.length; i++) {
if (dragon.intersects(bubbles[i])) {
// Create a PoppedBubble at the bubble's position
var pop = game.addChild(new PoppedBubble());
pop.x = bubbles[i].x;
pop.y = bubbles[i].y;
// Destroy the bubble
bubbles[i].destroy();
bubbles.splice(i, 1);
// Play pop sound when a bubble is popped
LK.getSound('pop').play();
// Destroy the PoppedBubble after 0.5 seconds
LK.setTimeout(function () {
pop.destroy();
}, 500);
break;
}
}
// Check if the dragon is intersecting a CapturingBubble
for (var i = capturingBubbles.length - 1; i >= 0; i--) {
var capturingBubble = capturingBubbles[i];
if (dragon.intersects(capturingBubble)) {
// Find and destroy the enemy that is the parent of the CapturingBubble
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (enemy.children.includes(capturingBubble)) {
// Create a PoppedBubble at the capturingBubble's position
var pop = game.addChild(new PoppedBubble());
pop.x = enemy.x;
pop.y = enemy.y;
// Destroy the enemy and capturingBubble
enemy.destroy();
enemies.splice(j, 1);
// Play pop sound when a capturing bubble is popped
LK.getSound('pop').play();
// Destroy the PoppedBubble after 2 seconds
LK.setTimeout(function () {
pop.destroy();
}, 1000);
break;
}
}
}
}
capturingBubbles.forEach(function (capturingBubble) {
var enemy = capturingBubble.parent;
if (enemy && !enemy.captured) {
enemy.y -= 150; // Make the enemy jump with the dragon
}
});
}
function updateJump() {
if (isJumping) {
// Calculate how far into the jump we are (0 to 1)
var jumpElapsed = Date.now() - jumpStartTime;
var jumpDuration = 200; // 200ms jump duration
var jumpProgress = Math.min(jumpElapsed / jumpDuration, 1);
// Calculate the position based on jumpStartY and current progress
var initialY = dragon.y; // Starting position
// Calculate maximum jump height based on click position
// The higher the click, the smaller the jump (limited by dragon's current position)
var maxJumpHeight = Math.min(dragon.y - jumpStartY, 500); // Cap maximum jump at 500px
var targetY = dragon.y - maxJumpHeight; // Target position based on click
var jumpDistance = initialY - targetY; // Total distance to cover
// Calculate new Y position
dragon.y = initialY - jumpDistance * jumpProgress;
// Check for intersection with any floor
var intersectingFloor = floors.find(function (floor) {
return !dragon.lastWasIntersecting && dragon.intersects(floor);
});
if (intersectingFloor) {
isJumping = false; // Stop jumping
isFalling = true; // Start falling when colliding with a floor
canJump = false; // Disallow jumping again until the dragon hits a floor
dragon.y = intersectingFloor.y - intersectingFloor.height * 1.5; // Align dragon to the top of the floor
}
// Check if jump duration has exceeded jump time
if (jumpProgress >= 1) {
isJumping = false;
isFalling = true;
}
}
// Update last known intersection state
dragon.lastWasIntersecting = floors.some(function (floor) {
return dragon.intersects(floor);
});
}
// BLOCKS
// Add a floor to the bottom of the screen
var floors = [];
for (var i = 0; i < 21; i++) {
var floor = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: i * 100,
y: 2732 - 30
});
game.addChild(floor);
floors.push(floor);
}
// Add continuous floor on the left margin of the screen
for (var j = 0; j < 27; j++) {
var leftFloor = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: j * 100
});
game.addChild(leftFloor);
floors.push(leftFloor);
}
// Add continuous floor on the right margin of the screen
for (var k = 0; k < 27; k++) {
var rightFloor = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 - 50,
y: k * 100
});
game.addChild(rightFloor);
floors.push(rightFloor);
}
// Add random platforms with irregular heights and positions
var platformYPositions = [];
var distinctHeights = [2300, 1900, 1500, 1100, 700]; // Define 4-5 distinct heights
var minPlatformLength = 5;
var maxPlatformLength = 14;
distinctHeights.forEach(function (height) {
platformYPositions.push(height);
});
// Add random platforms with irregular heights and positions
for (var j = 0; j < platformYPositions.length; j++) {
var _behaviours$enemyType;
var platformLength = Math.floor(Math.random() * (maxPlatformLength - minPlatformLength + 1)) + minPlatformLength;
var startX = Math.floor(Math.random() * (2048 - platformLength * 100)); // Random start position
var startY = platformYPositions[j];
// Generate a random tint color for the platforms
var randomTint = Math.floor(Math.random() * 16777215);
for (var i = 0; i < platformLength; i++) {
var newX = startX + i * 100;
if (newX > 1900 || newX < 120) {
continue;
}
var platform = LK.getAsset('floor', {
anchorX: 0.5,
anchorY: 0.5,
x: startX + i * 100,
y: platformYPositions[j]
});
platform.tint = randomTint; // Apply the random tint to the platform
game.addChild(platform);
floors.push(platform);
}
// Spawn an enemy on top of each platform
var enemyType = 'enemy' + (i % 5 + 1); // Cycle through enemy1 to enemy5
var behaviour = (_behaviours$enemyType = behaviours[enemyType]) !== null && _behaviours$enemyType !== void 0 ? _behaviours$enemyType : easingFunctions[Math.floor(Math.random() * easingFunctions.length)]; // Assign random easing function;
behaviours[enemyType] = behaviour;
var enemy = LK.getAsset(enemyType, {
anchorX: 0.5,
anchorY: 0.5,
x: startX + 100,
y: platformYPositions[j] - 100,
type: enemyType
});
if (enemyType === 'enemy5' || enemyType === 'enemy2') {
enemy.tint = Math.floor(Math.random() * 0x7FFFFF) + 0x808080; // Ensure light tint
}
enemy.captured = false;
game.addChild(enemy);
enemies.push(enemy);
}
/* LEVEL MANAGEMENT 1 */
var levelTextBackground = new Text2('LEVEL ' + level.toString(), {
size: 210,
fill: 0x000000
});
levelTextBackground.anchor.set(0.5, 0.5);
levelTextBackground.x = 2048 / 2;
levelTextBackground.y = 2732 / 2;
game.addChild(levelTextBackground);
LK.setTimeout(function () {
levelTextBackground.destroy();
}, 2000);
var levelText = new Text2('LEVEL ' + level.toString(), {
size: 200,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
levelText.x = 2048 / 2;
levelText.y = 2732 / 2;
game.addChild(levelText);
LK.setTimeout(function () {
levelText.destroy();
}, 2000);
}
A version of this bubble but exploded
brick, brown color, pixel style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
better wings, pixel style, more contrasted, more visible, blue color
a pixel clouds background. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a pixel clouds background, with mountains, full height full width Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a similar image. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a pixel clouds background, with mountains, full height full width Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A popped blue bobble, pixel style, bubble booble arcade game inspired. In-Game asset. 2d. High contrast. No shadows
A bubble popping, pixel style, retro. In-Game asset. 2d. High contrast. No shadows