User prompt
Add spiders that lunge at the player to kill them ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Forest Escape: Journey to the Grasslands
Initial prompt
A cube going through a forest to get to the grasslands
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Obstacle = Container.expand(function (obstacleType) {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset(obstacleType, {
anchorX: 0.5,
anchorY: 0.5
});
self.obstacleType = obstacleType;
self.speed = 2;
self.lastY = undefined;
self.lastIntersecting = false;
self.update = function () {
self.y += self.speed;
};
return self;
});
var MovingBranch = Obstacle.expand(function () {
var self = Obstacle.call(this, 'branch');
self.moveDirection = Math.random() > 0.5 ? 1 : -1;
self.moveSpeed = 1 + Math.random() * 2;
self.update = function () {
self.y += self.speed;
self.x += self.moveDirection * self.moveSpeed;
// Bounce off edges
if (self.x < 100 || self.x > 1948) {
self.moveDirection *= -1;
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 3;
self.targetX = 2048 / 2;
self.targetY = 2500;
self.update = function () {
// Smooth movement towards target position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
self.x += dx * 0.08;
self.y += dy * 0.08;
// Auto-move upward through forest
self.targetY -= self.speed;
// Keep player in bounds
if (self.targetX < 100) self.targetX = 100;
if (self.targetX > 1948) self.targetX = 1948;
};
return self;
});
var Spider = Container.expand(function () {
var self = Container.call(this);
var spiderGraphics = self.attachAsset('spider', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5;
self.lungeCooldown = 0;
self.isLunging = false;
self.detectionRange = 300;
self.lungeSpeed = 8;
self.lastY = undefined;
self.lastIntersecting = false;
self.update = function () {
// Normal downward movement
if (!self.isLunging) {
self.y += self.speed;
// Check if player is in detection range
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
// Lunge at player if in range and cooldown is over
if (distanceToPlayer < self.detectionRange && self.lungeCooldown <= 0 && player.y < self.y) {
self.isLunging = true;
self.lungeCooldown = 120; // 2 seconds at 60fps
LK.getSound('spiderLunge').play();
// Calculate lunge direction
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var lungeX = self.x + dx / distance * 200;
var lungeY = self.y + dy / distance * 200;
// Animate the lunge using tween
tween(self, {
x: lungeX,
y: lungeY,
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 800,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isLunging = false;
// Return to normal size
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.easeIn
});
}
});
}
}
// Decrease cooldown
if (self.lungeCooldown > 0) {
self.lungeCooldown--;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
// Game variables
var player;
var obstacles = [];
var distanceTraveled = 0;
var gameSpeed = 2;
var obstacleSpawnTimer = 0;
var forestDensity = 60; // Lower = more dense
var dragNode = null;
// Initialize player
player = game.addChild(new Player());
player.x = 2048 / 2;
player.y = 2500;
// Score display
var scoreTxt = new Text2('Distance: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
// Distance display
var distanceTxt = new Text2('Forest Depth: 0m', {
size: 50,
fill: 0x90EE90
});
distanceTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(distanceTxt);
// Victory check distance (reach grasslands)
var victoryDistance = 5000;
// Spawn obstacle function
function spawnObstacle() {
var obstacleTypes = ['tree', 'branch', 'log', 'rock', 'spider'];
var randomType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
var obstacle;
if (randomType === 'branch' && Math.random() > 0.7) {
obstacle = new MovingBranch();
} else if (randomType === 'spider') {
obstacle = new Spider();
} else {
obstacle = new Obstacle(randomType);
}
obstacle.x = 200 + Math.random() * 1648;
obstacle.y = -100;
if (randomType !== 'spider') {
obstacle.speed = gameSpeed + Math.random() * 2;
}
obstacle.lastY = obstacle.y;
obstacle.lastIntersecting = false;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Handle input
function handleMove(x, y, obj) {
if (dragNode) {
dragNode.targetX = x;
dragNode.targetY = y;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
dragNode = player;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
// Update distance traveled
distanceTraveled += gameSpeed;
// Update displays
scoreTxt.setText('Score: ' + LK.getScore());
distanceTxt.setText('Forest Depth: ' + Math.floor(distanceTraveled / 10) + 'm');
// Increase game difficulty over time
if (LK.ticks % 300 === 0) {
gameSpeed += 0.1;
if (forestDensity > 20) forestDensity -= 2;
}
// Spawn obstacles
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= forestDensity) {
spawnObstacle();
obstacleSpawnTimer = 0;
}
// Update 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 off-screen obstacles
if (obstacle.lastY < 2800 && obstacle.y >= 2800) {
obstacle.destroy();
obstacles.splice(i, 1);
// Award points for avoiding obstacle
LK.setScore(LK.getScore() + 10);
LK.getSound('dodge').play();
continue;
}
// Check collision with player
var currentIntersecting = obstacle.intersects(player);
if (!obstacle.lastIntersecting && currentIntersecting) {
// Collision detected
LK.getSound('crash').play();
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
return;
}
obstacle.lastY = obstacle.y;
obstacle.lastIntersecting = currentIntersecting;
}
// Check victory condition
if (distanceTraveled >= victoryDistance) {
LK.effects.flashScreen(0x00ff00, 1000);
LK.showYouWin();
return;
}
// Keep player in forest bounds
if (player.y < 100) {
player.targetY = 100;
}
if (player.y > 2600) {
player.targetY = 2600;
}
};
// Start background music
LK.playMusic('forestTheme'); ===================================================================
--- original.js
+++ change.js
@@ -57,8 +57,68 @@
if (self.targetX > 1948) self.targetX = 1948;
};
return self;
});
+var Spider = Container.expand(function () {
+ var self = Container.call(this);
+ var spiderGraphics = self.attachAsset('spider', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.speed = 1.5;
+ self.lungeCooldown = 0;
+ self.isLunging = false;
+ self.detectionRange = 300;
+ self.lungeSpeed = 8;
+ self.lastY = undefined;
+ self.lastIntersecting = false;
+ self.update = function () {
+ // Normal downward movement
+ if (!self.isLunging) {
+ self.y += self.speed;
+ // Check if player is in detection range
+ var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
+ // Lunge at player if in range and cooldown is over
+ if (distanceToPlayer < self.detectionRange && self.lungeCooldown <= 0 && player.y < self.y) {
+ self.isLunging = true;
+ self.lungeCooldown = 120; // 2 seconds at 60fps
+ LK.getSound('spiderLunge').play();
+ // Calculate lunge direction
+ var dx = player.x - self.x;
+ var dy = player.y - self.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ var lungeX = self.x + dx / distance * 200;
+ var lungeY = self.y + dy / distance * 200;
+ // Animate the lunge using tween
+ tween(self, {
+ x: lungeX,
+ y: lungeY,
+ scaleX: 1.3,
+ scaleY: 1.3
+ }, {
+ duration: 800,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.isLunging = false;
+ // Return to normal size
+ tween(self, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 300,
+ easing: tween.easeIn
+ });
+ }
+ });
+ }
+ }
+ // Decrease cooldown
+ if (self.lungeCooldown > 0) {
+ self.lungeCooldown--;
+ }
+ };
+ return self;
+});
/****
* Initialize Game
****/
@@ -98,19 +158,23 @@
// Victory check distance (reach grasslands)
var victoryDistance = 5000;
// Spawn obstacle function
function spawnObstacle() {
- var obstacleTypes = ['tree', 'branch', 'log', 'rock'];
+ var obstacleTypes = ['tree', 'branch', 'log', 'rock', 'spider'];
var randomType = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];
var obstacle;
if (randomType === 'branch' && Math.random() > 0.7) {
obstacle = new MovingBranch();
+ } else if (randomType === 'spider') {
+ obstacle = new Spider();
} else {
obstacle = new Obstacle(randomType);
}
obstacle.x = 200 + Math.random() * 1648;
obstacle.y = -100;
- obstacle.speed = gameSpeed + Math.random() * 2;
+ if (randomType !== 'spider') {
+ obstacle.speed = gameSpeed + Math.random() * 2;
+ }
obstacle.lastY = obstacle.y;
obstacle.lastIntersecting = false;
obstacles.push(obstacle);
game.addChild(obstacle);