User prompt
obstacle 3 shouldd be slowly spining on its axis
Code edit (1 edits merged)
Please save this source code
User prompt
shapes can randomly have up to 100% more space between each grid element. but each wave will have the same spacing between its elements.
User prompt
shapes can randomly have up to 100% more space between each grid element
Code edit (2 edits merged)
Please save this source code
User prompt
bubbles tint should also get darker like background
User prompt
when a new wave is spawned, the obstacles x speed should not impact the previous obstacles x speed. they should be independent on each wave.
User prompt
when buubble moves sideways it should also move extra to the side the obstacle is movig
User prompt
increase a little bubble speed
User prompt
bubbles should also cahnge their y speed when obstacles change it
User prompt
when an obstacles is created create a temporary variable with their y original speed that will not be updated when a new wave is spawned
User prompt
change bubbles y speed the same way obstacles do
User prompt
bubbles should have the same y speed as obstacles
User prompt
each obstacle wave should keep their original obstacle.y speed independent from a new wave spawning with a new y speed
User prompt
when a new waveof obstacles is created, do not change the speed x of the obstacles already on the screen
Code edit (1 edits merged)
Please save this source code
User prompt
also increase the frequency whne a wave is spawned as the game gets harder
User prompt
obstacle should keep the x speed of when its created and not change (unless touched by shield or other obstacle)
User prompt
on tick check self.x speed of obstacle, and if not being touched by shield or repelled by other obstacle go back to its original speed
Code edit (1 edits merged)
Please save this source code
User prompt
on tick, make obstacle go back to their original x direciton
User prompt
when repulsion force is not applied anymore, make sure obstacles go back to their original x speed
User prompt
make sure obstacles do not change their x speed in any other part of the game other than the start and when shield or other obstacle moves them
User prompt
shieldoff should only play once
/****
* Classes
****/
// Background class
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = self.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732
});
backgroundGraphics.anchor.set(0, 0);
// Add black overlay on top of the background
var overlay = self.attachAsset('shape', {
width: 2048,
height: 2732,
color: 0x000000,
alpha: 0.0,
shape: 'box'
});
overlay.anchor.set(0, 0);
// This is automatically called every game tick, if the background is attached!
self.update = function () {
if (overlay.alpha < 1) {
overlay.alpha += 0.0001; // Increase alpha over time
}
};
});
// Bubble class
var Bubble = Container.expand(function () {
var self = Container.call(this);
var bubbleGraphics = self.attachAsset('bubble', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
var scale = Math.random() * 0.5 + 0.5;
bubbleGraphics.scale.set(scale, scale);
// Set bubble speed
self.speed = -2;
// Initialize colliding property
self.colliding = false;
// This is automatically called every game tick, if the bubble is attached!
self.update = function () {
// Move the bubble upwards and sideways
self.y += self.speed;
self.x += Math.sin(LK.ticks / 10) * 0.1;
// Reset the position of the bubble when it reaches the top
if (self.y <= 0) {
self.y = 2732;
}
// Check if the bubble is colliding with an obstacle using spatial hash
var cellSize = 150;
var hashX = Math.floor(self.x / cellSize);
var hashY = Math.floor(self.y / cellSize);
var hashKey = hashX + ',' + hashY;
if (spatialHash[hashKey]) {
for (var i = 0; i < spatialHash[hashKey].length; i++) {
var obstacle = spatialHash[hashKey][i];
if (self.intersects(obstacle)) {
// Bring the bubble to the top of the z axis
game.setChildIndex(self, game.children.length - 1);
self.colliding = true;
} else {
self.collidingWithShield = false;
self.colliding = false;
}
}
} else {
self.colliding = false;
}
};
});
// Diver class
var Diver = Container.expand(function () {
var self = Container.call(this);
var diverGraphics = self.attachAsset('diver', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.7
});
// Add an invisible hitbox with smaller dimensions
var hitbox = self.attachAsset('shape', {
width: 200,
// Smaller width
height: 260,
// Increased height by 30%
// Smaller height
color: 0x000000,
alpha: 0 // Invisible
});
// Add a sideways movement to the diver
self.movement = 0;
self.direction = 1;
self.update = function () {
self.movement += self.direction * 0.03;
if (self.movement > 0.5 || self.movement < -0.5) {
self.direction *= -1;
}
self.x += self.movement;
};
// Center the hitbox on the diver
hitbox.anchor.set(0.5, 0.5);
// Add flippers to the diver
var leftFlipper = self.addChild(new Flipper());
leftFlipper.x = -50;
leftFlipper.depth = -1;
var rightFlipper = self.addChild(new Flipper());
rightFlipper.x = 60;
rightFlipper.depth = -1;
});
// Flipper class
var Flipper = Container.expand(function () {
var self = Container.call(this);
var flipperGraphics = self.attachAsset('flippers', {
anchorX: 0.5,
anchorY: 1.0,
scaleX: 0.7,
scaleY: 0.7
});
// Set flipper movement
self.movement = 0;
self.direction = 1;
// This is automatically called every game tick, if the flipper is attached!
self.update = function () {
// Move the flipper subtly to simulate flipping
self.movement += self.direction * 0.03;
if (self.movement > 0.5 || self.movement < -0.5) {
self.direction *= -1;
}
self.rotation = self.movement;
};
});
// Obstacle1 class
var Obstacle1 = Container.expand(function () {
var self = Container.call(this);
var obstacle1Graphics = self.attachAsset('obstacle1', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: Math.random() < 0.5 ? 0.7 : -0.7,
// Randomly mirror horizontally
scaleY: 0.7
});
// Set obstacle1 speed
self.speed = -5;
self.originalSpeedX = self.speed;
// This is automatically called every game tick, if the obstacle1 is attached!
self.update = function () {
// Rotate obstacle1 on its axis
self.rotation += 0.05;
// Check if the obstacle is colliding with the shield
if (self.intersects(shield, {
tolerance: 10
})) {
if (!self.collidingWithShield) {
LK.getSound('bubble').play();
self.collidingWithShield = true;
}
// Calculate the direction vector between the shield and the obstacle
var dx = self.x - shield.x;
var dy = self.y - shield.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Push the obstacle away from the shield
self.x += dx * 5;
self.y += dy * 5;
} else {
self.collidingWithShield = false;
self.speed = self.originalSpeedX;
}
// Check for collision with diver
if (self.intersects(diver.children.find(function (child) {
return child.alpha === 0;
}), {
tolerance: 10
})) {
// Flash screen red for 1 second (1000ms) to show game over
LK.effects.flashScreen(0xff0000, 1000);
// Show game over. The game will be automatically paused while game over is showing.
LK.showGameOver();
}
// Update spatial hash
var oldHashX = Math.floor((self.x - self.speed * speedMultiplier) / cellSize);
var oldHashY = Math.floor((self.y - self.speed * speedMultiplier) / cellSize);
var newHashX = Math.floor(self.x / cellSize);
var newHashY = Math.floor(self.y / cellSize);
var oldHashKey = oldHashX + ',' + oldHashY;
var newHashKey = newHashX + ',' + newHashY;
if (oldHashKey !== newHashKey) {
if (spatialHash[oldHashKey]) {
var index = spatialHash[oldHashKey].indexOf(self);
if (index > -1) {
spatialHash[oldHashKey].splice(index, 1);
}
}
if (!spatialHash[newHashKey]) {
spatialHash[newHashKey] = [];
}
spatialHash[newHashKey].push(self);
}
// Continue moving upwards
if (wavePositionLabel === 'right') {
self.x -= 1.5;
} else if (wavePositionLabel === 'left') {
self.x += 1;
}
self.y += self.speed * speedMultiplier;
self.scale.x = 1 + Math.sin(LK.ticks / 10) * 0.02;
self.scale.y = 1 + Math.sin(LK.ticks / 10) * 0.02;
if (self.y < 0) {
self.destroy();
var index = obstacles.indexOf(self);
if (index > -1) {
obstacles.splice(index, 1);
}
}
// Check if the obstacle is colliding with another obstacle
for (var i = 0; i < obstacles.length; i++) {
var otherObstacle = obstacles[i];
if (self !== otherObstacle && self.intersects(otherObstacle)) {
// Calculate the direction vector between the two obstacles
var dx = self.x - otherObstacle.x;
var dy = self.y - otherObstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Increase the repulsion force and always push the obstacle to the outside
self.x += dx * 10;
self.y += dy * 10;
}
}
};
});
// Obstacle2 class
var Obstacle2 = Container.expand(function () {
var self = Container.call(this);
var obstacle2Graphics = self.attachAsset('obstacle2', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: Math.random() < 0.5 ? 0.7 : -0.7,
// Randomly mirror horizontally
scaleY: 0.7
});
// Set obstacle2 speed
self.speed = -5;
self.originalSpeedX = self.speed;
// This is automatically called every game tick, if the obstacle2 is attached!
self.update = function () {
// Check if the obstacle is colliding with the shield
if (self.intersects(shield, {
tolerance: 10
})) {
if (!self.collidingWithShield) {
LK.getSound('bubble').play();
self.collidingWithShield = true;
}
// Calculate the direction vector between the shield and the obstacle
var dx = self.x - shield.x;
var dy = self.y - shield.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Push the obstacle away from the shield
self.x += dx * 5;
self.y += dy * 5;
} else {
self.collidingWithShield = false;
self.speed = self.originalSpeedX;
}
// Check for collision with diver
if (self.intersects(diver.children.find(function (child) {
return child.alpha === 0;
}), {
tolerance: 10
})) {
// Flash screen red for 1 second (1000ms) to show game over
LK.effects.flashScreen(0xff0000, 1000);
// Show game over. The game will be automatically paused while game over is showing.
LK.showGameOver();
}
// Update spatial hash
var oldHashX = Math.floor((self.x - self.speed * speedMultiplier) / cellSize);
var oldHashY = Math.floor((self.y - self.speed * speedMultiplier) / cellSize);
var newHashX = Math.floor(self.x / cellSize);
var newHashY = Math.floor(self.y / cellSize);
var oldHashKey = oldHashX + ',' + oldHashY;
var newHashKey = newHashX + ',' + newHashY;
if (oldHashKey !== newHashKey) {
if (spatialHash[oldHashKey]) {
var index = spatialHash[oldHashKey].indexOf(self);
if (index > -1) {
spatialHash[oldHashKey].splice(index, 1);
}
}
if (!spatialHash[newHashKey]) {
spatialHash[newHashKey] = [];
}
spatialHash[newHashKey].push(self);
}
// Continue moving upwards
if (wavePositionLabel === 'right') {
self.x -= 1.5;
} else if (wavePositionLabel === 'left') {
self.x += 1.5;
}
self.y += self.speed * speedMultiplier;
// Add wiggly movement to the obstacle
self.scale.x = 1 + Math.sin(LK.ticks / 10) * 0.02;
self.scale.y = 1 + Math.sin(LK.ticks / 10) * 0.02;
if (self.y < 0) {
self.destroy();
var index = obstacles.indexOf(self);
if (index > -1) {
obstacles.splice(index, 1);
}
}
// Check if the obstacle is colliding with another obstacle
for (var i = 0; i < obstacles.length; i++) {
var otherObstacle = obstacles[i];
if (self !== otherObstacle && self.intersects(otherObstacle)) {
// Calculate the direction vector between the two obstacles
var dx = self.x - otherObstacle.x;
var dy = self.y - otherObstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Increase the repulsion force and always push the obstacle to the outside
self.x += dx * 10;
self.y += dy * 10;
}
}
};
});
// Obstacle3 class
var Obstacle3 = Container.expand(function () {
var self = Container.call(this);
var obstacle3Graphics = self.attachAsset('obstacle3', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: Math.random() < 0.5 ? 0.7 : -0.7,
// Randomly mirror horizontally
scaleY: 0.7
});
// Set obstacle3 speed
self.speed = -5;
self.originalSpeedX = self.speed;
// This is automatically called every game tick, if the obstacle3 is attached!
self.update = function () {
// Check if the obstacle is colliding with the shield
if (self.intersects(shield, {
tolerance: 10
})) {
if (!self.collidingWithShield) {
LK.getSound('bubble').play();
self.collidingWithShield = true;
}
// Calculate the direction vector between the shield and the obstacle
var dx = self.x - shield.x;
var dy = self.y - shield.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Push the obstacle away from the shield
self.x += dx * 5;
self.y += dy * 5;
} else {
self.collidingWithShield = false;
self.speed = self.originalSpeedX;
}
// Check for collision with diver
if (self.intersects(diver.children.find(function (child) {
return child.alpha === 0;
}), {
tolerance: 10
})) {
// Flash screen red for 1 second (1000ms) to show game over
LK.effects.flashScreen(0xff0000, 1000);
// Show game over. The game will be automatically paused while game over is showing.
LK.showGameOver();
}
// Update spatial hash
var oldHashX = Math.floor((self.x - self.speed * speedMultiplier) / cellSize);
var oldHashY = Math.floor((self.y - self.speed * speedMultiplier) / cellSize);
var newHashX = Math.floor(self.x / cellSize);
var newHashY = Math.floor(self.y / cellSize);
var oldHashKey = oldHashX + ',' + oldHashY;
var newHashKey = newHashX + ',' + newHashY;
if (oldHashKey !== newHashKey) {
if (spatialHash[oldHashKey]) {
var index = spatialHash[oldHashKey].indexOf(self);
if (index > -1) {
spatialHash[oldHashKey].splice(index, 1);
}
}
if (!spatialHash[newHashKey]) {
spatialHash[newHashKey] = [];
}
spatialHash[newHashKey].push(self);
}
// Continue moving upwards
if (wavePositionLabel === 'right') {
self.x -= 1.5;
} else if (wavePositionLabel === 'left') {
self.x += 1.5;
}
self.y += self.speed * speedMultiplier;
// Add unique behavior to obstacle3
self.scale.x = 1 + Math.sin(LK.ticks / 5) * 0.05; // Larger size change
self.scale.y = 1 + Math.sin(LK.ticks / 5) * 0.05;
if (self.y < 0) {
self.destroy();
var index = obstacles.indexOf(self);
if (index > -1) {
obstacles.splice(index, 1);
}
}
// Check if the obstacle is colliding with another obstacle
for (var i = 0; i < obstacles.length; i++) {
var otherObstacle = obstacles[i];
if (self !== otherObstacle && self.intersects(otherObstacle)) {
// Calculate the direction vector between the two obstacles
var dx = self.x - otherObstacle.x;
var dy = self.y - otherObstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Increase the repulsion force and always push the obstacle to the outside
self.x += dx * 10;
self.y += dy * 10;
}
}
};
});
// Obstacle4 class
var Obstacle4 = Container.expand(function () {
var self = Container.call(this);
var obstacle4Graphics = self.attachAsset('obstacle4', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: Math.random() < 0.5 ? 0.7 : -0.7,
// Randomly mirror horizontally
scaleY: 0.7
});
// Set obstacle4 speed
self.speed = -5;
self.originalSpeedX = self.speed;
// This is automatically called every game tick, if the obstacle4 is attached!
self.update = function () {
// Add up and down movement
self.y += Math.sin(LK.ticks / 20) * 2;
// Check if the obstacle is colliding with the shield
if (self.intersects(shield, {
tolerance: 10
})) {
if (!self.collidingWithShield) {
LK.getSound('bubble').play();
self.collidingWithShield = true;
}
// Calculate the direction vector between the shield and the obstacle
var dx = self.x - shield.x;
var dy = self.y - shield.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Push the obstacle away from the shield
self.x += dx * 5;
self.y += dy * 5;
} else {
self.collidingWithShield = false;
self.speed = self.originalSpeedX;
}
// Check for collision with diver
if (self.intersects(diver.children.find(function (child) {
return child.alpha === 0;
}), {
tolerance: 10
})) {
// Flash screen red for 1 second (1000ms) to show game over
LK.effects.flashScreen(0xff0000, 1000);
// Show game over. The game will be automatically paused while game over is showing.
LK.showGameOver();
}
// Update spatial hash
var oldHashX = Math.floor((self.x - self.speed * speedMultiplier) / cellSize);
var oldHashY = Math.floor((self.y - self.speed * speedMultiplier) / cellSize);
var newHashX = Math.floor(self.x / cellSize);
var newHashY = Math.floor(self.y / cellSize);
var oldHashKey = oldHashX + ',' + oldHashY;
var newHashKey = newHashX + ',' + newHashY;
if (oldHashKey !== newHashKey) {
if (spatialHash[oldHashKey]) {
var index = spatialHash[oldHashKey].indexOf(self);
if (index > -1) {
spatialHash[oldHashKey].splice(index, 1);
}
}
if (!spatialHash[newHashKey]) {
spatialHash[newHashKey] = [];
}
spatialHash[newHashKey].push(self);
}
// Continue moving upwards
if (wavePositionLabel === 'right') {
self.x -= 1.5;
} else if (wavePositionLabel === 'left') {
self.x += 1.5;
}
self.y += self.speed * speedMultiplier + Math.sin(LK.ticks / 20) * 2;
self.scale.x = 1 + Math.sin(LK.ticks / 15) * 0.03; // Different size change
self.scale.y = 1 + Math.sin(LK.ticks / 15) * 0.03;
if (self.y < 0) {
self.destroy();
var index = obstacles.indexOf(self);
if (index > -1) {
obstacles.splice(index, 1);
}
}
// Check if the obstacle is colliding with another obstacle
for (var i = 0; i < obstacles.length; i++) {
var otherObstacle = obstacles[i];
if (self !== otherObstacle && self.intersects(otherObstacle)) {
// Calculate the direction vector between the two obstacles
var dx = self.x - otherObstacle.x;
var dy = self.y - otherObstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Increase the repulsion force and always push the obstacle to the outside
self.x += dx * 10;
self.y += dy * 10;
}
}
};
});
// Obstacle5 class
var Obstacle5 = Container.expand(function () {
var self = Container.call(this);
var obstacle5Graphics = self.attachAsset('obstacle5', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: Math.random() < 0.5 ? 0.7 : -0.7,
// Randomly mirror horizontally
scaleY: 0.7
});
// Set obstacle5 speed
self.speed = -5;
self.originalSpeedX = self.speed;
// This is automatically called every game tick, if the obstacle5 is attached!
self.update = function () {
// Add very small sideways movement
self.x += Math.sin(LK.ticks / 100) * 0.5;
// Check if the obstacle is colliding with the shield
if (self.intersects(shield, {
tolerance: 10
})) {
if (!self.collidingWithShield) {
LK.getSound('bubble').play();
self.collidingWithShield = true;
}
// Calculate the direction vector between the shield and the obstacle
var dx = self.x - shield.x;
var dy = self.y - shield.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Push the obstacle away from the shield
self.x += dx * 5;
self.y += dy * 5;
} else {
self.collidingWithShield = false;
self.speed = self.originalSpeedX;
}
// Check for collision with diver
if (self.intersects(diver.children.find(function (child) {
return child.alpha === 0;
}), {
tolerance: 10
})) {
// Flash screen red for 1 second (1000ms) to show game over
LK.effects.flashScreen(0xff0000, 1000);
// Show game over. The game will be automatically paused while game over is showing.
LK.showGameOver();
}
// Update spatial hash
var oldHashX = Math.floor((self.x - self.speed * speedMultiplier) / cellSize);
var oldHashY = Math.floor((self.y - self.speed * speedMultiplier) / cellSize);
var newHashX = Math.floor(self.x / cellSize);
var newHashY = Math.floor(self.y / cellSize);
var oldHashKey = oldHashX + ',' + oldHashY;
var newHashKey = newHashX + ',' + newHashY;
if (oldHashKey !== newHashKey) {
if (spatialHash[oldHashKey]) {
var index = spatialHash[oldHashKey].indexOf(self);
if (index > -1) {
spatialHash[oldHashKey].splice(index, 1);
}
}
if (!spatialHash[newHashKey]) {
spatialHash[newHashKey] = [];
}
spatialHash[newHashKey].push(self);
}
// Continue moving upwards
if (wavePositionLabel === 'right') {
self.x -= 1.5;
} else if (wavePositionLabel === 'left') {
self.x += 1.5;
}
self.y += self.speed * speedMultiplier;
// Add unique behavior to obstacle5
self.scale.x = 1 + Math.sin(LK.ticks / 20) * 0.1; // Increase size change amplitude
self.scale.y = 1 + Math.sin(LK.ticks / 20) * 0.1;
if (self.y < 0) {
self.destroy();
var index = obstacles.indexOf(self);
if (index > -1) {
obstacles.splice(index, 1);
}
}
// Check if the obstacle is colliding with another obstacle
for (var i = 0; i < obstacles.length; i++) {
var otherObstacle = obstacles[i];
if (self !== otherObstacle && self.intersects(otherObstacle)) {
// Calculate the direction vector between the two obstacles
var dx = self.x - otherObstacle.x;
var dy = self.y - otherObstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Increase the repulsion force and always push the obstacle to the outside
self.x += dx * 10;
self.y += dy * 10;
}
}
};
});
// Obstacle6 class
var Obstacle6 = Container.expand(function () {
var self = Container.call(this);
var obstacle6Graphics = self.attachAsset('obstacle6', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: Math.random() < 0.5 ? 0.7 : -0.7,
// Randomly mirror horizontally
scaleY: 0.7
});
// Set obstacle6 speed
self.speed = -5;
self.originalSpeedX = self.speed;
// This is automatically called every game tick, if the obstacle6 is attached!
self.update = function () {
// Flickering effect
self.alpha = Math.random() * 0.5 + 0.5; // Random alpha between 0.5 and 1
// Fast side-to-side movement
self.x += Math.sin(LK.ticks / 10) * 1; // Further reduced horizontal movement
// Check if the obstacle is colliding with the shield
if (self.intersects(shield, {
tolerance: 10
})) {
if (!self.collidingWithShield) {
LK.getSound('bubble').play();
self.collidingWithShield = true;
}
// Calculate the direction vector between the shield and the obstacle
var dx = self.x - shield.x;
var dy = self.y - shield.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Push the obstacle away from the shield
self.x += dx * 5;
self.y += dy * 5;
} else {
self.collidingWithShield = false;
self.speed = self.originalSpeedX;
}
// Check for collision with diver
if (self.intersects(diver.children.find(function (child) {
return child.alpha === 0;
}), {
tolerance: 10
})) {
// Flash screen red for 1 second (1000ms) to show game over
LK.effects.flashScreen(0xff0000, 1000);
// Show game over. The game will be automatically paused while game over is showing.
LK.showGameOver();
}
// Update spatial hash
var oldHashX = Math.floor((self.x - self.speed * speedMultiplier) / cellSize);
var oldHashY = Math.floor((self.y - self.speed * speedMultiplier) / cellSize);
var newHashX = Math.floor(self.x / cellSize);
var newHashY = Math.floor(self.y / cellSize);
var oldHashKey = oldHashX + ',' + oldHashY;
var newHashKey = newHashX + ',' + newHashY;
if (oldHashKey !== newHashKey) {
if (spatialHash[oldHashKey]) {
var index = spatialHash[oldHashKey].indexOf(self);
if (index > -1) {
spatialHash[oldHashKey].splice(index, 1);
}
}
if (!spatialHash[newHashKey]) {
spatialHash[newHashKey] = [];
}
spatialHash[newHashKey].push(self);
}
// Continue moving upwards
if (wavePositionLabel === 'right') {
self.x -= 1.5;
} else if (wavePositionLabel === 'left') {
self.x += 1.5;
}
self.y += self.speed * speedMultiplier;
// Add unique behavior to obstacle6
self.scale.x = 1 + Math.sin(LK.ticks / 25) * 0.05; // Different size change
self.scale.y = 1 + Math.sin(LK.ticks / 25) * 0.05;
self.alpha = Math.random() * 0.5 + 0.5; // Random alpha between 0.5 and 1
self.x += Math.sin(LK.ticks / 5) * 10; // Fast horizontal movement
if (self.y < 0) {
self.destroy();
var index = obstacles.indexOf(self);
if (index > -1) {
obstacles.splice(index, 1);
}
}
// Check if the obstacle is colliding with another obstacle
for (var i = 0; i < obstacles.length; i++) {
var otherObstacle = obstacles[i];
if (self !== otherObstacle && self.intersects(otherObstacle)) {
// Calculate the direction vector between the two obstacles
var dx = self.x - otherObstacle.x;
var dy = self.y - otherObstacle.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Increase the repulsion force and always push the obstacle to the outside
self.x += dx * 10;
self.y += dy * 10;
}
}
};
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphics = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
self.y += 1.6; // Move power-up downwards (reduced by 20%)
self.x += Math.sin(LK.ticks / 20) * 2; // Add pendular movement
// Check if the power-up is colliding with the shield
if (self.intersects(shield, {
tolerance: 10
})) {
if (!self.collidingWithShield) {
LK.getSound('bubble').play();
self.collidingWithShield = true;
}
// Calculate the direction vector between the shield and the power-up
var dx = self.x - shield.x;
var dy = self.y - shield.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize the direction vector
dx /= distance;
dy /= distance;
// Push the power-up away from the shield
self.x += dx * 5;
self.y += dy * 5;
} else {
self.collidingWithShield = false;
}
if (self.intersects(diver)) {
LK.getSound('powerup').play();
shield.scale.x *= 2;
shield.scale.y *= 2;
LK.setTimeout(function () {
// Start blinking effect after 8 seconds
var blinkInterval = LK.setInterval(function () {
shield.alpha = shield.alpha === 1 ? 0.5 : 1;
if (shield.alpha === 0.5 && !self.shieldOffPlayed) {
LK.getSound('shieldoff').play();
self.shieldOffPlayed = true;
}
}, 60); // Blink every 500ms
// Stop blinking and reset shield size after 10 seconds
LK.setTimeout(function () {
LK.clearInterval(blinkInterval);
shield.alpha = 0.9; // Reset alpha to original value
shield.scale.x /= 2;
shield.scale.y /= 2;
self.shieldOffPlayed = false;
}, 2000); // Blink for 2 seconds
}, 8000); // Start blinking after 8 seconds
self.destroy();
}
};
});
// Shield class
var Shield = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.75
});
self.originalAlpha = shieldGraphics.alpha; // Store the original alpha value
self.down = function (x, y, obj) {
dragNode = shield;
};
});
/****
* Initialize Game
****/
// Create a diver instance
//<Assets used in the game will automatically appear here>
var game = new LK.Game({
backgroundColor: 0xADD8E6 //Init game with a softer blue background
});
/****
* Game Code
****/
var wavePositionLabel;
// Function to spawn power-ups every 20 seconds
function spawnPowerUp() {
if (!firstPowerUpSpawned) {
if (LK.ticks < 300) {
// 300 ticks = 5 seconds
return;
}
firstPowerUpSpawned = true;
} else if (LK.ticks - lastPowerUpSpawnTime < 1200) {
// 1200 ticks = 20 seconds
return;
}
var powerUp = game.addChild(new PowerUp());
lastPowerUpSpawnTime = LK.ticks;
do {
powerUp.x = Math.random() * 2048;
} while (diver && Math.abs(powerUp.x - diver.x) < 200);
powerUp.y = -100; // Start offscreen at the top
// Schedule the next power-up spawn
LK.setTimeout(spawnPowerUp, 20000); // 20 seconds
}
// Initial call to spawn the first power-up after 20 seconds
LK.setTimeout(spawnPowerUp, 20000);
var lastBubbleSoundTime = 0;
var lastPowerUpSpawnTime = 0;
var speedMultiplier = 1;
var firstPowerUpSpawned = false;
// Declare and initialize backgroundMusic variable
var backgroundMusic = LK.getSound('background');
// Play background music on loop when the game starts
LK.on('tick', function () {
if (!backgroundMusic.playing) {
backgroundMusic.play();
}
});
var background1 = game.addChild(new Background());
background1.y = 0;
// Create a shield instance
var shield = game.addChildAt(new Shield(), game.children.length);
// Position the shield at the center of the screen
shield.x = 2048 / 2;
shield.y = 2732 / 2;
// Create a diver instance
var dragNode = null;
var diver = new Diver();
diver.depth = 2;
// Position the diver at the top center of the screen, 200 pixels down from the top
diver.x = 2048 / 2;
diver.y = 500;
// Ensure diver's dimensions are fully initialized before positioning flippers
diver.on('added', function () {
// Position the flippers relative to the diver
diver.children[0].y = diver.height / 2 - 20; // Left flipper
diver.children[1].y = diver.height / 2 - 20; // Right flipper
});
// Position the flippers relative to the diver
diver.children[0].y = diver.height / 2 - 20; // Left flipper
diver.children[0].y = diver.children[0].y; // Right flipper
// Set diver to a higher depth than flippers
diver.depth = 2;
// Create an obstacle1 instance
game.move = function (x, y, obj) {
if (dragNode) {
if (dragNode !== shield) {
shield.x += x - shield.x;
shield.y += y - shield.y;
} else {
dragNode.x = x;
dragNode.y = y;
}
}
if (dragNode === shield) {
shield.x = x;
shield.y = y;
}
};
var obstacles = [];
var spatialHash = {};
game.addChild(diver);
game.setChildIndex(diver, game.children.length - 1);
// Create power-up instance
var powerUp = game.addChild(new PowerUp());
do {
powerUp.x = Math.random() * 2048;
} while (Math.abs(powerUp.x - diver.x) < 200);
powerUp.y = -100; // Start offscreen at the top
// Create bubbles after obstacles
var bubbles = [];
for (var i = 0; i < 20; i++) {
var bubble = new Bubble();
bubble.x = Math.random() * 2048;
bubble.y = Math.random() * 2732;
bubbles.push(bubble);
game.addChildAt(bubble, game.children.length);
}
// Spawn the first wave of obstacles
spawnWave();
;
// Initialize score
var score = LK.getScore();
// Create score text
var depthScoreText = new Text2('Depth:0m', {
size: 70,
fill: "#ffffff",
stroke: "#000000",
strokeThickness: 6,
font: "monospace" // Change font to be more square
});
depthScoreText.anchor.set(0.5, 0.5);
depthScoreText.x = 400;
depthScoreText.y = 100;
LK.gui.top.addChild(depthScoreText);
// Initialize a timer to update the score every second and increase speed multiplier
var scoreUpdateInterval = LK.setInterval(function () {
LK.setScore(LK.getScore() + 1);
if (depthScoreText) {
depthScoreText.setText('Depth:' + LK.getScore() + 'm');
}
speedMultiplier += 0.01; // Increase speed multiplier by 0.02 every second
}, 1000);
game.up = function (x, y, obj) {
dragNode = null;
};
// Check if background music is playing, if not, play it
if (!backgroundMusic.playing) {
backgroundMusic.play();
}
// Update background
background1.update();
// Update bubbles
for (var i = 0; i < bubbles.length; i++) {
bubbles[i].update();
}
// Define the current wave
var currentWave = 0;
var allWavesSpawnedOnce = false;
// Spawn wave function
function spawnWave() {
// Define the layout of the obstacles for each wave
var obstacleLayouts = [{
type: 'line',
grid: ['.....', '.....', '.#.#.', '.....', '.....']
}, {
type: 'triangle',
grid: ['.....', '..#..', '.....', '.#.#.', '.....']
}, {
type: 'square',
grid: ['.....', '.#.#.', '.....', '.#.#.', '.....']
}, {
type: 'circle',
grid: ['.....', '..#..', '.#.#.', '.#.#.', '..#..']
}, {
type: 'cross',
grid: ['.....', '..#..', '.###.', '..#..', '.....']
}, {
type: 'hexagon',
grid: ['.....', '..#..', '.#.#.', '.#.#.', '..#..']
}, {
type: 'heptagon',
grid: ['..#..', '..#..', '#...#', '..#..', '..#..']
}, {
type: 'octagon',
grid: ['.....', '#####', '.....', '.....', '.....']
}, {
type: 'nonagon',
grid: ['.....', '..#..', '.#.#.', '.#.#.', '..#..']
}, {
type: 'decagon',
grid: ['.....', '..#..', '.#.#.', '.#.#.', '..#..']
}];
// Get the layout for the current wave
var layout = obstacleLayouts[currentWave];
if (!layout) {
console.error('Error: layout is undefined. Check the obstacleLayouts array.');
return;
}
var layoutPositions = [];
layout.grid.forEach(function (row, rowIndex) {
row.split('').forEach(function (cell, colIndex) {
if (cell === '#') {
layoutPositions.push({
x: colIndex,
y: rowIndex
});
}
});
});
// Randomly choose an obstacle type for the entire wave
var obstacleTypes = [Obstacle1, Obstacle2, Obstacle3, Obstacle4, Obstacle5, Obstacle6];
var obstacleType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
// Randomly choose one of the three starting x positions for the entire wave
var startXPositions = [{
position: 2048 / 4.5,
label: 'left'
}, {
position: 2048 / 1.08,
label: 'right'
}, {
position: 2048 / 1.9,
label: 'center'
}];
var randomStart = startXPositions[Math.floor(Math.random() * startXPositions.length)];
var randomStartX = randomStart.position;
wavePositionLabel = randomStart.label;
console.log('Wave starting position:', wavePositionLabel);
console.log('Wave starting position:', wavePositionLabel);
layoutPositions.forEach(function (position) {
var obstacle = game.addChild(new obstacleType());
// Position the obstacles according to the layout, using the grid for positioning
obstacle.x = randomStartX + (position.x - gridSize / 2) * cellSize;
obstacle.y = 2732 + position.y * cellSize; // Spawn obstacles offscreen at the bottom
obstacles.push(obstacle);
});
currentWave++;
if (currentWave >= obstacleLayouts.length) {
allWavesSpawnedOnce = true;
currentWave = 0;
}
if (allWavesSpawnedOnce) {
currentWave = Math.floor(Math.random() * (obstacleLayouts.length - 3)) + 3;
}
// Add interval of wait between waves
LK.setTimeout(function () {
spawnWave();
}, 5000); // 5 seconds wait between waves
}
// Define the grid size and the size of each cell in the grid
var gridSize = 5;
var cellSize = 150;
// Call the spawn wave function every 1 second
// Initial call to spawn the first wave
spawnWave();
;
8bit. cartoon. jellyfish.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
empty 8 bit cartoon white circle. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon. 8-bit. octopus. colorful.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon. 8-bit. sea urchin. colorful. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon 8bit stingray. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.