/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0,
currentLevel: 1
});
/****
* Classes
****/
var Agent = Container.expand(function () {
var self = Container.call(this);
// Agent properties
self.speed = 10;
self.state = 'ready'; // ready, charging, breaching, recovering
self.chargeSpeed = 0;
// Create agent asset
var agentAsset = self.attachAsset('agent', {
anchorX: 0.5,
anchorY: 0.5
});
// Create battering ram
var ramAsset = self.attachAsset('ram', {
anchorX: 0.5,
anchorY: 0.5,
x: 300,
y: 0
});
// Method to charge at the door
self.charge = function () {
if (self.state !== 'ready') {
return;
}
self.state = 'charging';
self.chargeSpeed = 0;
};
// Method to update agent's position and state
self.update = function () {
if (self.state === 'charging') {
// Increase charge speed
self.chargeSpeed += 1;
self.x += self.chargeSpeed;
} else if (self.state === 'recovering') {
// Move back to starting position
self.x -= self.speed;
if (self.x <= self.startX) {
self.x = self.startX;
self.state = 'ready';
}
}
};
// Method to reset agent
self.reset = function (startX, startY) {
self.startX = startX;
self.startY = startY;
self.x = startX;
self.y = startY;
self.state = 'ready';
self.chargeSpeed = 0;
};
return self;
});
var Door = Container.expand(function () {
var self = Container.call(this);
// Door properties
self.health = 100;
self.breachable = false;
self.breached = false;
// Create door asset
var doorAsset = self.attachAsset('door', {
anchorX: 0.5,
anchorY: 0.5
});
// Doorknob removed
// Breach effect (hidden initially)
var breachEffect = self.attachAsset('breach_effect', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
// Method to animate the breach
self.breach = function () {
if (self.breached) {
return;
}
self.breached = true;
// Flash the breach effect
breachEffect.alpha = 0.8;
tween(breachEffect, {
alpha: 0
}, {
duration: 500
});
// Play door breaking sound
LK.getSound('breach').play();
// Animate door opening
tween(doorAsset, {
rotation: Math.PI / 2
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
// Play the FBI OPEN UP sound after door opens
LK.getSound('fbi_open_up').play();
}
});
};
// Method to reset door
self.reset = function () {
doorAsset.rotation = 0;
self.breached = false;
self.health = 100;
breachEffect.alpha = 0;
};
// Method to set the door's difficulty level
self.setLevel = function (level) {
// Adjust door properties based on level
self.health = 100 + level * 20;
};
return self;
});
var InstructionText = Container.expand(function () {
var self = Container.call(this);
// Create instruction text
var instructionText = new Text2('TAP AND HOLD TO CHARGE\nRELEASE AT THE RIGHT MOMENT', {
size: 60,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
self.addChild(instructionText);
// Method to update instruction text
self.updateText = function (text) {
instructionText.setText(text);
};
return self;
});
var LevelInfo = Container.expand(function () {
var self = Container.call(this);
// Create level text
var levelText = new Text2('LEVEL 1', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
self.addChild(levelText);
// Create score text
var scoreText = new Text2('SCORE: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0.5, 0);
scoreText.y = 100;
self.addChild(scoreText);
// Method to update level display
self.updateLevel = function (level) {
levelText.setText('LEVEL ' + level);
};
// Method to update score display
self.updateScore = function (score) {
scoreText.setText('SCORE: ' + score);
};
return self;
});
var ProgressBar = Container.expand(function () {
var self = Container.call(this);
// Properties
self.currentValue = 0;
self.maxValue = 100;
// Background bar
var bgBar = self.attachAsset('progressBarBg', {
anchorX: 0,
anchorY: 0.5
});
// Progress bar
var progressBar = self.attachAsset('progressBar', {
anchorX: 0,
anchorY: 0.5
});
// Target zone for perfect timing
var targetZone = self.attachAsset('targetZone', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
// Update the progress bar display
self.updateProgress = function (value) {
self.currentValue = value;
if (value > self.maxValue) {
self.currentValue = self.maxValue;
}
if (value < 0) {
self.currentValue = 0;
}
var percentage = self.currentValue / self.maxValue;
progressBar.scale.x = percentage;
};
// Set the target zone position
self.setTargetZone = function (min, max) {
var center = (min + max) / 2;
var width = max - min;
targetZone.x = bgBar.width * center;
targetZone.scale.x = width;
};
// Check if the current value is in the target zone
self.isInTargetZone = function () {
var minTarget = (targetZone.x - targetZone.width * targetZone.scale.x / 2) / bgBar.width * self.maxValue;
var maxTarget = (targetZone.x + targetZone.width * targetZone.scale.x / 2) / bgBar.width * self.maxValue;
return self.currentValue >= minTarget && self.currentValue <= maxTarget;
};
// Reset the progress bar
self.reset = function () {
self.updateProgress(0);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x333333
});
/****
* Game Code
****/
// Game variables
var currentLevel = storage.currentLevel || 1;
var score = 0;
var highScore = storage.highScore || 0;
var isCharging = false;
var gameState = 'ready'; // ready, charging, breaching, success, fail
// Create game elements
var door = new Door();
var agent = new Agent();
var progressBar = new ProgressBar();
var levelInfo = new LevelInfo();
var instructionText = new InstructionText();
// Initialize level parameters based on difficulty
var levelParams = {
chargeSpeed: 1,
targetMin: 0.7,
targetMax: 0.8,
timeLimit: 5000
};
// Set up game timer
var gameTimer = null;
// Initialize game layout
function initGame() {
// Play background music
LK.playMusic('game_theme');
// Set up door
door.x = 2048 / 2 + 500;
door.y = 2732 / 2;
door.setLevel(currentLevel);
game.addChild(door);
// Set up agent
agent.reset(400, 2732 / 2);
game.addChild(agent);
// Set up progress bar
progressBar.x = 2048 / 2 - 750;
progressBar.y = 2732 - 300;
progressBar.setTargetZone(levelParams.targetMin, levelParams.targetMax);
game.addChild(progressBar);
// Set up level info
levelInfo.x = 2048 / 2;
levelInfo.y = 150;
levelInfo.updateLevel(currentLevel);
levelInfo.updateScore(score);
game.addChild(levelInfo);
// Set up instruction text
instructionText.x = 2048 / 2;
instructionText.y = 2732 - 450;
game.addChild(instructionText);
// Update level parameters based on current level
updateLevelParams();
}
// Update level parameters based on difficulty
function updateLevelParams() {
levelParams.chargeSpeed = 1 + currentLevel * 0.2;
levelParams.targetMin = Math.max(0.4, 0.8 - currentLevel * 0.05);
levelParams.targetMax = Math.min(0.9, levelParams.targetMin + 0.1);
levelParams.timeLimit = Math.max(2000, 5000 - currentLevel * 200);
// Update progress bar target zone
progressBar.setTargetZone(levelParams.targetMin, levelParams.targetMax);
}
// Reset level for next attempt
function resetLevel() {
door.reset();
agent.reset(400, 2732 / 2);
progressBar.reset();
gameState = 'ready';
isCharging = false;
if (gameTimer) {
LK.clearTimeout(gameTimer);
gameTimer = null;
}
instructionText.updateText('TAP AND HOLD TO CHARGE\nRELEASE AT THE RIGHT MOMENT');
}
// Start next level
function nextLevel() {
currentLevel++;
storage.currentLevel = currentLevel;
// Update level display
levelInfo.updateLevel(currentLevel);
// Update level parameters
updateLevelParams();
// Reset level
resetLevel();
}
// Handle successful breach
function handleSuccess() {
gameState = 'success';
// Calculate score based on timing accuracy
var accuracyBonus = progressBar.isInTargetZone() ? 100 : 50;
var levelBonus = currentLevel * 50;
var levelScore = 100 + accuracyBonus + levelBonus;
// Update total score
score += levelScore;
levelInfo.updateScore(score);
// Update high score if needed
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
}
// Show success message
instructionText.updateText('PERFECT BREACH! +' + levelScore + ' POINTS');
// Play success sound
LK.getSound('success').play();
// Go to next level after delay
LK.setTimeout(function () {
nextLevel();
}, 2000);
}
// Handle failed breach
function handleFail(reason) {
gameState = 'fail';
// Show fail message
instructionText.updateText('BREACH FAILED: ' + reason);
// Play fail sound
LK.getSound('fail').play();
// Reset level after delay
LK.setTimeout(function () {
resetLevel();
}, 2000);
}
// Game input handlers
game.down = function (x, y, obj) {
if (gameState !== 'ready') {
return;
}
// Start charging
isCharging = true;
gameState = 'charging';
// Set time limit for charge
gameTimer = LK.setTimeout(function () {
if (gameState === 'charging') {
handleFail('TIME EXPIRED');
}
}, levelParams.timeLimit);
};
game.up = function (x, y, obj) {
if (gameState !== 'charging' || !isCharging) {
return;
}
// Stop charging and check breach success
isCharging = false;
gameState = 'breaching';
// Clear timeout
if (gameTimer) {
LK.clearTimeout(gameTimer);
gameTimer = null;
}
// Check if breach was successful based on progress bar
if (progressBar.currentValue > 0) {
if (progressBar.isInTargetZone()) {
// Perfect breach
door.breach();
handleSuccess();
} else if (progressBar.currentValue > levelParams.targetMax * 100) {
// Too much force
handleFail('TOO MUCH FORCE');
} else {
// Not enough force
handleFail('NOT ENOUGH FORCE');
}
} else {
// No charge
handleFail('NO CHARGE APPLIED');
}
};
// Game update function
game.update = function () {
// Update agent
agent.update();
// Update charging progress
if (gameState === 'charging' && isCharging) {
var newValue = progressBar.currentValue + levelParams.chargeSpeed;
progressBar.updateProgress(newValue);
// If progress exceeds max, auto-release
if (progressBar.currentValue >= 100) {
// Simulate releasing the charge
game.up(0, 0, null);
}
}
};
// Initialize the game
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -72,15 +72,9 @@
var doorAsset = self.attachAsset('door', {
anchorX: 0.5,
anchorY: 0.5
});
- // Add doorknob
- var doorknob = self.attachAsset('doorknob', {
- anchorX: 0.5,
- anchorY: 0.5,
- x: 320,
- y: 0
- });
+ // Doorknob removed
// Breach effect (hidden initially)
var breachEffect = self.attachAsset('breach_effect', {
anchorX: 0.5,
anchorY: 0.5,