User prompt
try adding constraints then
User prompt
if a bullet is stuck in the wall, destroy it
User prompt
do not spawn bullets in wall
User prompt
prepopulate the game with 20 bullets. start their lifespan only after player start moving
User prompt
don't spawn bullets if player's not moving
User prompt
remove the "distance to mouse" speed changing
Code edit (1 edits merged)
Please save this source code
User prompt
make player unit move to mouse cursor pos instantly, then stop
Code edit (2 edits merged)
Please save this source code
User prompt
remove graceperiod
Code edit (1 edits merged)
Please save this source code
User prompt
you did not fix gradient
User prompt
I incresed bullet harmless time. fix gradient.
Code edit (1 edits merged)
Please save this source code
User prompt
double grace time
Code edit (1 edits merged)
Please save this source code
User prompt
add a red dot to center of player unit.
Code edit (1 edits merged)
Please save this source code
/**** * Classes ****/ //<Assets used in the game will automatically appear here> // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5, shape: 'ellipse', hitArea: new Rectangle(49.5, 49.5, 1, 1) }); var bulletCircle = self.attachAsset('yellowCircle', { anchorX: 0.5, anchorY: 0.5, alpha: 0.1, scaleX: 2, scaleY: 2 }); self.speed = 0.25; // Half the player's movement speed self.lifespan = 100; // 1 second lifespan (60 frames) self.update = function () { self.x += self.speedX * self.speed; self.y += self.speedY * self.speed; self.lifespan--; if (self.lifespan > 0) { self.alpha = 0.3; // Make the bullet half transparent } else { self.alpha = 0.6; // Make the bullet fully opaque } self.speed *= 0.99995; // Slow down the bullet over time self.scale.x += 0.0005; // Increase the bullet size over time self.scale.y += 0.0005; // Increase the bullet size over time bulletCircle.scale.x = self.scale.x * 2; // Update the circle size bulletCircle.scale.y = self.scale.y * 2; // Update the circle size // Change the bullet's color over time var progress = self.lifespan / 100; // Assuming lifespan is 100 frames var startColor = 0xff0000; // Red var endColor = 0x0000ff; // Blue var currentColor = interpolateColor(startColor, endColor, progress); bulletGraphics.tint = currentColor; if (self.y + bulletGraphics.height / 2 > 2732) { self.speedY = -self.speedY; LK.getSound('bulletWallCollision').play(); } if (self.y - bulletGraphics.height / 2 < 0) { self.speedY = -self.speedY; LK.getSound('bulletWallCollision').play(); } if (self.x + bulletGraphics.width / 2 > 2048) { self.speedX = -self.speedX; LK.getSound('bulletWallCollision').play(); } if (self.x - bulletGraphics.width / 2 < 0) { self.speedX = -self.speedX; LK.getSound('bulletWallCollision').play(); } }; }); var Pellet = Container.expand(function () { var self = Container.call(this); var pelletGraphics = self.attachAsset('pellet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0.95; // Half the player's movement speed self.speedX = Math.random() * 2 - 1; // Random direction self.speedY = Math.random() * 2 - 1; // Random direction self.update = function () { self.x += self.speedX * self.speed; self.y += self.speedY * self.speed; if (self.y + pelletGraphics.height / 2 > 2732) { self.speedY = -self.speedY; LK.getSound('bulletWallCollision').play(); } if (self.y - pelletGraphics.height / 2 < 0) { self.speedY = -self.speedY; LK.getSound('bulletWallCollision').play(); } if (self.x + pelletGraphics.width / 2 > 2048) { self.speedX = -self.speedX; LK.getSound('bulletWallCollision').play(); } if (self.x - pelletGraphics.width / 2 < 0) { self.speedX = -self.speedX; LK.getSound('bulletWallCollision').play(); } }; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('snakeHead', { anchorX: 0.5, anchorY: 0.5, shape: 'ellipse', hitArea: new Rectangle(25, 25, 50, 50) }); self.speed = 3; // Initialize player speed self.update = function () { var dx = targetX - self.x; var dy = targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 1) { // Only move if the distance is greater than a small threshold var speed = Math.min(Math.max(distance / 100, 3), 9); // Speed is proportional to distance, capped at 20 var newDirection = { x: dx / distance, y: dy / distance }; var directionChange = Math.abs(playerDirection.x - newDirection.x) + Math.abs(playerDirection.y - newDirection.y); if (directionChange > 0.01) { // If the player is turning, slow down self.speed = Math.max(self.speed * 0.985, 3); } else { // If the player is not turning, speed up self.speed += 0.03; } self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; playerDirection = newDirection; playerMovedDistance += distance; speedTxt.setText(Math.round(player.speed * 100) / 100); } // Check for collision with pellet for (var i = pellets.length - 1; i >= 0; i--) { if (self.intersects(pellets[i])) { console.log("Player intersects with pellet"); var redCircle = new RedCircle(); redCircle.x = pellets[i].x; redCircle.y = pellets[i].y; game.addChild(redCircle); pellets[i].destroy(); pellets.splice(i, 1); // Destroy bullets overlapping with redCircle on the frame it is created for (var j = bullets.length - 1; j >= 0; j--) { if (bullets[j].intersects(redCircle)) { bullets[j].destroy(); bullets.splice(j, 1); score++; scoreTxt.setText(score); } } // Play sound effect for pellet eaten LK.getSound('pelletEaten').play(); } } }; self.down = function (x, y, obj) { var game_position = game.toLocal(obj.global); targetX = game_position.x; targetY = game_position.y; }; self.move = function (x, y, obj) { var game_position = game.toLocal(obj.global); targetX = game_position.x; targetY = game_position.y; }; }); // RedCircle class var RedCircle = Container.expand(function () { var self = Container.call(this); var circleGraphics = self.attachAsset('redCircle', { anchorX: 0.5, anchorY: 0.5, scaleX: 4, scaleY: 4 }); self.lifespan = 170; // Decrease lifespan as score increases self.update = function () { self.lifespan--; if (self.lifespan > 0) { self.alpha = self.lifespan / 110 - 0.5; // Fade out over time self.scale.x = self.scale.y = self.lifespan / 130; // Decrease size over time } else { self.destroy(); // Destroy the circle when it's fully faded } }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ // Helper function to interpolate between two colors var scoreTxt = new Text2('0', { size: 400, fill: "#202000", font: "monospace", strokeThickness: 0 }); scoreTxt.anchor.set(0.5, 0.5); scoreTxt.x = 2048 / 2; scoreTxt.y = 2732 / 2; game.addChild(scoreTxt); var speedTxt = new Text2('0', { size: 100, fill: "#ffffff", font: "monospace", strokeThickness: 0 }); speedTxt.anchor.set(0.5, 0); speedTxt.x = 2048 / 2; speedTxt.y = 50; LK.gui.top.addChild(speedTxt); // Add scoreTxt after bullets to ensure it is drawn above them function interpolateColor(color1, color2, factor) { var r1 = color1 >> 16 & 0xff; var g1 = color1 >> 8 & 0xff; var b1 = color1 & 0xff; var r2 = color2 >> 16 & 0xff; var g2 = color2 >> 8 & 0xff; var b2 = color2 & 0xff; var r = Math.round(r1 + factor * (r2 - r1)); var g = Math.round(g1 + factor * (g2 - g1)); var b = Math.round(b1 + factor * (b2 - b1)); return r << 16 | g << 8 | b; } var bullets = []; var score = 0; var gracePeriod = 180; // 3 seconds at 60FPS var playerDirection = { x: 0, y: 0 }; var playerMovedDistance = 0; var pellets = []; var player = new Player(); player.x = 2048 / 2; player.y = 2732 / 2; game.addChild(player); var targetX = player.x; var targetY = player.y; game.update = function () { for (var i = bullets.length - 1; i >= 0; i--) { bullets[i].update(); if (gracePeriod <= 0 && bullets[i].lifespan <= 0) { var playerCenter = { x: player.x, y: player.y }; var bulletCenter = { x: bullets[i].x, y: bullets[i].y }; if (Math.abs(playerCenter.x - bulletCenter.x) < player.width / 2 && Math.abs(playerCenter.y - bulletCenter.y) < player.height / 2) { console.log("Bullet intersects with player center at:", playerCenter, "Bullet center at:", bulletCenter); LK.effects.flashScreen(0xff0000, 1000); LK.showGameOver(); return; } } } if (gracePeriod > 0) { gracePeriod--; } if (pellets.length < 2 && LK.ticks % 60 == 0) { // Spawn a pellet every second if there are less than two pellets var newPellet = new Pellet(); // Ensure pellet does not spawn close to the wall var distance; do { newPellet.x = Math.random() * (2048 - 400) + 200; // Random x position newPellet.y = Math.random() * (2732 - 400) + 200; // Random y position distance = Math.sqrt(Math.pow(newPellet.x - player.x, 2) + Math.pow(newPellet.y - player.y, 2)); } while (distance < 500); // Ensure pellet spawns at least 500 units away from the player game.addChild(newPellet); pellets.push(newPellet); } if (playerMovedDistance >= 50 && LK.ticks % Math.max(20 - Math.log(LK.getScore() + 1), 5) == 0) { var newBullet = new Bullet(); newBullet.x = player.x - playerDirection.x * 60; // Spawn bullet closer to the player newBullet.y = player.y - playerDirection.y * 60; newBullet.speedX = playerDirection.x * 5; // Bullet moves in the player's direction newBullet.speedY = playerDirection.y * 5; bullets.push(newBullet); game.addChild(newBullet); // Play sound effect for bullet spawn LK.getSound('bulletSpawn').play(); } }; game.down = function (x, y, obj) { player.down(x, y, obj); }; game.move = function (x, y, obj) { player.move(x, y, obj); }; game.up = function (x, y, obj) { // No action needed on up event };
/****
* Classes
****/
//<Assets used in the game will automatically appear here>
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5,
shape: 'ellipse',
hitArea: new Rectangle(49.5, 49.5, 1, 1)
});
var bulletCircle = self.attachAsset('yellowCircle', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.1,
scaleX: 2,
scaleY: 2
});
self.speed = 0.25; // Half the player's movement speed
self.lifespan = 100; // 1 second lifespan (60 frames)
self.update = function () {
self.x += self.speedX * self.speed;
self.y += self.speedY * self.speed;
self.lifespan--;
if (self.lifespan > 0) {
self.alpha = 0.3; // Make the bullet half transparent
} else {
self.alpha = 0.6; // Make the bullet fully opaque
}
self.speed *= 0.99995; // Slow down the bullet over time
self.scale.x += 0.0005; // Increase the bullet size over time
self.scale.y += 0.0005; // Increase the bullet size over time
bulletCircle.scale.x = self.scale.x * 2; // Update the circle size
bulletCircle.scale.y = self.scale.y * 2; // Update the circle size
// Change the bullet's color over time
var progress = self.lifespan / 100; // Assuming lifespan is 100 frames
var startColor = 0xff0000; // Red
var endColor = 0x0000ff; // Blue
var currentColor = interpolateColor(startColor, endColor, progress);
bulletGraphics.tint = currentColor;
if (self.y + bulletGraphics.height / 2 > 2732) {
self.speedY = -self.speedY;
LK.getSound('bulletWallCollision').play();
}
if (self.y - bulletGraphics.height / 2 < 0) {
self.speedY = -self.speedY;
LK.getSound('bulletWallCollision').play();
}
if (self.x + bulletGraphics.width / 2 > 2048) {
self.speedX = -self.speedX;
LK.getSound('bulletWallCollision').play();
}
if (self.x - bulletGraphics.width / 2 < 0) {
self.speedX = -self.speedX;
LK.getSound('bulletWallCollision').play();
}
};
});
var Pellet = Container.expand(function () {
var self = Container.call(this);
var pelletGraphics = self.attachAsset('pellet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0.95; // Half the player's movement speed
self.speedX = Math.random() * 2 - 1; // Random direction
self.speedY = Math.random() * 2 - 1; // Random direction
self.update = function () {
self.x += self.speedX * self.speed;
self.y += self.speedY * self.speed;
if (self.y + pelletGraphics.height / 2 > 2732) {
self.speedY = -self.speedY;
LK.getSound('bulletWallCollision').play();
}
if (self.y - pelletGraphics.height / 2 < 0) {
self.speedY = -self.speedY;
LK.getSound('bulletWallCollision').play();
}
if (self.x + pelletGraphics.width / 2 > 2048) {
self.speedX = -self.speedX;
LK.getSound('bulletWallCollision').play();
}
if (self.x - pelletGraphics.width / 2 < 0) {
self.speedX = -self.speedX;
LK.getSound('bulletWallCollision').play();
}
};
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('snakeHead', {
anchorX: 0.5,
anchorY: 0.5,
shape: 'ellipse',
hitArea: new Rectangle(25, 25, 50, 50)
});
self.speed = 3; // Initialize player speed
self.update = function () {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 1) {
// Only move if the distance is greater than a small threshold
var speed = Math.min(Math.max(distance / 100, 3), 9); // Speed is proportional to distance, capped at 20
var newDirection = {
x: dx / distance,
y: dy / distance
};
var directionChange = Math.abs(playerDirection.x - newDirection.x) + Math.abs(playerDirection.y - newDirection.y);
if (directionChange > 0.01) {
// If the player is turning, slow down
self.speed = Math.max(self.speed * 0.985, 3);
} else {
// If the player is not turning, speed up
self.speed += 0.03;
}
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
playerDirection = newDirection;
playerMovedDistance += distance;
speedTxt.setText(Math.round(player.speed * 100) / 100);
}
// Check for collision with pellet
for (var i = pellets.length - 1; i >= 0; i--) {
if (self.intersects(pellets[i])) {
console.log("Player intersects with pellet");
var redCircle = new RedCircle();
redCircle.x = pellets[i].x;
redCircle.y = pellets[i].y;
game.addChild(redCircle);
pellets[i].destroy();
pellets.splice(i, 1);
// Destroy bullets overlapping with redCircle on the frame it is created
for (var j = bullets.length - 1; j >= 0; j--) {
if (bullets[j].intersects(redCircle)) {
bullets[j].destroy();
bullets.splice(j, 1);
score++;
scoreTxt.setText(score);
}
}
// Play sound effect for pellet eaten
LK.getSound('pelletEaten').play();
}
}
};
self.down = function (x, y, obj) {
var game_position = game.toLocal(obj.global);
targetX = game_position.x;
targetY = game_position.y;
};
self.move = function (x, y, obj) {
var game_position = game.toLocal(obj.global);
targetX = game_position.x;
targetY = game_position.y;
};
});
// RedCircle class
var RedCircle = Container.expand(function () {
var self = Container.call(this);
var circleGraphics = self.attachAsset('redCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 4,
scaleY: 4
});
self.lifespan = 170; // Decrease lifespan as score increases
self.update = function () {
self.lifespan--;
if (self.lifespan > 0) {
self.alpha = self.lifespan / 110 - 0.5; // Fade out over time
self.scale.x = self.scale.y = self.lifespan / 130; // Decrease size over time
} else {
self.destroy(); // Destroy the circle when it's fully faded
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
// Helper function to interpolate between two colors
var scoreTxt = new Text2('0', {
size: 400,
fill: "#202000",
font: "monospace",
strokeThickness: 0
});
scoreTxt.anchor.set(0.5, 0.5);
scoreTxt.x = 2048 / 2;
scoreTxt.y = 2732 / 2;
game.addChild(scoreTxt);
var speedTxt = new Text2('0', {
size: 100,
fill: "#ffffff",
font: "monospace",
strokeThickness: 0
});
speedTxt.anchor.set(0.5, 0);
speedTxt.x = 2048 / 2;
speedTxt.y = 50;
LK.gui.top.addChild(speedTxt);
// Add scoreTxt after bullets to ensure it is drawn above them
function interpolateColor(color1, color2, factor) {
var r1 = color1 >> 16 & 0xff;
var g1 = color1 >> 8 & 0xff;
var b1 = color1 & 0xff;
var r2 = color2 >> 16 & 0xff;
var g2 = color2 >> 8 & 0xff;
var b2 = color2 & 0xff;
var r = Math.round(r1 + factor * (r2 - r1));
var g = Math.round(g1 + factor * (g2 - g1));
var b = Math.round(b1 + factor * (b2 - b1));
return r << 16 | g << 8 | b;
}
var bullets = [];
var score = 0;
var gracePeriod = 180; // 3 seconds at 60FPS
var playerDirection = {
x: 0,
y: 0
};
var playerMovedDistance = 0;
var pellets = [];
var player = new Player();
player.x = 2048 / 2;
player.y = 2732 / 2;
game.addChild(player);
var targetX = player.x;
var targetY = player.y;
game.update = function () {
for (var i = bullets.length - 1; i >= 0; i--) {
bullets[i].update();
if (gracePeriod <= 0 && bullets[i].lifespan <= 0) {
var playerCenter = {
x: player.x,
y: player.y
};
var bulletCenter = {
x: bullets[i].x,
y: bullets[i].y
};
if (Math.abs(playerCenter.x - bulletCenter.x) < player.width / 2 && Math.abs(playerCenter.y - bulletCenter.y) < player.height / 2) {
console.log("Bullet intersects with player center at:", playerCenter, "Bullet center at:", bulletCenter);
LK.effects.flashScreen(0xff0000, 1000);
LK.showGameOver();
return;
}
}
}
if (gracePeriod > 0) {
gracePeriod--;
}
if (pellets.length < 2 && LK.ticks % 60 == 0) {
// Spawn a pellet every second if there are less than two pellets
var newPellet = new Pellet();
// Ensure pellet does not spawn close to the wall
var distance;
do {
newPellet.x = Math.random() * (2048 - 400) + 200; // Random x position
newPellet.y = Math.random() * (2732 - 400) + 200; // Random y position
distance = Math.sqrt(Math.pow(newPellet.x - player.x, 2) + Math.pow(newPellet.y - player.y, 2));
} while (distance < 500); // Ensure pellet spawns at least 500 units away from the player
game.addChild(newPellet);
pellets.push(newPellet);
}
if (playerMovedDistance >= 50 && LK.ticks % Math.max(20 - Math.log(LK.getScore() + 1), 5) == 0) {
var newBullet = new Bullet();
newBullet.x = player.x - playerDirection.x * 60; // Spawn bullet closer to the player
newBullet.y = player.y - playerDirection.y * 60;
newBullet.speedX = playerDirection.x * 5; // Bullet moves in the player's direction
newBullet.speedY = playerDirection.y * 5;
bullets.push(newBullet);
game.addChild(newBullet);
// Play sound effect for bullet spawn
LK.getSound('bulletSpawn').play();
}
};
game.down = function (x, y, obj) {
player.down(x, y, obj);
};
game.move = function (x, y, obj) {
player.move(x, y, obj);
};
game.up = function (x, y, obj) {
// No action needed on up event
};