User prompt
Make the door in bottom layer
User prompt
t still grows ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Dont make any large and shrink,remove it ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Large first grow is soo much ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
It grows soo much once when its completed
User prompt
Make it 2x less grow ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make it a little less grow ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ok dont vibrate it,make it continuously grow and shrink again ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Just make it go to random near location and make it come back to normal location,repeat it
User prompt
Its only vibrating once make it continiusly
User prompt
Vibrate it more
User prompt
Make it still virate until the game ends
User prompt
It still vibrating until the game ends.
User prompt
If a task completed make it task vibrate a little
User prompt
Tasks required time change bettwen 3 and 5(randomized every task
User prompt
Make me 1.15x slower
User prompt
Make impostor 1.5x faster
User prompt
Add two cabinet(up left corner,bottom right corner) so i can hide from impostor,if im hiding impostor starts walk to left bottom and wait until i stop hiding,cabinet works like task,i need to touch it and be near it.
User prompt
Mwke the impostor 2x slower
User prompt
One task is going over to screen make it normal
User prompt
Put the door to top layer,impostor 2nd,player 3nd,and the generators in the 4nd layer
User prompt
Put the tasks further
User prompt
Make me bigger
User prompt
Change the task N/N to generator N/N
User prompt
Make this change %12,5
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Crewmate/Impostor player class
var Player = Container.expand(function () {
var self = Container.call(this);
// Role: 'crewmate' or 'impostor'
self.role = 'crewmate';
self.isAlive = true;
self.isLocal = false; // Only one player is local (user-controlled)
self.playerId = 0; // Unique id
// Attach asset based on role
self.setRole = function (role) {
self.role = role;
if (self.sprite) {
self.removeChild(self.sprite);
}
var assetId = role === 'impostor' ? 'impostor' : 'crewmate';
self.sprite = self.attachAsset(assetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Make impostor 2x bigger, and make crewmate (player) 2x bigger as well
if (role === 'impostor' || role === 'crewmate') {
self.sprite.scaleX = 2;
self.sprite.scaleY = 2;
} else {
self.sprite.scaleX = 1;
self.sprite.scaleY = 1;
}
self.facing = 1; // 1 = right, -1 = left
self.sprite.scaleX *= self.facing;
};
// Show dead body
self.showDeadBody = function () {
if (self.sprite) self.removeChild(self.sprite);
self.sprite = self.attachAsset('deadbody', {
anchorX: 0.5,
anchorY: 0.5
});
};
// For touch feedback
self.flash = function () {
LK.effects.flashObject(self, 0xffffff, 200);
};
// For movement tween
self.moveTo = function (x, y, duration) {
tween(self, {
x: x,
y: y
}, {
duration: duration || 200,
easing: tween.easeInOut
});
};
// For kill animation
self.kill = function () {
self.isAlive = false;
self.showDeadBody();
tween(self, {
alpha: 0.7
}, {
duration: 400
});
};
// For respawn (not used in MVP)
self.respawn = function () {
self.isAlive = true;
self.setRole(self.role);
self.alpha = 1;
};
// Set initial role
self.setRole('crewmate');
return self;
});
// Task class
var Task = Container.expand(function () {
var self = Container.call(this);
self.completed = false;
self.taskId = 0;
self.sprite = self.attachAsset('task', {
anchorX: 0.5,
anchorY: 0.5
});
// Mark as completed
self.complete = function () {
self.completed = true;
tween(self.sprite, {
alpha: 0.3
}, {
duration: 300
});
};
return self;
});
// Button class (for tasks and emergency)
var UIButton = Container.expand(function () {
var self = Container.call(this);
self.label = '';
self.onPress = null;
self.type = 'button'; // 'button' or 'emergency'
self.bg = self.attachAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
self.text = new Text2('', {
size: 60,
fill: 0x222222
});
self.text.anchor.set(0.5, 0.5);
self.addChild(self.text);
self.setType = function (type) {
self.type = type;
if (type === 'emergency') {
self.removeChild(self.bg);
self.bg = self.attachAsset('emergency', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChildAt(self.bg, 0);
}
};
self.setLabel = function (label) {
self.label = label;
self.text.setText(label);
};
// Touch event
self.down = function (x, y, obj) {
if (self.onPress && typeof self.onPress === 'function') {
self.onPress();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222b38
});
/****
* Game Code
****/
// --- GAME STATE ---
var player; // The local player (user)
var impostor; // The AI chasing impostor
var tasks = []; // All task objects
var completedTasks = 0;
var totalTasks = 5;
var taskTimers = []; // Timers for each task
var taskInProgress = null; // Currently active task
var taskProgressBar = null; // Progress bar UI
var escapeDoor = null; // Door object
var doorOpen = false;
var escapeText = null;
var gameEnded = false;
// --- LAYOUT CONSTANTS ---
var margin = 200;
var playWidth = 2048;
var playHeight = 2732;
// --- UTILS ---
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// --- SETUP TASKS ---
tasks = [];
for (var i = 0; i < totalTasks; ++i) {
var t = new Task();
t.taskId = i;
// Place tasks in a circle further from the center, but clamp so they don't go off screen
var angle = i / totalTasks * Math.PI * 2;
var radius = 1000; // Increased from 700 to 1000
var tx = playWidth / 2 + Math.cos(angle) * radius;
var ty = playHeight / 2 + Math.sin(angle) * radius;
// Clamp so task stays fully on screen
var taskHalfW = t.sprite.width / 2;
var taskHalfH = t.sprite.height / 2;
tx = Math.max(margin + taskHalfW, Math.min(playWidth - margin - taskHalfW, tx));
ty = Math.max(margin + taskHalfH, Math.min(playHeight - margin - taskHalfH, ty));
t.x = tx;
t.y = ty;
t.completed = false;
t.interactive = true;
t.down = function (task) {
return function (x, y, obj) {
if (gameEnded) return;
if (task.completed) return;
if (taskInProgress) return; // Only one at a time
// Move player instantly to the task if not close enough
var dx = player.x - task.x;
var dy = player.y - task.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 180) {
// Too far, do not start task
LK.effects.flashObject(player, 0xff0000, 200);
return;
}
startTask(task);
};
}(t);
tasks.push(t);
}
// --- SETUP PLAYER ---
player = new Player();
player.isLocal = true;
player.x = playWidth / 2;
player.y = playHeight - 400;
player.setRole('crewmate');
// --- SETUP IMPOSTOR ---
impostor = new Player();
impostor.setRole('impostor');
impostor.x = playWidth / 2;
impostor.y = 400;
impostor.isLocal = false;
impostor.isAlive = true;
// --- SETUP ESCAPE DOOR (hidden until all tasks complete) ---
escapeDoor = LK.getAsset('button', {
anchorX: 0.5,
anchorY: 0.5
});
escapeDoor.width = 220;
escapeDoor.height = 300; // Make the button taller
escapeDoor.x = playWidth / 2;
escapeDoor.y = margin + 120; // Move the door further down
escapeDoor.visible = false;
// Add generators (tasks) first (bottom layer)
for (var i = 0; i < tasks.length; ++i) {
game.addChild(tasks[i]);
}
// Add player (3rd layer from top)
game.addChild(player);
// Add impostor (2nd layer from top)
game.addChild(impostor);
// Add door (top layer)
game.addChild(escapeDoor);
// --- ESCAPE TEXT ---
escapeText = new Text2('ESCAPE!', {
size: 90,
fill: 0xFFFFFF
});
escapeText.anchor.set(0.5, 0.5);
escapeText.x = escapeDoor.x;
escapeText.y = escapeDoor.y - 110; // Place text above the door
escapeText.visible = false;
game.addChild(escapeText);
// --- TASK PROGRESS BAR (GUI) ---
taskProgressBar = new Text2('', {
size: 80,
fill: 0xF7E85C
});
taskProgressBar.anchor.set(0.5, 0);
LK.gui.top.addChild(taskProgressBar);
// --- UPDATE TASK PROGRESS BAR ---
function updateTaskProgressBar() {
taskProgressBar.setText("Generator: " + completedTasks + "/" + totalTasks);
}
updateTaskProgressBar();
// --- TASK LOGIC ---
function startTask(task) {
if (gameEnded) return;
taskInProgress = task;
// Randomize duration between 3 and 5 seconds (3000-5000 ms)
var duration = randomInt(3000, 5000);
var startTime = Date.now();
var progressText = new Text2('Fixing generator...', {
size: 80,
fill: 0xF7E85C
});
progressText.anchor.set(0.5, 0.5);
progressText.x = playWidth / 2;
progressText.y = playHeight / 2;
game.addChild(progressText);
// Add a countdown timer text
var countdownText = new Text2('', {
size: 100,
fill: 0xffffff
});
countdownText.anchor.set(0.5, 0);
countdownText.x = playWidth / 2;
countdownText.y = playHeight / 2 + 100;
game.addChild(countdownText);
// Progress bar update
var interval = LK.setInterval(function () {
var elapsed = Date.now() - startTime;
var pct = Math.min(1, elapsed / duration);
var secondsLeft = Math.ceil((duration - elapsed) / 1000);
if (secondsLeft < 0) secondsLeft = 0;
var pctDisplay = (pct * 100).toFixed(1).replace('.', ',');
progressText.setText("Fixing generator: %" + pctDisplay);
countdownText.setText("Time left: " + secondsLeft + "s");
// If player moves too far, cancel
var dx = player.x - task.x;
var dy = player.y - task.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 220) {
LK.clearInterval(interval);
game.removeChild(progressText);
game.removeChild(countdownText);
taskInProgress = null;
LK.effects.flashObject(player, 0xff0000, 200);
}
if (pct >= 1) {
LK.clearInterval(interval);
game.removeChild(progressText);
game.removeChild(countdownText);
completeTask(task);
taskInProgress = null;
}
}, 100);
taskTimers[task.taskId] = interval;
}
function completeTask(task) {
if (task.completed) return;
task.complete();
// Animate the task sprite to continuously grow and shrink (pulsate) on completion
if (!task._pulseTween) {
var _startPulse = function startPulse() {
// Grow (reduced amplitude)
task._pulseTween = tween(task.sprite, {
scaleX: 2.18,
scaleY: 2.18
}, {
duration: 320,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Shrink back
task._pulseTween = tween(task.sprite, {
scaleX: 2,
scaleY: 2
}, {
duration: 320,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (!gameEnded) _startPulse();
}
});
}
});
};
_startPulse();
}
completedTasks++;
updateTaskProgressBar();
if (completedTasks >= totalTasks) {
openEscapeDoor();
}
}
// --- ESCAPE DOOR LOGIC ---
function openEscapeDoor() {
doorOpen = true;
escapeDoor.visible = true;
escapeText.visible = true;
LK.effects.flashObject(escapeDoor, 0x00ff00, 800);
}
// --- PLAYER ESCAPE LOGIC ---
function checkPlayerEscape() {
if (!doorOpen || gameEnded) return;
// If player is close to door, escape!
var dx = player.x - escapeDoor.x;
var dy = player.y - escapeDoor.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 120) {
gameEnded = true;
escapeText.setText("You Escaped!");
LK.effects.flashScreen(0x00ff00, 1200);
LK.setTimeout(function () {
LK.showYouWin();
}, 1200);
}
}
// --- IMPOSTOR AI LOGIC ---
impostor.lastX = impostor.x;
impostor.lastY = impostor.y;
impostor.speed = 2.625;
impostor.killCooldown = 0;
impostor.killDelay = 1500; // ms
function updateImpostorAI() {
if (!impostor.isAlive || !player.isAlive || gameEnded) return;
// Chase player
var dx = player.x - impostor.x;
var dy = player.y - impostor.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 10) {
var step = Math.min(impostor.speed, dist);
var prevX = impostor.x;
impostor.x += dx / dist * step;
impostor.y += dy / dist * step;
// Turning logic: face right if moving right, left if moving left
var moveDir = impostor.x - prevX;
if (moveDir !== 0) {
var newFacing = moveDir > 0 ? 1 : -1;
if (impostor.facing !== newFacing) {
impostor.facing = newFacing;
if (impostor.sprite) {
impostor.sprite.scaleX = Math.abs(impostor.sprite.scaleX) * impostor.facing;
}
}
}
}
// Kill if close and cooldown expired
if (dist < 120 && impostor.killCooldown <= 0 && player.isAlive) {
impostor.killCooldown = impostor.killDelay;
killPlayer();
}
if (impostor.killCooldown > 0) {
impostor.killCooldown -= 1000 / 60;
if (impostor.killCooldown < 0) impostor.killCooldown = 0;
}
impostor.lastX = impostor.x;
impostor.lastY = impostor.y;
}
// --- KILL PLAYER ---
function killPlayer() {
if (!player.isAlive || gameEnded) return;
// 20% chance to dodge
if (Math.random() < 0.2) {
// Dodged!
escapeText.setText("Dodged!");
escapeText.visible = true;
LK.effects.flashObject(player, 0x00ff00, 400);
// Hide text after 1 second
LK.setTimeout(function () {
if (!gameEnded) escapeText.visible = false;
}, 1000);
return;
}
player.kill();
gameEnded = true;
escapeText.setText("You were caught!");
escapeText.visible = true;
LK.effects.flashScreen(0xff0000, 1200);
LK.setTimeout(function () {
LK.showGameOver();
}, 1200);
}
// --- PLAYER MOVEMENT (TAP TO WALK) ---
var playerTarget = null;
var playerMoveSpeed = 8 / 1.15; // px per frame (1.15x slower)
game.down = function (x, y, obj) {
if (gameEnded) return;
// Set target position to where user touched, clamped to play area
var tx = Math.max(margin, Math.min(playWidth - margin, x));
var ty = Math.max(margin, Math.min(playHeight - margin, y));
playerTarget = {
x: tx,
y: ty
};
};
game.up = function (x, y, obj) {
// No-op for tap-to-move
};
game.move = function (x, y, obj) {
// No-op for tap-to-move
};
// Move player toward target in game.update
// --- ESCAPE DOOR INTERACTION ---
escapeDoor.interactive = true;
escapeDoor.down = function (x, y, obj) {
if (gameEnded) return;
checkPlayerEscape();
};
// --- MAIN GAME LOOP ---
game.update = function () {
if (gameEnded) {
// Stop all task grow/shrink (pulse) tweens
for (var i = 0; i < tasks.length; ++i) {
if (tasks[i]._pulseTween) {
tween.stop(tasks[i].sprite, {
scaleX: true,
scaleY: true
});
tasks[i]._pulseTween = null;
// Restore to original scale
if (tasks[i].sprite) {
tasks[i].sprite.scaleX = 2;
tasks[i].sprite.scaleY = 2;
}
}
}
return;
}
// --- PLAYER TAP-TO-MOVE LOGIC ---
if (playerTarget && player.isAlive) {
var dx = playerTarget.x - player.x;
var dy = playerTarget.y - player.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var prevX = player.x;
if (dist > playerMoveSpeed) {
player.x += dx / dist * playerMoveSpeed;
player.y += dy / dist * playerMoveSpeed;
} else {
player.x = playerTarget.x;
player.y = playerTarget.y;
playerTarget = null;
}
// Turning logic: face right if moving right, left if moving left
var moveDir = player.x - prevX;
if (moveDir !== 0) {
var newFacing = moveDir > 0 ? 1 : -1;
if (player.facing !== newFacing) {
player.facing = newFacing;
if (player.sprite) {
player.sprite.scaleX = Math.abs(player.sprite.scaleX) * player.facing;
}
}
}
}
updateImpostorAI();
checkPlayerEscape();
}; ===================================================================
--- original.js
+++ change.js
@@ -321,12 +321,12 @@
task.complete();
// Animate the task sprite to continuously grow and shrink (pulsate) on completion
if (!task._pulseTween) {
var _startPulse = function startPulse() {
- // Grow
+ // Grow (reduced amplitude)
task._pulseTween = tween(task.sprite, {
- scaleX: 2.4,
- scaleY: 2.4
+ scaleX: 2.18,
+ scaleY: 2.18
}, {
duration: 320,
easing: tween.easeInOut,
onFinish: function onFinish() {
Wooden door. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat,sharp edges,straight lines,creepy and bloody look
A skull head holding a knife . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat.dark,bloody look on knife and head,make my drawing better
A scared man,make my drawing better . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat.only head,make hands as a circle.dont add body
Cabinet,metal,bloody look,sharp edges. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "die by moonlight" and with the description "A game where player fix generators and tries to escape killer.". No text on banner,put the name on the up-left corner