/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BreakableAsset = Container.expand(function () {
var self = Container.call(this);
// Attach the breakable asset
var breakableGraphics = self.attachAsset('bg_KrampusBreakable', {
anchorX: 0.5,
anchorY: 0.5
});
// Define the down event for the breakable asset
self.down = function (x, y, obj) {
self.down = null;
// Play a breaking sound
LK.getSound('s_BreakingSound').play();
animateSmokeTransition(self);
// Create a breaking animation
tween(breakableGraphics, {
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Instantiate a defined item when the breakable asset is broken
if (self.onBreak) {
var item = self.onBreak();
if (item) {
item.x = self.x;
item.y = self.y + 135;
game.addChild(item);
}
bringForwardVCR();
}
// Destroy the asset after the animation
self.destroy();
var newAsset = null; // Define newAsset variable
return newAsset;
}
});
};
});
var Collectible = Container.expand(function () {
var self = Container.call(this);
// Attach the collectible asset
var collectibleGraphics = self.attachAsset('bg_Collectible', {
anchorX: 0.5,
anchorY: 0.5
});
// Define the down event for the collectible asset
self.down = function (x, y, obj) {
self.down = null; // Disable further interaction after first click
collectibleDefaultDownBehaviour(self);
};
});
var Enemy = Container.expand(function (enemyType) {
var self = Container.call(this);
// Determine the enemy asset based on the enemyType
var enemyAssetId = enemyType === 'bg_Doll01' ? 'bg_Doll01' : 'bg_Doll02';
// Attach the enemy asset
var enemyGraphics = self.attachAsset(enemyAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
// Set initial speed and scale
self.speed = 2;
if (is_room3) {
self.scaleFactor = 0.02;
} else if (is_room5) {
self.scaleFactor = 0.04; // Increase scale factor for room5
} else {
self.scaleFactor = 0.01;
}
// Add tap event to play sound, rotate, and destroy after 2 seconds
self.down = function (x, y, obj) {
// Play the death sound at random
var randomDeathSound = Math.random() < 0.5 ? 's_DollDeath01' : 's_DollDeath02';
LK.getSound(randomDeathSound).play();
// Disable further interaction with the enemy
self.down = null; //{9.1}
// Stop movement towards the center
self.speed = 0;
// Stop scaling
self.scaleFactor = 0;
// Stop the wobble effect
tween.stop(self, {
x: true
}); //{9.1}
// Determine random direction: -1 for left, 1 for right
var direction = Math.random() < 0.5 ? -1 : 1;
// Make the enemy fly off the screen with rotation
tween(self, {
x: self.x + direction * 3000,
// Move off screen
y: self.y - 1000,
// Move upwards
rotation: Math.PI * 4 * direction // Rotate 4 full circles in the direction
}, {
duration: 2000,
easing: tween.easeOut
});
// Destroy the enemy after 2 seconds
LK.setTimeout(function () {
self.destroy();
}, 2000);
};
// Update function to move towards the center and scale up
self.update = function () {
// Calculate direction towards the center
var directionX = 2048 / 2 - self.x;
var directionY = 2732 / 2 - self.y;
var length = Math.sqrt(directionX * directionX + directionY * directionY);
directionX /= length;
directionY /= length;
// Move towards the center with wobble effect
self.x += directionX * self.speed + Math.sin(LK.ticks / 10) * 2; // Wobble effect
self.y += directionY * self.speed;
// Scale up
if (!is_gameover) {
self.scaleX += self.scaleFactor;
self.scaleY += self.scaleFactor;
}
// Check if the enemy has reached the center and scaled up
if (Math.abs(self.x - 2048 / 2) < 5 && Math.abs(self.y - 2732 / 2) < 5 && self.scaleX >= 4 && !is_room5) {
// Stop movement and scaling
self.speed = 0;
self.scaleFactor = 0;
// Stop the wobble effect on the enemy
tween.stop(self, {
x: true
});
// Disable further interaction with the enemy
self.down = null; //{9.1}
gameOver();
} else if (self.scaleX >= 5 && self.scaleY >= 5 && is_room5) {
// Stop movement and scaling
self.speed = 0;
self.scaleFactor = 0;
// Stop the wobble effect on the enemy
tween.stop(self, {
x: true
});
// Disable further interaction with the enemy
self.down = null; //{9.1}
gameOver();
}
};
});
// Create a Snowflake class by using the LK expand method to extend Container.
var Snowflake = Container.expand(function () {
var self = Container.call(this);
// Get and automatically addChild to self asset with id 'bg_Snowflake' with the anchor point set to .5, .5
var scale = Math.random() * 0.5 + 0.5; // Random scale between 0.5 and 1
var snowflakeGraphics = self.attachAsset('bg_Snowflake', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scale,
scaleY: scale
});
// Set snowflake speed
self.speed = Math.random() * 0.5 + 0.5;
// This is automatically called every game tick, if the snowflake is attached!
self.update = function () {
self.y += self.speed;
// If the snowflake is off the screen, destroy it
if (self.y > 2732 || self.x < 0) {
self.destroy();
}
};
});
/****
* Initialize Game
****/
//---------------------------------------------------------------------------------------------------
//create variables for the various assets that will be loaded and unloaded and their various types
//---------------------------------------------------------------------------------------------------
//array for the elements of the menu so that we can easily destroy them or add them to the game
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
function animateLeftRight(asset, distance, duration) {
// Move asset to the right
tween(asset, {
x: asset.x + distance
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Move asset to the left
tween(asset, {
x: asset.x - distance
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Repeat the animation
animateLeftRight(asset, distance, duration);
}
});
}
});
}
function animateSmokeTransition(asset) {
// Retrieve the initial smoke asset
var smoke = LK.getAsset('bg_Smoke2', {
anchorX: 0.5,
anchorY: 0.5,
x: asset.x,
y: asset.y,
alpha: 1
});
game.addChild(smoke);
// Transition to bg_Smoke1
tween(smoke, {
alpha: 0
}, {
duration: 150,
onFinish: function onFinish() {
var smoke1 = LK.getAsset('bg_Smoke1', {
anchorX: 0.5,
anchorY: 0.5,
x: asset.x,
y: asset.y,
alpha: 0
});
game.addChild(smoke1);
smoke.destroy();
tween(smoke1, {
alpha: 1
}, {
duration: 150,
onFinish: function onFinish() {
LK.setTimeout(function () {
smoke1.destroy();
}, 150);
}
});
}
});
}
function collectibleDefaultDownBehaviour(asset) {
asset.down = null;
LK.getSound('s_Collected').play();
// Increment the collectible counter
collectibleCounter++;
// Update the collectible counter text
// Create and display 'Collectible found!' text at the collectible's position
var collectibleText = new Text2("Collectible \n found!", {
size: 60,
fill: 0xFFFFFF,
stroke: 0xFFFFFF,
// Add white outline
strokeThickness: 5,
// Thickness of the outline
font: "bold Garamond",
align: "center"
});
collectibleText.anchor.set(0.5, 0.5);
collectibleText.x = asset.x;
collectibleText.y = asset.y;
game.addChild(collectibleText);
// Remove the text after 2 seconds
LK.setTimeout(function () {
collectibleText.destroy();
}, 2000);
// Destroy the collectible after pickup
asset.destroy();
}
//put the default behaviour here
function defaultDownLoreTextBehaviour(text) {
// Instantiate help icon in the center of the playspace
helpIcon = game.addChildAt(LK.getAsset('bg_HelpMenu', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}), game.children.indexOf(grain) - 1);
// Create red text above the help icon
helpText = new Text2(text, {
size: 100,
fill: 0x000000,
font: "Garamond",
align: "center" // Ensure text alignment is set
});
helpText.anchor.set(0.5, 1);
helpText.x = helpIcon.x + 50; // Center helpText on helpIcon
helpText.y = helpIcon.y + 550; // Position helpText below helpIcon
game.addChildAt(helpText, game.children.indexOf(grain) - 1);
// Play crumpled paper sound
LK.getSound('s_CrumpledPaper').play();
// Set help icon as active
isHelpIconActive = true;
}
function defaultUpLoreTextBehaviour() {
if (isHelpIconActive && helpIcon) {
helpIcon.destroy();
if (helpText) {
helpText.destroy();
}
LK.getSound('s_CrumpledPaper').play();
isHelpIconActive = false;
}
}
// Create and display the collectible counter at the top right of the screen
var collectibleCounterText;
// Update the collectible counter text whenever the collectibleCounter changes
// Ensure this function is called in the Collectible class where the counter is incremented
function calculateLevelCompletionTime(startTime, endTime) {
var timeTaken = endTime.hours * 3600 + endTime.minutes * 60 + endTime.seconds - (startTime.hours * 3600 + startTime.minutes * 60 + startTime.seconds);
var seconds = Math.floor(timeTaken % 60);
var minutes = Math.floor(timeTaken / 60 % 60);
var hours = Math.floor(timeTaken / 3600);
return {
hours: hours,
minutes: minutes,
seconds: seconds
};
}
function scaleAssetBigger(asset) {
asset.scaleX *= 1.1;
asset.scaleY *= 1.1;
}
var isHelpIconActive = false;
function centerAsset(asset, centerX, centerY) {
asset.x = centerX; //- asset.width / 2;
asset.y = centerY; //- asset.height / 2;
}
// Function to play a sound every 10000ms
var soundIntervalId = null; // Variable to store the interval ID
function playSoundEveryInterval(soundId, interval) {
if (soundIntervalId == null) {
LK.getSound(soundId).play();
soundIntervalId = LK.setInterval(function () {
LK.getSound(soundId).play();
}, interval);
}
}
// Function to stop the sound playing at intervals
function stopSoundInterval() {
console.log("trying to stop sound" + soundIntervalId);
if (soundIntervalId) {
LK.clearInterval(soundIntervalId);
soundIntervalId = null;
console.log("supposed to have cleared it " + soundIntervalId);
}
}
function gameOver() {
if (!is_gameover) {
is_gameover = true;
var fadeOut = LK.getAsset('bg_DarkFilter', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(fadeOut);
tween(fadeOut, {
alpha: 1
}, {
duration: 2000,
onFinish: function onFinish() {
// Play shutdown sound with fade effect
LK.getSound('s_ShutdownSound').play();
tween(LK.getSound('s_ShutdownSound'), {
volume: 0
}, {
duration: 4000,
easing: tween.easeOut
});
// Instantiate Krampus in the center of the playspace
var krampus = game.addChild(LK.getAsset('bg_Krampus', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 1000
}));
// Play Krampus laugh sound
LK.getSound('s_KrampusLaugh02').play();
// Add Krampus animation
krampusAnimationLaugh(krampus);
// Display game over text
var gameOverText = new Text2("", {
size: 150,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 5,
font: "Garamond",
align: "center"
});
var endTime = {
hours: clock.hours,
minutes: clock.minutes,
seconds: clock.seconds
};
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2 - 800;
game.addChild(gameOverText);
var gameOverTextSequence = ["Hello again...", "I hope you are ready...", " ...for what is waiting for you!"];
var currentGameOverTextIndex = 0;
function displayNextGameOverText() {
if (currentGameOverTextIndex < gameOverTextSequence.length) {
gameOverText.setText(gameOverTextSequence[currentGameOverTextIndex]);
shakeText(gameOverText, function () {
currentGameOverTextIndex++;
LK.setTimeout(displayNextGameOverText, 2000);
});
}
}
displayNextGameOverText();
bringForwardVCR();
// Fade out Krampus after 3 seconds
LK.setTimeout(function () {
tween(krampus, {
alpha: 0
}, {
duration: 2000,
easing: tween.easeOut,
onFinish: function onFinish() {
LK.getSound('s_KrampusScream').play();
// Instantiate KrampusZoomedIn after Krampus fades out
var krampusZoomedIn = game.addChild(LK.getAsset('bg_KrampusZoomedIn', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 600
}));
// Shake Krampus at the end of the gameOver function
shakeAsset(krampusZoomedIn);
// Set a timeout to remove KrampusZoomedIn after 3 seconds
LK.setTimeout(function () {
krampusZoomedIn.destroy();
gameOverText.destroy();
var detailsText = new Text2("", {
size: 150,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 5,
font: "bold Garamond",
align: "center"
});
detailsText.anchor.set(0.5, 0);
detailsText.x = 2048 / 2;
detailsText.y = 400;
detailsText.setText("Ending: C\nTime to game over: " + calculateLevelCompletionTime(initialClock, endTime).minutes + "m " + calculateLevelCompletionTime(initialClock, endTime).seconds + "s\nCollectibles: " + collectibleCounter + "/" + maxCollectibles);
game.addChild(detailsText);
}, 1500);
}
});
}, 3000);
// End the game after 4 seconds
LK.setTimeout(function () {
LK.showGameOver();
}, 10000);
}
});
}
}
//---------------------------------------------------------------------------------------------------
//create variables for the various assets that will be loaded and unloaded and their various types
//---------------------------------------------------------------------------------------------------
//array for the elements of the menu so that we can easily destroy them or add them to the game
var inventory = new Array(2).fill(null); // Inventory array of length 2
var dragNode = null; // Define dragNode in the global scope
var isMoving = false;
var lastPosition = {
x: 0,
y: 0
};
var safeStatus = {
is_note1_found: false,
is_note2_found: false,
is_note3_found: false
};
var collectibleCounter = 0;
var maxCollectibles = 7;
var movementCheckInterval;
var inventoryCoordinateLeftX = 2048 / 2 - 780; //2048 / 2 - 500;
var inventoryCoordY = 2732 - 250;
var inventoryCoordinateRightX = 2048 / 2 - 280; //+ 500;
var collidableObjects = {};
var menuObjects = [];
var howToObjects = [];
var levelObjs = [];
var inventoryUI1;
var inventoryUI2;
//elements of the narration screen so that we can easily destroy or add them to the game
var introObjects = [];
//array for the snowflakes
var snowflakes = [];
//variables for the vcr effect that will hold the various assets of the effect
var grain, scanLines;
var flashlightMask = null;
// Create a variable to keep track of the flicker state
var is_flickerState = false;
var is_room2 = false;
var is_gameover = false;
var is_room3 = false;
var is_room4 = false;
var is_room5 = false;
var is_room6 = false;
var loreNote1 = "He is real… \n HE IS REAL! \nThe Krampus… \nHe is not only a legend! \nWhy did I not believe \nthe people in the \ntown when I visited\n on November 28th…";
var loreNote2 = "I thought it would \nbe fun to dress up\n as Santa and\n prank children. \nWhat is the harm? \nSanta and Krampus \ndon’t exist anyway…";
var loreNote3 = "Two days after\n Krampuslauf I was still\n nursing my injuries… \n I should not have\n done anything to \nbe on the naughty \nlist… ";
var room5State = {
is_key_found: false,
is_event_done: false,
is_gameover: false,
is_collectible_found: false,
is_medallion_found: false,
is_breakable_found: false,
enemy_counter: 16,
keyX: 2048 / 2 + 50,
keyY: 2732 / 2 + 675,
arrowRightX: 2048 - 150,
arrowRightY: 1500,
medallionX: 500,
medallionY: 1850,
breakableX: 1300,
breakableY: 1450,
collectibleX: 500,
collectibleY: 800
};
var room4State = {
is_key_found: false,
is_dollKey_found: false,
is_possible_pick_up: false,
// is_candle1_lit: true,
is_candle2_lit: false,
is_candle3_lit: false,
is_candle4_lit: false,
is_candle5_lit: false,
is_medallionA: false,
is_medallionB: false,
is_breakable_found: false,
is_collectible_found: false,
is_secret_enabled: false,
medallionAX: 2048 / 2 + 25,
medallionAY: 2732 / 2 - 500,
medallionBX: 2048 / 2 - 75,
medallionBY: 2732 / 2 - 500,
medallionPlaqueX: 2048 / 2 - 25,
medallionPlaqueY: 2732 / 2 - 450,
arrowLeftX: 200,
arrowLeftY: 2732 / 2,
candle2_x: 2048 / 2 + 50,
candle2_y: 2732 / 2 + 900,
candle3_x: 2048 / 2 + 400,
candle3_y: 2732 / 2 + 600,
candle4_x: 2048 / 2 - 400,
candle4_y: 2732 / 2 + 600,
candle5_x: 2048 / 2,
candle5_y: 2732 / 2 + 400,
collectibleX: 1775,
collectibleY: 1915,
dollkeyX: 2048 / 2 + 900,
dollkeyY: 2732 / 2 - 200,
krampusHalfX: 2048 / 2,
krampusHalfY: 2732 / 2 + 600,
breakableX: 400,
breakableY: 1750
};
var room3State = {
// is_lockLight_unlocked: false,
is_lockDoll_unlocked: false,
is_lockKrampus_unlocked: false,
is_collectible_found: false,
is_attack_done: false,
is_medallion_found: false,
lockDollX: 500,
lockDollY: 1500,
lockKrampusX: 2048 / 2 + 25,
lockKrampusY: 1450,
collectibleX: 1200,
collectibleY: 1800,
creepyDollX: 2048 / 2,
creepyDollY: 2732 / 2 + 150,
keyX: 1100,
keyY: 1900,
arrowRightX: 1500,
arrowRightY: 1500,
medallionX: 2048 / 2 + 40,
medallionY: 525,
loreNoteX: 2048 / 2 + 600,
loreNoteY: 1800
};
var room2State = {
// is_unlocked: false,
is_fusebox_fixed: false,
is_fuse_found: false,
is_collectible_found: false,
is_key_found: false,
is_safe_unlocked: false,
is_first_entry: true,
is_breakable_down: false,
fuseX: 100,
fuseY: 2150,
fuseboxX: 600,
fuseboxY: 1100,
safeX: 500,
safeY: 500,
lockX: 1300,
lockY: 2500,
collectibleX: 1900,
collectibleY: 1900,
breakableX: 500,
breakableY: 1300,
elfX: 2048 - 400,
elfY: 2732 / 2 + 350,
arrowLeftX: 200,
arrowLeftY: 2732 / 2,
keyX: 1100,
keyY: 1900,
fusebox_redX: 650,
fusebox_redY: 975,
fusebox_greenX: 675,
fusebox_greenY: 975,
fuseboxRed: null,
loreNoteX: 2048 / 2 + 100,
loreNoteY: 2732 / 2 + 250
};
var room1State = {
is_unlocked: false,
is_collectible_found: false,
is_tutorial_over: false,
is_collectible2_found: false,
is_medallion_picked_up: false,
lockX: 2048 - 150,
lockY: 2732 / 2 + 300,
collectibleX: 225,
collectibleY: 1450,
elfX: 2048 / 2 - 525,
elfY: 2732 / 2 + 550,
collectible2X: 2048 / 2 + 500,
collectible2Y: 2300,
safeX: 2048 / 2 + 100,
safeY: 2000
};
// Define eyeFlash variable
var eyeFlash;
//variable to keep track of if we are in the mainMenu or not
var is_mainMenu = false;
//variable to keep track of the help menu
var is_helpMenuVisible = false;
// Create a variable to keep track of the time elapsed
var timeElapsed = 0;
// Create a clock variable to store the initial time of 11 hours and 45 minutes
var initialClock = {
hours: 11,
minutes: 55,
seconds: 0
};
var clock = {
hours: initialClock.hours,
minutes: initialClock.minutes,
seconds: initialClock.seconds
};
var is_level1 = false;
var clockInterval = null;
var clockText = ""; // Define clockText in the global scope
function removeItemFromInventory(asset) {
for (var i = 0; i < inventory.length; i++) {
if (inventory[i] !== null && inventory[i].asset === asset) {
inventory[i].asset.destroy();
inventory[i] = null;
break;
}
}
}
function findCollidableObjects(assetID) {
var asset = null;
if (collidableObjects !== null && collidableObjects.hasOwnProperty(assetID)) {
asset = collidableObjects[assetID];
}
return asset;
}
function addCollidableObjects(asset, assetID) {
if (!collidableObjects.hasOwnProperty(assetID)) {
collidableObjects[assetID] = asset;
return true;
}
return false;
}
function removeCollidableObjects(assetID) {
if (collidableObjects !== null && collidableObjects.hasOwnProperty(assetID)) {
var asset = collidableObjects[assetID];
if (asset) {
// asset.destroy(); // Destroy the game object
delete collidableObjects[assetID]; // Remove the property from collidableObjects
return true; // Indicate success
}
}
return false; // Indicate failure
}
//a function to allow to find the asset in the inventory
function findInInventory(assetID) {
var asset = null;
for (i = 0; i < inventory.length; i++) {
if (inventory[i] !== null && inventory[i].hasOwnProperty("id") && inventory[i].hasOwnProperty("asset")) {
if (inventory[i].id == assetID) {
asset = inventory[i].asset;
}
}
}
return asset;
}
function addItemToInventory(assetName) {
// Find the first empty index in the inventory
var index = findFirstEmptyInventoryIndex();
// If there's an empty slot, proceed to add the item
if (index !== -1) {
// Determine the location using the inventoryCoordinate function
var location = inventoryCoordinate(index);
// Instantiate the asset based on the location
var asset;
if (location === "left") {
asset = LK.getAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5,
x: inventoryCoordinateLeftX,
y: inventoryCoordY
});
bringForwardVCR();
} else if (location === "right") {
asset = LK.getAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5,
x: inventoryCoordinateRightX,
y: inventoryCoordY
});
bringForwardVCR();
}
// Add the asset to the game and inventory
if (asset) {
var assetObject = {
id: assetName,
asset: asset
};
game.addChild(asset);
// Store original position
asset.originalX = asset.x;
asset.originalY = asset.y;
// Enable dragging for the asset
asset.down = function (x, y, obj) {
dragNode = asset;
};
asset.move = function (x, y, obj) {
if (dragNode === asset) {
//setting the position received to the position where it is
//on a global scale of the entire screen.
//this prevents the lag effect that is generated when using the relative position
var localPosition = game.toLocal(obj.global);
asset.x = localPosition.x;
asset.y = localPosition.y;
}
};
asset.up = function (x, y, obj) {
if (dragNode === asset) {
dragNode = null;
//resetting the postition variables to out of bound since the touch has been stopped.
lastPosition.x = -1;
lastPosition.y = -1;
// Return asset to its original position
tween(asset, {
x: asset.originalX,
y: asset.originalY
}, {
duration: 500,
easing: tween.easeOut
});
}
};
inventory[index] = assetObject;
bringForwardVCR(); // Ensure VCR effects are on top
return true; // Indicate success
}
}
//case where the inventory is full
else {
// Create and display 'inventory full' message
var inventoryFullText = new Text2("Inventory Full", {
size: 150,
fill: 0xFF0000,
font: "Garamond"
});
inventoryFullText.anchor.set(0.5, 0.5);
inventoryFullText.x = 2048 / 2;
inventoryFullText.y = 2732 / 2;
game.addChild(inventoryFullText);
// Remove the message after 3 seconds
LK.setTimeout(function () {
inventoryFullText.destroy();
}, 3000);
return false; // Indicate failure
}
}
function inventoryCoordinate(index) {
if (index === 0) {
return "left";
} else if (index === 1) {
return "right";
} else {
return -1;
}
}
function findFirstEmptyInventoryIndex() {
for (var i = 0; i < inventory.length; i++) {
if (inventory[i] === null) {
return i;
}
}
return -1; // Return -1 if no empty index is found
}
function startClock() {
if (!clockInterval) {
clockInterval = LK.setInterval(function () {
clock.seconds++;
if (clock.seconds >= 60) {
clock.seconds = 0;
clock.minutes++;
if (clock.minutes >= 60) {
clock.minutes = 0;
clock.hours++;
if (clock.hours >= 24) {
clock.hours = 0;
}
}
}
}, 1000);
}
}
function pauseClock() {
if (clockInterval) {
LK.clearInterval(clockInterval);
clockInterval = null;
}
}
// Function to animate an asset up and down
function animateUpDown(asset, distance, duration) {
// Move asset up
tween(asset, {
y: asset.y - distance
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Move asset down
tween(asset, {
y: asset.y + distance
}, {
duration: duration,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Repeat the animation
animateUpDown(asset, distance, duration);
}
});
}
});
}
//------------------------------------------------------------------------------------
//functions for the visual and sound effects
//------------------------------------------------------------------------------------
//function that adds the effect of a vcr screen to the game.
function vcr() {
// Add bg_Grain in the center of the playspace and set its alpha to 20%
grain = game.addChild(LK.getAsset('bg_Grain', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.15
}));
// Instantiate bg_ScanLines in the center of the playspace above bg_grain
scanLines = game.addChild(LK.getAsset('bg_ScanLine', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0.12
}));
// Ensure bg_Grain and bg_ScanLines are always on the top layer
game.setChildIndex(grain, game.children.length - 1);
game.setChildIndex(scanLines, game.children.length - 1);
// Function to animate bg_ScanLines
function animateScanLines() {
// Randomly move up or down by a small amount
var jumpHeight = Math.random() * 600 - 300; // Random value between -25 and 25
scanLines.y += jumpHeight;
// Reposition to center after a short delay
LK.setTimeout(function () {
scanLines.x = 2048 / 2;
scanLines.y = 2732 / 2;
}, 1000); // 1 second delay
}
// Set interval to animate bg_ScanLines every few seconds
LK.setInterval(animateScanLines, 3000); // Every 3 seconds
}
function bringForwardVCR() {
// Ensure bg_Grain and bg_ScanLines are always on the top layer
game.setChildIndex(grain, game.children.length - 1);
game.setChildIndex(scanLines, game.children.length - 1);
}
function bringForwardInventory() {
// Ensure inventory UI elements are on the top layer
game.setChildIndex(inventoryUI1, game.children.length - 1);
game.setChildIndex(inventoryUI2, game.children.length - 1);
// Ensure all inventory items are on the top layer
inventory.forEach(function (item) {
if (item !== null && item.asset) {
game.setChildIndex(item.asset, game.children.length - 1);
}
});
}
function bringForwardClock(clockText) {
// Ensure the clock text is always on the top layer
if (game.children.includes(clockText)) {
game.setChildIndex(clockText, game.children.length - 1);
}
}
function shakeAsset(asset) {
var originalX = asset.x;
var originalY = asset.y;
LK.getSound('s_Locked').play();
// Shake the lock
tween(asset, {
x: originalX + 10
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(asset, {
x: originalX - 20
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(asset, {
x: originalX + 20
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(asset, {
x: originalX - 10
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Return to original position
tween(asset, {
x: originalX
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
}
});
}
});
}
});
}
//function to add snowflakes on the screen
function createSnowflake() {
var newSnowflake = new Snowflake();
// Ensure the snowflake spawns from the top of the playspace
newSnowflake.x = Math.random() * 2048;
newSnowflake.y = -50;
snowflakes.push(newSnowflake);
game.addChild(newSnowflake);
}
//function to add screams to a scene
function addScream() {
var randomSound = Math.floor(Math.random() * 4);
switch (randomSound) {
case 0:
LK.getSound('s_ManScream01').play();
break;
case 1:
LK.getSound('s_ManScream02').play();
break;
case 2:
LK.getSound('s_WomanScream01').play();
break;
case 3:
LK.getSound('s_WomanScream02').play();
break;
}
}
//a function to make some text shake
function shakeText(textObject, _onFinish) {
tween(textObject, {
x: textObject.x + 10
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(textObject, {
x: textObject.x - 20
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(textObject, {
x: textObject.x + 20
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(textObject, {
x: textObject.x - 20
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(textObject, {
x: textObject.x + 10
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: _onFinish
});
}
});
}
});
}
});
}
});
}
//function for an animation of the krampus bobbing up and down.
function krampusAnimationLaugh(krampus) {
tween(krampus, {
x: krampus.x + 10,
scaleX: 1.2,
scaleY: 0.8
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(krampus, {
x: krampus.x - 20,
scaleX: 0.8,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(krampus, {
x: krampus.x + 20,
scaleX: 1.2,
scaleY: 0.8
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(krampus, {
x: krampus.x - 20,
scaleX: 0.8,
scaleY: 1.2
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(krampus, {
x: krampus.x + 10,
scaleX: 1,
scaleY: 1
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
}
});
}
});
}
});
}
// Function to make bg_FakeDoll wobble towards the right
function wobbleFakeDoll() {
tween(fakeDoll, {
x: fakeDoll.x + 25,
y: fakeDoll.y + Math.sin(LK.ticks / 10) * 3 // Wobble up and down with even less vertical movement
}, {
duration: 5,
easing: tween.easeInOut,
onFinish: function onFinish() {
if (fakeDoll.alpha === 1 && !fakeDoll.soundPlayed) {
LK.getSound('s_CartoonRun').play();
fakeDoll.soundPlayed = true;
}
if (fakeDoll.x < 2048 + fakeDoll.width) {
wobbleFakeDoll();
} else {
fakeDoll.destroy();
}
}
});
}
//--------------------------------------------------------------------------------
//functions that will be for the various loading of the game.
//--------------------------------------------------------------------------------
//a function to load the menu screen
function loadMenu() {
is_mainMenu = true;
// Retrieve the 'bg_TitleScreen' asset and position it at the center of the playspace
var titleScreen = game.addChild(LK.getAsset('bg_TitleScreen', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 100,
y: 2732 / 2
}));
// Use the animateLeftRight function to make the title screen move
animateLeftRight(titleScreen, 50, 2000);
// Instantiate bg_DarkNumber in the center of the playspace
var darkNumber = game.addChild(LK.getAsset('bg_DarkNumber', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 700,
y: 2732 / 2 + 250
}));
// Instantiate bg_DarkNumber28 in the center of the playspace
var darkNumber28 = game.addChild(LK.getAsset('bg_DarkNumber28', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 850,
y: 2732 / 2 + 200
}));
// Instantiate bg_DarkNumber7 in the center of the playspace
var darkNumber7 = game.addChild(LK.getAsset('bg_DarkNumber7', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 825,
y: 2732 / 2
}));
// Instantiate bg_DarkNumber0 in the center of the playspace
var darkNumber0 = game.addChild(LK.getAsset('bg_DarkNumber0', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 835,
y: 2732 / 2 - 260
}));
animateLeftRight(darkNumber, 30, 2000);
animateLeftRight(darkNumber28, 30, 2000);
animateLeftRight(darkNumber7, 30, 2000);
animateLeftRight(darkNumber0, 30, 2000);
menuObjects.push(darkNumber);
menuObjects.push(darkNumber28);
menuObjects.push(darkNumber7);
menuObjects.push(darkNumber0);
menuObjects.push(titleScreen);
// Play s_splashscreen when the game starts
LK.setTimeout(function () {
LK.playMusic('s_SplashScreen', {
loop: true
});
}, 1000);
// Retrieve the 'bg_TornRope' asset and position it at the bottom middle of the playspace
var tornRope = game.addChild(LK.getAsset('bg_TornRope', {
anchorX: 0.5,
anchorY: 1.0,
x: 2048 / 2,
y: 2832
}));
menuObjects.push(tornRope);
// Retrieve the 'bg_eyeflash' asset, position it at the center of the playspace and set its alpha to 50%
eyeFlash = game.addChild(LK.getAsset('bg_eyeflash', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 75,
y: 2732 / 2 - 100,
alpha: 0.20
}));
animateLeftRight(eyeFlash, 50, 2000);
menuObjects.push(eyeFlash);
// Retrieve the 'bg_StartButton' asset and position it at the bottom left of the playspace
var startButton = game.addChild(LK.getAsset('bg_StartButton', {
anchorX: 0.0,
anchorY: 1.0,
x: 150,
y: 2732
}));
menuObjects.push(startButton);
// Add a down event to the startButton
startButton.down = function (x, y, obj) {
// Disable how-to button
howTo.down = null;
// Close the help menu if it's open
if (is_helpMenuVisible) {
exitHowTo();
is_helpMenuVisible = false;
}
// Flash the screen white for a brief moment
LK.effects.flashScreen(0xFFFFFF, 500);
// Play s_LightBuzz sound
LK.getSound('s_LightBuzz').play();
loadIntroNarrative();
};
// Retrieve the 'bg_HowTo' asset and position it at the bottom right of the playspace
var howTo = game.addChild(LK.getAsset('bg_HowTo', {
anchorX: 1.0,
anchorY: 1.0,
x: 1950,
y: 2732
}));
menuObjects.push(howTo);
// Variable to track the state of bg_HelpMenu
is_helpMenuVisible = false;
var helpMenu;
// Add a down event to the howTo button
howTo.down = function (x, y, obj) {
if (!is_helpMenuVisible) {
helpMenu = openHowToButton();
} else {
// Destroy bg_HelpMenu
if (is_helpMenuVisible == true) {
exitHowTo();
is_helpMenuVisible = false;
}
}
// Play s_CrumpledPaper sound
LK.getSound('s_CrumpledPaper').play();
};
}
//a function that will remove all objects from memory when leaving the main menu.
function exitMainMenu() {
is_mainMenu = false;
//destroy all mainMenu objects
for (var i = menuObjects.length - 1; i >= 0; i--) {
if (menuObjects[i]) {
menuObjects[i].destroy();
}
}
//destroy all snowflakes
for (var i = snowflakes.length - 1; i >= 0; i--) {
if (snowflakes[i]) {
snowflakes[i].destroy();
}
}
// Stop all sounds
LK.stopMusic();
}
//function to destroy the objects that are created once the how to menu is opened.
function exitHowTo() {
for (var i = howToObjects.length - 1; i >= 0; i--) {
if (howToObjects[i]) {
howToObjects[i].destroy();
}
}
}
//function for the functionnality of the help button
function openHowToButton() {
// Instantiate bg_HelpMenu in the center of the playspace
helpMenu = game.addChild(LK.getAsset('bg_HelpMenu', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 150
}));
howToObjects.push(helpMenu);
is_helpMenuVisible = true;
// Include bg_ClownKey, bg_HelpIcon01, and bg_InventoryUI
var clownKey = game.addChild(LK.getAsset('bg_ClownKey', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 375,
y: 2732 / 2 + 625
}));
howToObjects.push(clownKey);
var helpAnim = game.addChild(LK.getAsset('bg_HelpAnim', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 550,
y: 2732 / 2 + 800
}));
howToObjects.push(helpAnim);
// Animate clownKey and helpAnim
function animateClownKeyAndHelpAnim() {
tween(clownKey, {
x: clownKey.x - 400,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Reset position and alpha after 1 second
LK.setTimeout(function () {
clownKey.x = 2048 / 2 - 375;
clownKey.alpha = 1;
}, 1000);
}
});
tween(helpAnim, {
x: helpAnim.x - 400,
alpha: 0
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
// Reset position and alpha after 1 second
LK.setTimeout(function () {
helpAnim.x = 2048 / 2 - 550;
helpAnim.y = 2732 / 2 + 800;
helpAnim.alpha = 1;
}, 1000);
}
});
}
// Start the animation loop
animateClownKeyAndHelpAnim();
LK.setInterval(animateClownKeyAndHelpAnim, 3000);
// Create red text at the top center of the screen
var naughtyText = new Text2("Tap or Hold screen to \n interact with the scene \n \n \n \n \n \n Drag from inventory to \n scene to use objects", {
size: 75,
fill: 0x000000,
stroke: 0x000000,
strokeThickness: 5,
font: "Garamond"
});
naughtyText.anchor.set(0.5, 0);
naughtyText.x = 2048 / 2 + 250;
naughtyText.y = 100 + 1175;
howToObjects.push(naughtyText);
game.addChild(naughtyText);
// Instantiate bg_HelpAnim asset on the top left of the naughtyText
var helpAnimTopLeft = LK.getAsset('bg_HelpAnim', {
anchorX: 0.5,
anchorY: 0.5,
x: naughtyText.x - naughtyText.width / 2 - 300,
// Position to the left of naughtyText
y: naughtyText.y // Position above naughtyText
});
game.addChild(helpAnimTopLeft);
howToObjects.push(helpAnimTopLeft);
var inventoryUI = LK.getAsset('bg_InventoryUI', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 375,
y: 2732 / 2 + 600
});
game.addChild(inventoryUI);
// Ensure clownKey and helpAnim are above inventory UI
game.setChildIndex(clownKey, game.children.length - 1);
game.setChildIndex(helpAnim, game.children.length - 1);
// Ensure bg_Grain and bg_ScanLines are always on the top layer
game.setChildIndex(scanLines, game.children.length - 1);
game.setChildIndex(grain, game.children.length - 1);
howToObjects.push(inventoryUI);
return helpMenu;
}
//function to load the intro narrative
function loadIntroNarrative() {
// Retrieve the 'bg_DarkFilter' asset, position it at the center of the playspace and set its alpha to 0
var darkFilter = game.addChild(LK.getAsset('bg_DarkFilter', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
}));
// Gradually fade in bg_darkfilter
var fadeInterval = LK.setInterval(function () {
darkFilter.alpha += 0.01;
if (darkFilter.alpha >= 1) {
LK.clearInterval(fadeInterval);
}
}, 10);
// Move the destruction of all game elements inside the fadeInterval function
LK.setTimeout(function () {
// Play shutdownsound
LK.getSound('s_ShutdownSound').play();
}, 10);
var fadeInterval = LK.setInterval(function () {
darkFilter.alpha += 0.01;
if (darkFilter.alpha >= 1) {
LK.clearInterval(fadeInterval);
// Ensure bg_Grain and bg_ScanLines are always on the top layer
game.setChildIndex(grain, game.children.length - 1);
game.setChildIndex(scanLines, game.children.length - 1);
LK.setTimeout(function () {
darkFilter.destroy();
}, 2000);
// Destroy all game elements including sounds after 1 second
LK.setTimeout(function () {
exitMainMenu();
// Play s_KrampusLaugh01 2 seconds after bg_darkfilter is at 100% alpha only once
if (!this.is_laughPlayed) {
LK.setTimeout(function () {
LK.getSound('s_KrampusLaugh01').play();
// Instantiate bg_Krampus in the center of the playspace
var krampus = game.addChild(LK.getAsset('bg_Krampus', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 3732 / 2 + 700
}));
// Create red text at the top center of the screen
var krampusText = new Text2("", {
size: 200,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 5,
font: "Garamond"
});
krampusText.anchor.set(0.5, 0);
krampusText.x = 2048 / 2;
krampusText.y = 300;
game.addChild(krampusText);
introObjects.push(krampusText);
// Add a skip button at the bottom right of the screen
var skipButton = game.addChild(LK.getAsset('bg_SkipButton', {
anchorX: 1.0,
anchorY: 1.0,
x: 2048 - 50,
y: 2732 - 50
}));
introObjects.push(skipButton);
// Add a down event to the skipButton
skipButton.down = function (x, y, obj) {
// Stop the parallel process of displayNextText
currentTextIndex = textSequence.length; // Set index to end to stop further text display
// Load level1 when the skip button is clicked
destroyObjects(introObjects);
level1();
};
var textSequence = ["Hello, Krampus here.", "You’ve been marked \n ‘naughty’ this year.", "But there’s hope \n left for you.", "Solve the puzzles \n before the clock \n strikes 12:00", "or face an unforgiving \n holiday spirit.", "GOOD LUCK!"];
var currentTextIndex = 0;
function displayNextText() {
if (currentTextIndex < textSequence.length) {
if (textSequence[currentTextIndex] === "GOOD LUCK!") {
LK.getSound('s_KrampusLaugh02').play();
krampusAnimationLaugh(krampus);
// Fade out Krampus and Krampus text 2 seconds after GOOD LUCK! is displayed
LK.setTimeout(function () {
tween(krampus, {
alpha: 0
}, {
duration: 2000
});
tween(krampusText, {
alpha: 0
}, {
duration: 2000
});
}, 2000);
level1();
}
krampusText.setText(textSequence[currentTextIndex]);
shakeText(krampusText, function () {
currentTextIndex++;
LK.setTimeout(displayNextText, 2000);
});
}
}
displayNextText();
introObjects.push(krampus);
game.setChildIndex(grain, game.children.length - 1);
game.setChildIndex(scanLines, game.children.length - 1);
}, 2000);
this.laughPlayed = true;
}
}, 1000);
}
}, 10);
}
//a function to load the first level of the game.
function level1() {
is_level1 = true;
stopSoundInterval();
//fade in bg_Room01
var room01 = LK.getAsset('bg_Room01', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(room01);
levelObjs.push(room01);
tween(room01, {
alpha: 1
}, {
duration: 3000,
onFinish: function onFinish() {
// Use playSoundEveryInterval to play s_Bathroom every 10000ms
playSoundEveryInterval('s_Bathroom', 10000);
}
});
// Variable to track if help icon is active
var isHelpIconActive = false;
var helpIcon = null;
var helpText = null;
// Start the clock
if (room1State.is_unlocked) {
var arrowRight = LK.getAsset('bg_ArrowRight', {
anchorX: 0.5,
anchorY: 0.5,
x: room1State.lockX,
y: room1State.lockY
});
game.addChild(arrowRight);
levelObjs.push(arrowRight);
animateUpDown(arrowRight, 20, 1000);
arrowRight.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
stopSoundInterval();
room2();
};
} //END OF IF THE ROOM IS UNLOCKED
else {
var elfEnvelope = LK.getAsset('bg_ElfEnvelope01', {
anchorX: 0.5,
anchorY: 0.5,
x: room1State.elfX,
y: room1State.elfY,
alpha: 0
});
game.addChild(elfEnvelope);
levelObjs.push(elfEnvelope);
// Add event listener for elf envelope
elfEnvelope.down = function (x, y, obj) {
if (!isHelpIconActive) {
// Instantiate help icon in the center of the playspace
helpIcon = game.addChildAt(LK.getAsset('bg_HelpIcon01', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}), game.children.indexOf(grain) - 1);
// Create red text above the help icon
helpText = new Text2("Tutorial: \n \n To escape the room, \n collect the key and \n drag it on the lock. \n\n Experiment by tapping \n various objects in \n the scene... ", {
size: 100,
fill: 0xFF0000,
font: "Garamond",
align: "center" // Ensure text alignment is set
});
helpText.anchor.set(0.5, 1);
helpText.x = helpIcon.x + 50; // Center helpText on helpIcon
helpText.y = helpIcon.y + 500; // Position helpText below helpIcon
game.addChildAt(helpText, game.children.indexOf(grain) - 1);
// Play crumpled paper sound
LK.getSound('s_CrumpledPaper').play();
// Set help icon as active
isHelpIconActive = true;
}
};
// Add event listener to destroy help icon and help text when screen is tapped
game.up = function (x, y, obj) {
if (isHelpIconActive && helpIcon) {
helpIcon.destroy();
if (helpText) {
helpText.destroy();
}
LK.getSound('s_CrumpledPaper').play();
isHelpIconActive = false;
}
};
startClock();
// Create and display the clock text at the top center of the screen
clockText = new Text2("", {
size: 100,
fill: is_room6 ? 0xFFFFFF : 0xFF0000,
// Red color
stroke: 0x000000,
// Black outline
strokeThickness: 20,
// Thickness of the outline
font: "bold Garamond",
align: "center"
});
clockText.anchor.set(0.5, 0);
clockText.x = 2048 / 2;
clockText.y = 50;
game.addChild(clockText);
// Update the clock text every second
LK.setInterval(function () {
clockText.setText(("0" + clock.hours).slice(-2) + ":" + ("0" + clock.minutes).slice(-2) + ":" + ("0" + clock.seconds).slice(-2));
}, 1000);
// Instantiate bg_BathroomLock in the middle right of the room 01 playspace
var bathroomLock = LK.getAsset('bg_BathroomLock', {
anchorX: 0.5,
anchorY: 0.5,
x: room1State.lockX,
// Positioned towards the right side
y: room1State.lockY,
alpha: 0
});
game.addChild(bathroomLock);
addCollidableObjects(bathroomLock, 'bg_BathroomLock');
// Add event listener for bathroomLock
bathroomLock.down = function (x, y, obj) {
shakeAsset(bathroomLock);
};
levelObjs.push(bathroomLock);
var bathRoomKey = LK.getAsset('bg_BathRoomKey', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 325,
y: 2732 / 2 + 125,
alpha: 0
});
game.addChild(bathRoomKey);
// Add event listener for bathRoomKey
bathRoomKey.down = function (x, y, obj) {
// Add bathroomKeyItem to the inventory
if (!addItemToInventory('bg_BathroomKeyItem')) {
console.log("Failed to add Bathroom Key Item to inventory.");
} else {
// Destroy the bathRoomKey
bathRoomKey.destroy();
// Play s_GetItem sound
LK.getSound('s_GetItem').play();
}
};
levelObjs.push(bathRoomKey);
// Instantiate bg_FakeDoll in the bottom middle of the playspace
fakeDoll = LK.getAsset('bg_FakeDoll', {
anchorX: 0.5,
anchorY: 1.0,
x: 2048 / 2 + 300,
y: 2732
});
game.addChild(fakeDoll);
levelObjs.push(fakeDoll);
// Start the wobble movement when room01 is fully visible
wobbleFakeDoll();
// Synchronize fade-in for all three elements
fadeInObj(bathRoomKey, 3000);
fadeInObj(elfEnvelope, 3000);
fadeInObj(bathroomLock, 3000);
// Add inventory UI at the left of the center at the bottom of the screen
inventoryUI1 = LK.getAsset('bg_InventoryUI', {
anchorX: 0.5,
anchorY: 0.5,
x: inventoryCoordinateLeftX,
// Position to the left of the center
y: inventoryCoordY // Position at the bottom of the screen
});
inventoryUI2 = LK.getAsset('bg_InventoryUI', {
anchorX: 0.5,
anchorY: 0.5,
x: inventoryCoordinateRightX,
// Position to the left of the center
y: inventoryCoordY // Position at the bottom of the screen
});
game.addChild(inventoryUI1);
game.addChild(inventoryUI2);
} //END OF IF THE ROOM IS LOCKED
if (!room1State.is_medallion_picked_up) {
var safe = LK.getAsset('bg_Safe', {
anchorX: 0.5,
anchorY: 0.5,
x: room1State.safeX,
y: room1State.safeY,
alpha: 0
});
levelObjs.push(safe);
fadeInObj(safe, 3000);
game.addChild(safe);
//if the safe is still locked
if (!safeStatus.is_note1_found || !safeStatus.is_note2_found || !safeStatus.is_note3_found) {
safe.down = function (x, y, obj) {
LK.getSound('s_LockedSafe').play();
var noteCounter = 0;
if (safeStatus.is_note1_found) {
noteCounter++;
}
if (safeStatus.is_note2_found) {
noteCounter++;
}
if (safeStatus.is_note3_found) {
noteCounter++;
}
var safeText = new Text2("Combination not found \n " + noteCounter + "/3", {
size: 60,
fill: 0xFFFFFF,
stroke: 0xFFFFFF,
// Add white outline
strokeThickness: 5,
// Thickness of the outline
font: "bold Garamond",
align: "center"
});
safeText.anchor.set(0.5, 0.5);
safeText.x = safe.x;
safeText.y = safe.y - 150;
game.addChild(safeText);
// Remove the text after 2 seconds
LK.setTimeout(function () {
safeText.destroy();
}, 2000);
};
} //notes are all found, we then instantiate the medallionb
else {
safe.down = function (x, y, obj) {
LK.getSound('s_SafeUnlocked').play();
var safeText = new Text2("Combination found!", {
size: 60,
fill: 0xFFFFFF,
stroke: 0xFFFFFF,
// Add white outline
strokeThickness: 5,
// Thickness of the outline
font: "bold Garamond",
align: "center"
});
safeText.anchor.set(0.5, 0.5);
safeText.x = safe.x;
safeText.y = safe.y - 150;
game.addChild(safeText);
// Remove the text after 2 seconds
LK.setTimeout(function () {
safeText.destroy();
}, 2000);
safe.destroy();
var medallionB = LK.getAsset('SE_MedallionB', {
anchorX: 0.5,
anchorY: 0.5,
x: room1State.safeX,
y: room1State.safeY + 150,
alpha: 0
});
game.addChild(medallionB);
fadeInObjWithAlpha(medallionB, 3000, 0.75);
levelObjs.push(medallionB);
medallionB.down = function (x, y, obj) {
if (addItemToInventory('SE_MedallionB')) {
room1State.is_medallion_picked_up = true;
medallionB.destroy();
room5State.is_medallion_found = true;
LK.getSound('s_GetItem').play();
bringForwardVCR();
}
};
};
}
}
// Instantiate collectible2 if not found
if (!room1State.is_collectible2_found) {
var collectible2 = new Collectible();
collectible2.x = room1State.collectible2X;
collectible2.y = room1State.collectible2Y;
collectible2.alpha = 0;
maxAlpha = 0.5; // Set max alpha to 0.75
game.addChild(collectible2);
levelObjs.push(collectible2);
fadeInObjWithAlpha(collectible2, 3000, maxAlpha);
collectible2.down = function (x, y, obj) {
collectibleDefaultDownBehaviour(collectible2);
collectible2.down = null;
room1State.is_collectible2_found = true;
};
}
// Instantiate a breakable object if collectible is not found
if (!room1State.is_collectible_found) {
var breakable = new BreakableAsset();
breakable.x = room1State.collectibleX;
breakable.y = room1State.collectibleY;
breakable.alpha = 0; // Start with alpha 0 for fade-in effect
breakable.setOnBreak(function () {
var collectible1 = new Collectible();
levelObjs.push(collectible1);
collectible1.down = function (x, y, obj) {
room1State.is_collectible_found = true;
collectible1.down = null;
collectibleDefaultDownBehaviour(collectible1);
};
return collectible1;
});
game.addChild(breakable);
levelObjs.push(breakable);
// Fade in the breakable object over 3 seconds
fadeInObj(breakable, 3000);
}
bringForwardClock(clockText);
bringForwardInventory();
bringForwardVCR();
}
function room2() {
if (is_level1) {
is_level1 = false;
}
is_room2 = true;
stopSoundInterval(); // Stop the bathroom sound when entering room2
playSoundEveryInterval('s_WindBlow', 10000);
var fadeOut = LK.getAsset('bg_DarkFilter', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(fadeOut);
tween(fadeOut, {
alpha: 1
}, {
duration: 1000,
onFinish: function onFinish() {
//depending on if the fusebox has been fixed or not
destroyObjects(levelObjs);
// Remove fadeOut filter
fadeOut.destroy();
// Instantiate room 2
var room02 = LK.getAsset('bg_Room02', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(room02);
levelObjs.push(room02);
var fusebox = LK.getAsset('bg_FuseBox', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.fuseboxX,
y: room2State.fuseboxY
});
game.addChild(fusebox);
levelObjs.push(fusebox);
addCollidableObjects(fusebox, 'bg_FuseBox');
var loreNote = LK.getAsset('s_DirtyLetter', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.loreNoteX,
y: room2State.loreNoteY,
alpha: 0.75
});
loreNote.rotation -= Math.PI / 4;
game.addChild(loreNote);
levelObjs.push(loreNote);
loreNote.down = function (x, y, obj) {
defaultDownLoreTextBehaviour(loreNote1);
safeStatus.is_note1_found = true;
};
loreNote.up = function (x, y, obj) {
defaultUpLoreTextBehaviour();
};
if (!room2State.is_collectible_found) {
var collectible = new Collectible();
collectible.x = room2State.collectibleX;
collectible.y = room2State.collectibleY;
collectible.alpha = 0;
var maxAlpha = 0.5; // Set max alpha to 0.05
game.addChild(collectible);
levelObjs.push(collectible);
fadeInObjWithAlpha(collectible, 1000, maxAlpha);
collectible.down = function (x, y, obj) {
collectible.down = null;
collectibleDefaultDownBehaviour(collectible);
room2State.is_collectible_found = true;
};
}
if (!room2State.is_breakable_down) {
var breakable = new BreakableAsset();
breakable.x = room2State.breakableX;
breakable.y = room2State.breakableY;
breakable.scaleY = 0.75;
breakable.scaleX = 0.75;
game.addChild(breakable);
levelObjs.push(breakable);
fadeInObj(breakable, 1000);
breakable.down = function (x, y, obj) {
breakable.down = null;
room2State.is_breakable_down = true;
LK.getSound('s_BreakingSound').play();
breakable.destroy();
animateSmokeTransition(breakable);
};
}
if (room2State.is_first_entry && !room2State.is_fusebox_fixed || !room2State.is_fusebox_fixed) {
room2State.is_first_entry = false;
var elfEnvelope = LK.getAsset('bg_ElfEnvelope01', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.elfX,
// Positioned towards the right side
y: room2State.elfY
});
game.addChild(elfEnvelope);
levelObjs.push(elfEnvelope);
// Add event listener for elf envelope
elfEnvelope.down = function (x, y, obj) {
if (!isHelpIconActive) {
// Instantiate help icon in the center of the playspace
helpIcon = game.addChildAt(LK.getAsset('bg_HelpIcon01', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
}), game.children.indexOf(grain) - 1);
// Create red text above the help icon
helpText = new Text2(" I wish I could \n see something... \n\n Tap around and see \n if something can \n be done.", {
size: 100,
fill: 0xFF0000,
font: "Garamond",
align: "center" // Ensure text alignment is set
});
helpText.anchor.set(0.5, 1);
helpText.x = 2048 / 2;
helpText.y = 2732 / 2 + 125;
game.addChildAt(helpText, game.children.indexOf(grain) - 1);
// Play crumpled paper sound
LK.getSound('s_CrumpledPaper').play();
// Set help icon as active
isHelpIconActive = true;
}
};
// Add event listener to destroy help icon and help text when screen is tapped
game.up = function (x, y, obj) {
if (isHelpIconActive && helpIcon) {
helpIcon.destroy();
if (helpText) {
helpText.destroy();
}
LK.getSound('s_CrumpledPaper').play();
isHelpIconActive = false;
}
};
}
// Instantiate bg_FlashLightMask in the center of the playspace
//we only instantiate it if the fusebox is not fixed.
// Instantiate bathroomLock if room2State is not unlocked
if (room2State.is_fusebox_fixed) {
// Instantiate ElfEnvelope on the center right of room2
var arrowUp = LK.getAsset('bg_ArrowDown', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.lockX,
y: room2State.lockY
});
game.addChild(arrowUp);
levelObjs.push(arrowUp);
animateUpDown(arrowUp, 20, 1000);
arrowUp.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
stopSoundInterval();
exitRoom2(levelObjs);
room3();
};
}
if (!room2State.is_key_found) {
var lighter = LK.getAsset('bg_Lighter', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.keyX,
y: room2State.keyY
});
game.addChild(lighter);
levelObjs.push(lighter);
lighter.down = function (x, y, obj) {
if (addItemToInventory('bg_LighterItem')) {
room2State.is_key_found = true;
lighter.destroy();
LK.getSound('s_GetItem').play();
bringForwardVCR();
}
};
}
var fuseboxRed = null;
if (room2State.is_fusebox_fixed) {
var fuseboxGreen = LK.getAsset('bg_FuseBoxGreen', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.fusebox_greenX,
y: room2State.fusebox_greenY
});
game.addChild(fuseboxGreen);
levelObjs.push(fuseboxGreen);
} else {
fuseboxRed = LK.getAsset('bg_FuseBoxRed', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.fusebox_redX,
y: room2State.fusebox_redY
});
game.addChild(fuseboxRed);
levelObjs.push(fuseboxRed);
room2State.fuseboxRed = fuseboxRed;
flashlightMask = LK.getAsset('bg_FlashLightMask', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.elfX,
y: room2State.elfY
});
game.addChild(flashlightMask);
levelObjs.push(flashlightMask);
}
var fuse = null;
if (!room2State.is_fuse_found) {
fuse = LK.getAsset('bg_Fuse', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.fuseX,
y: room2State.fuseY,
alpha: 0.5
});
game.addChild(fuse);
levelObjs.push(fuse);
// Add event listener to fuse
fuse.down = function (x, y, obj) {
if (addItemToInventory('bg_FuseItem')) {
room2State.is_fuse_found = true;
fuse.destroy();
LK.getSound('s_GetItem').play();
}
};
}
game.down = function (x, y, obj) {
if (!room2State.is_fusebox_fixed) {
centerAsset(flashlightMask, game.toLocal(obj.global).x, game.toLocal(obj.global).y);
}
};
//bring mask to top level if the fusebox is not fixed
if (!room2State.is_fusebox_fixed) {
game.setChildIndex(flashlightMask, game.children.length - 1);
game.setChildIndex(fuseboxRed, game.children.length - 1);
}
//bring in the arrow left to be able to go back to the bathroom
// Instantiate arrow left in room 2 with animation and click action to use level1()
var arrowLeft = LK.getAsset('bg_ArrowLeft', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.arrowLeftX,
y: room2State.arrowLeftY
});
game.addChild(arrowLeft);
animateUpDown(arrowLeft, 20, 1000);
arrowLeft.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
is_room2 = false;
exitRoom2(levelObjs);
level1();
};
levelObjs.push(arrowLeft);
// Bring forward inventory
bringForwardInventory();
// Bring forward the clock
bringForwardClock(clockText);
// Bring forward VCR effects
bringForwardVCR();
}
});
}
function exitRoom2(objArray) {
destroyObjects(objArray);
is_room2 = false;
stopSoundInterval();
}
function destroyObjects(objectArray) {
if (!objectArray) {
return;
} // Check if objectArray is undefined
for (var i = objectArray.length - 1; i >= 0; i--) {
if (objectArray[i]) {
objectArray[i].destroy();
}
}
objectArray.length = 0; // Clear the array
}
function unlockLock(keyAsset, lockAsset, lockAssetName, arrowAssetName, x, y) {
LK.getSound('s_UnlockSound').play();
lockAsset.destroy();
removeCollidableObjects(lockAssetName);
removeItemFromInventory(keyAsset);
var arrow = LK.getAsset(arrowAssetName, {
anchorX: 0.5,
anchorY: 0.5,
x: x,
y: y
});
return arrow;
}
function room3() {
is_room3 = true;
destroyObjects(levelObjs);
// Retrieve the 'bg_Room03' asset, position it at the center of the playspace and set its alpha to 0
var room03 = LK.getAsset('bg_Room03', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(room03);
levelObjs.push(room03);
// Fade in bg_Room03
fadeInObj(room03, 3000);
//the lorenote
var loreNote = LK.getAsset('s_DirtyLetter', {
anchorX: 0.5,
anchorY: 0.5,
x: room3State.loreNoteX,
y: room3State.loreNoteY,
alpha: 0
});
loreNote.rotation += Math.PI / 4;
game.addChild(loreNote);
levelObjs.push(loreNote);
loreNote.down = function (x, y, obj) {
defaultDownLoreTextBehaviour(loreNote2);
safeStatus.is_note2_found = true;
};
loreNote.up = function (x, y, obj) {
defaultUpLoreTextBehaviour();
};
fadeInObj(loreNote, 3000);
//WE BEGIN TO INSTANTIATE DEPENDING ON THE ROOMSTATE
//krampus lock checks, krampus lock leads to victory end
if (!room3State.is_lockKrampus_unlocked) {
var krampusLock = LK.getAsset('bg_KrampusLock', {
anchorX: 0.5,
anchorY: 0.5,
x: room3State.lockKrampusX,
y: room3State.lockKrampusY,
alpha: 0
});
game.addChild(krampusLock);
levelObjs.push(krampusLock);
fadeInObj(krampusLock, 3000);
krampusLock.down = function (x, y, obj) {
shakeAsset(krampusLock);
};
addCollidableObjects(krampusLock, 'bg_KrampusLock');
}
//we instantiate the arrow
else {
var arrow = LK.getAsset('bg_ArrowUp', {
anchoseX: 0.5,
anchorY: 0.5,
x: room3State.lockKrampusX,
y: room3State.lockKrampusY,
alpha: 0
});
fadeInObj(arrow, 3000);
game.addChild(arrow);
animateUpDown(arrow, 20, 1000);
levelObjs.push(arrow);
arrow.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
stopSoundInterval();
exitRoom3();
room6();
arrow.destroy();
};
}
//creepy doll lock
if (!room3State.is_lockDoll_unlocked) {
var creepyDollLock = LK.getAsset('bg_DollLock', {
anchorX: 0.5,
anchorY: 0.5,
x: room3State.lockDollX,
y: room3State.lockDollY,
alpha: 0
});
game.addChild(creepyDollLock);
levelObjs.push(creepyDollLock);
fadeInObj(creepyDollLock, 3000);
creepyDollLock.down = function (x, y, obj) {
shakeAsset(creepyDollLock);
};
addCollidableObjects(creepyDollLock, 'bg_DollLock');
}
//else we put the arrow to go to the room
else {
var arrowLeft = LK.getAsset('bg_ArrowLeft', {
anchorX: 0.5,
anchorY: 0.5,
x: room3State.lockDollX,
y: room3State.lockDollY
});
game.addChild(arrowLeft);
animateUpDown(arrowLeft, 20, 1000);
arrowLeft.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
exitRoom3();
room5();
};
levelObjs.push(arrowLeft);
fadeInObj(arrowLeft, 3000);
}
//we instantiate the arrow right to go the christmas room
var arrowRight = LK.getAsset('bg_ArrowRight', {
anchorX: 0.5,
anchorY: 0.5,
x: room3State.arrowRightX,
y: room3State.arrowRightY
});
game.addChild(arrowRight);
animateUpDown(arrowRight, 20, 1000);
arrowRight.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
exitRoom3();
room4();
};
levelObjs.push(arrowRight);
fadeInObj(arrowRight, 3000);
//we instantiate the arrow down to go to the garage
var arrowDown = LK.getAsset('bg_ArrowDown', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.lockX,
y: room2State.lockY
});
game.addChild(arrowDown);
animateUpDown(arrowDown, 20, 1000);
arrowDown.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
exitRoom3();
room2();
};
levelObjs.push(arrowDown);
fadeInObj(arrowDown, 3000);
if (!room3State.is_collectible_found) {
var collectible = new Collectible();
collectible.x = room3State.collectibleX;
collectible.y = room3State.collectibleY;
collectible.alpha = 0;
maxAlpha = 0.5; // Set max alpha to 0.75
game.addChild(collectible);
levelObjs.push(collectible);
fadeInObjWithAlpha(collectible, 3000, maxAlpha);
collectible.down = function (x, y, obj) {
collectible.down = null;
collectibleDefaultDownBehaviour(collectible);
room3State.is_collectible_found = true;
};
}
//we instantiate the attack if if has not been done yet
if (!room3State.is_attack_done) {
var enemy = new Enemy();
var randomLaughSound = Math.random() < 0.5 ? 's_DollLaugh01' : 's_DollLaugh02';
LK.getSound(randomLaughSound).play();
LK.getSound('s_FirstDollMusic').play();
enemy.x = room3State.creepyDollX;
enemy.y = room3State.creepyDollY;
game.addChild(enemy);
room3State.is_attack_done = true;
}
// Instantiate SE_MedallionA if not found
if (!room3State.is_medallion_found) {
var medallion = LK.getAsset('SE_MedallionA', {
anchorX: 0.5,
anchorY: 0.5,
x: room3State.medallionX,
y: room3State.medallionY,
alpha: 0
});
game.addChild(medallion);
var maxAlpha = 0.75;
levelObjs.push(medallion);
fadeInObjWithAlpha(medallion, 3000, maxAlpha);
medallion.down = function (x, y, obj) {
if (addItemToInventory('SE_MedallionA')) {
medallion.destroy();
room3State.is_medallion_found = true;
LK.getSound('s_GetItem').play();
bringForwardVCR();
}
};
}
bringForwardInventory();
bringForwardClock(clockText);
bringForwardVCR();
}
function exitRoom3() {
stopSoundInterval();
destroyObjects(levelObjs);
is_room3 = false;
removeCollidableObjects('bg_DollLock');
removeCollidableObjects('bg_KrampusLock');
}
function room5() {
is_room5 = true;
var room05 = LK.getAsset('bg_Room05', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(room05);
levelObjs.push(room05);
// Fade in bg_Room05
fadeInObj(room05, 3000);
// Spawn enemies at random intervals for 6 seconds
if (!room5State.is_attack_done) {
LK.getSound('s_EncounterMusic').play();
}
//ensure that if we are entering the room after the attack but the key was not picked up then it can be taken.
if (room5State.is_attack_done) {
if (!room5State.is_key_found) {
// Instantiate krampushalfA at room5state keyX and keyY after enemy spawning
var krampusHalfA = LK.getAsset('bg_KrampusHalfKey_A', {
anchorX: 0.5,
anchorY: 0.5,
x: room5State.keyX,
y: room5State.keyY,
alpha: 0
});
game.addChild(krampusHalfA);
fadeInObj(krampusHalfA, 1000);
levelObjs.push(krampusHalfA);
// Add interaction to krampusHalfA
krampusHalfA.down = function (x, y, obj) {
if (addItemToInventory('bg_KrampusHalfKey_A')) {
removeCollidableObjects('bg_KrampusHalfKey_A');
krampusHalfA.destroy(); // Destroy krampusHalfA
room5State.is_key_found = true; // Update room5state
LK.getSound('s_GetItem').play(); // Play sound
}
};
}
// Instantiate arrowRight at room5state.arrowRightX and room5state.arrowRightY
var arrowRight = LK.getAsset('bg_ArrowRight', {
anchorX: 0.5,
anchorY: 0.5,
x: room5State.arrowRightX,
y: room5State.arrowRightY
});
game.addChild(arrowRight);
levelObjs.push(arrowRight);
animateUpDown(arrowRight, 20, 1000);
arrowRight.down = function (x, y, obj) {
exitRoom5();
LK.getSound('s_Footsteps').play();
room3();
};
}
//add collectible
if (!room5State.is_collectible_found) {
var collectible = new Collectible();
collectible.x = room5State.collectibleX;
collectible.y = room5State.collectibleY;
collectible.alpha = 0;
var maxAlpha = 0.5; // Set max alpha to 0.5
game.addChild(collectible);
levelObjs.push(collectible);
fadeInObjWithAlpha(collectible, 3000, maxAlpha);
collectible.down = function (x, y, obj) {
collectible.down = null;
collectibleDefaultDownBehaviour(collectible);
room5State.is_collectible_found = true;
};
}
//add the breakable
if (!room5State.is_breakable_found) {
var breakable = new BreakableAsset();
breakable.x = room5State.breakableX;
breakable.y = room5State.breakableY;
breakable.scaleX = 0.5;
breakable.scaleY = 0.5;
breakable.alpha = 0; // Start with alpha 0 for fade-in effect//{hC.1}
breakable.setOnBreak(function () {
room5State.is_breakable_found = true;
// Define any additional behavior when the breakable is broken
});
game.addChild(breakable);
levelObjs.push(breakable);
// Fade in the breakable object over 3 seconds
fadeInObj(breakable, 3000);
}
//add the medallion
//if we don't have all the notes then we want to have the safe to be there
var loreNote = LK.getAsset('s_DirtyLetter', {
anchorX: 0.5,
anchorY: 0.5,
x: room5State.medallionX,
y: room5State.medallionY,
alpha: 0
});
loreNote.rotation += Math.PI / 4;
game.addChild(loreNote);
levelObjs.push(loreNote);
loreNote.down = function (x, y, obj) {
defaultDownLoreTextBehaviour(loreNote3);
safeStatus.is_note3_found = true;
};
loreNote.up = function (x, y, obj) {
defaultUpLoreTextBehaviour();
};
fadeInObj(loreNote, 3000);
//ONCE WE ARE DONE INSTANTIATING, BRING FORTH THE CLOCK, INVENTORY AND VCR EFFECT.
bringForwardInventory();
bringForwardClock(clockText);
bringForwardVCR();
}
function exitRoom5() {
if (findCollidableObjects('bg_KrampusHalfKey_A')) {
removeCollidableObjects('bg_KrampusHalfKey_A');
}
console.log(collidableObjects);
is_room5 = false;
stopSoundInterval();
destroyObjects(levelObjs);
}
function room6() {
is_room6 = true;
var room06 = LK.getAsset('bg_Room06', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(room06);
levelObjs.push(room06);
// Play the same sound as in the main menu
LK.playMusic('s_SplashScreen', {
loop: true
});
// Fade in bg_Room05
fadeInObj(room06, 3000);
// Create and display the text sequence in room6
var room6Text = new Text2("", {
size: 150,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 5,
font: "bold Garamond",
align: "center"
});
room6Text.anchor.set(0.5, 0);
room6Text.x = 2048 / 2;
room6Text.y = 400;
game.addChild(room6Text);
var room6TextSequence = ["I am free!", "I am out!", "I better make sure \n I am never on the naughty list \n ever again..."];
var currentRoom6TextIndex = 0;
function displayNextRoom6Text() {
if (currentRoom6TextIndex < room6TextSequence.length) {
room6Text.setText(room6TextSequence[currentRoom6TextIndex]);
shakeText(room6Text, function () {
currentRoom6TextIndex++;
LK.setTimeout(displayNextRoom6Text, 2000);
});
} else {
var endTime = {
hours: clock.hours,
minutes: clock.minutes,
seconds: clock.seconds
};
room6Text.setText("Ending: A\nTime to completion: " + calculateLevelCompletionTime(initialClock, endTime).minutes + "m " + calculateLevelCompletionTime(initialClock, endTime).seconds + "s\nCollectibles: " + collectibleCounter + "/" + maxCollectibles);
LK.setTimeout(function () {
LK.showGameOver();
}, 4000);
}
}
displayNextRoom6Text();
pauseClock();
//ONCE WE ARE DONE INSTANTIATING, BRING FORTH THE CLOCK, INVENTORY AND VCR EFFECT.
//bringForwardInventory();
// bringForwardClock(clockText);
// clockText.fill = 0xFFFFFF; // Change clock text color to white
bringForwardVCR();
}
function exitRoom6() {
is_room6 = false;
stopSoundInterval();
destroyObjects(levelObjs);
}
function room4() {
is_room4 = true;
var room4 = LK.getAsset('bg_Room04', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(room4);
levelObjs.push(room4);
// Fade in room4
fadeInObj(room4, 3000);
var arrowLeft = LK.getAsset('bg_ArrowLeft', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.arrowLeftX,
y: room4State.arrowLeftY
});
game.addChild(arrowLeft);
animateUpDown(arrowLeft, 20, 1000);
arrowLeft.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
exitRoom4();
room3();
};
levelObjs.push(arrowLeft);
fadeInObj(arrowLeft, 3000);
//instantiate the breakables and the collectibles
if (!room4State.is_collectible_found) {
var collectible = new Collectible();
collectible.x = room4State.collectibleX;
collectible.y = room4State.collectibleY;
collectible.alpha = 0;
maxAlpha = 0.5; // Set max alpha to 0.75
game.addChild(collectible);
levelObjs.push(collectible);
fadeInObjWithAlpha(collectible, 3000, maxAlpha);
collectible.down = function (x, y, obj) {
collectible.down = null;
collectibleDefaultDownBehaviour(collectible);
room4State.is_collectible_found = true;
};
}
if (!room4State.is_breakable_found) {
var breakable = new BreakableAsset();
breakable.x = room4State.breakableX;
breakable.y = room4State.breakableY;
breakable.alpha = 0; // Start with alpha 0 for fade-in effect
breakable.setOnBreak(function () {
var collectible1 = new Collectible();
levelObjs.push(collectible1);
collectible1.down = function (x, y, obj) {
collectible1.down = null;
room4State.is_breakable_found = true;
collectibleDefaultDownBehaviour(collectible1);
};
return collectible1;
});
game.addChild(breakable);
levelObjs.push(breakable);
// Fade in the breakable object over 3 seconds
fadeInObjWithAlpha(breakable, 3000, 0.75);
}
// Instantiate krampusframe at specified coordinates
var krampusFrame = LK.getAsset('s_KrampusFrame', {
anchorX: 0.5,
// Center the anchor point
anchorY: 0.5,
// Center the anchor point
x: room4State.medallionPlaqueX,
// Use the x-coordinate from room2State
y: room4State.medallionPlaqueY,
// Use the y-coordinate from room2State
alpha: 0
});
game.addChild(krampusFrame);
levelObjs.push(krampusFrame);
fadeInObjWithAlpha(krampusFrame, 3000, 0.5);
addCollidableObjects(krampusFrame, 's_KrampusFrame');
if (room4State.is_medallionA) {
var medallionA = LK.getAsset('SE_MedallionA', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.medallionAX,
y: room4State.medallionAY,
alpha: 0
});
game.addChild(medallionA);
fadeInObj(medallionA, 3000);
levelObjs.push(medallionA);
}
if (room4State.is_medallionB) {
var medallionB = LK.getAsset('SE_MedallionB', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.medallionBX,
y: room4State.medallionBY,
alpha: 0
});
game.addChild(medallionB);
fadeInObj(medallionB, 3000);
levelObjs.push(medallionB);
}
if (room4State.is_secret_enabled) {
// Instantiate SE_QuestionMark
var questionMark = LK.getAsset('SE_QuestionMark', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.medallionPlaqueX,
y: room4State.medallionPlaqueY,
alpha: 0
});
game.addChild(questionMark);
levelObjs.push(questionMark);
fadeInObjWithAlpha(questionMark, 1000, 0.75);
// Animate SE_QuestionMark up and down
animateUpDown(questionMark, 20, 1000);
bringForwardVCR();
// Add click event to trigger room7
questionMark.down = function (x, y, obj) {
exitRoom4();
secretEnding();
};
}
// Instantiate candles using coordinates from room4State
//candle 2 should be lit from the start all the time in order to give the hint to the player that they can
//light up the candles if they have the right tools
var candle2 = LK.getAsset('bg_Candle', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle2_x,
y: room4State.candle2_y,
alpha: 0
});
game.addChild(candle2);
levelObjs.push(candle2);
fadeInObj(candle2, 3000);
var flameAboveCandle2 = LK.getAsset('bg_Flame', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle2_x,
y: room4State.candle2_y - 185,
// Position flame above the candle
alpha: 0
});
game.addChild(flameAboveCandle2);
levelObjs.push(flameAboveCandle2);
fadeInObj(flameAboveCandle2, 3000);
animateUpDown(flameAboveCandle2, 10, 500);
room4State.is_candle2_lit = true;
var candle3 = LK.getAsset('bg_Candle', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle3_x,
y: room4State.candle3_y,
alpha: 0
});
game.addChild(candle3);
levelObjs.push(candle3);
fadeInObj(candle3, 3000);
addCollidableObjects(candle3, 'bg_Candle3');
//if the candle 3 is lit, instantiate the flame.
if (room4State.is_candle3_lit) {
var flameAboveCandle3 = LK.getAsset('bg_Flame', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle3_x,
y: room4State.candle3_y - 185,
// Position flame above the candle
alpha: 0
});
game.addChild(flameAboveCandle3);
levelObjs.push(flameAboveCandle3);
fadeInObj(flameAboveCandle3, 3000);
animateUpDown(flameAboveCandle3, 10, 500);
}
//candle 4
var candle4 = LK.getAsset('bg_Candle', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle4_x,
y: room4State.candle4_y,
alpha: 0
});
game.addChild(candle4);
levelObjs.push(candle4);
fadeInObj(candle4, 3000);
addCollidableObjects(candle4, 'bg_Candle4');
if (room4State.is_candle4_lit) {
var flameAboveCandle4 = LK.getAsset('bg_Flame', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle4_x,
y: room4State.candle4_y - 185,
// Position flame above the candle
alpha: 0
});
game.addChild(flameAboveCandle4);
levelObjs.push(flameAboveCandle4);
fadeInObj(flameAboveCandle4, 3000);
animateUpDown(flameAboveCandle4, 10, 500);
}
//candle 5
var candle5 = LK.getAsset('bg_Candle', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle5_x,
y: room4State.candle5_y,
alpha: 0
});
game.addChild(candle5);
levelObjs.push(candle5);
fadeInObj(candle5, 3000);
addCollidableObjects(candle5, 'bg_Candle5');
if (room4State.is_candle5_lit) {
var flameAboveCandle5 = LK.getAsset('bg_Flame', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle5_x,
y: room4State.candle5_y - 185,
// Position flame above the candle
alpha: 0
});
game.addChild(flameAboveCandle5);
levelObjs.push(flameAboveCandle5);
fadeInObj(flameAboveCandle5, 3000);
animateUpDown(flameAboveCandle5, 10, 500);
}
// Instantiate the dollkey if it is not found
if (!room4State.is_dollKey_found) {
var dollKey = LK.getAsset('bg_DollKey', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.dollkeyX,
y: room4State.dollkeyY,
alpha: 0
});
game.addChild(dollKey);
levelObjs.push(dollKey);
fadeInObj(dollKey, 3000);
dollKey.down = function (x, y, obj) {
if (addItemToInventory('bg_DollKeyItem')) {
dollKey.destroy();
room4State.is_dollKey_found = true;
LK.getSound('s_GetItem').play();
}
};
}
if (room4State.is_possible_pick_up && room4State.is_key_found && room4State.is_candle2_lit && room4State.is_candle3_lit && room4State.is_candle4_lit && room4State.is_candle5_lit) {
var krampushalfB = LK.getAsset('bg_KrampusHalfKey_B', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.krampusHalfX,
y: room4State.krampusHalfY,
alpha: 0
});
game.addChild(krampushalfB);
levelObjs.push(krampushalfB);
fadeInObj(krampushalfB, 3000);
krampushalfB.down = function (x, y, obj) {
// Add bathroomKeyItem to the inventory
if (!addItemToInventory('bg_KrampusHalfKey_B')) {
console.log("Failed to add krampus Key Item to inventory.");
} else {
room4State.is_possible_pick_up = false;
krampushalfB.destroy();
// Play s_GetItem sound
LK.getSound('s_GetItem').play();
}
bringForwardVCR();
};
}
bringForwardInventory();
bringForwardClock(clockText);
bringForwardVCR();
}
function exitRoom4() {
stopSoundInterval();
is_room4 = false;
destroyObjects(levelObjs);
removeCollidableObjects('s_KrampusFrame');
}
//A function that allows to fade objects into the scene.
function fadeInObj(asset, time) {
tween(asset, {
alpha: 1
}, {
duration: time
});
}
function fadeInObjWithAlpha(asset, time, alpha) {
tween(asset, {
alpha: alpha
}, {
duration: time
});
}
function secretEnding() {
pauseClock();
// Destroy all game elements except the VCR effect
// Iterate over game.children and destroy all except grain and scanlines
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
if (child !== grain && child !== scanLines) {
child.destroy();
}
}
// Fade in bg_Room07 during secretEnding
var room07 = LK.getAsset('bg_Room07', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2,
alpha: 0
});
game.addChild(room07);
fadeInObj(room07, 3000);
//make sure any other music is gone and start the new one
stopSoundInterval();
playSoundEveryInterval('s_ChristmasMusic', 7500);
//instantiate krampus, make the text appear and shake
// Instantiate Krampus in the center of the playspace
var krampus = game.addChild(LK.getAsset('bg_Krampus', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2 + 1000,
alpha: 1
}));
// Add bg_ChristmasHat on top of Krampus
var christmasHat = game.addChild(LK.getAsset('bg_ChristmasHat', {
anchorX: 0.5,
anchorY: 0.5,
x: krampus.x + 75,
y: krampus.y - 1100,
// Position the hat above Krampus
alpha: 1
}));
var krampusMulledWine = game.addChild(LK.getAsset('s_MulledWine', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 + 600,
y: 2732 / 2 + 1200,
alpha: 0.75
}));
LK.getSound("s_Slurping").play;
var gameOverText = new Text2("", {
size: 150,
fill: 0xFF0000,
stroke: 0x000000,
strokeThickness: 20,
//{mD} // Increased stroke thickness for a more prominent outline
font: "bold Garamond",
align: "center"
});
var endTime = {
hours: clock.hours,
minutes: clock.minutes,
seconds: clock.seconds
};
gameOverText.anchor.set(0.5, 0.5);
gameOverText.x = 2048 / 2;
gameOverText.y = 2732 / 2 - 800;
game.addChild(gameOverText);
var gameOverTextSequence = ["Oh dear!", " You found me!", "I did not think you \n would find my lair...", " ...since it has come to this...", "...want some mulled wine?"];
var currentGameOverTextIndex = 0;
function displayNextGameOverText() {
if (currentGameOverTextIndex < gameOverTextSequence.length) {
LK.getSound('s_Slurping').play();
gameOverText.setText(gameOverTextSequence[currentGameOverTextIndex]);
shakeText(gameOverText, function () {
currentGameOverTextIndex++;
LK.setTimeout(displayNextGameOverText, 2000);
});
} else {
gameOverText.destroy();
// Display details text after the last gameOverTextSequence has displayed
var detailsText = new Text2("", {
size: 150,
fill: 0xFFFFFF,
stroke: 0x000000,
strokeThickness: 5,
font: "bold Garamond",
align: "center"
});
detailsText.anchor.set(0.5, 0);
detailsText.x = 2048 / 2;
detailsText.y = 400;
detailsText.setText("Ending: B\nTime to completion: " + calculateLevelCompletionTime(initialClock, endTime).minutes + "m " + calculateLevelCompletionTime(initialClock, endTime).seconds + "s\nCollectibles: " + collectibleCounter + "/" + maxCollectibles);
game.addChild(detailsText);
LK.getSound('s_MulledWine').play();
// Instantiate KrampusZoomedIn after Krampus fades out
var playerMulledWine = game.addChild(LK.getAsset('s_MulledWine', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5,
x: 2048 / 2,
y: 2732 / 2 + 900
}));
bringForwardVCR();
// Shake Krampus at the end of the gameOver function
shakeAsset(playerMulledWine);
LK.setTimeout(function () {
LK.showGameOver();
}, 4000);
}
}
displayNextGameOverText();
bringForwardVCR();
// End the game after 4 seconds
LK.setTimeout(function () {
LK.showGameOver();
}, 40000);
// Ensure VCR effects are on top
bringForwardVCR();
}
//----------------------------------------------------------------------------------------------------
//the update function and the game flow
//----------------------------------------------------------------------------------------------------
//the game update function that looks at the state of the game.
var enemyMax = Math.floor(Math.random() * 6) + 10; // Random number between 10 and 15
var enemyCount = 0;
game.update = function () {
// Create a new snowflake every 90 ticks only if the main menu is on
if (is_mainMenu) {
// Play either s_manscream01, s_manscream02, s_womanscream01, s_womanscream02 every 10 to 20 seconds
if (timeElapsed % (Math.floor(Math.random() * (1200 - 600 + 1)) + 600) == 0) {
addScream();
}
//have the snowflakes effect
if (LK.ticks % 90 == 0) {
createSnowflake();
}
}
// Check collision between bathroomKeyItem and bathroomLock
//actions to validate if we are in the level 1
if (is_level1) {
//check for collision between the key and the lock.
var bathroomKeyItem = findInInventory("bg_BathroomKeyItem"); // Retrieve bathroomKeyItem from inventory
var bathroomLock = findCollidableObjects('bg_BathroomLock'); // Define bathroomLock variable
if (bathroomKeyItem !== null && bathroomLock !== null && !room1State.is_unlocked) {
if (bathroomKeyItem.intersects(bathroomLock)) {
var arrow = unlockLock(bathroomKeyItem, bathroomLock, "bg_BathroomLock", 'bg_ArrowRight', bathroomLock.x, bathroomLock.y);
room1State.is_unlocked = true;
game.addChild(arrow);
animateUpDown(arrow, 20, 1000);
arrow.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
stopSoundInterval();
room2();
arrow.destroy();
};
bringForwardVCR();
// Remove bathroomKeyItem from inventory
removeItemFromInventory(bathroomKeyItem);
}
}
}
//things to keep an eye on if we are in room2
if (is_room2) {
if (LK.ticks % 90 == 0) {
createSnowflake();
}
//if the fusebox is not fixed and the fuse is found, we want to check for collision
if (!room2State.is_fusebox_fixed && room2State.is_fuse_found) {
var fuseItem = findInInventory("bg_FuseItem");
var fuseboxItem = findCollidableObjects("bg_FuseBox");
if (fuseItem !== null && fuseboxItem !== null) {
if (fuseItem.intersects(fuseboxItem)) {
room2State.is_fusebox_fixed = true; //set to true
removeCollidableObjects("bg_FuseBox"); //remove the potential collision
//remove red light
var fuseboxLight = room2State.fuseboxRed;
fuseboxLight.destroy();
room2State.fuseboxRed = null;
LK.getSound("s_FuseBoxOn").play();
//add green light
var fuseboxGreen = LK.getAsset('bg_FuseBoxGreen', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.fusebox_greenX,
y: room2State.fusebox_greenY
});
game.addChild(fuseboxGreen);
levelObjs.push(fuseboxGreen);
removeItemFromInventory(fuseItem); // Remove fuse from inventory
flashlightMask.destroy();
flashlightMask = null;
// var arrow = unlockLock(keyItem, lockItem, "bg_BathroomLock", 'bg_ArrowDown', lockItem.x, lockItem.y);
// room2State.is_unlocked = true;
var arrowUp = LK.getAsset('bg_ArrowDown', {
anchorX: 0.5,
anchorY: 0.5,
x: room2State.lockX,
y: room2State.lockY
});
game.addChild(arrowUp);
levelObjs.push(arrowUp);
animateUpDown(arrowUp, 20, 1000);
arrowUp.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
stopSoundInterval();
exitRoom2(levelObjs);
room3();
arrowUp.destroy();
};
bringForwardVCR();
}
}
}
}
//collision checks for the various collidable items in the hallway
if (is_room3) {
if (is_gameover) {
destroyObjects(levelObjs);
}
//try to get the keys and the locks from the inventory and the collidable items in the scene
var krampusKeyItem = findInInventory("bg_KrampusKey");
var krampusLock = findCollidableObjects('bg_KrampusLock');
var dollKey = findInInventory("bg_DollKeyItem");
var dollLock = findCollidableObjects('bg_DollLock');
//do collision checks on each valid combo of lock and key if they are present
//krampus lock and key checks.
if (krampusKeyItem !== null && krampusLock !== null && !room3State.is_lockKrampus_unlocked) {
if (krampusKeyItem.intersects(krampusLock)) {
var arrow = unlockLock(krampusKeyItem, krampusLock, "bg_KrampusLock", 'bg_ArrowUp', krampusLock.x, krampusLock.y);
room3State.is_lockKrampus_unlocked = true;
game.addChild(arrow);
animateUpDown(arrow, 20, 1000);
levelObjs.push(arrow);
arrow.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
stopSoundInterval();
exitRoom3();
room6();
arrow.destroy();
};
bringForwardVCR();
// Remove bathroomKeyItem from inventory
removeItemFromInventory(krampusKeyItem);
}
}
//doll lock check
if (dollKey !== null && dollLock !== null && !room3State.is_lockDoll_unlocked) {
if (dollKey.intersects(dollLock)) {
var arrow = unlockLock(dollKey, dollLock, "bg_DollLock", 'bg_ArrowLeft', dollLock.x, dollLock.y);
room3State.is_lockDoll_unlocked = true;
game.addChild(arrow);
animateUpDown(arrow, 20, 1000);
arrow.down = function (x, y, obj) {
LK.getSound('s_Footsteps').play();
stopSoundInterval();
exitRoom3();
room5();
arrow.destroy();
};
bringForwardVCR();
// Remove bathroomKeyItem from inventory
removeItemFromInventory(dollKey);
}
}
}
//collision checks for the items in the room 4 (christmas tree and candle puzzle)
if (is_room4) {
var lighter = findInInventory('bg_LighterItem');
var candle3 = findCollidableObjects('bg_Candle3');
var candle4 = findCollidableObjects('bg_Candle4');
var candle5 = findCollidableObjects('bg_Candle5');
var frame = findCollidableObjects('s_KrampusFrame');
var medallionA = findInInventory('SE_MedallionA');
var medallionB = findInInventory('SE_MedallionB');
//check for medallionA
if (medallionA && frame) {
if (medallionA.intersects(frame)) {
removeItemFromInventory(medallionA);
room4State.is_medallionA = true;
//add the medallion on the frame
var medallionOnFrame = LK.getAsset('SE_MedallionA', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.medallionAX,
y: room4State.medallionAY,
alpha: 0
});
game.addChild(medallionOnFrame);
levelObjs.push(medallionOnFrame);
fadeInObj(medallionOnFrame, 1000);
bringForwardVCR();
LK.getSound('s_Appear').play();
// Create particles effect
for (var i = 0; i < 20; i++) {
var offsetX = Math.random() * 100 - 50; // Random offset between -50 and 50
var offsetY = Math.random() * 100 - 100; // Random offset between -50 and 50
var particles = LK.getAsset('bg_Snowflake', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.medallionAX + offsetX,
y: room4State.medallionAY + offsetY,
alpha: 1
});
levelObjs.push(particles);
game.addChild(particles);
tween(particles, {
alpha: 0
}, {
duration: 3000,
onFinish: function onFinish() {
particles.destroy();
}
});
}
}
}
//check for medallionB
if (medallionB && frame) {
if (medallionB.intersects(frame)) {
removeItemFromInventory(medallionB);
room4State.is_medallionB = true;
//add the medallion on the frame
var medallionOnFrame = LK.getAsset('SE_MedallionB', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.medallionBX,
y: room4State.medallionBY,
alpha: 0
});
game.addChild(medallionOnFrame);
levelObjs.push(medallionOnFrame);
fadeInObj(medallionOnFrame, 1000);
bringForwardVCR();
LK.getSound('s_Appear').play();
// Create particles effect
for (var i = 0; i < 20; i++) {
var offsetX = Math.random() * 100 - 50; // Random offset between -50 and 50
var offsetY = Math.random() * 100 - 100; // Random offset between -50 and 50
var particles = LK.getAsset('bg_Snowflake', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.medallionBX + offsetX,
y: room4State.medallionBY + offsetY,
alpha: 1
});
levelObjs.push(particles);
game.addChild(particles);
tween(particles, {
alpha: 0
}, {
duration: 3000,
onFinish: function onFinish() {
particles.destroy();
}
});
}
}
}
//check for both being put
if (room4State.is_medallionA && room4State.is_medallionB && !room4State.is_secret_enabled) {
room4State.is_secret_enabled = true;
// Instantiate SE_QuestionMark
var questionMark = LK.getAsset('SE_QuestionMark', {
anchorX: 0.5,
anchorY: 0.5,
x: frame.x,
y: frame.y,
alpha: 0
});
game.addChild(questionMark);
levelObjs.push(questionMark);
fadeInObjWithAlpha(questionMark, 1000, 0.75);
// Animate SE_QuestionMark up and down
animateUpDown(questionMark, 20, 1000);
bringForwardVCR();
// Add click event to trigger room7
questionMark.down = function (x, y, obj) {
exitRoom4();
secretEnding();
};
}
//check state and collision for candle3
if (lighter && !room4State.is_candle3_lit && candle3) {
if (lighter.intersects(candle3)) {
LK.getSound('s_Extinguished').play();
room4State.is_candle3_lit = true;
//then we instantiate the flame on top of it with the animation
var flameAboveCandle3 = LK.getAsset('bg_Flame', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle3_x,
y: room4State.candle3_y - 185,
// Position flame above the candle
alpha: 0
});
game.addChild(flameAboveCandle3);
levelObjs.push(flameAboveCandle3);
fadeInObj(flameAboveCandle3, 1500);
animateUpDown(flameAboveCandle3, 10, 500);
bringForwardVCR();
}
}
//check state and collision for candle4
if (lighter && !room4State.is_candle4_lit && candle4) {
if (lighter.intersects(candle4)) {
LK.getSound('s_Extinguished').play();
room4State.is_candle4_lit = true;
//then we instantiate the flame on top of it with the animation
var flameAboveCandle4 = LK.getAsset('bg_Flame', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle4_x,
y: room4State.candle4_y - 185,
// Position flame above the candle
alpha: 0
});
game.addChild(flameAboveCandle4);
levelObjs.push(flameAboveCandle4);
fadeInObj(flameAboveCandle4, 1500);
animateUpDown(flameAboveCandle4, 10, 500);
bringForwardVCR();
}
}
//check state and collision for candle5
if (lighter && !room4State.is_candle5_lit && candle5) {
if (lighter.intersects(candle5)) {
LK.getSound('s_Extinguished').play();
room4State.is_candle5_lit = true;
//then we instantiate the flame on top of it with the animation
var flameAboveCandle5 = LK.getAsset('bg_Flame', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.candle5_x,
y: room4State.candle5_y - 185,
// Position flame above the candle
alpha: 0
});
game.addChild(flameAboveCandle5);
levelObjs.push(flameAboveCandle5);
fadeInObj(flameAboveCandle5, 1500);
animateUpDown(flameAboveCandle5, 10, 500);
bringForwardVCR();
}
}
// Check if all candles are lit
if (!room4State.is_key_found && room4State.is_candle2_lit && room4State.is_candle3_lit && room4State.is_candle4_lit && room4State.is_candle5_lit) {
removeItemFromInventory(lighter); // Destroy the lighter
room4State.is_key_found = true;
room4State.is_possible_pick_up = true;
// Instantiate the doll key
var krampusHalfB_item = LK.getAsset('bg_KrampusHalfKey_B', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.krampusHalfX,
y: room4State.krampusHalfY,
alpha: 0
});
game.addChild(krampusHalfB_item);
levelObjs.push(krampusHalfB_item);
fadeInObj(krampusHalfB_item, 1000);
bringForwardVCR();
LK.getSound('s_Appear').play();
// Create particles effect
for (var i = 0; i < 20; i++) {
var offsetX = Math.random() * 100 - 50; // Random offset between -50 and 50
var offsetY = Math.random() * 100 - 100; // Random offset between -50 and 50
var particles = LK.getAsset('bg_Snowflake', {
anchorX: 0.5,
anchorY: 0.5,
x: room4State.krampusHalfX + offsetX,
y: room4State.krampusHalfY + offsetY,
alpha: 1
});
levelObjs.push(particles);
game.addChild(particles);
tween(particles, {
alpha: 0
}, {
duration: 3000,
onFinish: function onFinish() {
particles.destroy();
}
});
}
krampusHalfB_item.down = function (x, y, obj) {
// Add bathroomKeyItem to the inventory
if (!addItemToInventory('bg_KrampusHalfKey_B')) {
console.log("Failed to add Doll Key Item to inventory.");
} else {
room4State.is_possible_pick_up = false;
// Destroy the dollKey when clicked
krampusHalfB_item.destroy();
// Play s_GetItem sound
LK.getSound('s_GetItem').play();
}
bringForwardVCR();
};
levelObjs.push(krampusHalfB_item);
}
}
if (is_room5) {
if (is_gameover) {
destroyObjects(levelObjs);
}
if (!room5State.is_attack_done && !is_gameover) {
if (LK.ticks % 90 == 0 || LK.ticks % 60 == 0) {
if (enemyCount < enemyMax) {
var enemyType = Math.random() < 0.5 ? 'bg_Doll01' : 'bg_Doll02';
var enemy = new Enemy(enemyType);
enemy.x = Math.random() * 2048;
enemy.y = Math.random() * (inventoryCoordY - 1366) + 1366 - 250;
game.addChild(enemy);
bringForwardVCR();
enemyCount++;
//if we are now at enemyCount16 it means the attack is now done.
if (enemyCount == enemyMax) {
room5State.is_attack_done = true;
LK.setTimeout(function () {
var arrowRight = LK.getAsset('bg_ArrowRight', {
anchorX: 0.5,
anchorY: 0.5,
x: room5State.arrowRightX,
y: room5State.arrowRightY
});
game.addChild(arrowRight);
levelObjs.push(arrowRight);
animateUpDown(arrowRight, 20, 1000);
arrowRight.down = function (x, y, obj) {
exitRoom5();
LK.getSound('s_Footsteps').play();
room3();
};
levelObjs.push(arrowRight);
// Instantiate krampushalfA at room5state keyX and keyY after enemy spawning
var krampusHalfA = LK.getAsset('bg_KrampusHalfKey_A', {
anchorX: 0.5,
anchorY: 0.5,
x: room5State.keyX,
y: room5State.keyY,
alpha: 0
});
game.addChild(krampusHalfA);
fadeInObj(krampusHalfA, 1000);
bringForwardVCR();
levelObjs.push(krampusHalfA);
LK.getSound('s_Appear').play();
// Create particles effect
for (var i = 0; i < 20; i++) {
var offsetX = Math.random() * 100 - 50; // Random offset between -50 and 50
var offsetY = Math.random() * 100 - 100; // Random offset between -50 and 50
var particles = LK.getAsset('bg_Snowflake', {
anchorX: 0.5,
anchorY: 0.5,
x: room5State.keyX + offsetX,
y: room5State.keyY + offsetY,
alpha: 1
});
levelObjs.push(particles);
game.addChild(particles);
tween(particles, {
alpha: 0
}, {
duration: 3000,
onFinish: function onFinish() {
particles.destroy();
}
});
}
addCollidableObjects(krampusHalfA, 'bg_KrampusHalfKey_A');
bringForwardVCR();
// Add interaction to krampusHalfA
krampusHalfA.down = function (x, y, obj) {
if (addItemToInventory('bg_KrampusHalfKey_A')) {
krampusHalfA.destroy(); // Destroy krampusHalfA
removeCollidableObjects('bg_KrampusHalfKey_A');
// Add to inventory
room5State.is_key_found = true; // Update room5state
LK.getSound('s_GetItem').play(); // Play sound
bringForwardVCR();
}
};
}, 2000); //end of the set timeout
}
}
}
}
}
if (is_flickerState) {
// If the state is true, set the alpha to 0.5
eyeFlash.alpha = 0.20;
} else {
// If the state is false, set the alpha to 0
eyeFlash.alpha = 0;
}
// Flip the state of the flicker
is_flickerState = !is_flickerState;
// Increment the time elapsed every tick
timeElapsed++;
// Check if the clock reaches 12:00:00
if (clock.hours === 12 && clock.minutes === 0 && clock.seconds === 0) {
gameOver();
}
//at any point in the game, check for the krampus halfA and krampushalfB and validate if the
//player is trying to combine the keys.
var krampusHalfA = findInInventory('bg_KrampusHalfKey_A');
var krampusHalfB = findInInventory('bg_KrampusHalfKey_B');
if (krampusHalfA && krampusHalfB) {
if (krampusHalfA.intersects(krampusHalfB)) {
console.log("Collision detected between krampushalfA and krampushalfB");
LK.getSound('s_GetItem').play();
// Remove both halves from inventory
removeItemFromInventory(krampusHalfA);
removeItemFromInventory(krampusHalfB);
// Add krampuskey to inventory
addItemToInventory('bg_KrampusKey');
}
}
};
//the game flow starts here
loadMenu();
// Call the vcr function to initialize bg_Grain and bg_ScanLine
vcr();
// Method to set what is instantiated when the breakable item is clicked
BreakableAsset.prototype.setOnBreak = function (callback) {
this.onBreak = callback;
};
Eerie Christmas-inspired toy shop The only text on screen should be the title "Krampus Lockdown" centered on the image.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a single cartoon snowflake. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple eerie christmas blank dirty ripped paper. Use christmas colors. Do not put text, just the dirty ripped paper so i can fill it myself with text. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. No text.
A heavily grainy screen filled with analog noise, washed-out colors, subtle scratches on the film, and a worn, nostalgic texture.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
horizontal scan lines, slightly distorted colors, subtle static noise, and faint glow around edges.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
bloody christmas elf glove tapping at screen clipart. Just the glove. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
the number 13 written in black. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
black gothic frame with a question mark inside silhouette. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple dirty, dark and eerie Christmas clown key. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
the number 28 written in black, make the numbers eerie. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
the number 7 written in black, make the numbers eerie. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
the number 0 written in black, make the numbers eerie. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Eerie Christmas-inspired room similar to a resident evil room Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Eerie Christmas-inspired bathroom similar to a resident evil room Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a cartoon envelope with an toy elf on it holding a questionmark. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple dirty, dark and eerie Christmas bathroom key. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
eerie christmas inspired krampus lock with a resident evil style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
eerie christmas inspired button as an arrow pointing right that says SKIP in a creepy font png. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Eerie Christmas-inspired garage similar to a resident evil room Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple fuse inspired from a resident evil puzzle graphics Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
an eerie wall fusebox Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Eerie Christmas-inspired hallway similar to a resident evil room Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
eerie creepy old rusty key with krampus face embossed on it png. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple dirty, dark and eerie Christmas bathroom key. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
eerie christmas inspired mistletoe lock with a resident evil style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
eerie christmas inspired tree lock with a resident evil style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple dirty, dark and eerie Christmas light key. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
eerie christmas inspired christmas light lock with a resident evil style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
eerie christmas inspired lump of coal with a resident evil style. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Eerie flame similar to a resident evil asset, realistic Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Eerie Christmas-inspired krampus statuette similar to a resident evil asset Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple eerie christmas blank dirty letter envelope. Use christmas colors. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. No text.
Eerie Christmas-inspired crypt room similar to a resident evil room Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
a simple dark red cartoon christmas hat Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. No text.
cartoon mulled wine. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
cartoon christmas inspired question mark Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
krampus with a christmas hat coin embossed on it png. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
mulled wine coin embossed on it png. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Eerie Christmas-inspired krampus doll sitting similar to a resident evil Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
old safe png grey with four buttons on the side. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
s_KrampusLaugh01
Sound effect
s_SplashScreen
Sound effect
s_KrampusLaugh02
Sound effect
s_WomanScream01
Sound effect
s_ManScream01
Sound effect
s_ManScream02
Sound effect
s_WomanScream02
Sound effect
s_LightBuzz
Sound effect
s_ShutdownSound
Sound effect
s_CrumpledPaper
Sound effect
s_Bathroom
Sound effect
s_GameOver
Sound effect
s_CartoonRun
Sound effect
s_GetItem
Sound effect
s_KrampusScream
Sound effect
s_UnlockSound
Sound effect
s_WindBlow
Sound effect
s_FuseBoxOn
Sound effect
s_GeneratorSound
Sound effect
s_Locked
Sound effect
s_Interior
Sound effect
s_DollDeath
Sound effect
s_Footsteps
Sound effect
s_DollLaugh01
Sound effect
s_DollLaugh02
Sound effect
s_DollDeath01
Sound effect
s_DollDeath02
Sound effect
s_EncounterMusic
Sound effect
s_FirstDollMusic
Sound effect
s_ChristmasMusic
Sound effect
s_BreakingSound
Sound effect
s_Collected
Sound effect
s_Extinguished
Sound effect
s_Appear
Sound effect
s_MulledWine
Sound effect
s_Slurping
Sound effect
s_SafeUnlocked
Sound effect
s_LockedSafe
Sound effect