/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Animatronic = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('animatronic', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.targetX = 1024;
self.targetY = 1366;
self.health = 100;
self.maxHealth = 100;
self.isStunned = false;
self.stunnedTime = 0;
self.update = function () {
if (self.isStunned) {
self.stunnedTime--;
if (self.stunnedTime <= 0) {
self.isStunned = false;
}
return;
}
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Reached player
gameOver();
}
};
self.takeDamage = function (amount) {
self.health -= amount;
self.isStunned = true;
self.stunnedTime = 30; // 0.5 seconds
if (self.health <= 0) {
self.destroy();
animatronics.splice(animatronics.indexOf(self), 1);
}
};
return self;
});
var Child = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Make children smaller and different color
graphics.scaleX = 0.6;
graphics.scaleY = 0.6;
graphics.tint = 0x87CEEB; // Light blue tint to distinguish from player
self.speed = 0.5;
self.targetX = Math.random() * 2048;
self.targetY = Math.random() * 2732;
self.walkTimer = 0;
self.maxWalkTime = 180 + Math.random() * 240; // 3-7 seconds
self.isMoving = false;
self.update = function () {
self.walkTimer++;
// Check if reached target or time to change direction
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10 || self.walkTimer >= self.maxWalkTime) {
// Pick new random target within game bounds
self.targetX = 200 + Math.random() * 1648; // Keep within bounds
self.targetY = 400 + Math.random() * 2032;
self.walkTimer = 0;
self.maxWalkTime = 180 + Math.random() * 240;
self.isMoving = true;
// Use tween for smooth movement
tween(self, {
x: self.targetX,
y: self.targetY
}, {
duration: self.maxWalkTime * 16.67,
// Convert frames to milliseconds
easing: tween.linear
});
}
};
return self;
});
var CookingStation = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('cookingStation', {
anchorX: 0.5,
anchorY: 0.5
});
self.currentHotDog = null;
self.startCooking = function () {
if (!self.currentHotDog) {
var hotdog = new HotDog();
hotdog.x = 0;
hotdog.y = -20;
self.addChild(hotdog);
self.currentHotDog = hotdog;
LK.getSound('cooking').play();
}
};
self.down = function (x, y, obj) {
if (gamePhase === 'day' && self.currentHotDog && self.currentHotDog.isCooked) {
serveHotDog();
}
};
return self;
});
var HotDog = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('hotdog', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCooked = false;
self.cookTime = 0;
self.maxCookTime = 180; // 3 seconds at 60fps
self.update = function () {
if (!self.isCooked && self.cookTime < self.maxCookTime) {
self.cookTime++;
if (self.cookTime >= self.maxCookTime) {
self.isCooked = true;
graphics.tint = 0x8B4513; // Darker brown when cooked
}
}
};
return self;
});
var OrderTicket = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('orderTicket', {
anchorX: 0.5,
anchorY: 0.5
});
var orderText = new Text2('Hot Dog', {
size: 24,
fill: 0x000000
});
orderText.anchor.set(0.5, 0.5);
self.addChild(orderText);
self.isCompleted = false;
self.down = function (x, y, obj) {
if (!self.isCompleted && gamePhase === 'day') {
// Mark order as taken
self.isCompleted = true;
// Visual feedback - change color to show order is taken
graphics.tint = 0x90EE90; // Light green to show order taken
orderText.setText('ORDER TAKEN');
// Remove hot dog from cooking station if it exists
if (cookingStations.length > 0 && cookingStations[0].currentHotDog) {
cookingStations[0].currentHotDog.destroy();
cookingStations[0].currentHotDog = null;
}
// Start cooking process
startCooking();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.moveSpeed = 3;
self.health = 100;
self.maxHealth = 100;
// Initialize player position
self.x = 1024;
self.y = 1366;
// Method to move player (can be used for future features)
self.moveTo = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
// Method to take damage (for future collision detection)
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
gameOver();
}
};
// Method to heal (for future power-ups)
self.heal = function (amount) {
self.health += amount;
if (self.health > self.maxHealth) {
self.health = self.maxHealth;
}
};
return self;
});
var Table = Container.expand(function (isClickable) {
var self = Container.call(this);
var graphics = self.attachAsset('table', {
anchorX: 0.5,
anchorY: 0.5
});
// Add visual distinction with slightly darker border effect
graphics.tint = 0x654321;
self.isClickable = isClickable || false;
// Make clickable tables visually distinct
if (self.isClickable) {
graphics.tint = 0x8B4513; // Lighter brown for clickable tables
// Add a subtle glow effect using tween
tween(graphics, {
alpha: 0.7
}, {
duration: 1000,
easing: tween.easeInOut,
yoyo: true,
repeat: -1
});
}
// Click handler for clickable tables
self.down = function (x, y, obj) {
if (self.isClickable && gamePhase === 'day') {
// Flash the table when clicked
LK.effects.flashObject(self, 0xFFFF00, 500);
// Add score bonus
LK.setScore(LK.getScore() + 5);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F4F
});
/****
* Game Code
****/
// Game state variables
var gamePhase = 'day'; // 'day' or 'night'
var dayTime = 0;
var nightTime = 0;
var maxDayTime = 1800; // 30 seconds
var maxNightTime = 1800; // 30 seconds
var currentDay = 1;
var ordersServed = 0;
var ordersNeeded = 3;
var nightSurvivalScore = 0;
var lastNightSecond = 0;
// Day phase elements
var orders = [];
var cookingStations = [];
var currentCooking = null;
// Night phase elements
var player;
var animatronics = [];
var children = [];
var tables = [];
var flashlightActive = false;
var flashlightBattery = 100;
var maxBattery = 100;
var batteryDrainRate = 0.3;
var batteryRechargeRate = 0.5;
var flashlightBeam;
// UI elements
var phaseText = new Text2('DAY SHIFT', {
size: 48,
fill: 0xFFFFFF
});
phaseText.anchor.set(0.5, 0);
LK.gui.top.addChild(phaseText);
var scoreText = new Text2('Orders: 0/3', {
size: 36,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 20;
LK.gui.topLeft.addChild(scoreText);
var batteryText = new Text2('Battery: 100%', {
size: 36,
fill: 0xFFFFFF
});
batteryText.anchor.set(1, 0);
LK.gui.topRight.addChild(batteryText);
var timeText = new Text2('Time: 30s', {
size: 36,
fill: 0xFFFFFF
});
timeText.anchor.set(0.5, 0);
timeText.y = 80;
LK.gui.top.addChild(timeText);
// Add flashlight button
var flashlightButton = LK.getAsset('flashlightButton', {
anchorX: 0.5,
anchorY: 1
});
var flashlightButtonText = new Text2('🔦 FLASHLIGHT', {
size: 32,
fill: 0xFFFFFF
});
flashlightButtonText.anchor.set(0.5, 0.5);
flashlightButton.addChild(flashlightButtonText);
LK.gui.bottom.addChild(flashlightButton);
// Flashlight button event handler
flashlightButton.down = function (x, y, obj) {
if (gamePhase === 'night' && flashlightBattery > 0) {
flashlightActive = true;
flashlightButton.tint = 0xFFFF00; // Yellow when active
updateFlashlight(1024, 1366); // Default direction
LK.getSound('flashlightClick').play();
}
};
flashlightButton.up = function (x, y, obj) {
if (gamePhase === 'night') {
flashlightActive = false;
flashlightButton.tint = 0xFFFFFF; // Normal color when inactive
updateFlashlight(1024, 1366);
}
};
// Initialize day phase
function initDayPhase() {
gamePhase = 'day';
dayTime = 0;
ordersServed = 0;
phaseText.setText('DAY SHIFT - Day ' + currentDay);
game.setBackgroundColor(0x87CEEB);
// Clear night elements
if (player) {
player.destroy();
player = null;
}
for (var i = animatronics.length - 1; i >= 0; i--) {
animatronics[i].destroy();
}
animatronics = [];
for (var i = children.length - 1; i >= 0; i--) {
children[i].destroy();
}
children = [];
if (flashlightBeam) {
flashlightBeam.destroy();
flashlightBeam = null;
}
// Create player for day phase
player = game.addChild(new Player());
player.x = 1024;
player.y = 1500;
// Create cooking station
var station = game.addChild(new CookingStation());
station.x = 1024;
station.y = 1000;
cookingStations = [station];
// Create initial orders
createOrder();
// Create tables around the game area
createTables();
// Spawn children walking around
spawnChildren();
// Hide flashlight button during day
if (flashlightButton) {
flashlightButton.visible = false;
}
}
function initNightPhase() {
gamePhase = 'night';
nightTime = 0;
lastNightSecond = 0;
phaseText.setText('NIGHT SHIFT - Day ' + currentDay);
game.setBackgroundColor(0x191970);
flashlightBattery = maxBattery;
// Clear day elements
for (var i = orders.length - 1; i >= 0; i--) {
orders[i].destroy();
}
orders = [];
for (var i = cookingStations.length - 1; i >= 0; i--) {
cookingStations[i].destroy();
}
cookingStations = [];
// Clear children from day phase
for (var i = children.length - 1; i >= 0; i--) {
children[i].destroy();
}
children = [];
// Create player
player = game.addChild(new Player());
// Create flashlight beam
flashlightBeam = game.addChild(LK.getAsset('flashlightBeam', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
}));
// Spawn initial animatronics
spawnAnimatronic();
// Create tables around the game area
createTables();
// No children during night phase for safety
// Show flashlight button during night
if (flashlightButton) {
flashlightButton.visible = true;
flashlightButton.tint = 0xFFFFFF;
}
}
function createOrder() {
if (orders.length < 2) {
var order = game.addChild(new OrderTicket());
order.x = 300 + orders.length * 250;
order.y = 200;
orders.push(order);
}
}
function startCooking() {
if (cookingStations.length > 0) {
cookingStations[0].startCooking();
}
}
function serveHotDog() {
if (cookingStations.length > 0 && cookingStations[0].currentHotDog) {
cookingStations[0].currentHotDog.destroy();
cookingStations[0].currentHotDog = null;
ordersServed++;
LK.getSound('serve').play();
// Remove an order
if (orders.length > 0) {
orders[0].destroy();
orders.splice(0, 1);
}
// Create new order if needed
createOrder();
scoreText.setText('Orders: ' + ordersServed + '/' + ordersNeeded);
LK.setScore(ordersServed * 10);
}
}
function spawnAnimatronic() {
var animatronic = game.addChild(new Animatronic());
// Spawn from random edge
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top
animatronic.x = Math.random() * 2048;
animatronic.y = -100;
break;
case 1:
// Right
animatronic.x = 2148;
animatronic.y = Math.random() * 2732;
break;
case 2:
// Bottom
animatronic.x = Math.random() * 2048;
animatronic.y = 2832;
break;
case 3:
// Left
animatronic.x = -100;
animatronic.y = Math.random() * 2732;
break;
}
animatronic.speed = 1 + currentDay * 0.5;
animatronics.push(animatronic);
LK.getSound('animatronicMove').play();
}
function spawnChildren() {
// Clear existing children
for (var i = children.length - 1; i >= 0; i--) {
children[i].destroy();
}
children = [];
// Only spawn children during day phase for safety
if (gamePhase === 'day') {
// Spawn 3-5 children randomly around the game area
var numChildren = 3 + Math.floor(Math.random() * 3);
for (var i = 0; i < numChildren; i++) {
var child = game.addChild(new Child());
child.x = 400 + Math.random() * 1248; // Keep within safe bounds
child.y = 500 + Math.random() * 1732;
children.push(child);
}
}
}
function updateFlashlight(x, y) {
if (player && flashlightBeam) {
flashlightBeam.x = player.x;
flashlightBeam.y = player.y;
var dx = x - player.x;
var dy = y - player.y;
var angle = Math.atan2(dy, dx);
flashlightBeam.rotation = angle;
if (flashlightActive && flashlightBattery > 0) {
flashlightBeam.alpha = 0.7;
// Check for animatronics in flashlight beam
for (var i = 0; i < animatronics.length; i++) {
var animatronic = animatronics[i];
var distance = Math.sqrt(Math.pow(animatronic.x - player.x, 2) + Math.pow(animatronic.y - player.y, 2));
if (distance < 400) {
var animatronicAngle = Math.atan2(animatronic.y - player.y, animatronic.x - player.x);
var angleDiff = Math.abs(angle - animatronicAngle);
if (angleDiff < Math.PI / 4) {
// 45 degree cone
animatronic.takeDamage(2);
// Make animatronic scared and move toward nearest edge
var edgeX, edgeY;
var distanceToLeft = animatronic.x;
var distanceToRight = 2048 - animatronic.x;
var distanceToTop = animatronic.y;
var distanceToBottom = 2732 - animatronic.y;
// Find the nearest edge
var minDistance = Math.min(distanceToLeft, distanceToRight, distanceToTop, distanceToBottom);
if (minDistance === distanceToLeft) {
// Move to left edge
edgeX = -50;
edgeY = animatronic.y;
} else if (minDistance === distanceToRight) {
// Move to right edge
edgeX = 2098;
edgeY = animatronic.y;
} else if (minDistance === distanceToTop) {
// Move to top edge
edgeX = animatronic.x;
edgeY = -50;
} else {
// Move to bottom edge
edgeX = animatronic.x;
edgeY = 2782;
}
// Visual feedback - make animatronic flash red when scared
tween(animatronic, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(animatronic, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
// Use tween to smoothly animate the scared retreat to edge
tween(animatronic, {
x: edgeX,
y: edgeY
}, {
duration: 1000,
easing: tween.easeOut
});
}
}
}
} else {
flashlightBeam.alpha = 0;
}
}
}
function gameOver() {
LK.showGameOver();
}
function createTables() {
// Clear existing tables
for (var i = tables.length - 1; i >= 0; i--) {
tables[i].destroy();
}
tables = [];
// Create tables positioned along the edges of the game area
var tablePositions = [
// Top edge - along the top
{
x: 700,
y: 200,
clickable: false
}, {
x: 1350,
y: 200,
clickable: false
}, {
x: 1750,
y: 200,
clickable: true
},
// Bottom edge - along the bottom
{
x: 300,
y: 2532,
clickable: true
}, {
x: 700,
y: 2532,
clickable: false
}, {
x: 1350,
y: 2532,
clickable: true
}, {
x: 1750,
y: 2532,
clickable: false
},
// Left edge - along the left side
{
x: 150,
y: 600,
clickable: true
}, {
x: 150,
y: 1366,
clickable: false
}, {
x: 150,
y: 2130,
clickable: true
},
// Right edge - along the right side
{
x: 1898,
y: 600,
clickable: true
}, {
x: 1898,
y: 1366,
clickable: true
}, {
x: 1898,
y: 2130,
clickable: false
}];
// Create table instances
for (var i = 0; i < tablePositions.length; i++) {
var table = game.addChild(new Table(tablePositions[i].clickable));
table.x = tablePositions[i].x;
table.y = tablePositions[i].y;
tables.push(table);
}
}
function nextDay() {
currentDay++;
ordersNeeded += 1;
initDayPhase();
}
// Game controls
game.down = function (x, y, obj) {
if (gamePhase === 'night') {
// Move player to touch/click position
if (player) {
player.x = x;
player.y = y;
}
flashlightActive = true;
updateFlashlight(x, y);
LK.getSound('flashlightClick').play();
}
};
game.up = function (x, y, obj) {
if (gamePhase === 'night') {
// Move player to release position
if (player) {
player.x = x;
player.y = y;
}
flashlightActive = false;
updateFlashlight(x, y);
}
};
game.move = function (x, y, obj) {
if (gamePhase === 'night') {
// Move player to mouse/touch position
if (player) {
player.x = x;
player.y = y;
}
// Update flashlight if active
if (flashlightActive) {
updateFlashlight(x, y);
}
}
};
// Main game loop
game.update = function () {
if (gamePhase === 'day') {
dayTime++;
var remainingTime = Math.ceil((maxDayTime - dayTime) / 60);
timeText.setText('Time: ' + remainingTime + 's');
if (dayTime >= maxDayTime || ordersServed >= ordersNeeded) {
if (ordersServed >= ordersNeeded) {
initNightPhase();
} else {
gameOver();
}
}
// Occasionally create new orders
if (dayTime % 300 === 0) {
createOrder();
}
} else if (gamePhase === 'night') {
nightTime++;
var remainingTime = Math.ceil((maxNightTime - nightTime) / 60);
timeText.setText('Time: ' + remainingTime + 's');
// Track survival time and add to score (10 points per second survived)
var currentNightSecond = Math.floor(nightTime / 60);
if (currentNightSecond > lastNightSecond) {
nightSurvivalScore += 10;
LK.setScore(LK.getScore() + 10);
lastNightSecond = currentNightSecond;
}
// Update flashlight battery
if (flashlightActive && flashlightBattery > 0) {
flashlightBattery -= batteryDrainRate;
if (flashlightBattery < 0) {
flashlightBattery = 0;
flashlightActive = false;
if (flashlightButton) flashlightButton.tint = 0xFFFFFF;
}
} else if (!flashlightActive && flashlightBattery < maxBattery) {
flashlightBattery += batteryRechargeRate;
if (flashlightBattery > maxBattery) flashlightBattery = maxBattery;
}
batteryText.setText('Battery: ' + Math.floor(flashlightBattery) + '%');
// Update flashlight button color based on battery
if (flashlightButton && gamePhase === 'night') {
if (flashlightBattery <= 0) {
flashlightButton.tint = 0x666666; // Gray when no battery
} else if (!flashlightActive) {
flashlightButton.tint = 0xFFFFFF; // Normal when available
}
}
// Check collision between player and animatronics
if (player) {
for (var i = 0; i < animatronics.length; i++) {
var animatronic = animatronics[i];
if (player.intersects(animatronic)) {
gameOver();
return;
}
}
}
// Spawn animatronics - spawn 2 every night
if (nightTime % (300 - currentDay * 30) === 0 && nightTime < maxNightTime - 300) {
spawnAnimatronic();
spawnAnimatronic(); // Spawn second animatronic
}
// Check win condition - continue forever
if (nightTime >= maxNightTime) {
nextDay();
}
}
};
// Start the game
initDayPhase(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Animatronic = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('animatronic', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1;
self.targetX = 1024;
self.targetY = 1366;
self.health = 100;
self.maxHealth = 100;
self.isStunned = false;
self.stunnedTime = 0;
self.update = function () {
if (self.isStunned) {
self.stunnedTime--;
if (self.stunnedTime <= 0) {
self.isStunned = false;
}
return;
}
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
} else {
// Reached player
gameOver();
}
};
self.takeDamage = function (amount) {
self.health -= amount;
self.isStunned = true;
self.stunnedTime = 30; // 0.5 seconds
if (self.health <= 0) {
self.destroy();
animatronics.splice(animatronics.indexOf(self), 1);
}
};
return self;
});
var Child = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Make children smaller and different color
graphics.scaleX = 0.6;
graphics.scaleY = 0.6;
graphics.tint = 0x87CEEB; // Light blue tint to distinguish from player
self.speed = 0.5;
self.targetX = Math.random() * 2048;
self.targetY = Math.random() * 2732;
self.walkTimer = 0;
self.maxWalkTime = 180 + Math.random() * 240; // 3-7 seconds
self.isMoving = false;
self.update = function () {
self.walkTimer++;
// Check if reached target or time to change direction
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 10 || self.walkTimer >= self.maxWalkTime) {
// Pick new random target within game bounds
self.targetX = 200 + Math.random() * 1648; // Keep within bounds
self.targetY = 400 + Math.random() * 2032;
self.walkTimer = 0;
self.maxWalkTime = 180 + Math.random() * 240;
self.isMoving = true;
// Use tween for smooth movement
tween(self, {
x: self.targetX,
y: self.targetY
}, {
duration: self.maxWalkTime * 16.67,
// Convert frames to milliseconds
easing: tween.linear
});
}
};
return self;
});
var CookingStation = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('cookingStation', {
anchorX: 0.5,
anchorY: 0.5
});
self.currentHotDog = null;
self.startCooking = function () {
if (!self.currentHotDog) {
var hotdog = new HotDog();
hotdog.x = 0;
hotdog.y = -20;
self.addChild(hotdog);
self.currentHotDog = hotdog;
LK.getSound('cooking').play();
}
};
self.down = function (x, y, obj) {
if (gamePhase === 'day' && self.currentHotDog && self.currentHotDog.isCooked) {
serveHotDog();
}
};
return self;
});
var HotDog = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('hotdog', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCooked = false;
self.cookTime = 0;
self.maxCookTime = 180; // 3 seconds at 60fps
self.update = function () {
if (!self.isCooked && self.cookTime < self.maxCookTime) {
self.cookTime++;
if (self.cookTime >= self.maxCookTime) {
self.isCooked = true;
graphics.tint = 0x8B4513; // Darker brown when cooked
}
}
};
return self;
});
var OrderTicket = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('orderTicket', {
anchorX: 0.5,
anchorY: 0.5
});
var orderText = new Text2('Hot Dog', {
size: 24,
fill: 0x000000
});
orderText.anchor.set(0.5, 0.5);
self.addChild(orderText);
self.isCompleted = false;
self.down = function (x, y, obj) {
if (!self.isCompleted && gamePhase === 'day') {
// Mark order as taken
self.isCompleted = true;
// Visual feedback - change color to show order is taken
graphics.tint = 0x90EE90; // Light green to show order taken
orderText.setText('ORDER TAKEN');
// Remove hot dog from cooking station if it exists
if (cookingStations.length > 0 && cookingStations[0].currentHotDog) {
cookingStations[0].currentHotDog.destroy();
cookingStations[0].currentHotDog = null;
}
// Start cooking process
startCooking();
}
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.moveSpeed = 3;
self.health = 100;
self.maxHealth = 100;
// Initialize player position
self.x = 1024;
self.y = 1366;
// Method to move player (can be used for future features)
self.moveTo = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.moveSpeed) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
} else {
self.x = targetX;
self.y = targetY;
}
};
// Method to take damage (for future collision detection)
self.takeDamage = function (amount) {
self.health -= amount;
if (self.health <= 0) {
self.health = 0;
gameOver();
}
};
// Method to heal (for future power-ups)
self.heal = function (amount) {
self.health += amount;
if (self.health > self.maxHealth) {
self.health = self.maxHealth;
}
};
return self;
});
var Table = Container.expand(function (isClickable) {
var self = Container.call(this);
var graphics = self.attachAsset('table', {
anchorX: 0.5,
anchorY: 0.5
});
// Add visual distinction with slightly darker border effect
graphics.tint = 0x654321;
self.isClickable = isClickable || false;
// Make clickable tables visually distinct
if (self.isClickable) {
graphics.tint = 0x8B4513; // Lighter brown for clickable tables
// Add a subtle glow effect using tween
tween(graphics, {
alpha: 0.7
}, {
duration: 1000,
easing: tween.easeInOut,
yoyo: true,
repeat: -1
});
}
// Click handler for clickable tables
self.down = function (x, y, obj) {
if (self.isClickable && gamePhase === 'day') {
// Flash the table when clicked
LK.effects.flashObject(self, 0xFFFF00, 500);
// Add score bonus
LK.setScore(LK.getScore() + 5);
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2F4F4F
});
/****
* Game Code
****/
// Game state variables
var gamePhase = 'day'; // 'day' or 'night'
var dayTime = 0;
var nightTime = 0;
var maxDayTime = 1800; // 30 seconds
var maxNightTime = 1800; // 30 seconds
var currentDay = 1;
var ordersServed = 0;
var ordersNeeded = 3;
var nightSurvivalScore = 0;
var lastNightSecond = 0;
// Day phase elements
var orders = [];
var cookingStations = [];
var currentCooking = null;
// Night phase elements
var player;
var animatronics = [];
var children = [];
var tables = [];
var flashlightActive = false;
var flashlightBattery = 100;
var maxBattery = 100;
var batteryDrainRate = 0.3;
var batteryRechargeRate = 0.5;
var flashlightBeam;
// UI elements
var phaseText = new Text2('DAY SHIFT', {
size: 48,
fill: 0xFFFFFF
});
phaseText.anchor.set(0.5, 0);
LK.gui.top.addChild(phaseText);
var scoreText = new Text2('Orders: 0/3', {
size: 36,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 20;
LK.gui.topLeft.addChild(scoreText);
var batteryText = new Text2('Battery: 100%', {
size: 36,
fill: 0xFFFFFF
});
batteryText.anchor.set(1, 0);
LK.gui.topRight.addChild(batteryText);
var timeText = new Text2('Time: 30s', {
size: 36,
fill: 0xFFFFFF
});
timeText.anchor.set(0.5, 0);
timeText.y = 80;
LK.gui.top.addChild(timeText);
// Add flashlight button
var flashlightButton = LK.getAsset('flashlightButton', {
anchorX: 0.5,
anchorY: 1
});
var flashlightButtonText = new Text2('🔦 FLASHLIGHT', {
size: 32,
fill: 0xFFFFFF
});
flashlightButtonText.anchor.set(0.5, 0.5);
flashlightButton.addChild(flashlightButtonText);
LK.gui.bottom.addChild(flashlightButton);
// Flashlight button event handler
flashlightButton.down = function (x, y, obj) {
if (gamePhase === 'night' && flashlightBattery > 0) {
flashlightActive = true;
flashlightButton.tint = 0xFFFF00; // Yellow when active
updateFlashlight(1024, 1366); // Default direction
LK.getSound('flashlightClick').play();
}
};
flashlightButton.up = function (x, y, obj) {
if (gamePhase === 'night') {
flashlightActive = false;
flashlightButton.tint = 0xFFFFFF; // Normal color when inactive
updateFlashlight(1024, 1366);
}
};
// Initialize day phase
function initDayPhase() {
gamePhase = 'day';
dayTime = 0;
ordersServed = 0;
phaseText.setText('DAY SHIFT - Day ' + currentDay);
game.setBackgroundColor(0x87CEEB);
// Clear night elements
if (player) {
player.destroy();
player = null;
}
for (var i = animatronics.length - 1; i >= 0; i--) {
animatronics[i].destroy();
}
animatronics = [];
for (var i = children.length - 1; i >= 0; i--) {
children[i].destroy();
}
children = [];
if (flashlightBeam) {
flashlightBeam.destroy();
flashlightBeam = null;
}
// Create player for day phase
player = game.addChild(new Player());
player.x = 1024;
player.y = 1500;
// Create cooking station
var station = game.addChild(new CookingStation());
station.x = 1024;
station.y = 1000;
cookingStations = [station];
// Create initial orders
createOrder();
// Create tables around the game area
createTables();
// Spawn children walking around
spawnChildren();
// Hide flashlight button during day
if (flashlightButton) {
flashlightButton.visible = false;
}
}
function initNightPhase() {
gamePhase = 'night';
nightTime = 0;
lastNightSecond = 0;
phaseText.setText('NIGHT SHIFT - Day ' + currentDay);
game.setBackgroundColor(0x191970);
flashlightBattery = maxBattery;
// Clear day elements
for (var i = orders.length - 1; i >= 0; i--) {
orders[i].destroy();
}
orders = [];
for (var i = cookingStations.length - 1; i >= 0; i--) {
cookingStations[i].destroy();
}
cookingStations = [];
// Clear children from day phase
for (var i = children.length - 1; i >= 0; i--) {
children[i].destroy();
}
children = [];
// Create player
player = game.addChild(new Player());
// Create flashlight beam
flashlightBeam = game.addChild(LK.getAsset('flashlightBeam', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
}));
// Spawn initial animatronics
spawnAnimatronic();
// Create tables around the game area
createTables();
// No children during night phase for safety
// Show flashlight button during night
if (flashlightButton) {
flashlightButton.visible = true;
flashlightButton.tint = 0xFFFFFF;
}
}
function createOrder() {
if (orders.length < 2) {
var order = game.addChild(new OrderTicket());
order.x = 300 + orders.length * 250;
order.y = 200;
orders.push(order);
}
}
function startCooking() {
if (cookingStations.length > 0) {
cookingStations[0].startCooking();
}
}
function serveHotDog() {
if (cookingStations.length > 0 && cookingStations[0].currentHotDog) {
cookingStations[0].currentHotDog.destroy();
cookingStations[0].currentHotDog = null;
ordersServed++;
LK.getSound('serve').play();
// Remove an order
if (orders.length > 0) {
orders[0].destroy();
orders.splice(0, 1);
}
// Create new order if needed
createOrder();
scoreText.setText('Orders: ' + ordersServed + '/' + ordersNeeded);
LK.setScore(ordersServed * 10);
}
}
function spawnAnimatronic() {
var animatronic = game.addChild(new Animatronic());
// Spawn from random edge
var edge = Math.floor(Math.random() * 4);
switch (edge) {
case 0:
// Top
animatronic.x = Math.random() * 2048;
animatronic.y = -100;
break;
case 1:
// Right
animatronic.x = 2148;
animatronic.y = Math.random() * 2732;
break;
case 2:
// Bottom
animatronic.x = Math.random() * 2048;
animatronic.y = 2832;
break;
case 3:
// Left
animatronic.x = -100;
animatronic.y = Math.random() * 2732;
break;
}
animatronic.speed = 1 + currentDay * 0.5;
animatronics.push(animatronic);
LK.getSound('animatronicMove').play();
}
function spawnChildren() {
// Clear existing children
for (var i = children.length - 1; i >= 0; i--) {
children[i].destroy();
}
children = [];
// Only spawn children during day phase for safety
if (gamePhase === 'day') {
// Spawn 3-5 children randomly around the game area
var numChildren = 3 + Math.floor(Math.random() * 3);
for (var i = 0; i < numChildren; i++) {
var child = game.addChild(new Child());
child.x = 400 + Math.random() * 1248; // Keep within safe bounds
child.y = 500 + Math.random() * 1732;
children.push(child);
}
}
}
function updateFlashlight(x, y) {
if (player && flashlightBeam) {
flashlightBeam.x = player.x;
flashlightBeam.y = player.y;
var dx = x - player.x;
var dy = y - player.y;
var angle = Math.atan2(dy, dx);
flashlightBeam.rotation = angle;
if (flashlightActive && flashlightBattery > 0) {
flashlightBeam.alpha = 0.7;
// Check for animatronics in flashlight beam
for (var i = 0; i < animatronics.length; i++) {
var animatronic = animatronics[i];
var distance = Math.sqrt(Math.pow(animatronic.x - player.x, 2) + Math.pow(animatronic.y - player.y, 2));
if (distance < 400) {
var animatronicAngle = Math.atan2(animatronic.y - player.y, animatronic.x - player.x);
var angleDiff = Math.abs(angle - animatronicAngle);
if (angleDiff < Math.PI / 4) {
// 45 degree cone
animatronic.takeDamage(2);
// Make animatronic scared and move toward nearest edge
var edgeX, edgeY;
var distanceToLeft = animatronic.x;
var distanceToRight = 2048 - animatronic.x;
var distanceToTop = animatronic.y;
var distanceToBottom = 2732 - animatronic.y;
// Find the nearest edge
var minDistance = Math.min(distanceToLeft, distanceToRight, distanceToTop, distanceToBottom);
if (minDistance === distanceToLeft) {
// Move to left edge
edgeX = -50;
edgeY = animatronic.y;
} else if (minDistance === distanceToRight) {
// Move to right edge
edgeX = 2098;
edgeY = animatronic.y;
} else if (minDistance === distanceToTop) {
// Move to top edge
edgeX = animatronic.x;
edgeY = -50;
} else {
// Move to bottom edge
edgeX = animatronic.x;
edgeY = 2782;
}
// Visual feedback - make animatronic flash red when scared
tween(animatronic, {
tint: 0xFF0000
}, {
duration: 200,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(animatronic, {
tint: 0xFFFFFF
}, {
duration: 200,
easing: tween.easeInOut
});
}
});
// Use tween to smoothly animate the scared retreat to edge
tween(animatronic, {
x: edgeX,
y: edgeY
}, {
duration: 1000,
easing: tween.easeOut
});
}
}
}
} else {
flashlightBeam.alpha = 0;
}
}
}
function gameOver() {
LK.showGameOver();
}
function createTables() {
// Clear existing tables
for (var i = tables.length - 1; i >= 0; i--) {
tables[i].destroy();
}
tables = [];
// Create tables positioned along the edges of the game area
var tablePositions = [
// Top edge - along the top
{
x: 700,
y: 200,
clickable: false
}, {
x: 1350,
y: 200,
clickable: false
}, {
x: 1750,
y: 200,
clickable: true
},
// Bottom edge - along the bottom
{
x: 300,
y: 2532,
clickable: true
}, {
x: 700,
y: 2532,
clickable: false
}, {
x: 1350,
y: 2532,
clickable: true
}, {
x: 1750,
y: 2532,
clickable: false
},
// Left edge - along the left side
{
x: 150,
y: 600,
clickable: true
}, {
x: 150,
y: 1366,
clickable: false
}, {
x: 150,
y: 2130,
clickable: true
},
// Right edge - along the right side
{
x: 1898,
y: 600,
clickable: true
}, {
x: 1898,
y: 1366,
clickable: true
}, {
x: 1898,
y: 2130,
clickable: false
}];
// Create table instances
for (var i = 0; i < tablePositions.length; i++) {
var table = game.addChild(new Table(tablePositions[i].clickable));
table.x = tablePositions[i].x;
table.y = tablePositions[i].y;
tables.push(table);
}
}
function nextDay() {
currentDay++;
ordersNeeded += 1;
initDayPhase();
}
// Game controls
game.down = function (x, y, obj) {
if (gamePhase === 'night') {
// Move player to touch/click position
if (player) {
player.x = x;
player.y = y;
}
flashlightActive = true;
updateFlashlight(x, y);
LK.getSound('flashlightClick').play();
}
};
game.up = function (x, y, obj) {
if (gamePhase === 'night') {
// Move player to release position
if (player) {
player.x = x;
player.y = y;
}
flashlightActive = false;
updateFlashlight(x, y);
}
};
game.move = function (x, y, obj) {
if (gamePhase === 'night') {
// Move player to mouse/touch position
if (player) {
player.x = x;
player.y = y;
}
// Update flashlight if active
if (flashlightActive) {
updateFlashlight(x, y);
}
}
};
// Main game loop
game.update = function () {
if (gamePhase === 'day') {
dayTime++;
var remainingTime = Math.ceil((maxDayTime - dayTime) / 60);
timeText.setText('Time: ' + remainingTime + 's');
if (dayTime >= maxDayTime || ordersServed >= ordersNeeded) {
if (ordersServed >= ordersNeeded) {
initNightPhase();
} else {
gameOver();
}
}
// Occasionally create new orders
if (dayTime % 300 === 0) {
createOrder();
}
} else if (gamePhase === 'night') {
nightTime++;
var remainingTime = Math.ceil((maxNightTime - nightTime) / 60);
timeText.setText('Time: ' + remainingTime + 's');
// Track survival time and add to score (10 points per second survived)
var currentNightSecond = Math.floor(nightTime / 60);
if (currentNightSecond > lastNightSecond) {
nightSurvivalScore += 10;
LK.setScore(LK.getScore() + 10);
lastNightSecond = currentNightSecond;
}
// Update flashlight battery
if (flashlightActive && flashlightBattery > 0) {
flashlightBattery -= batteryDrainRate;
if (flashlightBattery < 0) {
flashlightBattery = 0;
flashlightActive = false;
if (flashlightButton) flashlightButton.tint = 0xFFFFFF;
}
} else if (!flashlightActive && flashlightBattery < maxBattery) {
flashlightBattery += batteryRechargeRate;
if (flashlightBattery > maxBattery) flashlightBattery = maxBattery;
}
batteryText.setText('Battery: ' + Math.floor(flashlightBattery) + '%');
// Update flashlight button color based on battery
if (flashlightButton && gamePhase === 'night') {
if (flashlightBattery <= 0) {
flashlightButton.tint = 0x666666; // Gray when no battery
} else if (!flashlightActive) {
flashlightButton.tint = 0xFFFFFF; // Normal when available
}
}
// Check collision between player and animatronics
if (player) {
for (var i = 0; i < animatronics.length; i++) {
var animatronic = animatronics[i];
if (player.intersects(animatronic)) {
gameOver();
return;
}
}
}
// Spawn animatronics - spawn 2 every night
if (nightTime % (300 - currentDay * 30) === 0 && nightTime < maxNightTime - 300) {
spawnAnimatronic();
spawnAnimatronic(); // Spawn second animatronic
}
// Check win condition - continue forever
if (nightTime >= maxNightTime) {
nextDay();
}
}
};
// Start the game
initDayPhase();
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Working at Huls" and with the description "A dual-phase survival game combining hot dog cooking simulation with horror survival. Work the day shift serving customers, then survive the night defending against animatronics with your flashlight.". No text on banner!
Kid. In-Game asset. 2d. High contrast. No shadows
hotdog. In-Game asset. 2d. High contrast. No shadows