Code edit (1 edits merged)
Please save this source code
User prompt
Add a flag called isMoving to each enemy. It should start with false. Then you set it to true when the enemy starts moving. When it finished moving back, set it to false. In game-update, make sure you check all the enemies are moving. If not, start their moving and tset the flag to true.
User prompt
Please fix the bug: 'RangeError: Maximum call stack size exceeded' in or related to this line: 'moveEnemy();' Line Number: 405
User prompt
Please fix the bug: 'RangeError: Maximum call stack size exceeded' in or related to this line: 'arguments.callee();' Line Number: 405
User prompt
The movement of the enemies - it should be never ending
Code edit (5 edits merged)
Please save this source code
User prompt
Move the enemies from left to right with some tween function but be careful, they can fall down if they don't stay on the floow, as it happens with the dragon ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Create a background image
Code edit (3 edits merged)
Please save this source code
User prompt
At the beginning of the game, spawn 1 different enemy (enemy1, enemy2, ,. ...) on top of each platform on the different hegihts)
Code edit (1 edits merged)
Please save this source code
User prompt
he intersection wtih a floor when jumping does not work properly. It allows half the dragon to get stuck in the floors. Please redo the intersection ONLY WHEN JUMPING so that: - You can't probably check "intersects" as that checks the center of the dragon. You probavly need to understand dragon and floor dimensions and check their bounding boxes properly
User prompt
The intersection wtih a floor when jumping does not work properly. It allows half the dragon to get stuck in the floors. Please redo it: - You can't probably check "intersects" as that checks the center of the dragon. You probavly need to understand dragon and floor dimensions and check their bounding boxes properly
Code edit (1 edits merged)
Please save this source code
User prompt
When there is an intersection of the dragon when it's jumping, you need to do the following: - First, stop immediately the tween with tween.stop - Update the dragon position so that it's below the floor and not intersecting - Make the dragon stall falling
Code edit (2 edits merged)
Please save this source code
User prompt
Check always that a dragon not standing on a floor should be falling
Code edit (1 edits merged)
Please save this source code
User prompt
f (jumpTrajectoryTop < floorBottom && dragon.y > floorTop && dragon.x + dragon.width <= floorRight && dragon.x - dragon.width >= floorLeft) This is not working well for detecting collisions. It frosm for calculating the trajectory up but combined with x and width it's not working properly.
Code edit (6 edits merged)
Please save this source code
User prompt
in canJump, as you have floorTop and floorBottom, calculate also floorLeft and floor Right
Code edit (2 edits merged)
Please save this source code
User prompt
This is not working at all. var canJump = true; for (var i = 0; i < floors.length; i++) { if (dragon.y > floors[i].y && dragon.y - 200 <= floors[i].y && dragon.x + dragon.width / 2 > floors[i].x - floors[i].width / 2 && dragon.x - dragon.width / 2 < floors[i].x + floors[i].width / 2) { canJump = false; break; } } Think about another way to do it
Code edit (3 edits merged)
Please save this source code
User prompt
Not sure I understand this, seems too restrictive to me. if (dragon.y > floors[i].y && dragon.y - 200 <= floors[i].y && dragon.intersects(floors[i])) { These are the conditions: - The jump is 200 pixels hight. Just check that the dragon trajectory up on 200 pixels is free (no floors). If not, the dragon can't jump.
/**** 
* 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;
	};
});
//<Assets used in the game will automatically appear here>
// Class for the Dragon character
var Dragon = Container.expand(function () {
	var self = Container.call(this);
	var 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;
		// If the dragon is looking right, the bubble should move to the right
		if (self.scale.x == 1) {
			bubble.speed = 10;
		} else {
			// If the dragon is looking left, the bubble should move to the left
			bubble.speed = -10;
		}
		game.addChild(bubble);
		bubbles.push(bubble);
	};
});
// 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: 0x000000 //Init game with black background
});
/**** 
* Game Code
****/ 
// Attach the background image to the game
var background = LK.getAsset('background', {
	anchorX: 0.5,
	anchorY: 0.5,
	x: 2048 / 2,
	y: 2732 / 2
});
game.addChild(background);
function isStandingOnFloor() {
	for (var i = 0; i < floors.length; i++) {
		if (dragon.intersects(floors[i])) {
			return true;
		}
	}
	return false;
}
function startDragonFall() {
	isFalling = true;
}
function updateFall() {
	if (isFalling || !isStandingOnFloor()) {
		dragon.y += 10; // Adjust fall speed as needed
		// Check for intersection with any floor
		for (var i = 0; i < floors.length; i++) {
			if (dragon.intersects(floors[i])) {
				isJumping = false; // Stop jumping
				isFalling = false; // Stop falling when colliding with a floor
				dragon.y -= floors[i].height / 8;
				dragon.targetX = undefined; // Reset targetX to allow movement after landing
				break;
			}
		}
	}
}
//<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 = 2732 - 90 - dragon.height / 2; // Position the dragon on top of the floor
var bubbles = [];
var enemies = [];
enemies.forEach(function (enemy) {
	enemy.isMoving = false; // Initialize isMoving flag to false
});
var floors = [];
// 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 (!isJumping && 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 x position
		if (dragon.targetX > 1024) {
			dragon.scale.x = -1;
		} else {
			dragon.scale.x = 1;
		}
	}
	// 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);
				// 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)) {
				// Capture enemy
				enemy.destroy();
				enemies.splice(i, 1);
				bubble.destroy();
				bubbles.splice(j, 1);
				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);
			// Destroy the PoppedBubble after 0.5 seconds
			LK.setTimeout(function () {
				pop.destroy();
			}, 500);
			break;
		}
	}
	updateFall();
};
// 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
game.down = function (x, y, obj) {
	var now = Date.now();
	if (now - lastShot > 500) {
		dragon.shootBubble();
		lastShot = now;
	}
	if (now - lastClick < 200 && (!isJumping && !isFalling || dragon.isIntersectingBubble)) {
		// Only allow the dragon to jump if it is not already jumping or if it is intersecting a bubble
		// Check if the jump trajectory is clear of floors
		var canJump = true;
		if (canJump) {
			isJumping = true; // Set isJumping to true when the dragon starts jumping
			// Make the dragon jump using a smooth animation
			tween(dragon, {
				y: dragon.y - 200
			}, {
				duration: 200,
				easing: tween.easeOut,
				onFinish: function onFinish() {
					isJumping = false; // Reset jumping state after the jump
					// Start dragon fall after jump
					startDragonFall();
				}
			});
		}
		// If the dragon is intersecting a bubble, show the pop asset before destroying the bubble
		if (dragon.isIntersectingBubble) {
			for (var i = 0; i < bubbles.length; i++) {
				if (dragon.intersects(bubbles[i])) {
					var pop = game.addChild(new PoppedBubble());
					pop.x = bubbles[i].x;
					pop.y = bubbles[i].y;
					bubbles[i].destroy();
					bubbles.splice(i, 1);
					LK.setTimeout(function () {
						pop.destroy();
					}, 500);
					break;
				}
			}
		}
	}
	lastClick = now;
};
// Add a floor to the bottom of the screen
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 random platforms with irregular heights and positions
var platformYPositions = [];
var currentY = 2300; // Start further from the bottom
var minPlatformHeight = 100;
var maxPlatformHeight = 400;
var minGap = 100;
var maxGap = 300;
var minPlatformLength = 5;
var maxPlatformLength = 15;
while (currentY > 400) {
	// Ensure platforms are not too close to the top
	var platformHeight = Math.floor(Math.random() * (maxPlatformHeight - minPlatformHeight + 1)) + minPlatformHeight;
	platformYPositions.push(currentY);
	currentY -= platformHeight + Math.floor(Math.random() * (maxGap - minGap + 1)) + minGap;
}
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)); // Random start position
	for (var i = 0; i < platformLength; i++) {
		var platform = LK.getAsset('floor', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: startX + i * 100,
			y: platformYPositions[j]
		});
		game.addChild(platform);
		floors.push(platform);
	}
}
// Add continuous floor on the left margin of the screen
for (var j = 0; j < 28; 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 < 28; 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
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)); // Random start position
	for (var i = 0; i < platformLength; i++) {
		var platform = LK.getAsset('floor', {
			anchorX: 0.5,
			anchorY: 0.5,
			x: startX + i * 100,
			y: platformYPositions[j]
		});
		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 enemy = LK.getAsset(enemyType, {
		anchorX: 0.5,
		anchorY: 0.5,
		x: startX + 100,
		y: platformYPositions[j] - 100 // Position enemy on top of the platform
	});
	game.addChild(enemy);
	enemies.push(enemy);
}
// Check if all enemies are moving and start their movement if not
enemies.forEach(function (enemy) {
	if (!enemy.isMoving) {
		// Start enemy movement
		tween(enemy, {
			x: enemy.x + 200
		}, {
			duration: 2000,
			easing: tween.linear,
			onFinish: function onFinish() {
				tween(enemy, {
					x: enemy.x - 200
				}, {
					duration: 2000,
					easing: tween.linear,
					onFinish: function onFinish() {
						enemy.isMoving = false; // Reset isMoving flag
					}
				});
			}
		});
		enemy.isMoving = true; // Set isMoving flag to true
	}
	if (enemy.lastX === undefined) {
		enemy.lastX = enemy.x;
	} // Initialize lastX for tracking changes on X
	if (enemy.lastY === undefined) {
		enemy.lastY = enemy.y;
	} // Initialize lastY for tracking changes on Y
	// Check if enemy is standing on a floor
	var isOnFloor = floors.some(function (floor) {
		return enemy.intersects(floor);
	});
	if (isOnFloor) {
		if (!enemy.isMoving) {
			enemy.isMoving = true; // Set isMoving flag to true when enemy starts moving
		}
		tween(enemy, {
			x: enemy.x + 200
		}, {
			duration: 2000,
			easing: tween.linear,
			onFinish: function onFinish() {
				// Reverse direction when reaching the edge of the platform
				tween(enemy, {
					x: enemy.x - 200
				}, {
					duration: 2000,
					easing: tween.linear,
					onFinish: function onFinish() {
						enemy.isMoving = false; // Set isMoving flag to false when enemy finishes moving back
					}
				});
			}
		});
	} else {
		// Make enemy fall if not on a floor
		enemy.y += 10;
	}
	// Update last known positions
	enemy.lastX = enemy.x;
	enemy.lastY = enemy.y;
}); ===================================================================
--- original.js
+++ change.js
@@ -130,8 +130,11 @@
 dragon.x = 1024; // Center horizontally
 dragon.y = 2732 - 90 - dragon.height / 2; // Position the dragon on top of the floor
 var bubbles = [];
 var enemies = [];
+enemies.forEach(function (enemy) {
+	enemy.isMoving = false; // Initialize isMoving flag to false
+});
 var floors = [];
 // Handle game updates
 game.update = function () {
 	// Move dragon incrementally towards target x
@@ -359,10 +362,31 @@
 	});
 	game.addChild(enemy);
 	enemies.push(enemy);
 }
-// Move enemies from left to right
+// Check if all enemies are moving and start their movement if not
 enemies.forEach(function (enemy) {
+	if (!enemy.isMoving) {
+		// Start enemy movement
+		tween(enemy, {
+			x: enemy.x + 200
+		}, {
+			duration: 2000,
+			easing: tween.linear,
+			onFinish: function onFinish() {
+				tween(enemy, {
+					x: enemy.x - 200
+				}, {
+					duration: 2000,
+					easing: tween.linear,
+					onFinish: function onFinish() {
+						enemy.isMoving = false; // Reset isMoving flag
+					}
+				});
+			}
+		});
+		enemy.isMoving = true; // Set isMoving flag to true
+	}
 	if (enemy.lastX === undefined) {
 		enemy.lastX = enemy.x;
 	} // Initialize lastX for tracking changes on X
 	if (enemy.lastY === undefined) {
@@ -372,9 +396,11 @@
 	var isOnFloor = floors.some(function (floor) {
 		return enemy.intersects(floor);
 	});
 	if (isOnFloor) {
-		// Tween enemy to move left to right
+		if (!enemy.isMoving) {
+			enemy.isMoving = true; // Set isMoving flag to true when enemy starts moving
+		}
 		tween(enemy, {
 			x: enemy.x + 200
 		}, {
 			duration: 2000,
@@ -386,25 +412,9 @@
 				}, {
 					duration: 2000,
 					easing: tween.linear,
 					onFinish: function onFinish() {
-						// Reverse direction when reaching the edge of the platform
-						tween(enemy, {
-							x: enemy.x - 200
-						}, {
-							duration: 2000,
-							easing: tween.linear,
-							onFinish: function onFinish() {
-								// Call the same function to create a loop
-								tween(enemy, {
-									x: enemy.x + 200
-								}, {
-									duration: 2000,
-									easing: tween.linear,
-									onFinish: arguments.callee
-								});
-							}
-						});
+						enemy.isMoving = false; // Set isMoving flag to false when enemy finishes moving back
 					}
 				});
 			}
 		});
 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