/****
* Plugins
****/
var facekit = LK.import("@upit/facekit.v1");
var storage = LK.import("@upit/storage.v1", {
GameplayBG: false,
CurrentSkin: "faceObject"
});
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = self.attachAsset('Background', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = 2048 / 2; // Set the x position to the center of the screen
self.y = 2732 / 2; // Set the y position to the center of the screen
});
var Button = Container.expand(function (text, x, y, callback) {
var self = Container.call(this);
self.buttonAsset = self.attachAsset('Buttom', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.buttonAsset.x = x;
self.buttonAsset.y = y;
var buttonText = new Text2(text, {
size: 100,
fill: 0xFFFFFF,
font: "'Press Start 2P', cursive"
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = x;
buttonText.y = y;
self.addChild(buttonText);
self.buttonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play();
callback(x, y, obj);
};
});
var EnemyArrow = Container.expand(function () {
var self = Container.call(this);
var bEnemyArrowGraphics = self.attachAsset('EnemyArrow', {
anchorX: 0.5,
anchorY: 0.5
});
var arrowSound = LK.getSound('ArrowCreated');
arrowSound.pitch = 0.9 + Math.random() * 0.2; // Random pitch between 0.9 and 1.1
arrowSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var speed = 17.5; // Fixed speed for straight trajectory
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation = angle;
};
});
var EnemyCircle = Container.expand(function () {
var self = Container.call(this);
var bEnemyCircleGraphics = self.attachAsset('EnemyCircle', {
anchorX: 0.5,
anchorY: 0.5
});
var circleSound = LK.getSound('CircleCreated');
circleSound.play();
// Add pulsing transparency and size increase animation
function addPulsingAnimation(target) {
tween(target, {
alpha: 0.5,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
alpha: 1.0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
addPulsingAnimation(target); // Loop the effect
}
});
}
});
}
addPulsingAnimation(bEnemyCircleGraphics);
enemyLogic(self);
// Determine target position based on random chance
var randomChance = Math.random();
var targetX, targetY;
if (randomChance < 0.33) {
// 33% chance to go to the player's last position
targetX = player.x;
targetY = player.y;
} else if (randomChance < 0.66) {
// 33% chance to go to a very offset position from the player's last position
var offsetX = (Math.random() - 0.5) * 800; // Random offset between -400 and 400
var offsetY = (Math.random() - 0.5) * 800; // Random offset between -400 and 400
targetX = player.x + offsetX;
targetY = player.y + offsetY;
} else {
// 33% chance to go to a random position within the player's movement area
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.random() * (rightBound - leftBound) + leftBound;
targetY = Math.random() * (bottomBound - topBound) + topBound;
}
var angle = Math.atan2(targetY - self.y, targetX - self.x);
var speed;
if (randomChance < 0.33) {
speed = 15; // Speed for direct to player
} else if (randomChance < 0.66) {
speed = 10; // Speed for nearby position
} else {
var _addPulsingSizeAnimation = function addPulsingSizeAnimation(target) {
tween(target, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
_addPulsingSizeAnimation(target); // Loop the effect
}
});
}
});
};
speed = 5; // Speed for random position
// Add pulsing size animation for slower EnemyCircle instances
_addPulsingSizeAnimation(self);
}
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.03; // Add rotation to Circle
};
});
var EnemyHexagon = Container.expand(function () {
var self = Container.call(this);
var bEnemyHexagonGraphics = self.attachAsset('EnemyHexagon', {
anchorX: 0.5,
anchorY: 0.5
});
var hexagonSound = LK.getSound('HexagonCreated');
hexagonSound.play();
enemyLogic(self);
// Determine target position based on random chance
var randomChance = Math.random();
var targetX, targetY;
if (randomChance < 0.5) {
// 50% chance to go to a nearby position from the player's last position
var offsetX = (Math.random() - 0.5) * 400; // Random offset between -200 and 200
var offsetY = (Math.random() - 0.5) * 400; // Random offset between -200 and 200
targetX = player.x + offsetX;
targetY = player.y + offsetY;
} else {
// 50% chance to go to a random position within the player's movement area
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.random() * (rightBound - leftBound) + leftBound;
targetY = Math.random() * (bottomBound - topBound) + topBound;
}
var angle = Math.atan2(targetY - self.y, targetX - self.x);
var speed = 10; // Adjusted speed for new movement pattern
var zigzagFrequency = 0.1; // Frequency of zig-zag movement
var zigzagAmplitude = 12; // Amplitude of zig-zag movement
self.update = function () {
if (!gamestart) {
return;
}
var zigzagOffset = Math.sin(LK.ticks * zigzagFrequency) * zigzagAmplitude;
self.x += Math.cos(angle) * speed + Math.cos(angle + Math.PI / 2) * zigzagOffset;
self.y += Math.sin(angle) * speed + Math.sin(angle + Math.PI / 2) * zigzagOffset;
self.rotation = angle;
};
});
var EnemyNinja = Container.expand(function () {
var self = Container.call(this);
var bEnemyNinjaGraphics = self.attachAsset('EnemyNinja', {
anchorX: 0.5,
anchorY: 0.5
});
var ninjaSound = LK.getSound('Ninjacreated');
ninjaSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges = 0;
var speed = 18; // Set speed for Ninja
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.1; // Add rotation to Ninja
// Check if Ninja is near the player and not on cooldown
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distanceToPlayer <= 600 && !self.cooldown) {
self.cooldown = true; // Set cooldown to prevent immediate re-triggering
LK.setTimeout(function () {
self.cooldown = false; // Reset cooldown after 2 seconds
}, 2000);
self.cooldown = true; // Set cooldown to prevent immediate re-triggering
// Create 4 Ninja Clones at 90-degree angles
for (var i = 0; i < 4; i++) {
var clone = new EnemyNinjaClone();
clone.x = self.x;
clone.y = self.y;
var cloneAngle = angle + Math.PI / 2 * i; // 90-degree increments
clone.update = function (cloneAngle) {
return function () {
this.x += Math.cos(cloneAngle) * speed;
this.y += Math.sin(cloneAngle) * speed;
this.rotation += 0.1;
};
}(cloneAngle);
game.addChild(clone);
// Limit the number of EnemyNinjaClones to 16
if (enemyNinjaClones.length >= 16) {
var oldestClone = enemyNinjaClones.shift(); // Remove the oldest clone
oldestClone.destroy(); // Destroy the oldest clone
}
enemyNinjaClones.push(clone);
// Play 'Ninjasepare' sound with a slight delay for each clone
LK.setTimeout(function () {
LK.getSound('Ninjasepare').play();
}, i * 100);
}
self.destroy();
enemyNinjas.splice(enemyNinjas.indexOf(self), 1);
}
};
});
var EnemyNinjaClone = Container.expand(function () {
var self = Container.call(this);
var bEnemyNinjaCloneGraphics = self.attachAsset('EnemyNinja', {
anchorX: 0.5,
anchorY: 0.5
});
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges = 0;
var speed = 12; // Set speed for Ninja Clone
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.1; // Add rotation to Ninja Clone
};
});
var EnemySaw = Container.expand(function () {
var self = Container.call(this);
var bEnemySawGraphics = self.attachAsset('EnemySaw', {
anchorX: 0.5,
anchorY: 0.5
});
var sawSound = LK.getSound('sawcreated');
sawSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var newAngle = null;
var speed = 12.5;
self.update = function () {
if (!gamestart) {
return;
}
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distanceToPlayer <= 450 && !self.hasPaused) {
self.hasPaused = true; // Set the boolean to true to ensure it only happens once
var originalSpeed = speed; // Store original speed
speed = 0;
LK.setTimeout(function () {
speed = originalSpeed * 2;
newAngle = Math.atan2(player.y - self.y, player.x - self.x); // Assign new angle towards player's position
LK.getSound('Sawcharge').play(); // Play 'Sawcharge' sound
}, 1000);
}
var currentAngle = newAngle !== null ? newAngle : angle; // Use new angle if available
self.x += Math.cos(currentAngle) * speed;
self.y += Math.sin(currentAngle) * speed;
self.rotation += 0.05;
};
});
var EnemyStar = Container.expand(function () {
var self = Container.call(this);
var bEnemyStarGraphics = self.attachAsset('EnemyStar', {
anchorX: 0.5,
anchorY: 0.5
});
var starSound = LK.getSound('StarCreated');
starSound.play();
enemyLogic(self);
self.directionChanges = 0;
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var speed = 10; // Maintain original speed
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (self.directionChanges < 3 && distanceToPlayer < 600 && !self.cooldown) {
speed *= 1.2;
angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges++;
self.cooldown = true;
LK.setTimeout(function () {
self.cooldown = false;
}, 1000);
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.05;
};
});
var Energy = Container.expand(function () {
var self = Container.call(this);
var energyGraphics = self.attachAsset('Energy', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 100; // Initial energy value
self.decrease = function (amount) {
self.value = Math.max(0, self.value - amount);
};
self.increase = function (amount) {
self.value = Math.min(100, self.value + amount);
};
});
var Life = Container.expand(function () {
var self = Container.call(this);
var lifeGraphics = self.attachAsset('Life', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 100; // Initial life value
self.decrease = function (amount) {
self.value = Math.max(0, self.value - amount);
if (self.value === 0) {
lifeQuantity = Math.max(0, lifeQuantity - 1);
updateLifeIcons();
if (lifeQuantity === 0) {
self.destroy();
LK.showGameOver();
}
}
};
self.increase = function (amount) {
self.value = Math.min(100, self.value + amount);
};
});
var Player = Container.expand(function () {
var self = Container.call(this);
var faceGraphics = self.attachAsset(CurrentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
// Update faceGraphics when CurrentSkin changes
self.updateSkin = function () {
self.removeChild(faceGraphics);
faceGraphics = self.attachAsset(CurrentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
};
self.update = function () {
if (!gamestart) {
return;
}
faceGraphics.alpha = inmunidad ? 0.5 : 1.0;
var smoothing = 0.075;
var targetX = facekit.noseTip.x;
var targetY = facekit.noseTip.y;
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.max(leftBound, Math.min(rightBound, targetX));
targetY = Math.max(topBound, Math.min(bottomBound, targetY));
self.x += (targetX - self.x) * smoothing;
self.y += (targetY - self.y) * smoothing;
var allEnemies = enemyArrows.concat(enemySaw, enemyNinjas, enemyNinjaClones, enemyStars, enemyCircles, enemyHexagons);
for (var i = 0; i < allEnemies.length; i++) {
if (self.intersects(allEnemies[i]) && !allEnemies[i].destroyed && !inmunidad) {
lifeQuantity = Math.max(0, lifeQuantity - 1);
updateLifeIcons();
allEnemies[i].destroy();
inmunidad = true;
LK.setTimeout(function () {
inmunidad = false;
}, 1000);
var enemyArray = [enemyArrows, enemySaw, enemyNinjas, enemyStars, enemyCircles, enemyHexagons, enemyNinjaClones];
for (var j = 0; j < enemyArray.length; j++) {
if (enemyArray[j].includes(allEnemies[i])) {
enemyArray[j].splice(enemyArray[j].indexOf(allEnemies[i]), 1);
break;
}
}
if (lifeQuantity === 0) {
self.destroy();
gamestart = false;
// Save the time when the game ends
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless'];
var currentLevelName = levelNames[levelID];
if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) {
arrowRecordTime = elapsedTime;
storage.arrowRecordTime = arrowRecordTime;
} else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) {
sawRecordTime = elapsedTime;
storage.sawRecordTime = sawRecordTime;
} else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) {
ninjaRecordTime = elapsedTime;
storage.ninjaRecordTime = ninjaRecordTime;
} else if (currentLevelName === 'star' && elapsedTime > starRecordTime) {
starRecordTime = elapsedTime;
storage.starRecordTime = starRecordTime;
} else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) {
circleRecordTime = elapsedTime;
storage.circleRecordTime = circleRecordTime;
} else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) {
hexagonRecordTime = elapsedTime;
storage.hexagonRecordTime = hexagonRecordTime;
} else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) {
endlessRecordTime = elapsedTime;
storage.endlessRecordTime = endlessRecordTime;
}
LK.stopMusic();
LK.showGameOver();
}
break;
}
}
};
});
var RangedLimiter = Container.expand(function () {
var self = Container.call(this);
var limiterGraphics = self.attachAsset('RangedLimiter', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
});
var TextElement = Container.expand(function (text, size, color, font, x, y) {
var self = Container.call(this);
var textElement = new Text2(text, {
size: size,
fill: color,
font: font
});
textElement.anchor.set(0.5, 0.5);
textElement.x = x;
textElement.y = y;
self.addChild(textElement);
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Retro red
// Retro yellow
// Retro light green
// Retro dark red
// Retro purple
// Retro dark purple
//{2} // Retro purple
//{3} // Retro blue
//{4} // Retro teal
//{5} // Retro green
var CurrentSkin = storage.CurrentSkin || 'faceObject'; // Load CurrentSkin from storage or set default
var skins = ['faceObject', 'Skin1', 'Skin2', 'Skin3', 'Skin4', 'Skin5', 'Skin6', 'Skin7', 'Skin8', 'Skin9', 'Skin10', 'Skin11', 'Skin12', 'Skin13', 'Skin14', 'Skin15', 'Skin16', 'Skin17', 'Skin18', 'Skin19', 'Skin20', 'Skin21', 'Skin22', 'Skin23'];
function showSkinsPage() {
// Create a new container for the skins page
var skinsContainer = new Container();
// Add a background to the skins page
var skinsBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
skinsBackground.x = 2048 / 2;
skinsBackground.y = 2732 / 2;
skinsContainer.addChild(skinsBackground);
// Add a title to the skins page
var skinsTitle = new TextElement('Colors', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
skinsContainer.addChild(skinsTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
skinsContainer.visible = false; // Hide the skins page
menuContainer.visible = true; // Show the main menu
});
skinsContainer.addChild(backButton);
// Add a grid layout for skins
var gridColumns = 6;
var gridSpacing = 300;
var startX = 2048 / 2 - (gridColumns - 1) * gridSpacing / 2;
var startY = 1000;
skins.forEach(function (skin, index) {
var skinAsset = LK.getAsset(skin, {
anchorX: 0.5,
anchorY: 0.5
});
var column = index % gridColumns;
var row = Math.floor(index / gridColumns);
skinAsset.x = startX + column * gridSpacing;
skinAsset.y = startY + row * gridSpacing;
skinAsset.down = function (x, y, obj) {
CurrentSkin = skin; // Change the current skin to the selected one
storage.CurrentSkin = CurrentSkin; // Save the current skin to storage
player.updateSkin(); // Update the player's skin
console.log("CurrentSkin changed to:", CurrentSkin);
LK.getSound('ButtomSound').play(); // Play sound when a skin is selected
skinChangeMessage.setText("Skin changed to: ".concat(skin));
LK.setTimeout(function () {
if (skinChangeMessage.text === "Skin changed to: ".concat(skin)) {
skinChangeMessage.setText(''); // Reset to empty string
}
}, 2000);
};
skinsContainer.addChild(skinAsset);
});
// Add a message display for skin change notification
var skinChangeMessage = new Text2('', {
size: 60,
fill: 0x00FF00,
// Green color for the message
font: "'Press Start 2P', cursive"
});
skinChangeMessage.anchor.set(0.5, 0.5);
skinChangeMessage.x = 2048 / 2;
skinChangeMessage.y = 2732 - 100; // Position at the bottom of the screen
skinsContainer.addChild(skinChangeMessage);
// Add the skins page to the game
game.addChild(skinsContainer);
}
var GameplayBG = storage.GameplayBG || false;
function showConfigPage() {
// Create a new container for the config page
var configContainer = new Container();
// Add a background to the config page
var configBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
configBackground.x = 2048 / 2;
configBackground.y = 2732 / 2;
configContainer.addChild(configBackground);
// Add a title to the config page
var configTitle = new TextElement('Settings', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
configContainer.addChild(configTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
configContainer.visible = false; // Hide the config page
menuContainer.visible = true; // Show the main menu
});
configContainer.addChild(backButton);
// Add a button to toggle GameplayBG
var toggleGameplayBGButton = new Button(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off', 2048 / 2, 1000, function (x, y, obj) {
GameplayBG = !GameplayBG; // Toggle the boolean value
storage.GameplayBG = GameplayBG; // Save the state to storage
background.alpha = GameplayBG ? 1 : 0; // Update background transparency
toggleGameplayBGButton.children[1].setText(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off'); // Update button text
});
configContainer.addChild(toggleGameplayBGButton);
// Add the config page to the game
game.addChild(configContainer);
}
var inmunidad = false;
function showHowToPlayPage() {
// Create a new container for the how to play page
var howToPlayContainer = new Container();
// Add the how to play background
var howToPlayBackground = LK.getAsset('HowToPlayOne', {
anchorX: 0.5,
anchorY: 0.5
});
howToPlayBackground.x = 2048 / 2;
howToPlayBackground.y = 2732 / 2;
howToPlayContainer.addChild(howToPlayBackground);
// Add event listener to hide how to play page on touch
howToPlayContainer.down = function (x, y, obj) {
howToPlayContainer.visible = false; // Hide the how to play page
menuContainer.visible = true; // Show the main menu
};
// Add the how to play page to the game
game.addChild(howToPlayContainer);
// Toggle between HowToPlayOne and HowToPlayTwo every second
var toggle = true;
LK.setInterval(function () {
var newBackground = LK.getAsset(toggle ? 'HowToPlayTwo' : 'HowToPlayOne', {
anchorX: 0.5,
anchorY: 0.5
});
newBackground.x = 2048 / 2;
newBackground.y = 2732 / 2;
howToPlayContainer.addChild(newBackground);
howToPlayContainer.removeChild(howToPlayBackground);
howToPlayBackground = newBackground;
toggle = !toggle;
}, 1000);
}
var levelCompletedArrow = storage.levelCompletedArrow || false;
var levelCompletedSaw = storage.levelCompletedSaw || false;
var levelCompletedNinja = storage.levelCompletedNinja || false;
var levelCompletedStar = storage.levelCompletedStar || false;
var levelCompletedCircle = storage.levelCompletedCircle || false;
var levelCompletedHexagon = storage.levelCompletedHexagon || false; // New level 'hexagon' completion tracking
// Initialize records for each level
var arrowRecordTime = storage.arrowRecordTime || 0;
var sawRecordTime = storage.sawRecordTime || 0;
var ninjaRecordTime = storage.ninjaRecordTime || 0;
var starRecordTime = storage.starRecordTime || 0;
var circleRecordTime = storage.circleRecordTime || 0;
var hexagonRecordTime = storage.hexagonRecordTime || 0;
var endlessRecordTime = storage.endlessRecordTime || 0;
function showSelectLevelPage() {
// Add pulsing transparency effect to RangedLimiter using tween plugin
function addPulsingEffect(target) {
tween(target, {
alpha: 0.2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
alpha: 0.5
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
addPulsingEffect(target); // Loop the effect
}
});
}
});
}
addPulsingEffect(rangerlimited);
var selectLevelContainer = new Container();
// Add a background to the select level page
var selectLevelBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
selectLevelBackground.x = 2048 / 2;
selectLevelBackground.y = 2732 / 2;
selectLevelContainer.addChild(selectLevelBackground);
// Add a title to the select level page
var selectLevelTitle = new TextElement('Select Level', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
selectLevelContainer.addChild(selectLevelTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
selectLevelContainer.visible = false; // Hide the select level page
menuContainer.visible = true; // Show the main menu
});
selectLevelContainer.addChild(backButton);
// Add 'How to Play' button to the select level page
var howToPlayButton = new Button('How to Play', 2048 / 2, 2100, function (x, y, obj) {
showHowToPlayPage();
});
selectLevelContainer.addChild(howToPlayButton);
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon']; // Rename '???' to 'hexagon'
var endlessModeName = 'endless'; // Endless mode
var levelSelectors = []; // Array to store level selectors
for (var i = 0; i < levelNames.length + 1; i++) {
var levelName = i < levelNames.length ? levelNames[i] : endlessModeName; // Add endless mode after last level
var levelSelector;
var levelAssets = {
'arrow': levelCompletedArrow ? 'LevelArrowEndless' : 'LevelArrow',
'saw': levelCompletedSaw ? 'LevelSawEndless' : 'LevelSaw',
'star': levelCompletedStar ? 'LevelStarEndless' : 'LevelStar',
'ninja': levelCompletedNinja ? 'LevelNinjaEndless' : 'LevelNinja',
'circle': levelCompletedCircle ? 'LevelCircleEndless' : 'LevelCircle',
'hexagon': levelCompletedHexagon ? 'LevelLaserEndless' : 'LevelHexagon',
'endless': 'LevelEndless'
};
levelSelector = LK.getAsset(levelAssets[levelName], {
anchorX: 0.5,
anchorY: 0.5
});
levelSelector.x = 2048 / 2;
levelSelector.y = 1300; // Align vertically
levelSelector.levelType = levelName;
levelSelector.down = function (index) {
// Create a closure to capture the current index
return function (x, y, obj) {
if (true) {
leftArrow.buttonAsset.down = null; // Disable left arrow button
rightArrow.buttonAsset.down = null; // Disable right arrow button
backButton.buttonAsset.down = null; // Disable back button
howToPlayButton.buttonAsset.down = null; // Disable how to play button
if (!this.soundPlayed) {
LK.getSound('InitialLevel').play(); // Play initial level sound
this.soundPlayed = true; // Ensure the sound only plays once
LK.setTimeout(function () {
LK.setTimeout(function () {
LK.playMusic('GameplayMusic', {
loop: true
}); // Play music after sound
}, 2000); // Add 2-second delay before starting music
}, 898); // Duration of 'InitialLevel' sound
}
LK.setTimeout(function () {
// Add a 3-second cooldown before starting the level
gamestart = true; // Start the game
selectLevelContainer.visible = false;
levelID = index;
console.log("Starting level:", obj.levelType);
}, 3000);
} else {
console.log("Previous level's endless mode not completed. Cannot start this level.");
}
};
}(i); // Pass the current index to the closure
selectLevelContainer.addChild(levelSelector);
// Add level text below each level selector
var levelTextContent = levelName === 'endless' ? 'endless\nmode' : levelName === 'arrow' && levelCompletedArrow ? 'endless\narrow' : levelName === 'saw' && levelCompletedSaw ? 'endless\nsaw' : levelName === 'ninja' && levelCompletedNinja ? 'endless\nninja' : levelName === 'star' && levelCompletedStar ? 'endless\nstar' : levelName === 'circle' && levelCompletedCircle ? 'endless\ncircle' : levelName === 'hexagon' && levelCompletedHexagon ? 'endless\nhexagon' : levelName;
var levelText = new Text2(levelTextContent, {
size: 80,
fill: 0xFFFFFF,
font: "'Press Start 2P', cursive"
});
levelText.anchor.set(0.5, 0.5);
levelText.x = levelSelector.x;
levelText.y = levelSelector.y + 300; // Position text below the selector
selectLevelContainer.addChild(levelText);
levelSelector.levelText = levelText; // Store levelText in levelSelector
levelSelectors.push(levelSelector); // Add to array
}
// Add arrow buttons for level navigation
var currentLevelIndex = 0;
function updateLevelSelectors() {
for (var i = 0; i < levelSelectors.length; i++) {
levelSelectors[i].visible = i === currentLevelIndex;
levelSelectors[i].levelText.visible = i === currentLevelIndex;
}
leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level
rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level
leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level
rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level
}
var leftArrow = new Button('<', 2048 / 2 - 900, 1300, function (x, y, obj) {
if (currentLevelIndex > 0) {
currentLevelIndex--;
updateLevelSelectors();
}
});
selectLevelContainer.addChild(leftArrow);
var rightArrow = new Button('>', 2048 / 2 + 900, 1300, function (x, y, obj) {
if (currentLevelIndex < levelSelectors.length - 1) {
currentLevelIndex++;
updateLevelSelectors();
}
});
selectLevelContainer.addChild(rightArrow);
updateLevelSelectors();
game.addChild(selectLevelContainer);
}
var levelID = 0;
var lifeQuantity = 3;
var energyQuantity = 100;
var gamestart = false;
function enemyLogic(entity) {
var spawnPositions = [{
x: Math.random() * 2000,
y: 0
}, {
x: Math.random() * 2000,
y: 3000
}, {
x: 0,
y: Math.random() * 2000
}, {
x: 3000,
y: Math.random() * 2000
}];
var position = spawnPositions[Math.floor(Math.random() * spawnPositions.length)];
entity.x = position.x;
entity.y = position.y;
entity.spawnTime = entity.spawnTime || Math.random() * 2000 + 2000;
}
var background = game.addChild(new Background());
background.alpha = GameplayBG ? 1 : 0;
var timerTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0.5, 0);
timerTxt.visible = false; // Initially hide the timer text
LK.gui.top.addChild(timerTxt);
var elapsedTime = 0;
var timerInterval = LK.setInterval(function () {
if (!gamestart) {
return;
} // Ensure timer only updates when gamestart is true
if (gamestart && !timerTxt.visible) {
timerTxt.visible = true; // Show timer text when game starts
} else if (!gamestart && timerTxt.visible) {
timerTxt.visible = false; // Hide timer text when game is not started
}
elapsedTime++;
if (elapsedTime >= 30 && (levelID === 1 && !levelCompletedSaw || levelID === 2 && !levelCompletedNinja || levelID === 3 && !levelCompletedStar || levelID === 0 && !levelCompletedArrow || levelID === 4 && !levelCompletedCircle || levelID === 5 && !levelCompletedHexagon)) {
// Check if the current time is greater than the record time for the level
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless'];
var currentLevelName = levelNames[levelID];
if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) {
arrowRecordTime = elapsedTime;
storage.arrowRecordTime = arrowRecordTime;
} else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) {
sawRecordTime = elapsedTime;
storage.sawRecordTime = sawRecordTime;
} else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) {
ninjaRecordTime = elapsedTime;
storage.ninjaRecordTime = ninjaRecordTime;
} else if (currentLevelName === 'star' && elapsedTime > starRecordTime) {
starRecordTime = elapsedTime;
storage.starRecordTime = starRecordTime;
} else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) {
circleRecordTime = elapsedTime;
storage.circleRecordTime = circleRecordTime;
} else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) {
hexagonRecordTime = elapsedTime;
storage.hexagonRecordTime = hexagonRecordTime;
} else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) {
endlessRecordTime = elapsedTime;
storage.endlessRecordTime = endlessRecordTime;
}
gamestart = false;
if (levelID === 0) {
levelCompletedArrow = true;
storage.levelCompletedArrow = true; // Save to cloud
} else if (levelID === 1) {
levelCompletedSaw = true;
storage.levelCompletedSaw = true; // Save to cloud
} else if (levelID === 2) {
levelCompletedNinja = true;
storage.levelCompletedNinja = true; // Save to cloud
} else if (levelID === 3) {
levelCompletedStar = true;
storage.levelCompletedStar = true; // Save to cloud
} else if (levelID === 4) {
levelCompletedCircle = true;
storage.levelCompletedCircle = true; // Save to cloud
} else if (levelID === 5) {
levelCompletedHexagon = true;
storage.levelCompletedHexagon = true; // Save to cloud
}
LK.stopMusic();
LK.showYouWin(); // Show "you win" and reset the game state
}
var minutes = Math.floor(elapsedTime / 60); // Calculate minutes
var seconds = elapsedTime % 60; // Calculate remaining seconds
var timeString = minutes > 0 ? minutes + "m " + seconds + "s" : seconds + "s"; // Format time string
timerTxt.setText(timeString);
}, 1000);
var player = game.addChild(new Player());
player.x = 2048 / 2; // Center the player on the x-axis
player.y = 2732 / 2; // Center the player on the y-axis
game.up = function (x, y, obj) {
player.scaleX = 1;
player.scaleY = 1;
if (energyDecreaseInterval) {
LK.clearInterval(energyDecreaseInterval); // Clear interval when player returns to normal size
}
};
game.down = function (x, y, obj) {
if (energy.value > 0) {
// Check if energy is greater than 0
player.scaleX = 0.5;
player.scaleY = 0.5;
energyDecreaseInterval = LK.setInterval(function () {
energy.decrease(1); // Decrease energy by 2%
energyText.setText(energy.value + '%'); // Update energy text
if (energy.value <= 0) {
player.scaleX = 1; // Reset player size if energy depletes
player.scaleY = 1;
LK.clearInterval(energyDecreaseInterval); // Clear interval
}
}, 500); // Decrease energy every second
}
};
// Create a list to store EnemyArrow instances
function spawnEnemy(type, interval, levelCheck, enemyArray, enemyClass) {
return LK.setInterval(function () {
if (!gamestart || !levelCheck()) {
return;
}
var newEnemy = game.addChild(new enemyClass());
enemyArray.push(newEnemy);
newEnemy.spawnTime = Date.now();
LK.setTimeout(function () {
if (enemyArray.includes(newEnemy) && Date.now() - newEnemy.spawnTime >= 10000) {
newEnemy.destroy();
enemyArray.splice(enemyArray.indexOf(newEnemy), 1);
}
}, 20000);
}, interval);
}
var enemyArrows = [];
var enemySaw = [];
var enemyNinjas = []; // New array to store EnemyNinja instances
var enemyNinjaClones = []; // New array to store EnemyNinjaClone instances
var enemyStars = []; // New array to store EnemyStar instances
var enemyCircles = []; // New array to store EnemyCircle instances
var enemyHexagons = []; // New array to store EnemyHexagon instances
var enemyLasers = []; // Define enemyLasers array to fix the ReferenceError
var enemyArrowInterval = spawnEnemy('arrow', 700, function () {
return levelID === 0;
}, enemyArrows, EnemyArrow);
var enemySawInterval = spawnEnemy('saw', 1000, function () {
return levelID === 1;
}, enemySaw, EnemySaw);
var enemyNinjaInterval = spawnEnemy('ninja', 1200, function () {
return levelID === 2;
}, enemyNinjas, EnemyNinja);
var enemyStarInterval = spawnEnemy('star', 1500, function () {
return levelID === 3;
}, enemyStars, EnemyStar);
var enemyCircleInterval = spawnEnemy('circle', 700, function () {
return levelID === 4;
}, enemyCircles, EnemyCircle);
var enemyHexagonInterval = spawnEnemy('hexagon', 1000, function () {
return levelID === 5;
}, enemyHexagons, EnemyHexagon);
// Endless mode logic for spawning two different enemies every 30 seconds
var endlessEnemyTypes = [EnemyArrow, EnemySaw, EnemyNinja, EnemyStar, EnemyCircle, EnemyHexagon];
var currentEndlessEnemyIndex = 0;
// Function to spawn 3 random enemies every 2 seconds in endless mode
var endlessModeInterval = LK.setInterval(function () {
if (levelID === 6 && gamestart) {
// Assuming levelID 6 is for endless mode
for (var i = 0; i < 2; i++) {
var randomEnemyType = endlessEnemyTypes[Math.floor(Math.random() * endlessEnemyTypes.length)];
var newEnemy = game.addChild(new randomEnemyType());
enemyArrows.push(newEnemy); // Assuming all enemies are stored in enemyArrows for simplicity
}
}
}, 2000);
var lifeIcons = [];
for (var i = 0; i < lifeQuantity; i++) {
var lifeIcon = game.addChild(new Life());
lifeIcon.x = 2048 / 2 - 600 + i * 160; // Position each life icon to the right of the previous one
lifeIcon.y = 100; // Align vertically with the timer
lifeIcons.push(lifeIcon);
}
// Function to update life icons when life decreases
function updateLifeIcons() {
for (var i = 0; i < lifeIcons.length; i++) {
if (i < lifeQuantity) {
lifeIcons[i].visible = true;
} else {
lifeIcons[i].visible = false;
}
}
}
var energy = game.addChild(new Energy());
energy.x = 2048 / 2 + 600; // Position energy to the right of the timer
energy.y = 100; // Align vertically with the timer
var energyText = new Text2(energyQuantity + '%', {
size: 80,
fill: 0xFFFFFF
});
energyText.anchor.set(1, 0.5); // Anchor to the right center
energyText.x = energy.x - 100; // Position to the left of energy
energyText.y = energy.y;
game.addChild(energyText);
var rangerlimited = game.addChild(new RangedLimiter());
rangerlimited.x = 2048 / 2; // Center the RangedLimiter on the x-axis
rangerlimited.y = 2732 / 2; // Center the RangedLimiter on the y-axis
// Create an initial menu
var menuContainer = new Container();
/*
* Menu inicial
*/
var menuBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
menuBackground.x = 2048 / 2;
menuBackground.y = 2732 / 2;
menuContainer.addChild(menuBackground);
// Add a title to the menu
var title = new TextElement('Extreme, skill\n and figures', 135, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
menuContainer.addChild(title);
// Add a reset progress button to the menu
var resetButtonAsset = LK.getAsset('ResetProgress', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xff0000 // Red color
});
resetButtonAsset.x = 2048 - 150;
resetButtonAsset.y = 2732 - 150;
var resetTapCount = 0;
var requiredTaps = 3;
var resetMessage = new Text2('', {
size: 60,
fill: 0xFF0000,
// Red color for the message
font: "'Press Start 2P', cursive"
});
resetMessage.anchor.set(0.5, 0.5);
resetMessage.x = 2048 / 2;
resetMessage.y = 2732 - 100; // Position at the bottom of the screen
menuContainer.addChild(resetMessage);
resetButtonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play(); // Play button sound when reset button is pressed
tween(resetButtonAsset, {
rotation: -Math.PI * 2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
resetButtonAsset.rotation = 0; // Reset rotation after tween
}
});
resetTapCount++;
if (resetTapCount < requiredTaps) {
resetMessage.setText("Press ".concat(requiredTaps - resetTapCount, " more times\nto reset progress"));
LK.setTimeout(function () {
resetMessage.setText('');
resetTapCount = 0; // Reset the tap count after message disappears
}, 4000);
} else {
// Reset all progress and records
storage.levelCompletedArrow = false;
storage.levelCompletedSaw = false;
storage.levelCompletedNinja = false;
storage.levelCompletedStar = false;
storage.levelCompletedCircle = false;
storage.levelCompletedHexagon = false;
storage.arrowRecordTime = 0;
storage.sawRecordTime = 0;
storage.ninjaRecordTime = 0;
storage.starRecordTime = 0;
storage.circleRecordTime = 0;
storage.hexagonRecordTime = 0;
storage.endlessRecordTime = 0;
storage.CurrentSkin = 'faceObject'; // Reset CurrentSkin to default
resetMessage.setText("Progress has been reset.");
resetTapCount = 0; // Reset the tap count
LK.setTimeout(function () {
LK.showGameOver(); // End the game after 2 seconds
}, 2000);
}
};
menuContainer.addChild(resetButtonAsset);
// Create buttons
var configButtonAsset = LK.getAsset('ConfigButon', {
anchorX: 0.5,
anchorY: 0.5
});
configButtonAsset.x = 150;
configButtonAsset.y = 2732 - 150;
configButtonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play(); // Play button sound when config button is pressed
menuContainer.visible = false; // Hide the main menu
showConfigPage(); // Show the config page
};
menuContainer.addChild(configButtonAsset);
var startButton = new Button('Play', 2048 / 2, 1200, function (x, y, obj) {
menuContainer.visible = false; // Hide the menu
showSelectLevelPage(); // Redirect to 'select level' page
});
menuContainer.addChild(startButton);
var colorsButton = new Button('Colors', 2048 / 2, 1500, function (x, y, obj) {
menuContainer.visible = false; // Hide the main menu
showSkinsPage(); // Show the colors page
});
menuContainer.addChild(colorsButton);
var creditsButton = new Button('Credits', 2048 / 2, 2100, function (x, y, obj) {
showCreditsPage();
});
menuContainer.addChild(creditsButton);
var recordButton = new Button('Record', 2048 / 2, 1800, function (x, y, obj) {
menuContainer.visible = false; // Hide the main menu
showRecordsPage(); // Show the records page
});
menuContainer.addChild(recordButton);
function showCreditsPage() {
// Create a new container for the credits page
var creditsContainer = new Container();
// Add the credits background
var creditsBackground = LK.getAsset('Credits', {
anchorX: 0.5,
anchorY: 0.5
});
creditsBackground.x = 2048 / 2;
creditsBackground.y = 2732 / 2;
creditsContainer.addChild(creditsBackground);
// Add event listener to hide credits page on touch
creditsBackground.down = function (x, y, obj) {
creditsContainer.visible = false; // Hide the credits page
menuContainer.visible = true; // Show the main menu
};
// Add the credits page to the game
game.addChild(creditsContainer);
}
game.addChild(menuContainer);
;
// Function to display the records page
function showRecordsPage() {
// Create a new container for the records page
var recordsContainer = new Container();
// Add a black background to the records page
var recordsBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
recordsBackground.x = 2048 / 2;
recordsBackground.y = 2732 / 2;
recordsContainer.addChild(recordsBackground);
// Add a title to the records page
var recordsTitle = new TextElement('Records', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
recordsContainer.addChild(recordsTitle);
// Display records for each level
var recordYPosition = 700;
var levels = [{
name: 'arrow',
recordTime: arrowRecordTime,
color: 0xFFBD4D
}, {
name: 'saw',
recordTime: sawRecordTime,
color: 0xF26A41
}, {
name: 'ninja',
recordTime: ninjaRecordTime,
color: 0xF61C32
}, {
name: 'star',
recordTime: starRecordTime,
color: 0xF61D64
}, {
name: 'circle',
recordTime: circleRecordTime,
color: 0xF61CAD
}, {
name: 'hexagon',
recordTime: hexagonRecordTime,
color: 0xF61CF6
}, {
name: 'endless',
recordTime: endlessRecordTime,
color: 0xFFFFFF // White for endless
}];
levels.forEach(function (level) {
var recordText = new Text2(level.name + ': ' + level.recordTime + 's', {
size: 80,
fill: level.color,
font: "'Press Start 2P', cursive"
});
recordText.anchor.set(0.5, 0.5);
recordText.x = 2048 / 2;
recordText.y = recordYPosition;
recordsContainer.addChild(recordText);
recordYPosition += 150; // Increase space between each record entry
});
var backButton = new Button('Back', 2048 / 2, 2300, function (x, y, obj) {
recordsContainer.visible = false; // Hide the records page
menuContainer.visible = true; // Show the main menu
});
recordsContainer.addChild(backButton);
game.addChild(recordsContainer);
} /****
* Plugins
****/
var facekit = LK.import("@upit/facekit.v1");
var storage = LK.import("@upit/storage.v1", {
GameplayBG: false,
CurrentSkin: "faceObject"
});
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = self.attachAsset('Background', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = 2048 / 2; // Set the x position to the center of the screen
self.y = 2732 / 2; // Set the y position to the center of the screen
});
var Button = Container.expand(function (text, x, y, callback) {
var self = Container.call(this);
self.buttonAsset = self.attachAsset('Buttom', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
self.buttonAsset.x = x;
self.buttonAsset.y = y;
var buttonText = new Text2(text, {
size: 100,
fill: 0xFFFFFF,
font: "'Press Start 2P', cursive"
});
buttonText.anchor.set(0.5, 0.5);
buttonText.x = x;
buttonText.y = y;
self.addChild(buttonText);
self.buttonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play();
callback(x, y, obj);
};
});
var EnemyArrow = Container.expand(function () {
var self = Container.call(this);
var bEnemyArrowGraphics = self.attachAsset('EnemyArrow', {
anchorX: 0.5,
anchorY: 0.5
});
var arrowSound = LK.getSound('ArrowCreated');
arrowSound.pitch = 0.9 + Math.random() * 0.2; // Random pitch between 0.9 and 1.1
arrowSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var speed = 17.5; // Fixed speed for straight trajectory
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation = angle;
};
});
var EnemyCircle = Container.expand(function () {
var self = Container.call(this);
var bEnemyCircleGraphics = self.attachAsset('EnemyCircle', {
anchorX: 0.5,
anchorY: 0.5
});
var circleSound = LK.getSound('CircleCreated');
circleSound.play();
// Add pulsing transparency and size increase animation
function addPulsingAnimation(target) {
tween(target, {
alpha: 0.5,
scaleX: 1.1,
scaleY: 1.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
alpha: 1.0,
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
addPulsingAnimation(target); // Loop the effect
}
});
}
});
}
addPulsingAnimation(bEnemyCircleGraphics);
enemyLogic(self);
// Determine target position based on random chance
var randomChance = Math.random();
var targetX, targetY;
if (randomChance < 0.33) {
// 33% chance to go to the player's last position
targetX = player.x;
targetY = player.y;
} else if (randomChance < 0.66) {
// 33% chance to go to a very offset position from the player's last position
var offsetX = (Math.random() - 0.5) * 800; // Random offset between -400 and 400
var offsetY = (Math.random() - 0.5) * 800; // Random offset between -400 and 400
targetX = player.x + offsetX;
targetY = player.y + offsetY;
} else {
// 33% chance to go to a random position within the player's movement area
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.random() * (rightBound - leftBound) + leftBound;
targetY = Math.random() * (bottomBound - topBound) + topBound;
}
var angle = Math.atan2(targetY - self.y, targetX - self.x);
var speed;
if (randomChance < 0.33) {
speed = 15; // Speed for direct to player
} else if (randomChance < 0.66) {
speed = 10; // Speed for nearby position
} else {
var _addPulsingSizeAnimation = function addPulsingSizeAnimation(target) {
tween(target, {
scaleX: 1.6,
scaleY: 1.6
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
_addPulsingSizeAnimation(target); // Loop the effect
}
});
}
});
};
speed = 5; // Speed for random position
// Add pulsing size animation for slower EnemyCircle instances
_addPulsingSizeAnimation(self);
}
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.03; // Add rotation to Circle
};
});
var EnemyHexagon = Container.expand(function () {
var self = Container.call(this);
var bEnemyHexagonGraphics = self.attachAsset('EnemyHexagon', {
anchorX: 0.5,
anchorY: 0.5
});
var hexagonSound = LK.getSound('HexagonCreated');
hexagonSound.play();
enemyLogic(self);
// Determine target position based on random chance
var randomChance = Math.random();
var targetX, targetY;
if (randomChance < 0.5) {
// 50% chance to go to a nearby position from the player's last position
var offsetX = (Math.random() - 0.5) * 400; // Random offset between -200 and 200
var offsetY = (Math.random() - 0.5) * 400; // Random offset between -200 and 200
targetX = player.x + offsetX;
targetY = player.y + offsetY;
} else {
// 50% chance to go to a random position within the player's movement area
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.random() * (rightBound - leftBound) + leftBound;
targetY = Math.random() * (bottomBound - topBound) + topBound;
}
var angle = Math.atan2(targetY - self.y, targetX - self.x);
var speed = 10; // Adjusted speed for new movement pattern
var zigzagFrequency = 0.1; // Frequency of zig-zag movement
var zigzagAmplitude = 12; // Amplitude of zig-zag movement
self.update = function () {
if (!gamestart) {
return;
}
var zigzagOffset = Math.sin(LK.ticks * zigzagFrequency) * zigzagAmplitude;
self.x += Math.cos(angle) * speed + Math.cos(angle + Math.PI / 2) * zigzagOffset;
self.y += Math.sin(angle) * speed + Math.sin(angle + Math.PI / 2) * zigzagOffset;
self.rotation = angle;
};
});
var EnemyNinja = Container.expand(function () {
var self = Container.call(this);
var bEnemyNinjaGraphics = self.attachAsset('EnemyNinja', {
anchorX: 0.5,
anchorY: 0.5
});
var ninjaSound = LK.getSound('Ninjacreated');
ninjaSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges = 0;
var speed = 18; // Set speed for Ninja
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.1; // Add rotation to Ninja
// Check if Ninja is near the player and not on cooldown
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distanceToPlayer <= 600 && !self.cooldown) {
self.cooldown = true; // Set cooldown to prevent immediate re-triggering
LK.setTimeout(function () {
self.cooldown = false; // Reset cooldown after 2 seconds
}, 2000);
self.cooldown = true; // Set cooldown to prevent immediate re-triggering
// Create 4 Ninja Clones at 90-degree angles
for (var i = 0; i < 4; i++) {
var clone = new EnemyNinjaClone();
clone.x = self.x;
clone.y = self.y;
var cloneAngle = angle + Math.PI / 2 * i; // 90-degree increments
clone.update = function (cloneAngle) {
return function () {
this.x += Math.cos(cloneAngle) * speed;
this.y += Math.sin(cloneAngle) * speed;
this.rotation += 0.1;
};
}(cloneAngle);
game.addChild(clone);
// Limit the number of EnemyNinjaClones to 16
if (enemyNinjaClones.length >= 16) {
var oldestClone = enemyNinjaClones.shift(); // Remove the oldest clone
oldestClone.destroy(); // Destroy the oldest clone
}
enemyNinjaClones.push(clone);
// Play 'Ninjasepare' sound with a slight delay for each clone
LK.setTimeout(function () {
LK.getSound('Ninjasepare').play();
}, i * 100);
}
self.destroy();
enemyNinjas.splice(enemyNinjas.indexOf(self), 1);
}
};
});
var EnemyNinjaClone = Container.expand(function () {
var self = Container.call(this);
var bEnemyNinjaCloneGraphics = self.attachAsset('EnemyNinja', {
anchorX: 0.5,
anchorY: 0.5
});
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges = 0;
var speed = 12; // Set speed for Ninja Clone
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.1; // Add rotation to Ninja Clone
};
});
var EnemySaw = Container.expand(function () {
var self = Container.call(this);
var bEnemySawGraphics = self.attachAsset('EnemySaw', {
anchorX: 0.5,
anchorY: 0.5
});
var sawSound = LK.getSound('sawcreated');
sawSound.play();
enemyLogic(self);
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var newAngle = null;
var speed = 12.5;
self.update = function () {
if (!gamestart) {
return;
}
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (distanceToPlayer <= 450 && !self.hasPaused) {
self.hasPaused = true; // Set the boolean to true to ensure it only happens once
var originalSpeed = speed; // Store original speed
speed = 0;
LK.setTimeout(function () {
speed = originalSpeed * 2;
newAngle = Math.atan2(player.y - self.y, player.x - self.x); // Assign new angle towards player's position
LK.getSound('Sawcharge').play(); // Play 'Sawcharge' sound
}, 1000);
}
var currentAngle = newAngle !== null ? newAngle : angle; // Use new angle if available
self.x += Math.cos(currentAngle) * speed;
self.y += Math.sin(currentAngle) * speed;
self.rotation += 0.05;
};
});
var EnemyStar = Container.expand(function () {
var self = Container.call(this);
var bEnemyStarGraphics = self.attachAsset('EnemyStar', {
anchorX: 0.5,
anchorY: 0.5
});
var starSound = LK.getSound('StarCreated');
starSound.play();
enemyLogic(self);
self.directionChanges = 0;
var angle = Math.atan2(player.y - self.y, player.x - self.x);
var speed = 10; // Maintain original speed
self.cooldown = false; // Initialize cooldown state
self.update = function () {
if (!gamestart) {
return;
}
var distanceToPlayer = Math.sqrt(Math.pow(player.x - self.x, 2) + Math.pow(player.y - self.y, 2));
if (self.directionChanges < 3 && distanceToPlayer < 600 && !self.cooldown) {
speed *= 1.2;
angle = Math.atan2(player.y - self.y, player.x - self.x);
self.directionChanges++;
self.cooldown = true;
LK.setTimeout(function () {
self.cooldown = false;
}, 1000);
}
self.x += Math.cos(angle) * speed;
self.y += Math.sin(angle) * speed;
self.rotation += 0.05;
};
});
var Energy = Container.expand(function () {
var self = Container.call(this);
var energyGraphics = self.attachAsset('Energy', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 100; // Initial energy value
self.decrease = function (amount) {
self.value = Math.max(0, self.value - amount);
};
self.increase = function (amount) {
self.value = Math.min(100, self.value + amount);
};
});
var Life = Container.expand(function () {
var self = Container.call(this);
var lifeGraphics = self.attachAsset('Life', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 100; // Initial life value
self.decrease = function (amount) {
self.value = Math.max(0, self.value - amount);
if (self.value === 0) {
lifeQuantity = Math.max(0, lifeQuantity - 1);
updateLifeIcons();
if (lifeQuantity === 0) {
self.destroy();
LK.showGameOver();
}
}
};
self.increase = function (amount) {
self.value = Math.min(100, self.value + amount);
};
});
var Player = Container.expand(function () {
var self = Container.call(this);
var faceGraphics = self.attachAsset(CurrentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
// Update faceGraphics when CurrentSkin changes
self.updateSkin = function () {
self.removeChild(faceGraphics);
faceGraphics = self.attachAsset(CurrentSkin, {
anchorX: 0.5,
anchorY: 0.5
});
};
self.update = function () {
if (!gamestart) {
return;
}
faceGraphics.alpha = inmunidad ? 0.5 : 1.0;
var smoothing = 0.075;
var targetX = facekit.noseTip.x;
var targetY = facekit.noseTip.y;
var leftBound = (2048 - 1000) / 2;
var rightBound = leftBound + 1000;
var topBound = (2732 - 1000) / 2;
var bottomBound = topBound + 1000;
targetX = Math.max(leftBound, Math.min(rightBound, targetX));
targetY = Math.max(topBound, Math.min(bottomBound, targetY));
self.x += (targetX - self.x) * smoothing;
self.y += (targetY - self.y) * smoothing;
var allEnemies = enemyArrows.concat(enemySaw, enemyNinjas, enemyNinjaClones, enemyStars, enemyCircles, enemyHexagons);
for (var i = 0; i < allEnemies.length; i++) {
if (self.intersects(allEnemies[i]) && !allEnemies[i].destroyed && !inmunidad) {
lifeQuantity = Math.max(0, lifeQuantity - 1);
updateLifeIcons();
allEnemies[i].destroy();
inmunidad = true;
LK.setTimeout(function () {
inmunidad = false;
}, 1000);
var enemyArray = [enemyArrows, enemySaw, enemyNinjas, enemyStars, enemyCircles, enemyHexagons, enemyNinjaClones];
for (var j = 0; j < enemyArray.length; j++) {
if (enemyArray[j].includes(allEnemies[i])) {
enemyArray[j].splice(enemyArray[j].indexOf(allEnemies[i]), 1);
break;
}
}
if (lifeQuantity === 0) {
self.destroy();
gamestart = false;
// Save the time when the game ends
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless'];
var currentLevelName = levelNames[levelID];
if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) {
arrowRecordTime = elapsedTime;
storage.arrowRecordTime = arrowRecordTime;
} else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) {
sawRecordTime = elapsedTime;
storage.sawRecordTime = sawRecordTime;
} else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) {
ninjaRecordTime = elapsedTime;
storage.ninjaRecordTime = ninjaRecordTime;
} else if (currentLevelName === 'star' && elapsedTime > starRecordTime) {
starRecordTime = elapsedTime;
storage.starRecordTime = starRecordTime;
} else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) {
circleRecordTime = elapsedTime;
storage.circleRecordTime = circleRecordTime;
} else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) {
hexagonRecordTime = elapsedTime;
storage.hexagonRecordTime = hexagonRecordTime;
} else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) {
endlessRecordTime = elapsedTime;
storage.endlessRecordTime = endlessRecordTime;
}
LK.stopMusic();
LK.showGameOver();
}
break;
}
}
};
});
var RangedLimiter = Container.expand(function () {
var self = Container.call(this);
var limiterGraphics = self.attachAsset('RangedLimiter', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
});
var TextElement = Container.expand(function (text, size, color, font, x, y) {
var self = Container.call(this);
var textElement = new Text2(text, {
size: size,
fill: color,
font: font
});
textElement.anchor.set(0.5, 0.5);
textElement.x = x;
textElement.y = y;
self.addChild(textElement);
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Retro red
// Retro yellow
// Retro light green
// Retro dark red
// Retro purple
// Retro dark purple
//{2} // Retro purple
//{3} // Retro blue
//{4} // Retro teal
//{5} // Retro green
var CurrentSkin = storage.CurrentSkin || 'faceObject'; // Load CurrentSkin from storage or set default
var skins = ['faceObject', 'Skin1', 'Skin2', 'Skin3', 'Skin4', 'Skin5', 'Skin6', 'Skin7', 'Skin8', 'Skin9', 'Skin10', 'Skin11', 'Skin12', 'Skin13', 'Skin14', 'Skin15', 'Skin16', 'Skin17', 'Skin18', 'Skin19', 'Skin20', 'Skin21', 'Skin22', 'Skin23'];
function showSkinsPage() {
// Create a new container for the skins page
var skinsContainer = new Container();
// Add a background to the skins page
var skinsBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
skinsBackground.x = 2048 / 2;
skinsBackground.y = 2732 / 2;
skinsContainer.addChild(skinsBackground);
// Add a title to the skins page
var skinsTitle = new TextElement('Colors', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
skinsContainer.addChild(skinsTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
skinsContainer.visible = false; // Hide the skins page
menuContainer.visible = true; // Show the main menu
});
skinsContainer.addChild(backButton);
// Add a grid layout for skins
var gridColumns = 6;
var gridSpacing = 300;
var startX = 2048 / 2 - (gridColumns - 1) * gridSpacing / 2;
var startY = 1000;
skins.forEach(function (skin, index) {
var skinAsset = LK.getAsset(skin, {
anchorX: 0.5,
anchorY: 0.5
});
var column = index % gridColumns;
var row = Math.floor(index / gridColumns);
skinAsset.x = startX + column * gridSpacing;
skinAsset.y = startY + row * gridSpacing;
skinAsset.down = function (x, y, obj) {
CurrentSkin = skin; // Change the current skin to the selected one
storage.CurrentSkin = CurrentSkin; // Save the current skin to storage
player.updateSkin(); // Update the player's skin
console.log("CurrentSkin changed to:", CurrentSkin);
LK.getSound('ButtomSound').play(); // Play sound when a skin is selected
skinChangeMessage.setText("Skin changed to: ".concat(skin));
LK.setTimeout(function () {
if (skinChangeMessage.text === "Skin changed to: ".concat(skin)) {
skinChangeMessage.setText(''); // Reset to empty string
}
}, 2000);
};
skinsContainer.addChild(skinAsset);
});
// Add a message display for skin change notification
var skinChangeMessage = new Text2('', {
size: 60,
fill: 0x00FF00,
// Green color for the message
font: "'Press Start 2P', cursive"
});
skinChangeMessage.anchor.set(0.5, 0.5);
skinChangeMessage.x = 2048 / 2;
skinChangeMessage.y = 2732 - 100; // Position at the bottom of the screen
skinsContainer.addChild(skinChangeMessage);
// Add the skins page to the game
game.addChild(skinsContainer);
}
var GameplayBG = storage.GameplayBG || false;
function showConfigPage() {
// Create a new container for the config page
var configContainer = new Container();
// Add a background to the config page
var configBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
configBackground.x = 2048 / 2;
configBackground.y = 2732 / 2;
configContainer.addChild(configBackground);
// Add a title to the config page
var configTitle = new TextElement('Settings', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
configContainer.addChild(configTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
configContainer.visible = false; // Hide the config page
menuContainer.visible = true; // Show the main menu
});
configContainer.addChild(backButton);
// Add a button to toggle GameplayBG
var toggleGameplayBGButton = new Button(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off', 2048 / 2, 1000, function (x, y, obj) {
GameplayBG = !GameplayBG; // Toggle the boolean value
storage.GameplayBG = GameplayBG; // Save the state to storage
background.alpha = GameplayBG ? 1 : 0; // Update background transparency
toggleGameplayBGButton.children[1].setText(GameplayBG ? 'GameplayBG: On' : 'GameplayBG: Off'); // Update button text
});
configContainer.addChild(toggleGameplayBGButton);
// Add the config page to the game
game.addChild(configContainer);
}
var inmunidad = false;
function showHowToPlayPage() {
// Create a new container for the how to play page
var howToPlayContainer = new Container();
// Add the how to play background
var howToPlayBackground = LK.getAsset('HowToPlayOne', {
anchorX: 0.5,
anchorY: 0.5
});
howToPlayBackground.x = 2048 / 2;
howToPlayBackground.y = 2732 / 2;
howToPlayContainer.addChild(howToPlayBackground);
// Add event listener to hide how to play page on touch
howToPlayContainer.down = function (x, y, obj) {
howToPlayContainer.visible = false; // Hide the how to play page
menuContainer.visible = true; // Show the main menu
};
// Add the how to play page to the game
game.addChild(howToPlayContainer);
// Toggle between HowToPlayOne and HowToPlayTwo every second
var toggle = true;
LK.setInterval(function () {
var newBackground = LK.getAsset(toggle ? 'HowToPlayTwo' : 'HowToPlayOne', {
anchorX: 0.5,
anchorY: 0.5
});
newBackground.x = 2048 / 2;
newBackground.y = 2732 / 2;
howToPlayContainer.addChild(newBackground);
howToPlayContainer.removeChild(howToPlayBackground);
howToPlayBackground = newBackground;
toggle = !toggle;
}, 1000);
}
var levelCompletedArrow = storage.levelCompletedArrow || false;
var levelCompletedSaw = storage.levelCompletedSaw || false;
var levelCompletedNinja = storage.levelCompletedNinja || false;
var levelCompletedStar = storage.levelCompletedStar || false;
var levelCompletedCircle = storage.levelCompletedCircle || false;
var levelCompletedHexagon = storage.levelCompletedHexagon || false; // New level 'hexagon' completion tracking
// Initialize records for each level
var arrowRecordTime = storage.arrowRecordTime || 0;
var sawRecordTime = storage.sawRecordTime || 0;
var ninjaRecordTime = storage.ninjaRecordTime || 0;
var starRecordTime = storage.starRecordTime || 0;
var circleRecordTime = storage.circleRecordTime || 0;
var hexagonRecordTime = storage.hexagonRecordTime || 0;
var endlessRecordTime = storage.endlessRecordTime || 0;
function showSelectLevelPage() {
// Add pulsing transparency effect to RangedLimiter using tween plugin
function addPulsingEffect(target) {
tween(target, {
alpha: 0.2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(target, {
alpha: 0.5
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
addPulsingEffect(target); // Loop the effect
}
});
}
});
}
addPulsingEffect(rangerlimited);
var selectLevelContainer = new Container();
// Add a background to the select level page
var selectLevelBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
selectLevelBackground.x = 2048 / 2;
selectLevelBackground.y = 2732 / 2;
selectLevelContainer.addChild(selectLevelBackground);
// Add a title to the select level page
var selectLevelTitle = new TextElement('Select Level', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
selectLevelContainer.addChild(selectLevelTitle);
// Add a back button to return to the main menu
var backButton = new Button('Back', 2048 / 2, 2400, function (x, y, obj) {
selectLevelContainer.visible = false; // Hide the select level page
menuContainer.visible = true; // Show the main menu
});
selectLevelContainer.addChild(backButton);
// Add 'How to Play' button to the select level page
var howToPlayButton = new Button('How to Play', 2048 / 2, 2100, function (x, y, obj) {
showHowToPlayPage();
});
selectLevelContainer.addChild(howToPlayButton);
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon']; // Rename '???' to 'hexagon'
var endlessModeName = 'endless'; // Endless mode
var levelSelectors = []; // Array to store level selectors
for (var i = 0; i < levelNames.length + 1; i++) {
var levelName = i < levelNames.length ? levelNames[i] : endlessModeName; // Add endless mode after last level
var levelSelector;
var levelAssets = {
'arrow': levelCompletedArrow ? 'LevelArrowEndless' : 'LevelArrow',
'saw': levelCompletedSaw ? 'LevelSawEndless' : 'LevelSaw',
'star': levelCompletedStar ? 'LevelStarEndless' : 'LevelStar',
'ninja': levelCompletedNinja ? 'LevelNinjaEndless' : 'LevelNinja',
'circle': levelCompletedCircle ? 'LevelCircleEndless' : 'LevelCircle',
'hexagon': levelCompletedHexagon ? 'LevelLaserEndless' : 'LevelHexagon',
'endless': 'LevelEndless'
};
levelSelector = LK.getAsset(levelAssets[levelName], {
anchorX: 0.5,
anchorY: 0.5
});
levelSelector.x = 2048 / 2;
levelSelector.y = 1300; // Align vertically
levelSelector.levelType = levelName;
levelSelector.down = function (index) {
// Create a closure to capture the current index
return function (x, y, obj) {
if (true) {
leftArrow.buttonAsset.down = null; // Disable left arrow button
rightArrow.buttonAsset.down = null; // Disable right arrow button
backButton.buttonAsset.down = null; // Disable back button
howToPlayButton.buttonAsset.down = null; // Disable how to play button
if (!this.soundPlayed) {
LK.getSound('InitialLevel').play(); // Play initial level sound
this.soundPlayed = true; // Ensure the sound only plays once
LK.setTimeout(function () {
LK.setTimeout(function () {
LK.playMusic('GameplayMusic', {
loop: true
}); // Play music after sound
}, 2000); // Add 2-second delay before starting music
}, 898); // Duration of 'InitialLevel' sound
}
LK.setTimeout(function () {
// Add a 3-second cooldown before starting the level
gamestart = true; // Start the game
selectLevelContainer.visible = false;
levelID = index;
console.log("Starting level:", obj.levelType);
}, 3000);
} else {
console.log("Previous level's endless mode not completed. Cannot start this level.");
}
};
}(i); // Pass the current index to the closure
selectLevelContainer.addChild(levelSelector);
// Add level text below each level selector
var levelTextContent = levelName === 'endless' ? 'endless\nmode' : levelName === 'arrow' && levelCompletedArrow ? 'endless\narrow' : levelName === 'saw' && levelCompletedSaw ? 'endless\nsaw' : levelName === 'ninja' && levelCompletedNinja ? 'endless\nninja' : levelName === 'star' && levelCompletedStar ? 'endless\nstar' : levelName === 'circle' && levelCompletedCircle ? 'endless\ncircle' : levelName === 'hexagon' && levelCompletedHexagon ? 'endless\nhexagon' : levelName;
var levelText = new Text2(levelTextContent, {
size: 80,
fill: 0xFFFFFF,
font: "'Press Start 2P', cursive"
});
levelText.anchor.set(0.5, 0.5);
levelText.x = levelSelector.x;
levelText.y = levelSelector.y + 300; // Position text below the selector
selectLevelContainer.addChild(levelText);
levelSelector.levelText = levelText; // Store levelText in levelSelector
levelSelectors.push(levelSelector); // Add to array
}
// Add arrow buttons for level navigation
var currentLevelIndex = 0;
function updateLevelSelectors() {
for (var i = 0; i < levelSelectors.length; i++) {
levelSelectors[i].visible = i === currentLevelIndex;
levelSelectors[i].levelText.visible = i === currentLevelIndex;
}
leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level
rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level
leftArrow.visible = currentLevelIndex > 0; // Hide left arrow if on the first level
rightArrow.visible = currentLevelIndex < levelSelectors.length - 1; // Hide right arrow if on the last level
}
var leftArrow = new Button('<', 2048 / 2 - 900, 1300, function (x, y, obj) {
if (currentLevelIndex > 0) {
currentLevelIndex--;
updateLevelSelectors();
}
});
selectLevelContainer.addChild(leftArrow);
var rightArrow = new Button('>', 2048 / 2 + 900, 1300, function (x, y, obj) {
if (currentLevelIndex < levelSelectors.length - 1) {
currentLevelIndex++;
updateLevelSelectors();
}
});
selectLevelContainer.addChild(rightArrow);
updateLevelSelectors();
game.addChild(selectLevelContainer);
}
var levelID = 0;
var lifeQuantity = 3;
var energyQuantity = 100;
var gamestart = false;
function enemyLogic(entity) {
var spawnPositions = [{
x: Math.random() * 2000,
y: 0
}, {
x: Math.random() * 2000,
y: 3000
}, {
x: 0,
y: Math.random() * 2000
}, {
x: 3000,
y: Math.random() * 2000
}];
var position = spawnPositions[Math.floor(Math.random() * spawnPositions.length)];
entity.x = position.x;
entity.y = position.y;
entity.spawnTime = entity.spawnTime || Math.random() * 2000 + 2000;
}
var background = game.addChild(new Background());
background.alpha = GameplayBG ? 1 : 0;
var timerTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
timerTxt.anchor.set(0.5, 0);
timerTxt.visible = false; // Initially hide the timer text
LK.gui.top.addChild(timerTxt);
var elapsedTime = 0;
var timerInterval = LK.setInterval(function () {
if (!gamestart) {
return;
} // Ensure timer only updates when gamestart is true
if (gamestart && !timerTxt.visible) {
timerTxt.visible = true; // Show timer text when game starts
} else if (!gamestart && timerTxt.visible) {
timerTxt.visible = false; // Hide timer text when game is not started
}
elapsedTime++;
if (elapsedTime >= 30 && (levelID === 1 && !levelCompletedSaw || levelID === 2 && !levelCompletedNinja || levelID === 3 && !levelCompletedStar || levelID === 0 && !levelCompletedArrow || levelID === 4 && !levelCompletedCircle || levelID === 5 && !levelCompletedHexagon)) {
// Check if the current time is greater than the record time for the level
var levelNames = ['arrow', 'saw', 'ninja', 'star', 'circle', 'hexagon', 'endless'];
var currentLevelName = levelNames[levelID];
if (currentLevelName === 'arrow' && elapsedTime > arrowRecordTime) {
arrowRecordTime = elapsedTime;
storage.arrowRecordTime = arrowRecordTime;
} else if (currentLevelName === 'saw' && elapsedTime > sawRecordTime) {
sawRecordTime = elapsedTime;
storage.sawRecordTime = sawRecordTime;
} else if (currentLevelName === 'ninja' && elapsedTime > ninjaRecordTime) {
ninjaRecordTime = elapsedTime;
storage.ninjaRecordTime = ninjaRecordTime;
} else if (currentLevelName === 'star' && elapsedTime > starRecordTime) {
starRecordTime = elapsedTime;
storage.starRecordTime = starRecordTime;
} else if (currentLevelName === 'circle' && elapsedTime > circleRecordTime) {
circleRecordTime = elapsedTime;
storage.circleRecordTime = circleRecordTime;
} else if (currentLevelName === 'hexagon' && elapsedTime > hexagonRecordTime) {
hexagonRecordTime = elapsedTime;
storage.hexagonRecordTime = hexagonRecordTime;
} else if (currentLevelName === 'endless' && elapsedTime > endlessRecordTime) {
endlessRecordTime = elapsedTime;
storage.endlessRecordTime = endlessRecordTime;
}
gamestart = false;
if (levelID === 0) {
levelCompletedArrow = true;
storage.levelCompletedArrow = true; // Save to cloud
} else if (levelID === 1) {
levelCompletedSaw = true;
storage.levelCompletedSaw = true; // Save to cloud
} else if (levelID === 2) {
levelCompletedNinja = true;
storage.levelCompletedNinja = true; // Save to cloud
} else if (levelID === 3) {
levelCompletedStar = true;
storage.levelCompletedStar = true; // Save to cloud
} else if (levelID === 4) {
levelCompletedCircle = true;
storage.levelCompletedCircle = true; // Save to cloud
} else if (levelID === 5) {
levelCompletedHexagon = true;
storage.levelCompletedHexagon = true; // Save to cloud
}
LK.stopMusic();
LK.showYouWin(); // Show "you win" and reset the game state
}
var minutes = Math.floor(elapsedTime / 60); // Calculate minutes
var seconds = elapsedTime % 60; // Calculate remaining seconds
var timeString = minutes > 0 ? minutes + "m " + seconds + "s" : seconds + "s"; // Format time string
timerTxt.setText(timeString);
}, 1000);
var player = game.addChild(new Player());
player.x = 2048 / 2; // Center the player on the x-axis
player.y = 2732 / 2; // Center the player on the y-axis
game.up = function (x, y, obj) {
player.scaleX = 1;
player.scaleY = 1;
if (energyDecreaseInterval) {
LK.clearInterval(energyDecreaseInterval); // Clear interval when player returns to normal size
}
};
game.down = function (x, y, obj) {
if (energy.value > 0) {
// Check if energy is greater than 0
player.scaleX = 0.5;
player.scaleY = 0.5;
energyDecreaseInterval = LK.setInterval(function () {
energy.decrease(1); // Decrease energy by 2%
energyText.setText(energy.value + '%'); // Update energy text
if (energy.value <= 0) {
player.scaleX = 1; // Reset player size if energy depletes
player.scaleY = 1;
LK.clearInterval(energyDecreaseInterval); // Clear interval
}
}, 500); // Decrease energy every second
}
};
// Create a list to store EnemyArrow instances
function spawnEnemy(type, interval, levelCheck, enemyArray, enemyClass) {
return LK.setInterval(function () {
if (!gamestart || !levelCheck()) {
return;
}
var newEnemy = game.addChild(new enemyClass());
enemyArray.push(newEnemy);
newEnemy.spawnTime = Date.now();
LK.setTimeout(function () {
if (enemyArray.includes(newEnemy) && Date.now() - newEnemy.spawnTime >= 10000) {
newEnemy.destroy();
enemyArray.splice(enemyArray.indexOf(newEnemy), 1);
}
}, 20000);
}, interval);
}
var enemyArrows = [];
var enemySaw = [];
var enemyNinjas = []; // New array to store EnemyNinja instances
var enemyNinjaClones = []; // New array to store EnemyNinjaClone instances
var enemyStars = []; // New array to store EnemyStar instances
var enemyCircles = []; // New array to store EnemyCircle instances
var enemyHexagons = []; // New array to store EnemyHexagon instances
var enemyLasers = []; // Define enemyLasers array to fix the ReferenceError
var enemyArrowInterval = spawnEnemy('arrow', 700, function () {
return levelID === 0;
}, enemyArrows, EnemyArrow);
var enemySawInterval = spawnEnemy('saw', 1000, function () {
return levelID === 1;
}, enemySaw, EnemySaw);
var enemyNinjaInterval = spawnEnemy('ninja', 1200, function () {
return levelID === 2;
}, enemyNinjas, EnemyNinja);
var enemyStarInterval = spawnEnemy('star', 1500, function () {
return levelID === 3;
}, enemyStars, EnemyStar);
var enemyCircleInterval = spawnEnemy('circle', 700, function () {
return levelID === 4;
}, enemyCircles, EnemyCircle);
var enemyHexagonInterval = spawnEnemy('hexagon', 1000, function () {
return levelID === 5;
}, enemyHexagons, EnemyHexagon);
// Endless mode logic for spawning two different enemies every 30 seconds
var endlessEnemyTypes = [EnemyArrow, EnemySaw, EnemyNinja, EnemyStar, EnemyCircle, EnemyHexagon];
var currentEndlessEnemyIndex = 0;
// Function to spawn 3 random enemies every 2 seconds in endless mode
var endlessModeInterval = LK.setInterval(function () {
if (levelID === 6 && gamestart) {
// Assuming levelID 6 is for endless mode
for (var i = 0; i < 2; i++) {
var randomEnemyType = endlessEnemyTypes[Math.floor(Math.random() * endlessEnemyTypes.length)];
var newEnemy = game.addChild(new randomEnemyType());
enemyArrows.push(newEnemy); // Assuming all enemies are stored in enemyArrows for simplicity
}
}
}, 2000);
var lifeIcons = [];
for (var i = 0; i < lifeQuantity; i++) {
var lifeIcon = game.addChild(new Life());
lifeIcon.x = 2048 / 2 - 600 + i * 160; // Position each life icon to the right of the previous one
lifeIcon.y = 100; // Align vertically with the timer
lifeIcons.push(lifeIcon);
}
// Function to update life icons when life decreases
function updateLifeIcons() {
for (var i = 0; i < lifeIcons.length; i++) {
if (i < lifeQuantity) {
lifeIcons[i].visible = true;
} else {
lifeIcons[i].visible = false;
}
}
}
var energy = game.addChild(new Energy());
energy.x = 2048 / 2 + 600; // Position energy to the right of the timer
energy.y = 100; // Align vertically with the timer
var energyText = new Text2(energyQuantity + '%', {
size: 80,
fill: 0xFFFFFF
});
energyText.anchor.set(1, 0.5); // Anchor to the right center
energyText.x = energy.x - 100; // Position to the left of energy
energyText.y = energy.y;
game.addChild(energyText);
var rangerlimited = game.addChild(new RangedLimiter());
rangerlimited.x = 2048 / 2; // Center the RangedLimiter on the x-axis
rangerlimited.y = 2732 / 2; // Center the RangedLimiter on the y-axis
// Create an initial menu
var menuContainer = new Container();
/*
* Menu inicial
*/
var menuBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
menuBackground.x = 2048 / 2;
menuBackground.y = 2732 / 2;
menuContainer.addChild(menuBackground);
// Add a title to the menu
var title = new TextElement('Extreme, skill\n and figures', 135, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
menuContainer.addChild(title);
// Add a reset progress button to the menu
var resetButtonAsset = LK.getAsset('ResetProgress', {
anchorX: 0.5,
anchorY: 0.5,
color: 0xff0000 // Red color
});
resetButtonAsset.x = 2048 - 150;
resetButtonAsset.y = 2732 - 150;
var resetTapCount = 0;
var requiredTaps = 3;
var resetMessage = new Text2('', {
size: 60,
fill: 0xFF0000,
// Red color for the message
font: "'Press Start 2P', cursive"
});
resetMessage.anchor.set(0.5, 0.5);
resetMessage.x = 2048 / 2;
resetMessage.y = 2732 - 100; // Position at the bottom of the screen
menuContainer.addChild(resetMessage);
resetButtonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play(); // Play button sound when reset button is pressed
tween(resetButtonAsset, {
rotation: -Math.PI * 2
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
resetButtonAsset.rotation = 0; // Reset rotation after tween
}
});
resetTapCount++;
if (resetTapCount < requiredTaps) {
resetMessage.setText("Press ".concat(requiredTaps - resetTapCount, " more times\nto reset progress"));
LK.setTimeout(function () {
resetMessage.setText('');
resetTapCount = 0; // Reset the tap count after message disappears
}, 4000);
} else {
// Reset all progress and records
storage.levelCompletedArrow = false;
storage.levelCompletedSaw = false;
storage.levelCompletedNinja = false;
storage.levelCompletedStar = false;
storage.levelCompletedCircle = false;
storage.levelCompletedHexagon = false;
storage.arrowRecordTime = 0;
storage.sawRecordTime = 0;
storage.ninjaRecordTime = 0;
storage.starRecordTime = 0;
storage.circleRecordTime = 0;
storage.hexagonRecordTime = 0;
storage.endlessRecordTime = 0;
storage.CurrentSkin = 'faceObject'; // Reset CurrentSkin to default
resetMessage.setText("Progress has been reset.");
resetTapCount = 0; // Reset the tap count
LK.setTimeout(function () {
LK.showGameOver(); // End the game after 2 seconds
}, 2000);
}
};
menuContainer.addChild(resetButtonAsset);
// Create buttons
var configButtonAsset = LK.getAsset('ConfigButon', {
anchorX: 0.5,
anchorY: 0.5
});
configButtonAsset.x = 150;
configButtonAsset.y = 2732 - 150;
configButtonAsset.down = function (x, y, obj) {
LK.getSound('ButtomSound').play(); // Play button sound when config button is pressed
menuContainer.visible = false; // Hide the main menu
showConfigPage(); // Show the config page
};
menuContainer.addChild(configButtonAsset);
var startButton = new Button('Play', 2048 / 2, 1200, function (x, y, obj) {
menuContainer.visible = false; // Hide the menu
showSelectLevelPage(); // Redirect to 'select level' page
});
menuContainer.addChild(startButton);
var colorsButton = new Button('Colors', 2048 / 2, 1500, function (x, y, obj) {
menuContainer.visible = false; // Hide the main menu
showSkinsPage(); // Show the colors page
});
menuContainer.addChild(colorsButton);
var creditsButton = new Button('Credits', 2048 / 2, 2100, function (x, y, obj) {
showCreditsPage();
});
menuContainer.addChild(creditsButton);
var recordButton = new Button('Record', 2048 / 2, 1800, function (x, y, obj) {
menuContainer.visible = false; // Hide the main menu
showRecordsPage(); // Show the records page
});
menuContainer.addChild(recordButton);
function showCreditsPage() {
// Create a new container for the credits page
var creditsContainer = new Container();
// Add the credits background
var creditsBackground = LK.getAsset('Credits', {
anchorX: 0.5,
anchorY: 0.5
});
creditsBackground.x = 2048 / 2;
creditsBackground.y = 2732 / 2;
creditsContainer.addChild(creditsBackground);
// Add event listener to hide credits page on touch
creditsBackground.down = function (x, y, obj) {
creditsContainer.visible = false; // Hide the credits page
menuContainer.visible = true; // Show the main menu
};
// Add the credits page to the game
game.addChild(creditsContainer);
}
game.addChild(menuContainer);
;
// Function to display the records page
function showRecordsPage() {
// Create a new container for the records page
var recordsContainer = new Container();
// Add a black background to the records page
var recordsBackground = LK.getAsset('BackgroundMenu', {
anchorX: 0.5,
anchorY: 0.5
});
recordsBackground.x = 2048 / 2;
recordsBackground.y = 2732 / 2;
recordsContainer.addChild(recordsBackground);
// Add a title to the records page
var recordsTitle = new TextElement('Records', 150, 0xFFFFFF, "'Press Start 2P', cursive", 2048 / 2, 500);
recordsContainer.addChild(recordsTitle);
// Display records for each level
var recordYPosition = 700;
var levels = [{
name: 'arrow',
recordTime: arrowRecordTime,
color: 0xFFBD4D
}, {
name: 'saw',
recordTime: sawRecordTime,
color: 0xF26A41
}, {
name: 'ninja',
recordTime: ninjaRecordTime,
color: 0xF61C32
}, {
name: 'star',
recordTime: starRecordTime,
color: 0xF61D64
}, {
name: 'circle',
recordTime: circleRecordTime,
color: 0xF61CAD
}, {
name: 'hexagon',
recordTime: hexagonRecordTime,
color: 0xF61CF6
}, {
name: 'endless',
recordTime: endlessRecordTime,
color: 0xFFFFFF // White for endless
}];
levels.forEach(function (level) {
var recordText = new Text2(level.name + ': ' + level.recordTime + 's', {
size: 80,
fill: level.color,
font: "'Press Start 2P', cursive"
});
recordText.anchor.set(0.5, 0.5);
recordText.x = 2048 / 2;
recordText.y = recordYPosition;
recordsContainer.addChild(recordText);
recordYPosition += 150; // Increase space between each record entry
});
var backButton = new Button('Back', 2048 / 2, 2300, function (x, y, obj) {
recordsContainer.visible = false; // Hide the records page
menuContainer.visible = true; // Show the main menu
});
recordsContainer.addChild(backButton);
game.addChild(recordsContainer);
}