/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Boss = Container.expand(function (level) { var self = Container.call(this); var graphics = self.attachAsset('bossChristian', { anchorX: 0.5, anchorY: 0.5 }); self.level = level || 1; self.maxHealth = 3 + level; self.health = self.maxHealth; self.speed = 2 + level * 0.5; self.direction = Math.random() * Math.PI * 2; self.attackTimer = 0; self.attackCooldown = 2000; // 2 seconds self.isDead = false; self.chargeAttacking = false; self.chargeSpeed = 12; // Health bar var healthBarBg = self.addChild(LK.getAsset('shape', { width: 120, height: 20, color: 0x660000, shape: 'box', anchorX: 0.5, anchorY: 0.5, y: -100 })); var healthBar = self.addChild(LK.getAsset('shape', { width: 120, height: 16, color: 0xff0000, shape: 'box', anchorX: 0.5, anchorY: 0.5, y: -100 })); self.updateHealthBar = function () { var healthPercent = self.health / self.maxHealth; healthBar.width = 120 * healthPercent; }; self.update = function () { if (self.isDead) return; self.attackTimer += 16.67; // Boss AI behavior if (self.chargeAttacking) { // Charge attack - move fast towards player var deltaX = player.x - self.x; var deltaY = player.y - self.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance > 10) { self.direction = Math.atan2(deltaY, deltaX); var newX = self.x + Math.cos(self.direction) * self.chargeSpeed; var newY = self.y + Math.sin(self.direction) * self.chargeSpeed; // Keep within bounds self.x = Math.max(shipBounds.left + 75, Math.min(shipBounds.right - 75, newX)); self.y = Math.max(shipBounds.top + 75, Math.min(shipBounds.bottom - 75, newY)); } // End charge attack after 1 second if (self.attackTimer >= 1000) { self.chargeAttacking = false; self.attackTimer = 0; } } else if (self.attackTimer >= self.attackCooldown) { // Start charge attack self.chargeAttacking = true; self.attackTimer = 0; LK.effects.flashObject(self, 0xffff00, 500); } else { // Normal movement - slower patrol var deltaX = player.x - self.x; var deltaY = player.y - self.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); if (distance > 200) { // Move towards player if far away self.direction = Math.atan2(deltaY, deltaX); } else { // Random movement when close if (Math.random() < 0.02) { self.direction = Math.random() * Math.PI * 2; } } var newX = self.x + Math.cos(self.direction) * self.speed; var newY = self.y + Math.sin(self.direction) * self.speed; // Bounce off boundaries if (newX < shipBounds.left + 75 || newX > shipBounds.right - 75) { self.direction = Math.PI - self.direction; } if (newY < shipBounds.top + 75 || newY > shipBounds.bottom - 75) { self.direction = -self.direction; } // Keep within bounds self.x = Math.max(shipBounds.left + 75, Math.min(shipBounds.right - 75, newX)); self.y = Math.max(shipBounds.top + 75, Math.min(shipBounds.bottom - 75, newY)); } }; self.takeDamage = function () { if (self.isDead) return false; self.health--; self.updateHealthBar(); LK.effects.flashObject(self, 0xffffff, 300); if (self.health <= 0) { self.isDead = true; LK.setScore(LK.getScore() + 500); LK.getSound('faithVictory').play(); scoreTxt.setText('Score: ' + LK.getScore()); return true; } return false; }; return self; }); var Christian = Container.expand(function (colorAsset) { var self = Container.call(this); var graphics = self.attachAsset(colorAsset || 'christian', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4; self.direction = Math.random() * Math.PI * 2; self.changeDirectionTimer = 0; self.isIdentified = false; self.update = function () { if (self.isIdentified) return; // Calculate direction towards player var deltaX = player.x - self.x; var deltaY = player.y - self.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Only chase if player is alive and within reasonable distance if (player.isAlive && distance > 10) { // Calculate angle towards player self.direction = Math.atan2(deltaY, deltaX); // Add some randomness to make movement less predictable var randomOffset = (Math.random() - 0.5) * 0.3; self.direction += randomOffset; } // Move in current direction var newX = self.x + Math.cos(self.direction) * self.speed; var newY = self.y + Math.sin(self.direction) * self.speed; // Bounce off ship boundaries if (newX < shipBounds.left + 40 || newX > shipBounds.right - 40) { self.direction = Math.PI - self.direction; } if (newY < shipBounds.top + 40 || newY > shipBounds.bottom - 40) { self.direction = -self.direction; } // Keep within bounds self.x = Math.max(shipBounds.left + 40, Math.min(shipBounds.right - 40, newX)); self.y = Math.max(shipBounds.top + 40, Math.min(shipBounds.bottom - 40, newY)); }; return self; }); var Mosque = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('mosque', { anchorX: 0.5, anchorY: 0.5 }); self.isCompleted = false; return self; }); var Muslim = Container.expand(function () { var self = Container.call(this); var graphics = self.attachAsset('muslim', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.isAlive = true; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ // Game variables var player; var christians = []; var mosques = []; var mosqueArea = {}; var gameState = 'playing'; // 'playing', 'praying', 'roundEnd' var roundNumber = 1; var prayersCompleted = 0; var prayingTimer = 0; var prayingDuration = 5000; // 5 seconds for praying var dragNode = null; // Missing variables that are referenced in the code var shipBounds = {}; var impostors = []; var taskStations = []; var tasksCompleted = 0; // Level system variables var currentLevel = 1; var maxLevel = 4; var currentBoss = null; var levelNames = ['Main Mosque', 'Prayer Hall', 'Minaret', 'Sacred Courtyard']; var levelBackgrounds = ['courtyard', 'mainMosque', 'prayerHall', 'minaret']; var currentMosque = null; var isLevelTransition = false; var levelTransitionDuration = 8000; // 8 seconds pause between levels var isLevelCompleted = false; // UI Elements var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var gameStateTxt = new Text2('Visit mosques to pray and avoid the pursuers!', { size: 60, fill: 0xFFFF00 }); gameStateTxt.anchor.set(0.5, 0); gameStateTxt.y = 100; LK.gui.top.addChild(gameStateTxt); var roundTxt = new Text2('Round 1', { size: 70, fill: 0x00FFFF }); roundTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(roundTxt); roundTxt.x = 120; // Avoid the menu icon var levelTxt = new Text2('Level 1: Main Mosque', { size: 60, fill: 0xff9900 }); levelTxt.anchor.set(0, 0); levelTxt.y = 80; LK.gui.topLeft.addChild(levelTxt); levelTxt.x = 120; var levelTransitionTxt = new Text2('', { size: 120, fill: 0xffff00 }); levelTransitionTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(levelTransitionTxt); levelTransitionTxt.alpha = 0; // Continue button for level completion var continueBtn = new Text2('CONTINUE', { size: 100, fill: 0x00ff00 }); continueBtn.anchor.set(0.5, 0.5); continueBtn.y = 200; LK.gui.center.addChild(continueBtn); continueBtn.alpha = 0; continueBtn.interactive = true; // Create level background function createLevelBackground() { if (currentMosque && currentMosque.parent) { currentMosque.destroy(); } var backgroundAsset = levelBackgrounds[currentLevel - 1] || 'courtyard'; currentMosque = game.attachAsset(backgroundAsset, { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); // Update mosque boundaries after creating new background mosqueArea = { left: currentMosque.x - currentMosque.width / 2, right: currentMosque.x + currentMosque.width / 2, top: currentMosque.y - currentMosque.height / 2, bottom: currentMosque.y + currentMosque.height / 2 }; // Create fresh mosques for the new level createMosques(); } createLevelBackground(); // Set mosque boundaries mosqueArea = { left: currentMosque.x - currentMosque.width / 2, right: currentMosque.x + currentMosque.width / 2, top: currentMosque.y - currentMosque.height / 2, bottom: currentMosque.y + currentMosque.height / 2 }; // Initialize shipBounds to match mosqueArea shipBounds = { left: mosqueArea.left, right: mosqueArea.right, top: mosqueArea.top, bottom: mosqueArea.bottom }; // Create player player = game.addChild(new Muslim()); player.x = 1024; player.y = 1600; // Create mosques function createMosques() { // Destroy existing mosques first for (var i = 0; i < mosques.length; i++) { if (mosques[i].parent) { mosques[i].destroy(); } } mosques = []; var positions = [{ x: 400, y: 800 }, { x: 1600, y: 800 }, { x: 800, y: 1000 }, { x: 1200, y: 1000 }, { x: 600, y: 1200 }]; for (var i = 0; i < positions.length; i++) { var mosque = game.addChild(new Mosque()); mosque.x = positions[i].x; mosque.y = positions[i].y; mosque.isCompleted = false; // Ensure mosque starts uncompleted mosques.push(mosque); } } // Create boss for boss rounds function createBoss() { if (currentBoss && currentBoss.parent) { currentBoss.destroy(); } currentBoss = game.addChild(new Boss(currentLevel)); currentBoss.x = 1024; currentBoss.y = 800; } // Create Christians for current round function createChristians() { christians = []; // Boss levels (every 3rd round) have boss instead of regular Christians if (roundNumber % 3 === 0) { createBoss(); return; // No regular Christians on boss rounds } var christianCount = Math.min(roundNumber + 1, 4); var colors = ['christian', 'christian2', 'christian3', 'christian']; for (var i = 0; i < christianCount; i++) { var christian = game.addChild(new Christian(colors[i % colors.length])); christian.x = mosqueArea.left + 100 + Math.random() * (mosqueArea.right - mosqueArea.left - 200); christian.y = mosqueArea.top + 100 + Math.random() * (mosqueArea.bottom - mosqueArea.top - 200); christian.speed = 4 + roundNumber * 0.8; christians.push(christian); } // Set impostors to reference christians for compatibility impostors = christians; // Set taskStations to reference mosques for compatibility taskStations = mosques; } // Initialize first round createMosques(); createChristians(); // Start level transition with pause function startLevelTransition() { isLevelTransition = true; isLevelCompleted = true; gameState = 'levelCompleted'; // Show level completion text levelTransitionTxt.setText('Level ' + (currentLevel - 1) + ' Complete!'); tween(levelTransitionTxt, { alpha: 1 }, { duration: 1000, onFinish: function onFinish() { // Show continue button after text appears tween(continueBtn, { alpha: 1, scaleX: 1.1, scaleY: 1.1 }, { duration: 800, easing: tween.easeOut }); } }); } // Handle continue button click continueBtn.down = function (x, y, obj) { if (isLevelCompleted) { // Fade out completion UI tween(levelTransitionTxt, { alpha: 0 }, { duration: 500 }); tween(continueBtn, { alpha: 0, scaleX: 1.0, scaleY: 1.0 }, { duration: 500, onFinish: function onFinish() { isLevelCompleted = false; isLevelTransition = false; // Continue from level completion gameState = 'playing'; continueNextRound(); } }); } }; // Continue next round after transition function continueNextRound() { prayersCompleted = 0; // Reset prayers completed for new round roundTxt.setText('Round ' + roundNumber); // Clean up old christians for (var i = 0; i < christians.length; i++) { if (christians[i].parent) { christians[i].destroy(); } } // Clean up boss if (currentBoss && currentBoss.parent) { currentBoss.destroy(); currentBoss = null; } // Reset mosques for (var i = 0; i < mosques.length; i++) { mosques[i].isCompleted = false; if (mosques[i].tint !== undefined) { mosques[i].tint = 0xffffff; } } // Create new christians or boss createChristians(); // Update game state text based on round type if (roundNumber % 3 === 0) { gameStateTxt.setText('BOSS ROUND ' + roundNumber + ' - Complete prayers and prepare for final confrontation!'); } else { gameStateTxt.setText('Round ' + roundNumber + ' - Complete prayers and avoid the pursuers!'); } // Flash screen to indicate new round LK.effects.flashScreen(0x0000ff, 500); } // Start next round function startNextRound() { roundNumber++; tasksCompleted = 0; prayersCompleted = 0; // Reset prayers completed for new round // Level progression every 3 rounds if (roundNumber % 3 === 1 && roundNumber > 1) { currentLevel = Math.min(currentLevel + 1, maxLevel); createLevelBackground(); levelTxt.setText('Level ' + currentLevel + ': ' + levelNames[currentLevel - 1]); LK.getSound('levelComplete').play(); // Start level completion screen instead of immediately continuing startLevelTransition(); return; // Exit early, transition will handle the rest } roundTxt.setText('Round ' + roundNumber); // Clean up old christians for (var i = 0; i < christians.length; i++) { if (christians[i].parent) { christians[i].destroy(); } } // Clean up boss if (currentBoss && currentBoss.parent) { currentBoss.destroy(); currentBoss = null; } // Reset mosques for (var i = 0; i < mosques.length; i++) { mosques[i].isCompleted = false; if (mosques[i].tint !== undefined) { mosques[i].tint = 0xffffff; } } // Create new christians or boss createChristians(); gameState = 'playing'; // Update game state text based on round type if (roundNumber % 3 === 0) { gameStateTxt.setText('BOSS ROUND ' + roundNumber + ' - Complete prayers and prepare for final confrontation!'); } else { gameStateTxt.setText('Round ' + roundNumber + ' - Complete prayers and avoid the pursuers!'); } // Flash screen to indicate new round LK.effects.flashScreen(0x0000ff, 500); } // Handle player movement function handleMove(x, y, obj) { if (dragNode && player.isAlive && gameState === 'playing') { var newX = Math.max(shipBounds.left + 40, Math.min(shipBounds.right - 40, x)); var newY = Math.max(shipBounds.top + 40, Math.min(shipBounds.bottom - 40, y)); dragNode.x = newX; dragNode.y = newY; } } game.move = handleMove; game.down = function (x, y, obj) { if (player.isAlive && gameState === 'playing') { dragNode = player; handleMove(x, y, obj); } }; game.up = function (x, y, obj) { dragNode = null; }; // Main game update loop game.update = function () { if (!player.isAlive) return; // Skip game logic during level transition or completion if (isLevelTransition || gameState === 'transition' || gameState === 'levelCompleted') { return; } if (gameState !== 'playing') return; // Check collisions with christians (only non-identified ones) for (var i = 0; i < christians.length; i++) { if (!christians[i].isIdentified && player.intersects(christians[i])) { // Player caught by christian player.isAlive = false; LK.effects.flashScreen(0xff0000, 1500); LK.getSound('elimination').play(); LK.showGameOver(); return; } } // Check collision with boss if (currentBoss && !currentBoss.isDead && player.intersects(currentBoss)) { // Player caught by boss player.isAlive = false; LK.effects.flashScreen(0xff0000, 1500); LK.getSound('elimination').play(); LK.showGameOver(); return; } // Check mosque prayer completion for (var i = 0; i < mosques.length; i++) { var mosque = mosques[i]; if (!mosque.isCompleted && player.intersects(mosque)) { mosque.isCompleted = true; if (mosque.tint !== undefined) { mosque.tint = 0x00ff00; } prayersCompleted++; LK.setScore(LK.getScore() + 50); LK.getSound('taskComplete').play(); scoreTxt.setText('Score: ' + LK.getScore()); // Check if all prayers completed if (prayersCompleted >= mosques.length) { startNextRound(); } } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Boss = Container.expand(function (level) {
var self = Container.call(this);
var graphics = self.attachAsset('bossChristian', {
anchorX: 0.5,
anchorY: 0.5
});
self.level = level || 1;
self.maxHealth = 3 + level;
self.health = self.maxHealth;
self.speed = 2 + level * 0.5;
self.direction = Math.random() * Math.PI * 2;
self.attackTimer = 0;
self.attackCooldown = 2000; // 2 seconds
self.isDead = false;
self.chargeAttacking = false;
self.chargeSpeed = 12;
// Health bar
var healthBarBg = self.addChild(LK.getAsset('shape', {
width: 120,
height: 20,
color: 0x660000,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5,
y: -100
}));
var healthBar = self.addChild(LK.getAsset('shape', {
width: 120,
height: 16,
color: 0xff0000,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5,
y: -100
}));
self.updateHealthBar = function () {
var healthPercent = self.health / self.maxHealth;
healthBar.width = 120 * healthPercent;
};
self.update = function () {
if (self.isDead) return;
self.attackTimer += 16.67;
// Boss AI behavior
if (self.chargeAttacking) {
// Charge attack - move fast towards player
var deltaX = player.x - self.x;
var deltaY = player.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 10) {
self.direction = Math.atan2(deltaY, deltaX);
var newX = self.x + Math.cos(self.direction) * self.chargeSpeed;
var newY = self.y + Math.sin(self.direction) * self.chargeSpeed;
// Keep within bounds
self.x = Math.max(shipBounds.left + 75, Math.min(shipBounds.right - 75, newX));
self.y = Math.max(shipBounds.top + 75, Math.min(shipBounds.bottom - 75, newY));
}
// End charge attack after 1 second
if (self.attackTimer >= 1000) {
self.chargeAttacking = false;
self.attackTimer = 0;
}
} else if (self.attackTimer >= self.attackCooldown) {
// Start charge attack
self.chargeAttacking = true;
self.attackTimer = 0;
LK.effects.flashObject(self, 0xffff00, 500);
} else {
// Normal movement - slower patrol
var deltaX = player.x - self.x;
var deltaY = player.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if (distance > 200) {
// Move towards player if far away
self.direction = Math.atan2(deltaY, deltaX);
} else {
// Random movement when close
if (Math.random() < 0.02) {
self.direction = Math.random() * Math.PI * 2;
}
}
var newX = self.x + Math.cos(self.direction) * self.speed;
var newY = self.y + Math.sin(self.direction) * self.speed;
// Bounce off boundaries
if (newX < shipBounds.left + 75 || newX > shipBounds.right - 75) {
self.direction = Math.PI - self.direction;
}
if (newY < shipBounds.top + 75 || newY > shipBounds.bottom - 75) {
self.direction = -self.direction;
}
// Keep within bounds
self.x = Math.max(shipBounds.left + 75, Math.min(shipBounds.right - 75, newX));
self.y = Math.max(shipBounds.top + 75, Math.min(shipBounds.bottom - 75, newY));
}
};
self.takeDamage = function () {
if (self.isDead) return false;
self.health--;
self.updateHealthBar();
LK.effects.flashObject(self, 0xffffff, 300);
if (self.health <= 0) {
self.isDead = true;
LK.setScore(LK.getScore() + 500);
LK.getSound('faithVictory').play();
scoreTxt.setText('Score: ' + LK.getScore());
return true;
}
return false;
};
return self;
});
var Christian = Container.expand(function (colorAsset) {
var self = Container.call(this);
var graphics = self.attachAsset(colorAsset || 'christian', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4;
self.direction = Math.random() * Math.PI * 2;
self.changeDirectionTimer = 0;
self.isIdentified = false;
self.update = function () {
if (self.isIdentified) return;
// Calculate direction towards player
var deltaX = player.x - self.x;
var deltaY = player.y - self.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Only chase if player is alive and within reasonable distance
if (player.isAlive && distance > 10) {
// Calculate angle towards player
self.direction = Math.atan2(deltaY, deltaX);
// Add some randomness to make movement less predictable
var randomOffset = (Math.random() - 0.5) * 0.3;
self.direction += randomOffset;
}
// Move in current direction
var newX = self.x + Math.cos(self.direction) * self.speed;
var newY = self.y + Math.sin(self.direction) * self.speed;
// Bounce off ship boundaries
if (newX < shipBounds.left + 40 || newX > shipBounds.right - 40) {
self.direction = Math.PI - self.direction;
}
if (newY < shipBounds.top + 40 || newY > shipBounds.bottom - 40) {
self.direction = -self.direction;
}
// Keep within bounds
self.x = Math.max(shipBounds.left + 40, Math.min(shipBounds.right - 40, newX));
self.y = Math.max(shipBounds.top + 40, Math.min(shipBounds.bottom - 40, newY));
};
return self;
});
var Mosque = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('mosque', {
anchorX: 0.5,
anchorY: 0.5
});
self.isCompleted = false;
return self;
});
var Muslim = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('muslim', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.isAlive = true;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game variables
var player;
var christians = [];
var mosques = [];
var mosqueArea = {};
var gameState = 'playing'; // 'playing', 'praying', 'roundEnd'
var roundNumber = 1;
var prayersCompleted = 0;
var prayingTimer = 0;
var prayingDuration = 5000; // 5 seconds for praying
var dragNode = null;
// Missing variables that are referenced in the code
var shipBounds = {};
var impostors = [];
var taskStations = [];
var tasksCompleted = 0;
// Level system variables
var currentLevel = 1;
var maxLevel = 4;
var currentBoss = null;
var levelNames = ['Main Mosque', 'Prayer Hall', 'Minaret', 'Sacred Courtyard'];
var levelBackgrounds = ['courtyard', 'mainMosque', 'prayerHall', 'minaret'];
var currentMosque = null;
var isLevelTransition = false;
var levelTransitionDuration = 8000; // 8 seconds pause between levels
var isLevelCompleted = false;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var gameStateTxt = new Text2('Visit mosques to pray and avoid the pursuers!', {
size: 60,
fill: 0xFFFF00
});
gameStateTxt.anchor.set(0.5, 0);
gameStateTxt.y = 100;
LK.gui.top.addChild(gameStateTxt);
var roundTxt = new Text2('Round 1', {
size: 70,
fill: 0x00FFFF
});
roundTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(roundTxt);
roundTxt.x = 120; // Avoid the menu icon
var levelTxt = new Text2('Level 1: Main Mosque', {
size: 60,
fill: 0xff9900
});
levelTxt.anchor.set(0, 0);
levelTxt.y = 80;
LK.gui.topLeft.addChild(levelTxt);
levelTxt.x = 120;
var levelTransitionTxt = new Text2('', {
size: 120,
fill: 0xffff00
});
levelTransitionTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(levelTransitionTxt);
levelTransitionTxt.alpha = 0;
// Continue button for level completion
var continueBtn = new Text2('CONTINUE', {
size: 100,
fill: 0x00ff00
});
continueBtn.anchor.set(0.5, 0.5);
continueBtn.y = 200;
LK.gui.center.addChild(continueBtn);
continueBtn.alpha = 0;
continueBtn.interactive = true;
// Create level background
function createLevelBackground() {
if (currentMosque && currentMosque.parent) {
currentMosque.destroy();
}
var backgroundAsset = levelBackgrounds[currentLevel - 1] || 'courtyard';
currentMosque = game.attachAsset(backgroundAsset, {
anchorX: 0.5,
anchorY: 0.5,
x: 1024,
y: 1366
});
// Update mosque boundaries after creating new background
mosqueArea = {
left: currentMosque.x - currentMosque.width / 2,
right: currentMosque.x + currentMosque.width / 2,
top: currentMosque.y - currentMosque.height / 2,
bottom: currentMosque.y + currentMosque.height / 2
};
// Create fresh mosques for the new level
createMosques();
}
createLevelBackground();
// Set mosque boundaries
mosqueArea = {
left: currentMosque.x - currentMosque.width / 2,
right: currentMosque.x + currentMosque.width / 2,
top: currentMosque.y - currentMosque.height / 2,
bottom: currentMosque.y + currentMosque.height / 2
};
// Initialize shipBounds to match mosqueArea
shipBounds = {
left: mosqueArea.left,
right: mosqueArea.right,
top: mosqueArea.top,
bottom: mosqueArea.bottom
};
// Create player
player = game.addChild(new Muslim());
player.x = 1024;
player.y = 1600;
// Create mosques
function createMosques() {
// Destroy existing mosques first
for (var i = 0; i < mosques.length; i++) {
if (mosques[i].parent) {
mosques[i].destroy();
}
}
mosques = [];
var positions = [{
x: 400,
y: 800
}, {
x: 1600,
y: 800
}, {
x: 800,
y: 1000
}, {
x: 1200,
y: 1000
}, {
x: 600,
y: 1200
}];
for (var i = 0; i < positions.length; i++) {
var mosque = game.addChild(new Mosque());
mosque.x = positions[i].x;
mosque.y = positions[i].y;
mosque.isCompleted = false; // Ensure mosque starts uncompleted
mosques.push(mosque);
}
}
// Create boss for boss rounds
function createBoss() {
if (currentBoss && currentBoss.parent) {
currentBoss.destroy();
}
currentBoss = game.addChild(new Boss(currentLevel));
currentBoss.x = 1024;
currentBoss.y = 800;
}
// Create Christians for current round
function createChristians() {
christians = [];
// Boss levels (every 3rd round) have boss instead of regular Christians
if (roundNumber % 3 === 0) {
createBoss();
return; // No regular Christians on boss rounds
}
var christianCount = Math.min(roundNumber + 1, 4);
var colors = ['christian', 'christian2', 'christian3', 'christian'];
for (var i = 0; i < christianCount; i++) {
var christian = game.addChild(new Christian(colors[i % colors.length]));
christian.x = mosqueArea.left + 100 + Math.random() * (mosqueArea.right - mosqueArea.left - 200);
christian.y = mosqueArea.top + 100 + Math.random() * (mosqueArea.bottom - mosqueArea.top - 200);
christian.speed = 4 + roundNumber * 0.8;
christians.push(christian);
}
// Set impostors to reference christians for compatibility
impostors = christians;
// Set taskStations to reference mosques for compatibility
taskStations = mosques;
}
// Initialize first round
createMosques();
createChristians();
// Start level transition with pause
function startLevelTransition() {
isLevelTransition = true;
isLevelCompleted = true;
gameState = 'levelCompleted';
// Show level completion text
levelTransitionTxt.setText('Level ' + (currentLevel - 1) + ' Complete!');
tween(levelTransitionTxt, {
alpha: 1
}, {
duration: 1000,
onFinish: function onFinish() {
// Show continue button after text appears
tween(continueBtn, {
alpha: 1,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 800,
easing: tween.easeOut
});
}
});
}
// Handle continue button click
continueBtn.down = function (x, y, obj) {
if (isLevelCompleted) {
// Fade out completion UI
tween(levelTransitionTxt, {
alpha: 0
}, {
duration: 500
});
tween(continueBtn, {
alpha: 0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 500,
onFinish: function onFinish() {
isLevelCompleted = false;
isLevelTransition = false;
// Continue from level completion
gameState = 'playing';
continueNextRound();
}
});
}
};
// Continue next round after transition
function continueNextRound() {
prayersCompleted = 0; // Reset prayers completed for new round
roundTxt.setText('Round ' + roundNumber);
// Clean up old christians
for (var i = 0; i < christians.length; i++) {
if (christians[i].parent) {
christians[i].destroy();
}
}
// Clean up boss
if (currentBoss && currentBoss.parent) {
currentBoss.destroy();
currentBoss = null;
}
// Reset mosques
for (var i = 0; i < mosques.length; i++) {
mosques[i].isCompleted = false;
if (mosques[i].tint !== undefined) {
mosques[i].tint = 0xffffff;
}
}
// Create new christians or boss
createChristians();
// Update game state text based on round type
if (roundNumber % 3 === 0) {
gameStateTxt.setText('BOSS ROUND ' + roundNumber + ' - Complete prayers and prepare for final confrontation!');
} else {
gameStateTxt.setText('Round ' + roundNumber + ' - Complete prayers and avoid the pursuers!');
}
// Flash screen to indicate new round
LK.effects.flashScreen(0x0000ff, 500);
}
// Start next round
function startNextRound() {
roundNumber++;
tasksCompleted = 0;
prayersCompleted = 0; // Reset prayers completed for new round
// Level progression every 3 rounds
if (roundNumber % 3 === 1 && roundNumber > 1) {
currentLevel = Math.min(currentLevel + 1, maxLevel);
createLevelBackground();
levelTxt.setText('Level ' + currentLevel + ': ' + levelNames[currentLevel - 1]);
LK.getSound('levelComplete').play();
// Start level completion screen instead of immediately continuing
startLevelTransition();
return; // Exit early, transition will handle the rest
}
roundTxt.setText('Round ' + roundNumber);
// Clean up old christians
for (var i = 0; i < christians.length; i++) {
if (christians[i].parent) {
christians[i].destroy();
}
}
// Clean up boss
if (currentBoss && currentBoss.parent) {
currentBoss.destroy();
currentBoss = null;
}
// Reset mosques
for (var i = 0; i < mosques.length; i++) {
mosques[i].isCompleted = false;
if (mosques[i].tint !== undefined) {
mosques[i].tint = 0xffffff;
}
}
// Create new christians or boss
createChristians();
gameState = 'playing';
// Update game state text based on round type
if (roundNumber % 3 === 0) {
gameStateTxt.setText('BOSS ROUND ' + roundNumber + ' - Complete prayers and prepare for final confrontation!');
} else {
gameStateTxt.setText('Round ' + roundNumber + ' - Complete prayers and avoid the pursuers!');
}
// Flash screen to indicate new round
LK.effects.flashScreen(0x0000ff, 500);
}
// Handle player movement
function handleMove(x, y, obj) {
if (dragNode && player.isAlive && gameState === 'playing') {
var newX = Math.max(shipBounds.left + 40, Math.min(shipBounds.right - 40, x));
var newY = Math.max(shipBounds.top + 40, Math.min(shipBounds.bottom - 40, y));
dragNode.x = newX;
dragNode.y = newY;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (player.isAlive && gameState === 'playing') {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game update loop
game.update = function () {
if (!player.isAlive) return;
// Skip game logic during level transition or completion
if (isLevelTransition || gameState === 'transition' || gameState === 'levelCompleted') {
return;
}
if (gameState !== 'playing') return;
// Check collisions with christians (only non-identified ones)
for (var i = 0; i < christians.length; i++) {
if (!christians[i].isIdentified && player.intersects(christians[i])) {
// Player caught by christian
player.isAlive = false;
LK.effects.flashScreen(0xff0000, 1500);
LK.getSound('elimination').play();
LK.showGameOver();
return;
}
}
// Check collision with boss
if (currentBoss && !currentBoss.isDead && player.intersects(currentBoss)) {
// Player caught by boss
player.isAlive = false;
LK.effects.flashScreen(0xff0000, 1500);
LK.getSound('elimination').play();
LK.showGameOver();
return;
}
// Check mosque prayer completion
for (var i = 0; i < mosques.length; i++) {
var mosque = mosques[i];
if (!mosque.isCompleted && player.intersects(mosque)) {
mosque.isCompleted = true;
if (mosque.tint !== undefined) {
mosque.tint = 0x00ff00;
}
prayersCompleted++;
LK.setScore(LK.getScore() + 50);
LK.getSound('taskComplete').play();
scoreTxt.setText('Score: ' + LK.getScore());
// Check if all prayers completed
if (prayersCompleted >= mosques.length) {
startNextRound();
}
}
}
};