User prompt
his body seems stable. but should be affected of wind and umbrella, make it visual ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make that motion as effect like his body moving ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
give character smooth motion by wind ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
umbrella should be upper on character icon
User prompt
put heart icons to below of best score
User prompt
game keep best scores ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
life power up spawn rate increase
User prompt
give wind chimp fade effect ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
give life power up icon a glow motion ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
give life power up icon a glow ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make distance text a lil bit smaller and use bold font and make it cloudy
User prompt
life power up icon should be bigger by x2 and increase the spawn rate
User prompt
the heart icons on scoreboard restore them to first scale
User prompt
the heart icons on scoreboard restore them to previous scale
User prompt
life power up icon should be bigger by x2 and increase the spawn rate
User prompt
reduce spawn rate of clouds to give character always an escape.
User prompt
for first 50 meter, no heart loss
User prompt
restore umbrella to previous scale
User prompt
make other obstacles but clouds bigger by x2
User prompt
every 100 meter game should be more difficult but first 500 meter can be easy
User prompt
CLOUDS SHOULD SPAWN BOTTOM ON THE SCREEN TOO
User prompt
remove the empty unused space at the top, the space above the score.
User prompt
analyse spawn mechanics and make it continous and matches with game logic
User prompt
make every image asset bigger by x 1.3. character should be same. distance and hearts should have gap vertical for ui. no frame at all, only game screen. obstacles should be spawn falling direction too
User prompt
Please fix the bug: 'ReferenceError: Can't find variable: Obstacle' in or related to this line: 'var obstacle = game.addChild(new Obstacle('cloud'));' Line Number: 399
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var AirPocket = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('airPocket', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.alpha = 0.3;
self.fallSpeed = 0; // For falling direction
self.update = function () {
// Support falling movement
if (self.fallSpeed > 0) {
self.y += self.fallSpeed;
}
graphics.alpha = 0.3 + Math.sin(LK.ticks * 0.1) * 0.2;
};
return self;
});
var Bird = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bird', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 5 + 3;
self.direction = Math.random() > 0.5 ? 1 : -1;
self.speedY = 0; // For falling direction
// Birds spawn from left or right edge and move in parallel lines
self.x = self.direction > 0 ? -100 : 2148; // Start from left or right edge
self.update = function () {
self.x += self.speed * self.direction;
if (self.speedY > 0) {
self.y += self.speedY; // Support falling movement
}
graphics.rotation += 0.1;
// Slight vertical bobbing
graphics.y = Math.sin(LK.ticks * 0.08) * 15;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.alpha = 0.6;
self.speed = Math.random() * 0.5 + 0.2;
self.update = function () {
// Clouds are now stationary - no horizontal movement
};
return self;
});
var Collectible = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var graphics = self.attachAsset(type, {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (self.type === 'star') {
graphics.rotation += 0.15;
graphics.scaleX = 1 + Math.sin(LK.ticks * 0.1) * 0.3;
graphics.scaleY = 1 + Math.sin(LK.ticks * 0.1) * 0.3;
} else if (self.type === 'windChime') {
graphics.x = Math.sin(LK.ticks * 0.08) * 10;
}
};
return self;
});
var LifePowerUp = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
graphics.rotation += 0.1;
graphics.scaleX = 1 + Math.sin(LK.ticks * 0.12) * 0.2;
graphics.scaleY = 1 + Math.sin(LK.ticks * 0.12) * 0.2;
};
return self;
});
var Lightning = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('lightning', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = Math.random() * 3 + 2;
// Lightning flicker effect
tween(graphics, {
alpha: 0.3
}, {
duration: 100,
easing: tween.easeInOut
});
LK.setTimeout(function () {
tween(graphics, {
alpha: 1
}, {
duration: 50
});
}, 100);
self.update = function () {
self.y += self.speed;
// Lightning sway
graphics.x = Math.sin(LK.ticks * 0.12) * 10;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var umbrella = self.attachAsset('umbrella', {
anchorX: 0.5,
anchorY: 0.5,
y: -40
});
var character = self.attachAsset('character', {
anchorX: 0.5,
anchorY: 0.5,
y: 20
});
self.fallSpeed = 3;
self.horizontalSpeed = 0;
self.windEffect = 0;
self.maxHorizontalSpeed = 8;
self.update = function () {
self.y += self.fallSpeed;
// Apply horizontal movement with wind effect
self.x += self.horizontalSpeed + self.windEffect;
// Enhanced umbrella wind animation
var baseRotation = Math.sin(LK.ticks * 0.05) * 0.1;
var windRotation = self.windEffect * 0.02;
var horizontalRotation = self.horizontalSpeed * 0.05;
umbrella.rotation = baseRotation + windRotation + horizontalRotation;
// Wind-affected umbrella bobbing
umbrella.y = -40 + Math.sin(LK.ticks * 0.08) * 3 + Math.abs(self.windEffect) * 0.5;
// Character sway matching umbrella movement
character.rotation = umbrella.rotation * 0.3;
character.x = Math.sin(LK.ticks * 0.06) * 2 + self.windEffect * 0.1;
// Keep player on screen horizontally
if (self.x < 70) {
self.x = 70;
self.horizontalSpeed = 0;
}
if (self.x > 2048 - 70) {
self.x = 2048 - 70;
self.horizontalSpeed = 0;
}
};
return self;
});
var Star = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
graphics.tint = 0xff6666;
// Stars spawn diagonally - choose random diagonal direction
var diagonalDirection = Math.random() > 0.5 ? 1 : -1;
self.speedX = diagonalDirection * (Math.random() * 2 + 2);
self.speedY = Math.random() * 2 + 3; // Moves downward in game flow
// Set starting position based on diagonal direction
if (diagonalDirection > 0) {
self.x = -50; // Start from left edge
} else {
self.x = 2098; // Start from right edge
}
self.update = function () {
self.x += self.speedX;
self.y += self.speedY;
graphics.rotation += 0.2;
graphics.scaleX = 1 + Math.sin(LK.ticks * 0.15) * 0.3;
graphics.scaleY = 1 + Math.sin(LK.ticks * 0.15) * 0.3;
};
return self;
});
var WindChime = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('windChime', {
anchorX: 0.5,
anchorY: 0.5
});
self.visible = true;
self.flickerTimer = 0;
self.fallSpeed = 0; // For falling direction
// Wind chimes spawn anywhere on screen and suddenly appear/disappear
self.x = Math.random() * (2048 - 100) + 50;
self.update = function () {
self.flickerTimer++;
// Support falling movement
if (self.fallSpeed > 0) {
self.y += self.fallSpeed;
}
// Sudden appear/disappear effect every second
if (self.flickerTimer % 60 === 0) {
self.visible = !self.visible;
graphics.alpha = self.visible ? 1 : 0;
}
// Gentle swaying when visible
if (self.visible) {
graphics.x = Math.sin(LK.ticks * 0.08) * 8;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Gradient sky effect
game.setBackgroundColor(0x87ceeb);
// Game variables
var player;
var obstacles = [];
var collectibles = [];
var clouds = [];
var lifePowerUps = [];
var windTimer = 0;
var spawnTimer = 0;
var difficultyTimer = 0;
var distanceFallen = 0;
var gameSpeed = 1;
var cameraY = 0;
var targetCameraY = 0;
var playerLives = 3;
var maxLives = 5;
// UI Elements
var distanceTxt = new Text2('Distance: 0m', {
size: 100,
fill: 0xFFFFFF
});
distanceTxt.anchor.set(0.5, 0);
distanceTxt.y = 30;
LK.gui.top.addChild(distanceTxt);
// Lives display
var livesContainer = new Container();
var lifeHearts = [];
for (var h = 0; h < maxLives; h++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heart.x = h * 60 - 120;
heart.y = 0;
heart.scaleX = 1.2;
heart.scaleY = 1.5;
livesContainer.addChild(heart);
lifeHearts.push(heart);
}
livesContainer.y = 200;
LK.gui.top.addChild(livesContainer);
// Update lives display function
function updateLivesDisplay() {
for (var i = 0; i < lifeHearts.length; i++) {
if (i < playerLives) {
lifeHearts[i].alpha = 1;
} else {
lifeHearts[i].alpha = 0.3;
}
}
}
updateLivesDisplay();
// Initialize player
player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 600;
// Create initial clouds
for (var i = 0; i < 8; i++) {
var cloud = game.addChild(new Cloud());
cloud.x = Math.random() * 2048;
cloud.y = Math.random() * 2732;
clouds.push(cloud);
}
// Touch controls
var isDragging = false;
var lastTouchX = 0;
game.down = function (x, y, obj) {
isDragging = true;
lastTouchX = x;
};
game.move = function (x, y, obj) {
if (isDragging) {
var deltaX = x - lastTouchX;
player.horizontalSpeed = Math.max(-player.maxHorizontalSpeed, Math.min(player.maxHorizontalSpeed, deltaX * 0.3));
lastTouchX = x;
}
};
game.up = function (x, y, obj) {
isDragging = false;
// Gradually reduce horizontal speed when not dragging
tween(player, {
horizontalSpeed: 0
}, {
duration: 500,
easing: tween.easeOut
});
};
// Main game loop
game.update = function () {
// Update distance fallen
distanceFallen += player.fallSpeed;
distanceTxt.setText('Distance: ' + Math.floor(distanceFallen / 10) + 'm');
// Camera tracking - follow player with smooth movement
targetCameraY = player.y - 1366; // Keep player in center vertically
var cameraDiff = targetCameraY - cameraY;
cameraY += cameraDiff * 0.08; // Smooth camera movement
game.y = -cameraY;
// Increase difficulty every 500 meters
var currentDistance = Math.floor(distanceFallen / 10);
var difficultyLevel = Math.floor(currentDistance / 500);
if (difficultyLevel > 0) {
gameSpeed = 1 + difficultyLevel * 0.3;
player.fallSpeed = Math.min(8, 3 + difficultyLevel * 0.5);
}
// Enhanced wind effect that actively guides the player
windTimer++;
if (windTimer % 150 === 0) {
// Every 2.5 seconds - more frequent wind
var windStrength = (Math.random() - 0.5) * 8 * gameSpeed; // Stronger wind
// Visual wind burst effect on umbrella
var umbrella = player.children[0]; // Get umbrella reference
tween(umbrella, {
scaleX: 1.3 + Math.abs(windStrength) * 0.15,
scaleY: 0.8 - Math.abs(windStrength) * 0.1,
rotation: umbrella.rotation + windStrength * 0.1
}, {
duration: 150,
easing: tween.easeOut
});
// Return umbrella to normal size
LK.setTimeout(function () {
tween(umbrella, {
scaleX: 1,
scaleY: 1
}, {
duration: 600,
easing: tween.easeOut
});
}, 150);
tween(player, {
windEffect: windStrength
}, {
duration: 150
});
LK.setTimeout(function () {
tween(player, {
windEffect: windStrength * 0.3
}, {
duration: 800,
easing: tween.easeOut
});
}, 600);
// Complete wind fade after longer period
LK.setTimeout(function () {
tween(player, {
windEffect: 0
}, {
duration: 400,
easing: tween.easeOut
});
}, 1400);
}
// Spawn clouds continuously based on player movement
spawnTimer++;
var cloudSpawnRate = Math.max(3, 10 - Math.floor(gameSpeed * 2));
if (spawnTimer % cloudSpawnRate === 0) {
// Calculate spawn position relative to player's current position
var spawnX = Math.random() * (2048 - 200) + 100;
var spawnY = player.y - 800 - Math.random() * 400; // Spawn ahead of player
// Check for life power-up spawn first (0.05% chance)
if (Math.random() < 0.0005) {
var lifePowerUp = game.addChild(new LifePowerUp());
lifePowerUp.x = spawnX;
lifePowerUp.y = spawnY;
lifePowerUps.push(lifePowerUp);
}
// Spawn cloud obstacles
else if (Math.random() < 0.85) {
var cloud = game.addChild(new Cloud());
cloud.x = spawnX;
cloud.y = spawnY;
obstacles.push(cloud);
} else {
// Collectible wind chimes
var collectible = game.addChild(new Collectible('windChime'));
collectible.x = spawnX;
collectible.y = spawnY;
collectibles.push(collectible);
}
}
// Independent bird spawning (rare, parallel lines from screen edges and falling direction)
if (Math.random() < 0.001 * gameSpeed) {
var bird = game.addChild(new Bird());
// 50% chance to spawn from above (falling direction) or from edges
if (Math.random() < 0.5) {
bird.x = Math.random() * 2048;
bird.y = player.y - Math.random() * 600 - 400;
bird.speedY = Math.random() * 2 + 1;
} else {
bird.y = player.y - Math.random() * 600 - 200;
}
obstacles.push(bird);
}
// Independent star spawning (rare, diagonal movement and falling direction)
if (Math.random() < 0.0008 * gameSpeed) {
var star = game.addChild(new Star());
// 50% chance to spawn from above (falling direction) or diagonally
if (Math.random() < 0.5) {
star.x = Math.random() * 2048;
star.y = player.y - Math.random() * 500 - 400;
star.speedX = (Math.random() - 0.5) * 4;
star.speedY = Math.random() * 2 + 2;
} else {
star.y = player.y - Math.random() * 500 - 300;
}
obstacles.push(star);
}
// Independent lightning spawning (rare, vertical path from above)
if (Math.random() < 0.0006 * gameSpeed) {
var lightning = game.addChild(new Lightning());
lightning.x = Math.random() * (2048 - 100) + 50;
lightning.y = player.y - Math.random() * 700 - 400;
obstacles.push(lightning);
}
// Independent wind chime spawning (rare, appear/disappear anywhere and falling)
if (Math.random() < 0.0004 * gameSpeed) {
var windChime = game.addChild(new WindChime());
// 50% chance to spawn from above (falling direction) or statically
if (Math.random() < 0.5) {
windChime.x = Math.random() * 2048;
windChime.y = player.y - Math.random() * 600 - 400;
windChime.fallSpeed = Math.random() * 1.5 + 0.5;
} else {
windChime.y = player.y - Math.random() * 600 - 200;
}
obstacles.push(windChime);
}
// Independent air pocket spawning (rare, spawn anywhere and falling direction)
if (Math.random() < 0.0005 * gameSpeed) {
var airPocket = game.addChild(new AirPocket());
airPocket.x = Math.random() * (2048 - 200) + 100;
// 50% chance to spawn from above (falling direction) or statically
if (Math.random() < 0.5) {
airPocket.y = player.y - Math.random() * 500 - 400;
airPocket.fallSpeed = Math.random() * 1 + 0.3;
} else {
airPocket.y = player.y - Math.random() * 500 - 300;
}
obstacles.push(airPocket);
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
if (obstacle.lastY === undefined) obstacle.lastY = obstacle.y;
if (obstacle.lastIntersecting === undefined) obstacle.lastIntersecting = false;
// Remove obstacles that are too far behind the player
if (obstacle.lastY < player.y + 1000 && obstacle.y >= player.y + 1000) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with player
var currentIntersecting = obstacle.intersects(player);
if (!obstacle.lastIntersecting && currentIntersecting) {
playerLives--;
updateLivesDisplay();
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
// Remove the obstacle that was hit
obstacle.destroy();
obstacles.splice(i, 1);
// Check if game over
if (playerLives <= 0) {
LK.showGameOver();
return;
}
continue;
}
obstacle.lastY = obstacle.y;
obstacle.lastIntersecting = currentIntersecting;
}
// Update and check collectibles
for (var j = collectibles.length - 1; j >= 0; j--) {
var collectible = collectibles[j];
if (collectible.lastY === undefined) collectible.lastY = collectible.y;
if (collectible.lastIntersecting === undefined) collectible.lastIntersecting = false;
// Remove collectibles that are too far behind the player
if (collectible.lastY < player.y + 1000 && collectible.y >= player.y + 1000) {
collectible.destroy();
collectibles.splice(j, 1);
continue;
}
// Check collection
var currentIntersecting = collectible.intersects(player);
if (!collectible.lastIntersecting && currentIntersecting) {
LK.getSound('collect').play();
// Visual effect
tween(collectible, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
collectible.destroy();
}
});
collectibles.splice(j, 1);
continue;
}
collectible.lastY = collectible.y;
collectible.lastIntersecting = currentIntersecting;
}
// Update and check life power-ups
for (var l = lifePowerUps.length - 1; l >= 0; l--) {
var lifePowerUp = lifePowerUps[l];
if (lifePowerUp.lastY === undefined) lifePowerUp.lastY = lifePowerUp.y;
if (lifePowerUp.lastIntersecting === undefined) lifePowerUp.lastIntersecting = false;
// Remove life power-ups that are too far behind the player
if (lifePowerUp.lastY < player.y + 1000 && lifePowerUp.y >= player.y + 1000) {
lifePowerUp.destroy();
lifePowerUps.splice(l, 1);
continue;
}
// Check collection
var currentIntersecting = lifePowerUp.intersects(player);
if (!lifePowerUp.lastIntersecting && currentIntersecting) {
if (playerLives < maxLives) {
playerLives++;
updateLivesDisplay();
LK.getSound('collect').play();
// Visual effect
tween(lifePowerUp, {
scaleX: 3,
scaleY: 3,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
lifePowerUp.destroy();
}
});
lifePowerUps.splice(l, 1);
continue;
}
}
lifePowerUp.lastY = lifePowerUp.y;
lifePowerUp.lastIntersecting = currentIntersecting;
}
// Check collision with clouds
for (var k = 0; k < clouds.length; k++) {
var cloud = clouds[k];
if (cloud.lastIntersecting === undefined) cloud.lastIntersecting = false;
var currentIntersecting = cloud.intersects(player);
if (!cloud.lastIntersecting && currentIntersecting) {
playerLives--;
updateLivesDisplay();
LK.getSound('hit').play();
LK.effects.flashScreen(0xffffff, 500);
// Check if game over
if (playerLives <= 0) {
LK.showGameOver();
return;
}
}
cloud.lastIntersecting = currentIntersecting;
}
// Remove game over condition for falling off screen - infinite fall game
// Game only ends when hitting obstacles or clouds
};
// Start ambient music
LK.playMusic('ambient'); ===================================================================
--- original.js
+++ change.js
@@ -12,9 +12,14 @@
anchorX: 0.5,
anchorY: 0.5
});
graphics.alpha = 0.3;
+ self.fallSpeed = 0; // For falling direction
self.update = function () {
+ // Support falling movement
+ if (self.fallSpeed > 0) {
+ self.y += self.fallSpeed;
+ }
graphics.alpha = 0.3 + Math.sin(LK.ticks * 0.1) * 0.2;
};
return self;
});
@@ -25,12 +30,16 @@
anchorY: 0.5
});
self.speed = Math.random() * 5 + 3;
self.direction = Math.random() > 0.5 ? 1 : -1;
+ self.speedY = 0; // For falling direction
// Birds spawn from left or right edge and move in parallel lines
self.x = self.direction > 0 ? -100 : 2148; // Start from left or right edge
self.update = function () {
self.x += self.speed * self.direction;
+ if (self.speedY > 0) {
+ self.y += self.speedY; // Support falling movement
+ }
graphics.rotation += 0.1;
// Slight vertical bobbing
graphics.y = Math.sin(LK.ticks * 0.08) * 15;
};
@@ -183,12 +192,17 @@
anchorY: 0.5
});
self.visible = true;
self.flickerTimer = 0;
+ self.fallSpeed = 0; // For falling direction
// Wind chimes spawn anywhere on screen and suddenly appear/disappear
self.x = Math.random() * (2048 - 100) + 50;
self.update = function () {
self.flickerTimer++;
+ // Support falling movement
+ if (self.fallSpeed > 0) {
+ self.y += self.fallSpeed;
+ }
// Sudden appear/disappear effect every second
if (self.flickerTimer % 60 === 0) {
self.visible = !self.visible;
graphics.alpha = self.visible ? 1 : 0;
@@ -233,9 +247,9 @@
size: 100,
fill: 0xFFFFFF
});
distanceTxt.anchor.set(0.5, 0);
-distanceTxt.y = 50;
+distanceTxt.y = 30;
LK.gui.top.addChild(distanceTxt);
// Lives display
var livesContainer = new Container();
var lifeHearts = [];
@@ -250,9 +264,9 @@
heart.scaleY = 1.5;
livesContainer.addChild(heart);
lifeHearts.push(heart);
}
-livesContainer.y = 150;
+livesContainer.y = 200;
LK.gui.top.addChild(livesContainer);
// Update lives display function
function updateLivesDisplay() {
for (var i = 0; i < lifeHearts.length; i++) {
@@ -382,27 +396,42 @@
else if (Math.random() < 0.85) {
var cloud = game.addChild(new Cloud());
cloud.x = spawnX;
cloud.y = spawnY;
- clouds.push(cloud);
+ obstacles.push(cloud);
} else {
// Collectible wind chimes
var collectible = game.addChild(new Collectible('windChime'));
collectible.x = spawnX;
collectible.y = spawnY;
collectibles.push(collectible);
}
}
- // Independent bird spawning (rare, parallel lines from screen edges)
+ // Independent bird spawning (rare, parallel lines from screen edges and falling direction)
if (Math.random() < 0.001 * gameSpeed) {
var bird = game.addChild(new Bird());
- bird.y = player.y - Math.random() * 600 - 200;
+ // 50% chance to spawn from above (falling direction) or from edges
+ if (Math.random() < 0.5) {
+ bird.x = Math.random() * 2048;
+ bird.y = player.y - Math.random() * 600 - 400;
+ bird.speedY = Math.random() * 2 + 1;
+ } else {
+ bird.y = player.y - Math.random() * 600 - 200;
+ }
obstacles.push(bird);
}
- // Independent star spawning (rare, diagonal movement from screen edges)
+ // Independent star spawning (rare, diagonal movement and falling direction)
if (Math.random() < 0.0008 * gameSpeed) {
var star = game.addChild(new Star());
- star.y = player.y - Math.random() * 500 - 300;
+ // 50% chance to spawn from above (falling direction) or diagonally
+ if (Math.random() < 0.5) {
+ star.x = Math.random() * 2048;
+ star.y = player.y - Math.random() * 500 - 400;
+ star.speedX = (Math.random() - 0.5) * 4;
+ star.speedY = Math.random() * 2 + 2;
+ } else {
+ star.y = player.y - Math.random() * 500 - 300;
+ }
obstacles.push(star);
}
// Independent lightning spawning (rare, vertical path from above)
if (Math.random() < 0.0006 * gameSpeed) {
@@ -410,19 +439,32 @@
lightning.x = Math.random() * (2048 - 100) + 50;
lightning.y = player.y - Math.random() * 700 - 400;
obstacles.push(lightning);
}
- // Independent wind chime spawning (rare, appear/disappear anywhere on screen)
+ // Independent wind chime spawning (rare, appear/disappear anywhere and falling)
if (Math.random() < 0.0004 * gameSpeed) {
var windChime = game.addChild(new WindChime());
- windChime.y = player.y - Math.random() * 600 - 200;
+ // 50% chance to spawn from above (falling direction) or statically
+ if (Math.random() < 0.5) {
+ windChime.x = Math.random() * 2048;
+ windChime.y = player.y - Math.random() * 600 - 400;
+ windChime.fallSpeed = Math.random() * 1.5 + 0.5;
+ } else {
+ windChime.y = player.y - Math.random() * 600 - 200;
+ }
obstacles.push(windChime);
}
- // Independent air pocket spawning (rare, spawn anywhere on screen)
+ // Independent air pocket spawning (rare, spawn anywhere and falling direction)
if (Math.random() < 0.0005 * gameSpeed) {
var airPocket = game.addChild(new AirPocket());
airPocket.x = Math.random() * (2048 - 200) + 100;
- airPocket.y = player.y - Math.random() * 500 - 300;
+ // 50% chance to spawn from above (falling direction) or statically
+ if (Math.random() < 0.5) {
+ airPocket.y = player.y - Math.random() * 500 - 400;
+ airPocket.fallSpeed = Math.random() * 1 + 0.3;
+ } else {
+ airPocket.y = player.y - Math.random() * 500 - 300;
+ }
obstacles.push(airPocket);
}
// Update and check obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {