User prompt
Increase the stones even more and arrange them so that they do not hit each other
User prompt
If rocks hit each other, they will break into pieces
User prompt
rocks should not pass through each other and the number of rocks should gradually increase
User prompt
Let some rocks fall faster
Code edit (1 edits merged)
Please save this source code
User prompt
Rock Dodge
Initial prompt
Make a game where we run away from falling rocks
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; return self; }); var Rock = Container.expand(function (rockType) { var self = Container.call(this); var assetName = rockType || 'rock_medium'; var rockGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); // Set falling speed based on rock type if (assetName === 'rock_small') { self.fallSpeed = 3; } else if (assetName === 'rock_medium') { self.fallSpeed = 4; } else { self.fallSpeed = 2; } // Add chance for fast-falling rocks (20% chance) if (Math.random() < 0.2) { self.fallSpeed *= 2.5; // Make some rocks fall much faster } // Store rock type for breaking logic self.rockType = assetName; self.update = function () { // Check collision with other rocks before moving var proposedY = self.y + self.fallSpeed; var canMove = true; var collidingRock = null; // Check against all other rocks for (var i = 0; i < rocks.length; i++) { var otherRock = rocks[i]; if (otherRock === self) continue; // Skip self // Check if we would collide with another rock var tempY = self.y; self.y = proposedY; if (self.intersects(otherRock)) { canMove = false; collidingRock = otherRock; } self.y = tempY; // Restore original position if (!canMove) break; } // If collision detected, break both rocks if (!canMove && collidingRock) { self.shouldBreak = true; collidingRock.shouldBreak = true; } // Only move if no collision would occur if (canMove) { self.y = proposedY; } }; return self; }); var RockPiece = Container.expand(function (size) { var self = Container.call(this); var pieceGraphics = self.attachAsset('rock_small', { anchorX: 0.5, anchorY: 0.5 }); // Scale down based on size parameter var scale = size || 0.3; pieceGraphics.scaleX = scale; pieceGraphics.scaleY = scale; // Random velocity for flying pieces self.velocityX = (Math.random() - 0.5) * 8; self.velocityY = -Math.random() * 5 - 2; self.gravity = 0.3; self.lifeTime = 0; self.maxLifeTime = 120; // 2 seconds at 60fps self.update = function () { // Apply physics self.x += self.velocityX; self.y += self.velocityY; self.velocityY += self.gravity; // Fade out over time self.lifeTime++; var alpha = 1 - self.lifeTime / self.maxLifeTime; pieceGraphics.alpha = Math.max(0, alpha); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb }); /**** * Game Code ****/ // Game variables var player; var rocks = []; var rockPieces = []; var rockSpawnTimer = 0; var rockSpawnDelay = 90; // Initial spawn delay (60fps = 1.5 seconds) var gameSpeed = 1; var speedIncreaseTimer = 0; var dragNode = null; // UI Elements var scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var timeTxt = new Text2('Time: 0s', { size: 60, fill: 0xFFFFFF }); timeTxt.anchor.set(0, 0); timeTxt.x = 50; timeTxt.y = 150; LK.gui.topLeft.addChild(timeTxt); // Initialize player player = game.addChild(new Player()); player.x = 2048 / 2; player.y = 2732 - 150; // Game state tracking var gameTime = 0; var lastIntersecting = false; // Rock types for variety var rockTypes = ['rock_small', 'rock_medium', 'rock_large']; // Event handlers function handleMove(x, y, obj) { if (dragNode) { // Convert to game coordinates and constrain to screen bounds var newX = x; var playerWidth = 40; // Half width for boundary checking if (newX < playerWidth) { newX = playerWidth; } else if (newX > 2048 - playerWidth) { newX = 2048 - playerWidth; } dragNode.x = newX; } } game.move = handleMove; game.down = function (x, y, obj) { dragNode = player; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; // Function to create rock pieces when rocks break function createRockPieces(rock) { var numPieces = 4 + Math.floor(Math.random() * 4); // 4-7 pieces for (var p = 0; p < numPieces; p++) { var piece = new RockPiece(0.2 + Math.random() * 0.3); piece.x = rock.x + (Math.random() - 0.5) * 40; piece.y = rock.y + (Math.random() - 0.5) * 40; rockPieces.push(piece); game.addChild(piece); } } // Spawn rock function function spawnRock() { var rockType = rockTypes[Math.floor(Math.random() * rockTypes.length)]; var newRock = new Rock(rockType); // Try to find a safe horizontal position to prevent immediate overlap var attempts = 0; var safePosition = false; var proposedX; while (!safePosition && attempts < 10) { proposedX = Math.random() * (2048 - 200) + 100; safePosition = true; // Check against existing rocks in the spawn area for (var i = 0; i < rocks.length; i++) { var existingRock = rocks[i]; if (existingRock.y < 200) { // Only check rocks near spawn area var distance = Math.abs(existingRock.x - proposedX); if (distance < 150) { // Minimum spacing safePosition = false; break; } } } attempts++; } newRock.x = proposedX; newRock.y = -100 - Math.random() * 50; // Vary spawn height slightly // Apply game speed multiplier newRock.fallSpeed *= gameSpeed; // Initialize tracking variables newRock.lastY = newRock.y; newRock.lastIntersecting = false; rocks.push(newRock); game.addChild(newRock); } // Main game update loop game.update = function () { gameTime++; // Update score and time display var seconds = Math.floor(gameTime / 60); LK.setScore(seconds); scoreTxt.setText(LK.getScore()); timeTxt.setText('Time: ' + seconds + 's'); // Increase difficulty over time speedIncreaseTimer++; if (speedIncreaseTimer >= 300) { // Every 5 seconds speedIncreaseTimer = 0; gameSpeed += 0.1; if (rockSpawnDelay > 10) { rockSpawnDelay -= 5; // Reduce spawn delay even more aggressively } // Ensure minimum spawn delay if (rockSpawnDelay < 8) { rockSpawnDelay = 8; } } // Spawn rocks rockSpawnTimer++; if (rockSpawnTimer >= rockSpawnDelay) { rockSpawnTimer = 0; // Spawn multiple rocks based on game progression var rocksToSpawn = 1; if (seconds > 15) rocksToSpawn = 2; if (seconds > 30) rocksToSpawn = 3; if (seconds > 45) rocksToSpawn = 4; if (seconds > 60) rocksToSpawn = 5; if (seconds > 90) rocksToSpawn = 6; if (seconds > 120) rocksToSpawn = 7; for (var spawnCount = 0; spawnCount < rocksToSpawn; spawnCount++) { spawnRock(); } } // Additional frequent spawning for more rocks if (rockSpawnTimer % Math.max(15, rockSpawnDelay / 3) === 0 && seconds > 10) { spawnRock(); } // Update and check rocks for (var i = rocks.length - 1; i >= 0; i--) { var rock = rocks[i]; // Check if rock should break if (rock.shouldBreak) { createRockPieces(rock); rock.destroy(); rocks.splice(i, 1); continue; } // Track off-screen removal if (rock.lastY <= 2732 + 100 && rock.y > 2732 + 100) { rock.destroy(); rocks.splice(i, 1); continue; } // Check collision with player var currentIntersecting = rock.intersects(player); if (!rock.lastIntersecting && currentIntersecting) { // Collision detected - game over LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } // Update tracking variables rock.lastY = rock.y; rock.lastIntersecting = currentIntersecting; } // Update rock pieces for (var j = rockPieces.length - 1; j >= 0; j--) { var piece = rockPieces[j]; // Remove pieces that have expired if (piece.lifeTime >= piece.maxLifeTime) { piece.destroy(); rockPieces.splice(j, 1); continue; } // Remove pieces that fall off screen if (piece.y > 2732 + 100) { piece.destroy(); rockPieces.splice(j, 1); continue; } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
return self;
});
var Rock = Container.expand(function (rockType) {
var self = Container.call(this);
var assetName = rockType || 'rock_medium';
var rockGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
// Set falling speed based on rock type
if (assetName === 'rock_small') {
self.fallSpeed = 3;
} else if (assetName === 'rock_medium') {
self.fallSpeed = 4;
} else {
self.fallSpeed = 2;
}
// Add chance for fast-falling rocks (20% chance)
if (Math.random() < 0.2) {
self.fallSpeed *= 2.5; // Make some rocks fall much faster
}
// Store rock type for breaking logic
self.rockType = assetName;
self.update = function () {
// Check collision with other rocks before moving
var proposedY = self.y + self.fallSpeed;
var canMove = true;
var collidingRock = null;
// Check against all other rocks
for (var i = 0; i < rocks.length; i++) {
var otherRock = rocks[i];
if (otherRock === self) continue; // Skip self
// Check if we would collide with another rock
var tempY = self.y;
self.y = proposedY;
if (self.intersects(otherRock)) {
canMove = false;
collidingRock = otherRock;
}
self.y = tempY; // Restore original position
if (!canMove) break;
}
// If collision detected, break both rocks
if (!canMove && collidingRock) {
self.shouldBreak = true;
collidingRock.shouldBreak = true;
}
// Only move if no collision would occur
if (canMove) {
self.y = proposedY;
}
};
return self;
});
var RockPiece = Container.expand(function (size) {
var self = Container.call(this);
var pieceGraphics = self.attachAsset('rock_small', {
anchorX: 0.5,
anchorY: 0.5
});
// Scale down based on size parameter
var scale = size || 0.3;
pieceGraphics.scaleX = scale;
pieceGraphics.scaleY = scale;
// Random velocity for flying pieces
self.velocityX = (Math.random() - 0.5) * 8;
self.velocityY = -Math.random() * 5 - 2;
self.gravity = 0.3;
self.lifeTime = 0;
self.maxLifeTime = 120; // 2 seconds at 60fps
self.update = function () {
// Apply physics
self.x += self.velocityX;
self.y += self.velocityY;
self.velocityY += self.gravity;
// Fade out over time
self.lifeTime++;
var alpha = 1 - self.lifeTime / self.maxLifeTime;
pieceGraphics.alpha = Math.max(0, alpha);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
// Game variables
var player;
var rocks = [];
var rockPieces = [];
var rockSpawnTimer = 0;
var rockSpawnDelay = 90; // Initial spawn delay (60fps = 1.5 seconds)
var gameSpeed = 1;
var speedIncreaseTimer = 0;
var dragNode = null;
// UI Elements
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var timeTxt = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeTxt.anchor.set(0, 0);
timeTxt.x = 50;
timeTxt.y = 150;
LK.gui.topLeft.addChild(timeTxt);
// Initialize player
player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2732 - 150;
// Game state tracking
var gameTime = 0;
var lastIntersecting = false;
// Rock types for variety
var rockTypes = ['rock_small', 'rock_medium', 'rock_large'];
// Event handlers
function handleMove(x, y, obj) {
if (dragNode) {
// Convert to game coordinates and constrain to screen bounds
var newX = x;
var playerWidth = 40; // Half width for boundary checking
if (newX < playerWidth) {
newX = playerWidth;
} else if (newX > 2048 - playerWidth) {
newX = 2048 - playerWidth;
}
dragNode.x = newX;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Function to create rock pieces when rocks break
function createRockPieces(rock) {
var numPieces = 4 + Math.floor(Math.random() * 4); // 4-7 pieces
for (var p = 0; p < numPieces; p++) {
var piece = new RockPiece(0.2 + Math.random() * 0.3);
piece.x = rock.x + (Math.random() - 0.5) * 40;
piece.y = rock.y + (Math.random() - 0.5) * 40;
rockPieces.push(piece);
game.addChild(piece);
}
}
// Spawn rock function
function spawnRock() {
var rockType = rockTypes[Math.floor(Math.random() * rockTypes.length)];
var newRock = new Rock(rockType);
// Try to find a safe horizontal position to prevent immediate overlap
var attempts = 0;
var safePosition = false;
var proposedX;
while (!safePosition && attempts < 10) {
proposedX = Math.random() * (2048 - 200) + 100;
safePosition = true;
// Check against existing rocks in the spawn area
for (var i = 0; i < rocks.length; i++) {
var existingRock = rocks[i];
if (existingRock.y < 200) {
// Only check rocks near spawn area
var distance = Math.abs(existingRock.x - proposedX);
if (distance < 150) {
// Minimum spacing
safePosition = false;
break;
}
}
}
attempts++;
}
newRock.x = proposedX;
newRock.y = -100 - Math.random() * 50; // Vary spawn height slightly
// Apply game speed multiplier
newRock.fallSpeed *= gameSpeed;
// Initialize tracking variables
newRock.lastY = newRock.y;
newRock.lastIntersecting = false;
rocks.push(newRock);
game.addChild(newRock);
}
// Main game update loop
game.update = function () {
gameTime++;
// Update score and time display
var seconds = Math.floor(gameTime / 60);
LK.setScore(seconds);
scoreTxt.setText(LK.getScore());
timeTxt.setText('Time: ' + seconds + 's');
// Increase difficulty over time
speedIncreaseTimer++;
if (speedIncreaseTimer >= 300) {
// Every 5 seconds
speedIncreaseTimer = 0;
gameSpeed += 0.1;
if (rockSpawnDelay > 10) {
rockSpawnDelay -= 5; // Reduce spawn delay even more aggressively
}
// Ensure minimum spawn delay
if (rockSpawnDelay < 8) {
rockSpawnDelay = 8;
}
}
// Spawn rocks
rockSpawnTimer++;
if (rockSpawnTimer >= rockSpawnDelay) {
rockSpawnTimer = 0;
// Spawn multiple rocks based on game progression
var rocksToSpawn = 1;
if (seconds > 15) rocksToSpawn = 2;
if (seconds > 30) rocksToSpawn = 3;
if (seconds > 45) rocksToSpawn = 4;
if (seconds > 60) rocksToSpawn = 5;
if (seconds > 90) rocksToSpawn = 6;
if (seconds > 120) rocksToSpawn = 7;
for (var spawnCount = 0; spawnCount < rocksToSpawn; spawnCount++) {
spawnRock();
}
}
// Additional frequent spawning for more rocks
if (rockSpawnTimer % Math.max(15, rockSpawnDelay / 3) === 0 && seconds > 10) {
spawnRock();
}
// Update and check rocks
for (var i = rocks.length - 1; i >= 0; i--) {
var rock = rocks[i];
// Check if rock should break
if (rock.shouldBreak) {
createRockPieces(rock);
rock.destroy();
rocks.splice(i, 1);
continue;
}
// Track off-screen removal
if (rock.lastY <= 2732 + 100 && rock.y > 2732 + 100) {
rock.destroy();
rocks.splice(i, 1);
continue;
}
// Check collision with player
var currentIntersecting = rock.intersects(player);
if (!rock.lastIntersecting && currentIntersecting) {
// Collision detected - game over
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
// Update tracking variables
rock.lastY = rock.y;
rock.lastIntersecting = currentIntersecting;
}
// Update rock pieces
for (var j = rockPieces.length - 1; j >= 0; j--) {
var piece = rockPieces[j];
// Remove pieces that have expired
if (piece.lifeTime >= piece.maxLifeTime) {
piece.destroy();
rockPieces.splice(j, 1);
continue;
}
// Remove pieces that fall off screen
if (piece.y > 2732 + 100) {
piece.destroy();
rockPieces.splice(j, 1);
continue;
}
}
};