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({
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(); // Still needed for collision checks
}
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
// Calculate jump height based on click position
var jumpHeight = Math.min(dragon.y - y, 600); // Limit max jump height
var targetY = dragon.y - jumpHeight;
// Cancel any previous tween
tween.stop(dragon, {
y: true
});
// Create tween to jump up
tween(dragon, {
y: targetY
}, {
duration: 600,
easing: tween.easeOutQuad,
onFinish: function onFinish() {
// Create tween to fall back down
tween(dragon, {
y: dragon.y + jumpHeight
}, {
duration: 600,
easing: tween.easeInQuad,
onFinish: function onFinish() {
isJumping = false;
isFalling = true;
}
});
}
});
} else {
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() {
// The jumping logic is now handled by the tween, but we still need to check for floor collisions
if (isJumping) {
// Check for intersection with any floor
var intersectingFloor = floors.find(function (floor) {
return !dragon.lastWasIntersecting && dragon.intersects(floor);
});
if (intersectingFloor) {
// Cancel any ongoing jump tween
tween.stop(dragon, {
y: true
});
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
}
}
// 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);
} ===================================================================
--- original.js
+++ change.js
@@ -518,9 +518,9 @@
});
dragon.addChild(dragon.dragonGraphics);
}*/
if (LK.ticks % 2 === 0) {
- updateJump();
+ updateJump(); // Still needed for collision checks
}
if (LK.ticks % 2 === 0) {
updateFall();
}
@@ -543,13 +543,39 @@
// 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 > 500) {
- dragon.shootBubble();
- lastShot = now;
- // }
+ // Calculate jump height based on click position
+ var jumpHeight = Math.min(dragon.y - y, 600); // Limit max jump height
+ var targetY = dragon.y - jumpHeight;
+ // Cancel any previous tween
+ tween.stop(dragon, {
+ y: true
+ });
+ // Create tween to jump up
+ tween(dragon, {
+ y: targetY
+ }, {
+ duration: 600,
+ easing: tween.easeOutQuad,
+ onFinish: function onFinish() {
+ // Create tween to fall back down
+ tween(dragon, {
+ y: dragon.y + jumpHeight
+ }, {
+ duration: 600,
+ easing: tween.easeInQuad,
+ onFinish: function onFinish() {
+ isJumping = false;
+ isFalling = true;
+ }
+ });
+ }
+ });
+ } else {
+ dragon.shootBubble();
+ lastShot = now;
+ }
lastClick = now;
};
function updateEnemiesMovement() {
enemies.forEach(function (enemy) {
@@ -783,25 +809,24 @@
}
});
}
function updateJump() {
+ // The jumping logic is now handled by the tween, but we still need to check for floor collisions
if (isJumping) {
- dragon.y -= 40; // Move dragon upwards with a fixed speed
// Check for intersection with any floor
var intersectingFloor = floors.find(function (floor) {
return !dragon.lastWasIntersecting && dragon.intersects(floor);
});
if (intersectingFloor) {
+ // Cancel any ongoing jump tween
+ tween.stop(dragon, {
+ y: true
+ });
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 0.2 seconds
- if (Date.now() - jumpStartTime >= 400) {
- isJumping = false;
- isFalling = true;
- }
}
// Update last known intersection state
dragon.lastWasIntersecting = floors.some(function (floor) {
return dragon.intersects(floor);
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