User prompt
There are some serious issues. After I jump to platforms I click on the dragon and bubbles are not shot.
User prompt
In here, you are not makign sure the buuble is only shoot if I click on myself, the dragon! 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 (!isJumping) { if (now - lastClick > 200) { dragon.shootBubble(); lastShot = now; } lastClick = now; };
Code edit (1 edits merged)
Please save this source code
User prompt
I donm't understand. I click very low in the scren and jumps a lot! It should jump max to the place on y I click / tap on the screen
Code edit (3 edits merged)
Please save this source code
User prompt
UpdateJump is incorrect. You should use jumpStartY to see where the dragon should be in the period of time the interval of the jump lasts and update in intervals until it reaches jumpStartY in that time.
Code edit (2 edits merged)
Please save this source code
User prompt
Remove the updateJump() function. Instead, when the dragon should jump, create a tween to the target position and back. Keep the isJumping because you will need it to make sure it lands on a floor if it finds it in its falling trajectory, etc. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: dragon.containsPoint is not a function' in or related to this line: 'if (dragon.containsPoint(obj.position)) {' Line Number: 572
User prompt
The bubbles are not always being triggered when clicking the dragon player. Please make sure always a bubble is triggered on tapping the dragon.
User prompt
Make that the jump is not a tween but a just linear movement using an interval or something super quick and performant.
User prompt
Redo the game
Code edit (1 edits merged)
Please save this source code
User prompt
The amount of things you do on every tick (game.update) is insane! updateJump(); updateFall(); } // Update game elements in an optimized order updateBubbles(); updateEnemiesMovement(); You can't do that so frequently. You need to come up with another way of doing all of that not on a tick frequency
User prompt
The amount of things you do on every tick (game.update) is insane! updateJump(); updateFall(); } // Update game elements in an optimized order updateBubbles(); updateEnemiesMovement(); You can't do that so frequently. You need to come up with another way of doing all of that not on a tick frequency
User prompt
Remove everything being check at a tick to remove all performance issues. Instead please do optimized checks
User prompt
Keep removing and simplifying everything that runs on ticks without breaking functionalities, to reduce to the maximum the RAM consumed and the CPU used.
User prompt
Remove the tweens from the enemies. Replace them with just a normal movement without the tween library.
User prompt
The performance is terrible on mobile, as there are many things being checked on a tick level + the tweens. Please, optimize the performance to the max but keeping all the same features intact. Don't touche the collisions between the dragon and the floors. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The floor collisions are broken: sometimes the dragon falls just by walking on them. Please firx that, a floor should never be able to be crossed by a dragon. A dragon should be able to always walk on floors. A dragon can never fall across a floor, it should stop on top of any floor it finds.
Code edit (2 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'var bottomFloorTop = floors.length > 0 ? bottomFloorY - floors[0].height / 2 : bottomFloorY; // Top edge of the bottom floor' Line Number: 497
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'length')' in or related to this line: 'var bottomFloorTop = floors.length > 0 ? bottomFloorY - floors[0].height / 2 : bottomFloorY; // Top edge of the bottom floor' Line Number: 490
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading '0')' in or related to this line: 'var bottomFloorTop = bottomFloorY - floors[0].height / 2; // Top edge of the bottom floor' Line Number: 488
/**** * 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({ // No title, no description // Always backgroundColor is black backgroundColor: 0x000000 });
===================================================================
--- original.js
+++ change.js
@@ -5,25 +5,38 @@
/****
* Classes
****/
-// Class for Bubbles - optimized for performance
+// 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.lastX = 0;
- self.lastY = 0;
self.update = function () {
- // Store last position
+ 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;
- // Move bubble
- self.x += self.speed;
- // Collision checks are now centralized in the updateBubbles function
};
});
var CapturingBubble = Container.expand(function () {
var self = Container.call(this);
@@ -36,859 +49,46 @@
self.scaleY = 2;
self.update = function () {};
});
//<Assets used in the game will automatically appear here>
-// Class for the Dragon character - optimized for performance
+// 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.lastX = 0;
- self.lastY = 0;
+ self.isIntersectingBubble = false; // Add a variable to track if the dragon is intersecting a bubble
self.shootBubble = function () {
- // Create new bubble and ensure it's properly initialized
var bubble = new Bubble();
- bubble.x = self.x + 200 * self.scale.x;
+ bubble.x = self.x + 200 * self.scaleX;
bubble.y = self.y - 5;
- bubble.lastX = bubble.x;
- bubble.lastY = bubble.y;
// 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;
}
- // Add bubble to game display list first to ensure it's rendered
game.addChild(bubble);
- // Ensure bubbles array exists before trying to push to it
- if (!bubbles) {
- bubbles = [];
- }
- // Always add bubble to tracking array
bubbles.push(bubble);
// Play bubble sound when a bubble is shot
LK.getSound('bubble').play();
};
});
-// Class for Pop - optimized version
+// Class for Pop
var PoppedBubble = Container.expand(function () {
var self = Container.call(this);
var popGraphics = self.attachAsset('poppedBubble', {
anchorX: 0.5,
anchorY: 0.5
});
- return self;
});
/****
* 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 less frequently to improve performance
-LK.setInterval(cycleRainbowColors, 1000);
-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();
-};
-// Properly initialize all global variables to prevent undefined errors
-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 = [];
-var jumpStartY = 0;
-var isJumping = false; // Initialize jumping state
-var canJump = true; // Initialize jump permission flag
-var isFalling = false; // Initialize falling state
-var lastShot = 0; // Track the last time a bubble was shot
-var lastClick = 0; // Track the last time the screen was clicked
-var jumpStartTime = 0; // Initialize jump start time
-var dragon; // Will be initialized later
-var background; // Will be initialized with a background image
-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);
- // Simplified utility function that replaces all the complex array handlers
- function getMinMaxFromFloors(floors, property) {
- var min = Infinity;
- var max = -Infinity;
- for (var i = 0; i < floors.length; i++) {
- var value = floors[i][property];
- if (value < min) {
- min = value;
- }
- if (value > max) {
- max = value;
- }
- }
- return {
- min: min,
- max: max
- };
- }
- 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() {
- // Store the dragon's position
- var dragonBottom = dragon.y + dragon.height / 2;
- for (var i = 0; i < floors.length; i++) {
- var floor = floors[i];
- var floorTop = floor.y - floor.height / 2;
- // More precise collision detection for standing on platforms
- if (dragon.intersects(floor) && Math.abs(dragonBottom - floorTop) < 20 && dragon.lastY < dragon.y) {
- return true;
- }
- }
- return false;
- }
- function updateFall() {
- if (isFalling) {
- // Store last position before moving
- var lastY = dragon.y;
- // Move dragon downwards with a smaller increment to prevent passing through platforms
- dragon.y += 20;
- // Check for collisions after moving
- var isIntersecting = false;
- for (var i = 0; i < floors.length; i++) {
- // Check if dragon is intersecting with a floor
- if (dragon.intersects(floors[i])) {
- isIntersecting = true;
- // Only stop falling if we weren't intersecting before (just collided)
- if (!dragon.lastWasIntersecting || lastY < floors[i].y - floors[i].height) {
- 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 = floors[i].y - floors[i].height * 1.5; // Align dragon to the top of the floor
- break;
- }
- }
- }
- // Update last known intersection state
- dragon.lastWasIntersecting = isIntersecting;
- }
- }
- //<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 with improved frame handling
- game.update = function () {
- // Store last position at the beginning of update
- if (dragon) {
- dragon.lastX = dragon.x;
- dragon.lastY = dragon.y;
- }
- // Handle game over animation for dragon without using tweens
- if (dragon.gameOverAnimation) {
- dragon.y += dragon.gameOverSpeed;
- if (dragon.y > 2732 + dragon.height) {
- LK.showGameOver();
- return;
- }
- }
- if (!dragon.gameOverAnimation) {
- // Move dragon incrementally towards target x with improved movement
- if (dragon.targetX !== undefined) {
- var increment = (dragon.targetX - dragon.x) / 5; // Faster movement for better responsiveness
- if (Math.abs(dragon.targetX - dragon.x) > 1) {
- dragon.x += increment;
- }
- // Adjust dragon's scale based on movement direction
- dragon.scale.x = dragon.targetX < dragon.x ? -1 : 1;
- }
- // Determine vertical state and update accordingly
- var standingOnFloor = isStandingOnFloor(); // Check floor status once per frame
- if (isJumping) {
- // Handle jump logic (includes potential transition to falling)
- updateJump();
- } else if (standingOnFloor) {
- // Dragon is on the floor and not jumping
- isFalling = false; // Ensure falling state is off
- canJump = true; // Can initiate a new jump
- // Optional: Could add code here to snap dragon precisely to floor y if needed
- } else {
- // Dragon is not jumping and not standing on a floor -> must be falling
- isFalling = true; // Ensure falling state is on
- updateFall(); // Handle fall logic (includes potential transition to grounded)
- }
- }
- // No per-tick updateBubbles or updateEnemiesMovement here!
- };
- // Use intervals for bubbles and enemies updates to reduce per-tick load
- var bubblesUpdateInterval = LK.setInterval(function () {
- if (started && !dragon.gameOverAnimation) {
- updateBubbles();
- }
- }, 350); // 20 times per second
- var enemiesUpdateInterval = LK.setInterval(function () {
- if (started && !dragon.gameOverAnimation) {
- updateEnemiesMovement();
- }
- }, 600); // 10 times per second
- // 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 (!isJumping) {
- // Reduce cooldown for more responsive shooting and fix bubble creation
- if (now - lastShot > 300) {
- // Ensure dragon exists before calling shootBubble
- if (dragon && typeof dragon.shootBubble === 'function') {
- dragon.shootBubble();
- lastShot = now;
- }
- }
- }
- lastClick = now;
- };
- function updateEnemiesMovement() {
- // Process all enemies once per frame with optimized movement and collision detection
- var allCaptured = true;
- for (var i = 0; i < enemies.length; i++) {
- var enemy = enemies[i];
- if (!enemy) {
- continue;
- }
- // Update allCaptured tracking
- if (!enemy.captured) {
- allCaptured = false;
- }
- if (enemy.captured) {
- if (enemy.isMoving) {
- enemy.isMoving = false;
- enemy.floating = true;
- enemy.floatSpeed = 5;
- enemy.floatStartY = enemy.y;
- } else if (enemy.floating) {
- // Direct position update for floating enemies
- enemy.y -= enemy.floatSpeed;
- // Check if enemy has reached the target height
- if (enemy.y <= 100) {
- // Change tint when reaching the top
- if (enemy.children && enemy.children[1]) {
- enemy.children[1].tint = 0xbf5555;
- }
- }
- }
- } else {
- // Initialize movement parameters only once
- if (!enemy.isMoving && !enemy.movementInitialized) {
- enemy.isMoving = true;
- enemy.movementInitialized = true;
- // Find platform boundaries in one pass
- var platformY = enemy.y + 100;
- var startX = 2048;
- var endX = 0;
- var foundPlatform = false;
- for (var j = 0; j < floors.length; j++) {
- var floor = floors[j];
- if (Math.abs(floor.y - platformY) < 10 && floor.x > 0 && floor.x < 2048 - 50) {
- foundPlatform = true;
- if (floor.x < startX) {
- startX = floor.x;
- }
- if (floor.x > endX) {
- endX = floor.x;
- }
- }
- }
- // Only set movement parameters if we found a valid platform
- if (foundPlatform && startX < endX) {
- enemy.alpha = 0.75; // Apply alpha when starting to move
- enemy.startX = startX;
- enemy.endX = endX;
- enemy.moveSpeed = 3; // Pixels per frame
- enemy.isMovingRight = true; // Start moving right
- }
- }
- // Handle horizontal movement for non-captured enemies
- if (enemy.isMoving && !enemy.captured) {
- // Update movement direction and position
- if (enemy.isMovingRight) {
- enemy.x += enemy.moveSpeed;
- if (enemy.x >= enemy.endX) {
- enemy.isMovingRight = false;
- }
- } else {
- enemy.x -= enemy.moveSpeed;
- if (enemy.x <= enemy.startX) {
- enemy.isMovingRight = true;
- }
- }
- }
- // Update enemy direction based on movement
- if (enemy.x !== enemy.lastX) {
- enemy.scale.x = enemy.x > enemy.lastX ? 1 : -1;
- }
- // Check for collision with dragon in a single pass
- if (!enemy.captured && dragon.intersects(enemy) && !game.gameOverTriggered) {
- game.gameOverTriggered = true;
- // Play game over sound when the dragon dies
- LK.getSound('gameover').play();
- // Rotate the dragon 90 degrees
- dragon.rotation = -3 * Math.PI * dragon.scale.x;
- // Direct position and property updates for game over animation
- dragon.gameOverAnimation = true;
- dragon.gameOverSpeed = 15;
- dragon.tint = 0xFF0000;
- }
- }
- // Update last known position in a single place
- enemy.lastX = enemy.x;
- enemy.lastY = enemy.y;
- }
- // Check if all enemies are captured and handle level completion
- if (allCaptured && 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,
- alpha: 0.95
- });
- game.addChild(background); // Add the new background
- // Combined level text creation to reduce object creation
- 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();
- }
- }
- }
- function updateBubbles() {
- // Ensure bubbles array exists to prevent errors
- if (!bubbles) {
- bubbles = [];
- return;
- }
- // Process all bubbles once per frame with optimized collision detection
- for (var i = bubbles.length - 1; i >= 0; i--) {
- var bubble = bubbles[i];
- if (!bubble) {
- bubbles.splice(i, 1);
- continue;
- }
- // Move bubble
- bubble.x += bubble.speed;
- // Early removal check for off-screen bubbles
- if (bubble.y < -50 || bubble.x < -50 || bubble.x > 2100) {
- bubble.destroy();
- bubbles.splice(i, 1);
- continue; // Skip further checks for this bubble
- }
- // Single-pass collision detection
- var collided = false;
- // Check for bubble-bubble intersections only once per pair
- for (var j = i - 1; j >= 0 && !collided; j--) {
- var otherBubble = bubbles[j];
- if (!otherBubble) {
- bubbles.splice(j, 1);
- continue;
- }
- if (bubble.intersects(otherBubble)) {
- // Create PoppedBubbles
- 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 bubbles
- bubble.destroy();
- otherBubble.destroy();
- // Remove from array
- bubbles.splice(i, 1);
- if (j < i) {
- bubbles.splice(j, 1);
- }
- // Play pop sound
- LK.getSound('pop').play();
- // Destroy PoppedBubbles after delay
- LK.setTimeout(function () {
- pop1.destroy();
- pop2.destroy();
- }, 500);
- collided = true;
- break; // Exit inner loop after collision
- }
- }
- // Skip further checks if already collided
- if (collided) {
- continue;
- }
- // Check for bubble-enemy collisions
- for (var k = enemies.length - 1; k >= 0 && !collided; k--) {
- var enemy = enemies[k];
- if (!enemy || enemy.captured) {
- continue;
- }
- if (bubble.intersects(enemy)) {
- // Destroy the original bubble
- bubble.destroy();
- bubbles.splice(i, 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);
- collided = true;
- break; // Exit inner loop after collision
- }
- }
- // Skip further checks if already collided
- if (collided) {
- continue;
- }
- // Check for dragon collision (simpler than floor check)
- if (dragon.intersects(bubble)) {
- var pop = game.addChild(new PoppedBubble());
- pop.x = bubble.x;
- pop.y = bubble.y;
- bubble.destroy();
- bubbles.splice(i, 1);
- LK.getSound('pop').play();
- LK.setTimeout(function () {
- pop.destroy();
- }, 500);
- collided = true;
- continue;
- }
- // Only check floor collisions if we haven't collided yet
- if (!collided) {
- // Optimize floor collision check - only check floors near bubble
- for (var m = 0; m < floors.length; m++) {
- if (bubble.intersects(floors[m])) {
- var pop = game.addChild(new PoppedBubble());
- pop.x = bubble.x;
- pop.y = bubble.y;
- bubble.destroy();
- bubbles.splice(i, 1);
- LK.getSound('pop').play();
- LK.setTimeout(function () {
- pop.destroy();
- }, 500);
- collided = true;
- break; // Exit inner loop after collision
- }
- }
- }
- }
- // Process capturing bubbles in a separate pass
- for (var i = capturingBubbles.length - 1; i >= 0; i--) {
- var capturingBubble = capturingBubbles[i];
- if (!capturingBubble) {
- capturingBubbles.splice(i, 1);
- continue;
- }
- var enemy = capturingBubble.parent;
- if (enemy && enemy.captured && !enemy.floating) {
- enemy.y -= 5; // Make the enemy float up more smoothly
- }
- // Check for dragon-capturing bubble collisions
- 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) {
- continue;
- }
- if (enemy.children && enemy.children.indexOf(capturingBubble) !== -1) {
- // 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);
- // Remove from capturing bubbles array
- capturingBubbles.splice(i, 1);
- // Play pop sound when a capturing bubble is popped
- LK.getSound('pop').play();
- // Destroy the PoppedBubble after 1 second
- LK.setTimeout(function () {
- pop.destroy();
- }, 1000);
- break; // Exit inner loop after collision
- }
- }
- }
- }
- }
- function updateJump() {
- if (isJumping) {
- // Calculate jump height based on click position
- var jumpHeight = (dragon.y - jumpStartY) / 10;
- // Store last position before moving
- dragon.lastY = dragon.y;
- // Move dragon upwards based on calculated jump height
- dragon.y -= jumpHeight;
- // Check for ceiling collisions with early termination
- var dragonIntersectsFloor = false;
- for (var i = 0; i < floors.length; i++) {
- if (dragon.intersects(floors[i])) {
- dragonIntersectsFloor = true;
- if (!dragon.lastWasIntersecting) {
- 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 -= 25; // Push dragon away from the floor
- }
- break;
- }
- }
- // Check if jump duration has exceeded 0.4 seconds
- if (Date.now() - jumpStartTime >= 400) {
- isJumping = false;
- isFalling = true;
- }
- // Update last known intersection state
- dragon.lastWasIntersecting = dragonIntersectsFloor;
- }
- }
- // 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);
-}
\ No newline at end of file
+ // No title, no description
+ // Always backgroundColor is black
+ backgroundColor: 0x000000
+});
\ No newline at end of file
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