/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Bullet class var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 45; self.vx = 0; self.scaleX = MaxScale; self.scaleY = MaxScale; self.update = function () { self.scaleX -= 0.1; self.scaleY -= 0.1; self.y -= self.speed; self.x += self.vx; self.rotation += 0.1; // Add rotation effect if (self.scaleX <= MinScale && self.scaleY <= MinScale) { var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } game.removeChild(self); self.destroy(); } for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var threshold = 0.1; if (self.intersects(enemy) && self.scaleY >= enemy.scaleY - threshold && self.scaleY <= enemy.scaleY + threshold) { // Bullet hit the enemy // Show particle effect on impact var particleEffect = LK.getAsset('bloodSplatter', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); particleEffect.x = self.x; particleEffect.y = self.y; game.addChild(particleEffect); tween(particleEffect, { alpha: 0, scaleX: 1, scaleY: 1 }, { duration: 500, onFinish: function onFinish() { game.removeChild(particleEffect); particleEffect.destroy(); } }); // Remove the bullet var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } game.removeChild(self); self.destroy(); //shake the enemy for 0.5 seconds if they are hit by bullet when frozen. if (enemy.state == STATES.FREEZE) { enemy.shake(); } else { // Play orc_hurt1 or orc_hurt2 sound at random if the enemy is not frozen. var hurtSound = Math.random() < 0.5 ? 'orc_hurt1' : 'orc_hurt2'; LK.getSound(hurtSound).play(); // Flash enemy red when hit tween(enemy, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { tween(enemy, { tint: 0xFFFFFF }, { duration: 100 }); } }); } // Decrease enemy health enemy.health -= 1; if (enemy.health <= 0 && enemy.state != STATES.DEAD) { enemy.prevState = enemy.state; enemy.state = STATES.DEAD; // Increment the kill counter killCounter++; killCounterText.setText('Kills: ' + killCounter); enemy.onDeath(); } break; // Stop the loop after one enemy is killed } } // Apply fade-in effect using tween tween(self, { alpha: 1 }, { duration: 500, easing: tween.easeIn }); }; }); // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); // Define states var STATES = { SPAWN: 'spawn', MOVE: 'move', ATTACK: 'attack', WAIT: 'wait', FREEZE: 'freeze', HURT: 'hurt', DEAD: 'dead' }; // Initialize state self.state = STATES.SPAWN; self.prevState = null; //handle dead state. self.onDeath = function () { var enemy = self; // Destroy the enemy var enemyIndex = enemies.indexOf(enemy); if (enemyIndex > -1) { enemies.splice(enemyIndex, 1); } tween(enemy, { tint: 0xFF0000, scaleY: enemy.scaleY - 0.5, alpha: 0, y: enemy.y - 300 }, { duration: 500, onFinish: function onFinish() { game.removeChild(enemy); enemy.destroy(); } }); }; self.shake = function () { var offsetVal = Math.random() < 0.5 ? -10 : 10; // Shake the enemy for 0.5 seconds tween(self, { x: self.x + offsetVal }, { duration: 100, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: self.x - offsetVal }, { duration: 100, easing: tween.easeInOut, onFinish: function onFinish() { tween(self, { x: self.x }, { duration: 100, easing: tween.easeInOut }); } }); } }); }; // State machine handler self.handleState = function () { switch (self.state) { case STATES.SPAWN: self.handleSpawnState(); break; case STATES.MOVE: self.handleMoveState(); break; case STATES.ATTACK: self.handleAttackState(); break; case STATES.WAIT: self.handleWaitState(); break; case STATES.FREEZE: self.handleFreezeState(); break; } }; //handle freeze state. self.handleFreezeState = function () { // Tint the enemy blue tween(self, { tint: 0x0000FF }, { duration: 250, onFinish: function onFinish() { // Tint the enemy white tween(self, { tint: 0xFFFFFF }, { duration: 250, onFinish: function onFinish() { // Repeat the tinting effect for 5 seconds LK.setTimeout(function () { self.state = self.prevState; // Return to previous state after 5 seconds }, 5000); } }); } }); }; // Handle spawn state self.handleSpawnState = function () { // Transition to move state after spawn tween is done if (self.speed == 2) { self.prevState = self.state; self.state = STATES.MOVE; } }; // Handle move state self.handleMoveState = function () { // Rotate enemy 10 degrees to the left and right alternatively if (LK.ticks % 60 < 30) { self.rotation = self.startRotation * Math.PI / 36; // Rotate 10 degrees to the left or right based on startRotation } else { self.rotation = -self.startRotation * Math.PI / 36; // Rotate 10 degrees to the right or left based on startRotation } if (self.y + self.speed < 2732 - 600) { self.targetReachedTime = null; // Reset targetReachedTime when moving away from target self.y += self.speed; self.scaleX += 0.002; self.scaleY += 0.002; } else { // Reset rotation to zero when reaching target self.rotation = 0; self.reachedTarget = true; // Set reachedTarget to true when target is reached self.prevState = self.state; //Transition to the wait state. self.state = STATES.WAIT; } // Pause enemy movement every 0.5 seconds for a duration of 0.25 seconds if (LK.ticks % 30 == 0) { self.speed = 0; LK.setTimeout(function () { self.speed = 2; }, 250); } }; // Handle wait state self.handleWaitState = function () { // Transition to move state after waiting for 1 second if (!self.waitStartTime) { self.waitStartTime = Date.now(); } if (Date.now() - self.waitStartTime >= 1000) { self.prevState = self.state; self.state = STATES.ATTACK; self.waitStartTime = null; } }; // Handle attack state self.handleAttackState = function () { // Check if enemy can attack player if (self.canAttackPlayer === false) { return; } // Play sword slash sound effect LK.getSound('sword_slash').play(); //toggle the canAttack so we dont' execute this again. self.canAttackPlayer = false; // Change enemy image to attack start self.removeChild(enemyGraphics); enemyGraphics = self.addChild(self.imageDictionary.enemy_attack_start); var curScale = self.scaleX; var curPos = { x: self.x, y: self.y }; // Animate enemy to move towards player and back tween(self, { x: player.x, y: player.y + player.height, scaleX: curScale + 2, scaleY: curScale + 2 }, { duration: 250, easing: tween.easeInOut, onFinish: function onFinish() { // Reduce health by making a circle invisible if (healthCircles.length > 0) { var circle = healthCircles.pop(); circle.visible = false; } // End game if no health circles are visible if (healthCircles.length === 0) { LK.showGameOver(); } //show attack_finish on anim finish self.removeChild(enemyGraphics); enemyGraphics = self.addChild(self.imageDictionary.enemy_attack_finish); // Flash the player's hands red to indicate an attack tween(handsIdleLeft, { tint: 0xFF0000 }, { duration: 250, onFinish: function onFinish() { tween(handsIdleLeft, { tint: 0xFFFFFF }, { duration: 250 }); } }); tween(handsIdleRight, { tint: 0xFF0000 }, { duration: 250, onFinish: function onFinish() { tween(handsIdleRight, { tint: 0xFFFFFF }, { duration: 250 }); } }); tween(self, { x: curPos.x, y: curPos.y, scaleX: curScale, scaleY: curScale }, { duration: 250, easing: tween.easeInOut, onFinish: function onFinish() { self.removeChild(enemyGraphics); enemyGraphics = self.addChild(self.imageDictionary.idle); } }); } }); }; // Dictionary of images for the enemy self.imageDictionary = { idle: LK.getAsset('enemy', { anchorX: 0.5, anchorY: 1 }), attack: LK.getAsset('hands_idle', { anchorX: 0.5, anchorY: 1 }), hit: LK.getAsset('bloodSplatter', { anchorX: 0.5, anchorY: 1 }), enemy_attack_start: LK.getAsset('enemy_attack_start', { anchorX: 0.5, anchorY: 1 }), enemy_attack_finish: LK.getAsset('enemy_attack_finish', { anchorX: 0.5, anchorY: 1 }) }; // Attach the default enemy image var enemyGraphics = self.addChild(self.imageDictionary.idle); self.health = Math.min(2 + Math.floor(killCounter / 5), 10); // Initialize health based on kill count self.reachedTarget = false; // Initialize reachedTarget to false self.canAttackPlayer = false; // Initialize canAttackPlayer to false self.speed = 0; self.scaleX = MinScale; self.scaleY = MinScale / 4; tween(self, { scaleX: MinScale, scaleY: MinScale }, { duration: 250, onFinish: function onFinish() { self.speed = 0; LK.setTimeout(function () { self.speed = 2; }, 500); } }); // Assign a random starting rotation to each enemy self.startRotation = Math.random() < 0.5 ? -1 : 1; self.handleTargetReached = function () {}; self.update = function () { self.handleState(); // Call state machine handler return; }; }); // FreezeBullet class var FreezeBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('FreezeBall', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 45; self.vx = 0; self.scaleX = MaxScale; self.scaleY = MaxScale; self.update = function () { self.scaleX -= 0.1; self.scaleY -= 0.1; self.y -= self.speed; self.x += self.vx; self.rotation += 0.1; // Add rotation effect if (self.scaleX <= MinScale && self.scaleY <= MinScale) { var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } game.removeChild(self); self.destroy(); } for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; var threshold = 0.1; if (self.intersects(enemy) && self.scaleY >= enemy.scaleY - threshold && self.scaleY <= enemy.scaleY + threshold) { // FreezeBullet hit the enemy // Show particle effect on impact var particleEffect = LK.getAsset('freezesplatter', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.5, scaleY: 0.5 }); particleEffect.x = self.x; particleEffect.y = self.y; game.addChild(particleEffect); tween(particleEffect, { alpha: 0, scaleX: 1, scaleY: 1 }, { duration: 500, onFinish: function onFinish() { game.removeChild(particleEffect); particleEffect.destroy(); } }); // Remove the bullet var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } game.removeChild(self); self.destroy(); // Decrease enemy health by 2 units // enemy.health -= 2; if (enemy.prevState != STATES.FREEZE) { enemy.prevState = enemy.state; enemy.state = STATES.FREEZE; } // Flash enemy red when hit tween(enemy, { tint: 0x0000ff }, { duration: 100, onFinish: function onFinish() { tween(enemy, { tint: 0xFFFFFF }, { duration: 100 }); } }); if (enemy.health <= 0) { // Destroy the enemy var enemyIndex = enemies.indexOf(enemy); if (enemyIndex > -1) { enemies.splice(enemyIndex, 1); } // Increment the kill counter killCounter++; killCounterText.setText('Kills: ' + killCounter); tween(enemy, { tint: 0xFF0000 }, { duration: 100, onFinish: function onFinish() { game.removeChild(enemy); enemy.destroy(); } }); } break; // Stop the loop after one enemy is killed } } // Apply fade-in effect using tween tween(self, { alpha: 1 }, { duration: 500, easing: tween.easeIn }); }; }); //<Assets used in the game will automatically appear here> // Player class var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.update = function () { // Make the player invisible self.alpha = 0; }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 //Init game with black background }); /**** * Game Code ****/ // Create a brown rectangle box to cover the width of the screen // Define states globally var GameplayEffects = function GameplayEffects(actor) { this.actor = actor; }; GameplayEffects.prototype.start = function () { // To be implemented by subclasses }; GameplayEffects.prototype.update = function () { // To be implemented by subclasses }; GameplayEffects.prototype.stop = function () { // To be implemented by subclasses }; var FireEffect = function FireEffect(actor) { GameplayEffects.call(this, actor); }; FireEffect.prototype = Object.create(GameplayEffects.prototype); FireEffect.prototype.constructor = FireEffect; FireEffect.prototype.start = function () { // Implement start logic for FireEffect }; FireEffect.prototype.update = function () { // Implement update logic for FireEffect }; FireEffect.prototype.stop = function () { // Implement stop logic for FireEffect }; var STATES = { SPAWN: 'spawn', MOVE: 'move', ATTACK: 'attack', WAIT: 'wait', FREEZE: 'freeze' }; var guiContainer = new Container(); var killCounterBackground = new Container(); var backgroundBox = LK.getAsset('rectangle', { anchorX: 0.5, anchorY: 0 }); backgroundBox.width = 2048; // Set width to cover the screen backgroundBox.height = 150; // Set height to fit behind the text backgroundBox.tint = 0x8B4513; // Brown color killCounterBackground.addChild(backgroundBox); killCounterBackground.y = 0; // Position at the top of the screen killCounterBackground.x = backgroundBox.width / 2; guiContainer.addChild(killCounterBackground); // Initialize kill counter var killCounter = 0; // Create a Text2 object to display the kill counter var killCounterText = new Text2('Kills: 0', { size: 100, fill: 0xf1ca04, font: "'Papyrus', 'Lucida Handwriting', 'Comic Sans MS'" // Use ancient script-like fonts }); killCounterText.anchor.set(0.5, 0); // Center the text horizontally killCounterText.x = killCounterBackground.width / 2; guiContainer.addChild(killCounterText); // Add the text to the GUI container // Initialize health circles var healthCircles = []; for (var i = 0; i < 3; i++) { var circle = LK.getAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5 }); circle.x = 2048 / 2 - 110 + i * 120; // Adjusted to have 20 units between circles circle.y = 2732 - 50; healthCircles.push(circle); guiContainer.addChild(circle); } // Initialize bullets var bullets = []; // Initialize bullet type var currentBulletType = 'magic'; // Create a small circle to indicate the selected bullet type var selectionIndicator = LK.getAsset('bulletselection', { anchorX: 0.5, anchorY: 0.5 }); selectionIndicator.scaleX = 1; selectionIndicator.scaleY = 1; guiContainer.addChild(selectionIndicator); // Function to update the position of the selection indicator function updateSelectionIndicator() { if (currentBulletType === 'magic') { selectionIndicator.x = magicButton.x; selectionIndicator.y = magicButton.y; } else if (currentBulletType === 'freeze' && typeof freezeButton !== 'undefined') { selectionIndicator.x = freezeButton.x; selectionIndicator.y = freezeButton.y; } } // Create button for Magic Ball var magicButton = LK.getAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); magicButton.x = 100; magicButton.y = 2732 - 100; guiContainer.addChild(magicButton); // Create button for Freeze Bullet var freezeButton = LK.getAsset('FreezeBall', { anchorX: 0.5, anchorY: 0.5 }); freezeButton.x = 100; freezeButton.y = 2732 - 300; guiContainer.addChild(freezeButton); // Create a fullscreen overlay var fullscreenOverlay = LK.getAsset('overlay', { anchorX: 0.5, anchorY: 0.5 }); fullscreenOverlay.x = 2048 / 2; fullscreenOverlay.y = 2732 / 2; fullscreenOverlay.width = 2048; fullscreenOverlay.height = 2732; fullscreenOverlay.color = "#000000"; fullscreenOverlay.alpha = 0.5; // Set transparency level fullscreenOverlay.visible = false; // Add the fullscreen overlay to the GUI container guiContainer.addChild(fullscreenOverlay); // Initial position of the selection indicator updateSelectionIndicator(); // Function to continuously fade in and out the selection indicator function animateSelectionIndicator() { tween(selectionIndicator, { alpha: 0.5 }, { duration: 500, easing: tween.easeInOut, onFinish: function onFinish() { tween(selectionIndicator, { alpha: 1 }, { duration: 500, easing: tween.easeInOut, onFinish: animateSelectionIndicator }); } }); } // Start the animation animateSelectionIndicator(); //initialize the locations of hands. var hand_initialy = 2732; var lefthand_initialx = 2048 / 2 - 600; var righthand_initialx = 2048 / 2 + 600; // Handle player movement game.move = function (x, y, obj) { player.x = (handsIdleLeft.x + handsIdleRight.x) / 2; player.y = (handsIdleLeft.y + handsIdleRight.y) / 2; }; // Handle shooting and hand animation game.down = function (x, y, obj) { console.log(obj, x, y); // Check if the click is on any bullet button var bulletButtons = [magicButton, freezeButton]; for (var index = 0; index < bulletButtons.length; index++) { var button = bulletButtons[index]; if (x >= button.x - button.width / 2 && x <= button.x + button.width / 2 && y >= button.y - button.height / 2 && y <= button.y + button.height / 2) { // Set current bullet type based on the button clicked currentBulletType = index === 0 ? 'magic' : 'freeze'; // Update the position of the selection indicator updateSelectionIndicator(); return; } } // Animate left hand tween(handsIdleLeft, { scaleX: 1.5, scaleY: 1.5, y: hand_initialy + 100 }, { duration: 125, easing: tween.easeInOut, onFinish: function onFinish() { tween(handsIdleLeft, { scaleX: 1, scaleY: 1, y: hand_initialy - 100 }, { duration: 125, easing: tween.easeInOut, onFinish: function onFinish() { // Create bullet after animation var bullet; if (currentBulletType === 'freeze') { bullet = new FreezeBullet(); } else { bullet = new Bullet(); } bullet.x = player.x; bullet.y = player.y - 100; var dx = (x - player.x) / bullet.speed; bullet.vx = dx; bullets.push(bullet); game.addChild(bullet); } }); } }); // Animate right hand tween(handsIdleRight, { scaleX: -1.5, scaleY: 1.5, y: hand_initialy + 100 }, { duration: 125, easing: tween.easeInOut, onFinish: function onFinish() { tween(handsIdleRight, { scaleX: -1, scaleY: 1, y: hand_initialy - 100 }, { duration: 125, easing: tween.easeInOut }); } }); }; game.addChild(player); // Initialize bullets var bullets = []; // Handle player movement game.move = function (x, y, obj) { player.x = x; player.y = y; }; // Handle shooting game.addChild(player); // Draw hands_idle image 200 units to the left of the horizontal center //<Assets used in the game will automatically appear here> var handsIdleLeft = game.addChild(LK.getAsset('hands_idle', { anchorX: 0.5, anchorY: 1 })); handsIdleLeft.x = lefthand_initialx; handsIdleLeft.y = hand_initialy; handsIdleLeft.rotation = Math.PI / 6; // Rotate 30 degrees //handsIdleLeft.scale.x = -1; // Draw hands_idle image 200 units to the right of the horizontal center var handsIdleRight = game.addChild(LK.getAsset('hands_idle', { anchorX: 0.5, anchorY: 1 })); handsIdleRight.x = righthand_initialx; handsIdleRight.y = hand_initialy; handsIdleRight.rotation = -Math.PI / 6; // Rotate -30 degrees handsIdleRight.scale.x = -1; // Initialize player // Define MinScale and MaxScale var MinScale = 1; var MaxScale = 4; var player = new Player(); player.x = 2048 / 2; player.y = 2732 - 200; // Initialize cyan rectangle var cyanRectangle = game.addChild(LK.getAsset('cyanRectangle', { anchorX: 0, anchorY: 1 })); cyanRectangle.x = 0; cyanRectangle.y = 2732 / 2; // Initialize another cyan rectangle var cyanRectangle2 = game.addChild(LK.getAsset('cyanRectangle', { anchorX: 1, anchorY: 1 })); cyanRectangle2.x = 2048; cyanRectangle2.y = 2732 / 2; // Initialize rectangle var rectangle = game.addChild(LK.getAsset('rectangle', { anchorX: 0.5, anchorY: 1 })); rectangle.x = 2048 / 2; rectangle.y = 2732 / 2; // Initialize grey rectangle var greyRectangle = game.addChildAt(LK.getAsset('greyRectangle', { anchorX: 0.5, anchorY: 0 }), 0); greyRectangle.x = 2048 / 2; greyRectangle.y = 2732 / 2; greyRectangle.height = 2732 / 2; // Adjust the height to cover the bottom half of the screen // Define base_y variable var base_y = greyRectangle.y - greyRectangle.height / 2; // Initialize enemies var enemies = []; var enemyContainer = new Container(); game.addChild(enemyContainer); var currentWave = 0; function spawnWave() { var predefinedPositions = [300, 700, 1100, 1500, 1900]; // Predefined x positions for enemies var usedPositions = []; // Track used positions for (var i = 0; i < currentWave % 2 + 1; i++) { var enemy = new Enemy(); var positionIndex; // Ensure each enemy picks a unique slot do { positionIndex = Math.floor(Math.random() * predefinedPositions.length); } while (usedPositions.includes(positionIndex)); usedPositions.push(positionIndex); enemy.x = predefinedPositions[positionIndex]; enemy.y = 2732 / 2 - enemy.height / 2 + 150; enemy.scaleX = 0; enemy.scaleY = 0; enemies.push(enemy); enemyContainer.addChild(enemy); // Tween enemy from random off screen point on X axis to spawn point var spawnX = enemy.x; enemy.x = Math.random() < 0.5 ? -100 : 2148; // Random off screen point on X axis tween(enemy, { x: spawnX }, { duration: 4000 }); } currentWave++; } spawnWave(); // Add enemies to game after the cyan and blue rectangles for (var i = 0; i < enemies.length; i++) { game.addChild(enemies[i]); } // Ensure hands are drawn over enemies game.addChild(handsIdleLeft); game.addChild(handsIdleRight); //add guicontainer after every other elment. game.addChild(guiContainer); // Initialize bullets var bullets = []; // Function to randomly select an enemy and set its canAttackPlayer to true function selectRandomEnemy() { if (enemies.length > 0) { // Reset all enemies' canAttackPlayer to false enemies.forEach(function (enemy) { return enemy.canAttackPlayer = false; }); // Select a random enemy var randomIndex = Math.floor(Math.random() * enemies.length); if (enemies[randomIndex].reachedTarget && enemies[randomIndex].state == STATES.ATTACK) { enemies[randomIndex].canAttackPlayer = true; } } } // Initialize enemy attack delay var enemyAttackDelay = 3000; // 3 seconds in milliseconds // Function to update enemy attack delay based on kill count function updateEnemyAttackDelay() { enemyAttackDelay = 3000 - Math.floor(killCounter / 5) * 100; if (enemyAttackDelay < 1000) { enemyAttackDelay = 1000; // Minimum delay of 1 second } } // Set interval to select a random enemy based on dynamic delay function scheduleEnemyAttack() { LK.setTimeout(function () { selectRandomEnemy(); scheduleEnemyAttack(); }, enemyAttackDelay); } // Start scheduling enemy attacks scheduleEnemyAttack(); // Handle player movement game.move = function (x, y, obj) {}; // Handle shooting // Add player to game game.addChild(player); // Game update loop game.update = function () { // Update enemies for (var j = 0; j < enemies.length; j++) { var enemy = enemies[j]; enemy.update(); } // Sort the enemies array in ascending order of enemy.y value enemyContainer.children.sort(function (a, b) { return a.y - b.y; }); // Tween tint of hands over 20 frames var tweenDuration = 500; var hand_boby = 20; if (LK.ticks % 60 === 0) { tween(handsIdleLeft, { y: hand_initialy - hand_boby }, { duration: tweenDuration, easing: tween.easeOut }); tween(handsIdleRight, { y: hand_initialy - hand_boby }, { duration: tweenDuration, easing: tween.easeOut }); } else if (LK.ticks % 60 === 30) { tween(handsIdleLeft, { y: hand_initialy + hand_boby }, { duration: tweenDuration, easing: tween.easeOut }); tween(handsIdleRight, { y: hand_initialy + hand_boby }, { duration: tweenDuration, easing: tween.easeOut }); } // Check if all enemies are dead or frozen if (enemies.length === 0) { // Spawn a new wave if all enemies are dead or frozen spawnWave(); } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Bullet class
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 45;
self.vx = 0;
self.scaleX = MaxScale;
self.scaleY = MaxScale;
self.update = function () {
self.scaleX -= 0.1;
self.scaleY -= 0.1;
self.y -= self.speed;
self.x += self.vx;
self.rotation += 0.1; // Add rotation effect
if (self.scaleX <= MinScale && self.scaleY <= MinScale) {
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
game.removeChild(self);
self.destroy();
}
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var threshold = 0.1;
if (self.intersects(enemy) && self.scaleY >= enemy.scaleY - threshold && self.scaleY <= enemy.scaleY + threshold) {
// Bullet hit the enemy
// Show particle effect on impact
var particleEffect = LK.getAsset('bloodSplatter', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
particleEffect.x = self.x;
particleEffect.y = self.y;
game.addChild(particleEffect);
tween(particleEffect, {
alpha: 0,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(particleEffect);
particleEffect.destroy();
}
});
// Remove the bullet
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
game.removeChild(self);
self.destroy();
//shake the enemy for 0.5 seconds if they are hit by bullet when frozen.
if (enemy.state == STATES.FREEZE) {
enemy.shake();
} else {
// Play orc_hurt1 or orc_hurt2 sound at random if the enemy is not frozen.
var hurtSound = Math.random() < 0.5 ? 'orc_hurt1' : 'orc_hurt2';
LK.getSound(hurtSound).play();
// Flash enemy red when hit
tween(enemy, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemy, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
}
// Decrease enemy health
enemy.health -= 1;
if (enemy.health <= 0 && enemy.state != STATES.DEAD) {
enemy.prevState = enemy.state;
enemy.state = STATES.DEAD;
// Increment the kill counter
killCounter++;
killCounterText.setText('Kills: ' + killCounter);
enemy.onDeath();
}
break; // Stop the loop after one enemy is killed
}
}
// Apply fade-in effect using tween
tween(self, {
alpha: 1
}, {
duration: 500,
easing: tween.easeIn
});
};
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Define states
var STATES = {
SPAWN: 'spawn',
MOVE: 'move',
ATTACK: 'attack',
WAIT: 'wait',
FREEZE: 'freeze',
HURT: 'hurt',
DEAD: 'dead'
};
// Initialize state
self.state = STATES.SPAWN;
self.prevState = null;
//handle dead state.
self.onDeath = function () {
var enemy = self;
// Destroy the enemy
var enemyIndex = enemies.indexOf(enemy);
if (enemyIndex > -1) {
enemies.splice(enemyIndex, 1);
}
tween(enemy, {
tint: 0xFF0000,
scaleY: enemy.scaleY - 0.5,
alpha: 0,
y: enemy.y - 300
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(enemy);
enemy.destroy();
}
});
};
self.shake = function () {
var offsetVal = Math.random() < 0.5 ? -10 : 10;
// Shake the enemy for 0.5 seconds
tween(self, {
x: self.x + offsetVal
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: self.x - offsetVal
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
x: self.x
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
}
});
};
// State machine handler
self.handleState = function () {
switch (self.state) {
case STATES.SPAWN:
self.handleSpawnState();
break;
case STATES.MOVE:
self.handleMoveState();
break;
case STATES.ATTACK:
self.handleAttackState();
break;
case STATES.WAIT:
self.handleWaitState();
break;
case STATES.FREEZE:
self.handleFreezeState();
break;
}
};
//handle freeze state.
self.handleFreezeState = function () {
// Tint the enemy blue
tween(self, {
tint: 0x0000FF
}, {
duration: 250,
onFinish: function onFinish() {
// Tint the enemy white
tween(self, {
tint: 0xFFFFFF
}, {
duration: 250,
onFinish: function onFinish() {
// Repeat the tinting effect for 5 seconds
LK.setTimeout(function () {
self.state = self.prevState; // Return to previous state after 5 seconds
}, 5000);
}
});
}
});
};
// Handle spawn state
self.handleSpawnState = function () {
// Transition to move state after spawn tween is done
if (self.speed == 2) {
self.prevState = self.state;
self.state = STATES.MOVE;
}
};
// Handle move state
self.handleMoveState = function () {
// Rotate enemy 10 degrees to the left and right alternatively
if (LK.ticks % 60 < 30) {
self.rotation = self.startRotation * Math.PI / 36; // Rotate 10 degrees to the left or right based on startRotation
} else {
self.rotation = -self.startRotation * Math.PI / 36; // Rotate 10 degrees to the right or left based on startRotation
}
if (self.y + self.speed < 2732 - 600) {
self.targetReachedTime = null; // Reset targetReachedTime when moving away from target
self.y += self.speed;
self.scaleX += 0.002;
self.scaleY += 0.002;
} else {
// Reset rotation to zero when reaching target
self.rotation = 0;
self.reachedTarget = true; // Set reachedTarget to true when target is reached
self.prevState = self.state;
//Transition to the wait state.
self.state = STATES.WAIT;
}
// Pause enemy movement every 0.5 seconds for a duration of 0.25 seconds
if (LK.ticks % 30 == 0) {
self.speed = 0;
LK.setTimeout(function () {
self.speed = 2;
}, 250);
}
};
// Handle wait state
self.handleWaitState = function () {
// Transition to move state after waiting for 1 second
if (!self.waitStartTime) {
self.waitStartTime = Date.now();
}
if (Date.now() - self.waitStartTime >= 1000) {
self.prevState = self.state;
self.state = STATES.ATTACK;
self.waitStartTime = null;
}
};
// Handle attack state
self.handleAttackState = function () {
// Check if enemy can attack player
if (self.canAttackPlayer === false) {
return;
}
// Play sword slash sound effect
LK.getSound('sword_slash').play();
//toggle the canAttack so we dont' execute this again.
self.canAttackPlayer = false;
// Change enemy image to attack start
self.removeChild(enemyGraphics);
enemyGraphics = self.addChild(self.imageDictionary.enemy_attack_start);
var curScale = self.scaleX;
var curPos = {
x: self.x,
y: self.y
};
// Animate enemy to move towards player and back
tween(self, {
x: player.x,
y: player.y + player.height,
scaleX: curScale + 2,
scaleY: curScale + 2
}, {
duration: 250,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Reduce health by making a circle invisible
if (healthCircles.length > 0) {
var circle = healthCircles.pop();
circle.visible = false;
}
// End game if no health circles are visible
if (healthCircles.length === 0) {
LK.showGameOver();
}
//show attack_finish on anim finish
self.removeChild(enemyGraphics);
enemyGraphics = self.addChild(self.imageDictionary.enemy_attack_finish);
// Flash the player's hands red to indicate an attack
tween(handsIdleLeft, {
tint: 0xFF0000
}, {
duration: 250,
onFinish: function onFinish() {
tween(handsIdleLeft, {
tint: 0xFFFFFF
}, {
duration: 250
});
}
});
tween(handsIdleRight, {
tint: 0xFF0000
}, {
duration: 250,
onFinish: function onFinish() {
tween(handsIdleRight, {
tint: 0xFFFFFF
}, {
duration: 250
});
}
});
tween(self, {
x: curPos.x,
y: curPos.y,
scaleX: curScale,
scaleY: curScale
}, {
duration: 250,
easing: tween.easeInOut,
onFinish: function onFinish() {
self.removeChild(enemyGraphics);
enemyGraphics = self.addChild(self.imageDictionary.idle);
}
});
}
});
};
// Dictionary of images for the enemy
self.imageDictionary = {
idle: LK.getAsset('enemy', {
anchorX: 0.5,
anchorY: 1
}),
attack: LK.getAsset('hands_idle', {
anchorX: 0.5,
anchorY: 1
}),
hit: LK.getAsset('bloodSplatter', {
anchorX: 0.5,
anchorY: 1
}),
enemy_attack_start: LK.getAsset('enemy_attack_start', {
anchorX: 0.5,
anchorY: 1
}),
enemy_attack_finish: LK.getAsset('enemy_attack_finish', {
anchorX: 0.5,
anchorY: 1
})
};
// Attach the default enemy image
var enemyGraphics = self.addChild(self.imageDictionary.idle);
self.health = Math.min(2 + Math.floor(killCounter / 5), 10); // Initialize health based on kill count
self.reachedTarget = false; // Initialize reachedTarget to false
self.canAttackPlayer = false; // Initialize canAttackPlayer to false
self.speed = 0;
self.scaleX = MinScale;
self.scaleY = MinScale / 4;
tween(self, {
scaleX: MinScale,
scaleY: MinScale
}, {
duration: 250,
onFinish: function onFinish() {
self.speed = 0;
LK.setTimeout(function () {
self.speed = 2;
}, 500);
}
});
// Assign a random starting rotation to each enemy
self.startRotation = Math.random() < 0.5 ? -1 : 1;
self.handleTargetReached = function () {};
self.update = function () {
self.handleState(); // Call state machine handler
return;
};
});
// FreezeBullet class
var FreezeBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('FreezeBall', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 45;
self.vx = 0;
self.scaleX = MaxScale;
self.scaleY = MaxScale;
self.update = function () {
self.scaleX -= 0.1;
self.scaleY -= 0.1;
self.y -= self.speed;
self.x += self.vx;
self.rotation += 0.1; // Add rotation effect
if (self.scaleX <= MinScale && self.scaleY <= MinScale) {
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
game.removeChild(self);
self.destroy();
}
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var threshold = 0.1;
if (self.intersects(enemy) && self.scaleY >= enemy.scaleY - threshold && self.scaleY <= enemy.scaleY + threshold) {
// FreezeBullet hit the enemy
// Show particle effect on impact
var particleEffect = LK.getAsset('freezesplatter', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.5,
scaleY: 0.5
});
particleEffect.x = self.x;
particleEffect.y = self.y;
game.addChild(particleEffect);
tween(particleEffect, {
alpha: 0,
scaleX: 1,
scaleY: 1
}, {
duration: 500,
onFinish: function onFinish() {
game.removeChild(particleEffect);
particleEffect.destroy();
}
});
// Remove the bullet
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
game.removeChild(self);
self.destroy();
// Decrease enemy health by 2 units
// enemy.health -= 2;
if (enemy.prevState != STATES.FREEZE) {
enemy.prevState = enemy.state;
enemy.state = STATES.FREEZE;
}
// Flash enemy red when hit
tween(enemy, {
tint: 0x0000ff
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemy, {
tint: 0xFFFFFF
}, {
duration: 100
});
}
});
if (enemy.health <= 0) {
// Destroy the enemy
var enemyIndex = enemies.indexOf(enemy);
if (enemyIndex > -1) {
enemies.splice(enemyIndex, 1);
}
// Increment the kill counter
killCounter++;
killCounterText.setText('Kills: ' + killCounter);
tween(enemy, {
tint: 0xFF0000
}, {
duration: 100,
onFinish: function onFinish() {
game.removeChild(enemy);
enemy.destroy();
}
});
}
break; // Stop the loop after one enemy is killed
}
}
// Apply fade-in effect using tween
tween(self, {
alpha: 1
}, {
duration: 500,
easing: tween.easeIn
});
};
});
//<Assets used in the game will automatically appear here>
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.update = function () {
// Make the player invisible
self.alpha = 0;
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 //Init game with black background
});
/****
* Game Code
****/
// Create a brown rectangle box to cover the width of the screen
// Define states globally
var GameplayEffects = function GameplayEffects(actor) {
this.actor = actor;
};
GameplayEffects.prototype.start = function () {
// To be implemented by subclasses
};
GameplayEffects.prototype.update = function () {
// To be implemented by subclasses
};
GameplayEffects.prototype.stop = function () {
// To be implemented by subclasses
};
var FireEffect = function FireEffect(actor) {
GameplayEffects.call(this, actor);
};
FireEffect.prototype = Object.create(GameplayEffects.prototype);
FireEffect.prototype.constructor = FireEffect;
FireEffect.prototype.start = function () {
// Implement start logic for FireEffect
};
FireEffect.prototype.update = function () {
// Implement update logic for FireEffect
};
FireEffect.prototype.stop = function () {
// Implement stop logic for FireEffect
};
var STATES = {
SPAWN: 'spawn',
MOVE: 'move',
ATTACK: 'attack',
WAIT: 'wait',
FREEZE: 'freeze'
};
var guiContainer = new Container();
var killCounterBackground = new Container();
var backgroundBox = LK.getAsset('rectangle', {
anchorX: 0.5,
anchorY: 0
});
backgroundBox.width = 2048; // Set width to cover the screen
backgroundBox.height = 150; // Set height to fit behind the text
backgroundBox.tint = 0x8B4513; // Brown color
killCounterBackground.addChild(backgroundBox);
killCounterBackground.y = 0; // Position at the top of the screen
killCounterBackground.x = backgroundBox.width / 2;
guiContainer.addChild(killCounterBackground);
// Initialize kill counter
var killCounter = 0;
// Create a Text2 object to display the kill counter
var killCounterText = new Text2('Kills: 0', {
size: 100,
fill: 0xf1ca04,
font: "'Papyrus', 'Lucida Handwriting', 'Comic Sans MS'" // Use ancient script-like fonts
});
killCounterText.anchor.set(0.5, 0); // Center the text horizontally
killCounterText.x = killCounterBackground.width / 2;
guiContainer.addChild(killCounterText); // Add the text to the GUI container
// Initialize health circles
var healthCircles = [];
for (var i = 0; i < 3; i++) {
var circle = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5
});
circle.x = 2048 / 2 - 110 + i * 120; // Adjusted to have 20 units between circles
circle.y = 2732 - 50;
healthCircles.push(circle);
guiContainer.addChild(circle);
}
// Initialize bullets
var bullets = [];
// Initialize bullet type
var currentBulletType = 'magic';
// Create a small circle to indicate the selected bullet type
var selectionIndicator = LK.getAsset('bulletselection', {
anchorX: 0.5,
anchorY: 0.5
});
selectionIndicator.scaleX = 1;
selectionIndicator.scaleY = 1;
guiContainer.addChild(selectionIndicator);
// Function to update the position of the selection indicator
function updateSelectionIndicator() {
if (currentBulletType === 'magic') {
selectionIndicator.x = magicButton.x;
selectionIndicator.y = magicButton.y;
} else if (currentBulletType === 'freeze' && typeof freezeButton !== 'undefined') {
selectionIndicator.x = freezeButton.x;
selectionIndicator.y = freezeButton.y;
}
}
// Create button for Magic Ball
var magicButton = LK.getAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
magicButton.x = 100;
magicButton.y = 2732 - 100;
guiContainer.addChild(magicButton);
// Create button for Freeze Bullet
var freezeButton = LK.getAsset('FreezeBall', {
anchorX: 0.5,
anchorY: 0.5
});
freezeButton.x = 100;
freezeButton.y = 2732 - 300;
guiContainer.addChild(freezeButton);
// Create a fullscreen overlay
var fullscreenOverlay = LK.getAsset('overlay', {
anchorX: 0.5,
anchorY: 0.5
});
fullscreenOverlay.x = 2048 / 2;
fullscreenOverlay.y = 2732 / 2;
fullscreenOverlay.width = 2048;
fullscreenOverlay.height = 2732;
fullscreenOverlay.color = "#000000";
fullscreenOverlay.alpha = 0.5; // Set transparency level
fullscreenOverlay.visible = false;
// Add the fullscreen overlay to the GUI container
guiContainer.addChild(fullscreenOverlay);
// Initial position of the selection indicator
updateSelectionIndicator();
// Function to continuously fade in and out the selection indicator
function animateSelectionIndicator() {
tween(selectionIndicator, {
alpha: 0.5
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(selectionIndicator, {
alpha: 1
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: animateSelectionIndicator
});
}
});
}
// Start the animation
animateSelectionIndicator();
//initialize the locations of hands.
var hand_initialy = 2732;
var lefthand_initialx = 2048 / 2 - 600;
var righthand_initialx = 2048 / 2 + 600;
// Handle player movement
game.move = function (x, y, obj) {
player.x = (handsIdleLeft.x + handsIdleRight.x) / 2;
player.y = (handsIdleLeft.y + handsIdleRight.y) / 2;
};
// Handle shooting and hand animation
game.down = function (x, y, obj) {
console.log(obj, x, y);
// Check if the click is on any bullet button
var bulletButtons = [magicButton, freezeButton];
for (var index = 0; index < bulletButtons.length; index++) {
var button = bulletButtons[index];
if (x >= button.x - button.width / 2 && x <= button.x + button.width / 2 && y >= button.y - button.height / 2 && y <= button.y + button.height / 2) {
// Set current bullet type based on the button clicked
currentBulletType = index === 0 ? 'magic' : 'freeze';
// Update the position of the selection indicator
updateSelectionIndicator();
return;
}
}
// Animate left hand
tween(handsIdleLeft, {
scaleX: 1.5,
scaleY: 1.5,
y: hand_initialy + 100
}, {
duration: 125,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(handsIdleLeft, {
scaleX: 1,
scaleY: 1,
y: hand_initialy - 100
}, {
duration: 125,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Create bullet after animation
var bullet;
if (currentBulletType === 'freeze') {
bullet = new FreezeBullet();
} else {
bullet = new Bullet();
}
bullet.x = player.x;
bullet.y = player.y - 100;
var dx = (x - player.x) / bullet.speed;
bullet.vx = dx;
bullets.push(bullet);
game.addChild(bullet);
}
});
}
});
// Animate right hand
tween(handsIdleRight, {
scaleX: -1.5,
scaleY: 1.5,
y: hand_initialy + 100
}, {
duration: 125,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(handsIdleRight, {
scaleX: -1,
scaleY: 1,
y: hand_initialy - 100
}, {
duration: 125,
easing: tween.easeInOut
});
}
});
};
game.addChild(player);
// Initialize bullets
var bullets = [];
// Handle player movement
game.move = function (x, y, obj) {
player.x = x;
player.y = y;
};
// Handle shooting
game.addChild(player);
// Draw hands_idle image 200 units to the left of the horizontal center
//<Assets used in the game will automatically appear here>
var handsIdleLeft = game.addChild(LK.getAsset('hands_idle', {
anchorX: 0.5,
anchorY: 1
}));
handsIdleLeft.x = lefthand_initialx;
handsIdleLeft.y = hand_initialy;
handsIdleLeft.rotation = Math.PI / 6; // Rotate 30 degrees
//handsIdleLeft.scale.x = -1;
// Draw hands_idle image 200 units to the right of the horizontal center
var handsIdleRight = game.addChild(LK.getAsset('hands_idle', {
anchorX: 0.5,
anchorY: 1
}));
handsIdleRight.x = righthand_initialx;
handsIdleRight.y = hand_initialy;
handsIdleRight.rotation = -Math.PI / 6; // Rotate -30 degrees
handsIdleRight.scale.x = -1;
// Initialize player
// Define MinScale and MaxScale
var MinScale = 1;
var MaxScale = 4;
var player = new Player();
player.x = 2048 / 2;
player.y = 2732 - 200;
// Initialize cyan rectangle
var cyanRectangle = game.addChild(LK.getAsset('cyanRectangle', {
anchorX: 0,
anchorY: 1
}));
cyanRectangle.x = 0;
cyanRectangle.y = 2732 / 2;
// Initialize another cyan rectangle
var cyanRectangle2 = game.addChild(LK.getAsset('cyanRectangle', {
anchorX: 1,
anchorY: 1
}));
cyanRectangle2.x = 2048;
cyanRectangle2.y = 2732 / 2;
// Initialize rectangle
var rectangle = game.addChild(LK.getAsset('rectangle', {
anchorX: 0.5,
anchorY: 1
}));
rectangle.x = 2048 / 2;
rectangle.y = 2732 / 2;
// Initialize grey rectangle
var greyRectangle = game.addChildAt(LK.getAsset('greyRectangle', {
anchorX: 0.5,
anchorY: 0
}), 0);
greyRectangle.x = 2048 / 2;
greyRectangle.y = 2732 / 2;
greyRectangle.height = 2732 / 2; // Adjust the height to cover the bottom half of the screen
// Define base_y variable
var base_y = greyRectangle.y - greyRectangle.height / 2;
// Initialize enemies
var enemies = [];
var enemyContainer = new Container();
game.addChild(enemyContainer);
var currentWave = 0;
function spawnWave() {
var predefinedPositions = [300, 700, 1100, 1500, 1900]; // Predefined x positions for enemies
var usedPositions = []; // Track used positions
for (var i = 0; i < currentWave % 2 + 1; i++) {
var enemy = new Enemy();
var positionIndex;
// Ensure each enemy picks a unique slot
do {
positionIndex = Math.floor(Math.random() * predefinedPositions.length);
} while (usedPositions.includes(positionIndex));
usedPositions.push(positionIndex);
enemy.x = predefinedPositions[positionIndex];
enemy.y = 2732 / 2 - enemy.height / 2 + 150;
enemy.scaleX = 0;
enemy.scaleY = 0;
enemies.push(enemy);
enemyContainer.addChild(enemy);
// Tween enemy from random off screen point on X axis to spawn point
var spawnX = enemy.x;
enemy.x = Math.random() < 0.5 ? -100 : 2148; // Random off screen point on X axis
tween(enemy, {
x: spawnX
}, {
duration: 4000
});
}
currentWave++;
}
spawnWave();
// Add enemies to game after the cyan and blue rectangles
for (var i = 0; i < enemies.length; i++) {
game.addChild(enemies[i]);
}
// Ensure hands are drawn over enemies
game.addChild(handsIdleLeft);
game.addChild(handsIdleRight);
//add guicontainer after every other elment.
game.addChild(guiContainer);
// Initialize bullets
var bullets = [];
// Function to randomly select an enemy and set its canAttackPlayer to true
function selectRandomEnemy() {
if (enemies.length > 0) {
// Reset all enemies' canAttackPlayer to false
enemies.forEach(function (enemy) {
return enemy.canAttackPlayer = false;
});
// Select a random enemy
var randomIndex = Math.floor(Math.random() * enemies.length);
if (enemies[randomIndex].reachedTarget && enemies[randomIndex].state == STATES.ATTACK) {
enemies[randomIndex].canAttackPlayer = true;
}
}
}
// Initialize enemy attack delay
var enemyAttackDelay = 3000; // 3 seconds in milliseconds
// Function to update enemy attack delay based on kill count
function updateEnemyAttackDelay() {
enemyAttackDelay = 3000 - Math.floor(killCounter / 5) * 100;
if (enemyAttackDelay < 1000) {
enemyAttackDelay = 1000; // Minimum delay of 1 second
}
}
// Set interval to select a random enemy based on dynamic delay
function scheduleEnemyAttack() {
LK.setTimeout(function () {
selectRandomEnemy();
scheduleEnemyAttack();
}, enemyAttackDelay);
}
// Start scheduling enemy attacks
scheduleEnemyAttack();
// Handle player movement
game.move = function (x, y, obj) {};
// Handle shooting
// Add player to game
game.addChild(player);
// Game update loop
game.update = function () {
// Update enemies
for (var j = 0; j < enemies.length; j++) {
var enemy = enemies[j];
enemy.update();
}
// Sort the enemies array in ascending order of enemy.y value
enemyContainer.children.sort(function (a, b) {
return a.y - b.y;
});
// Tween tint of hands over 20 frames
var tweenDuration = 500;
var hand_boby = 20;
if (LK.ticks % 60 === 0) {
tween(handsIdleLeft, {
y: hand_initialy - hand_boby
}, {
duration: tweenDuration,
easing: tween.easeOut
});
tween(handsIdleRight, {
y: hand_initialy - hand_boby
}, {
duration: tweenDuration,
easing: tween.easeOut
});
} else if (LK.ticks % 60 === 30) {
tween(handsIdleLeft, {
y: hand_initialy + hand_boby
}, {
duration: tweenDuration,
easing: tween.easeOut
});
tween(handsIdleRight, {
y: hand_initialy + hand_boby
}, {
duration: tweenDuration,
easing: tween.easeOut
});
}
// Check if all enemies are dead or frozen
if (enemies.length === 0) {
// Spawn a new wave if all enemies are dead or frozen
spawnWave();
}
};
magic energy ball in 16 bit pixel art style. It should have a glow effect so it feels like a powerful magic spell. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
brick wall with shield and swords hanging in the middle of it.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
the brick wall is seamless and i should be able to use it to repeat the image multiple times by placing them side by side.
dungeon floor with cracks in the floor. Small grass scattered on the floor. . No shadows. 2d. In-Game asset. flat
red colored heart for representing player health in the game.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Magical projectile that will freeze the enemies.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
magic projectile impact effect. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
magical fireball. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
orc mage, leather armor, staff with glowing crystal with freezing power. front facing, arms and legs clearly visible, wearing a hood made of cloth.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows, 16 bit pixel art