Code edit (1 edits merged)
Please save this source code
User prompt
show enemy_attack_finish when the enemy reaches player position. Change the image shown back to enemy when enemy moves away from player.
User prompt
i want to show the enemy_attack_start image when the enemy starts the attack animation.
User prompt
add "enemy_attack_start" and "enemy_attack_finish" to the imageDictionary.
Code edit (1 edits merged)
Please save this source code
User prompt
I want the enemies to not use image width and height to check collisions. I want them to have their own width and height values that are set to 300, 300 to be used for collision checks.
User prompt
Update the collision dimensions to 300 , 300
User prompt
Separate out the domensions used to draw enemy image on screen and the dimensions used for collision detection
User prompt
When the enemy is drawn on screen, its width and height are to be used and not the enemy width and height
User prompt
Enemy with and height should be defined as 300, 300 instead of using the image width and height
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: palyer is not defined' in or related to this line: 'tween(self, {' Line Number: 141
Code edit (1 edits merged)
Please save this source code
User prompt
ensure that that an enemy can attack the player only after it has been at the target for atleast 1 second.
User prompt
when selecting at random for attacking the player it should check if the enemy has reached the target or not.
User prompt
the delay after which an enemy is given the ability to attack should keep changing as the player gets more kills. Initially it should start from 3 seconds. After that it should reduce by 0.1 seconds for every 5 kills that the player makes.
User prompt
draw the hearts with 20 units between them.
User prompt
draw the hearts below the wooden box at the top of the screen. Draw them with a gap of 20 units between them.
User prompt
move the hearts representing player health to the top left corner and draw each heart with 10 units distance between them.
User prompt
i want to show three circles at the bottom of the screen horizontally centered that show the health that the player has. Each hit from enemy should make one circle invisible and when all the 3 circles are invisible the game ends.
User prompt
i would like the players hands to flash red instead of the full screen.
User prompt
when the enemy attacks the player i would like the full screen to flash red.
User prompt
for each enemy i would like to have a dictionary of images that i can pick and draw from.
Code edit (3 edits merged)
Please save this source code
User prompt
In the enemy update function, if the enemy has reached its' target and canattackplayer then animate the enemy to move towards the player and back to their target position in 0.5 seconds. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/**** * 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 = 0; i < enemies.length; 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 // Remove the bullet var index = bullets.indexOf(self); if (index > -1) { bullets.splice(index, 1); } game.removeChild(self); self.destroy(); // 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 }); }; }); // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); // 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.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 = 5; }, 500); } }); // Assign a random starting rotation to each enemy self.startRotation = Math.random() < 0.5 ? -1 : 1; self.handleTargetReached = function () { // Check if enemy can attack player if (self.canAttackPlayer === false) { return; } //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 / 2, 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.enemy); } }); } }); }; self.update = function () { if (self.speed < 1) { return; } // 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.01; self.scaleY += 0.01; } else { // Reset rotation to zero when reaching target self.rotation = 0; self.reachedTarget = true; // Set reachedTarget to true when target is reached if (!self.targetReachedTime) { self.targetReachedTime = Date.now(); // Record the time when the target is reached } if (Date.now() - self.targetReachedTime >= 1000) { // Check if 1 second has passed self.handleTargetReached(); } } // 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 = 5; }, 250); } }; }); //<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 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 LK.gui.top.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: 0xFFFFFF, font: "'Papyrus', 'Lucida Handwriting', 'Comic Sans MS'" // Use ancient script-like fonts }); killCounterText.anchor.set(0.5, 0); // Center the text horizontally LK.gui.top.addChild(killCounterText); // Add the text to the top of the screen // 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); game.addChild(circle); } // Initialize bullets var bullets = []; //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) { // 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 = 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 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 + 50; enemy.scaleX = 0; enemy.scaleY = 0; enemies.push(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]); } // 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].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(); } // 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 if (enemies.length === 0) { // Spawn a new wave if all enemies are dead spawnWave(); // Add enemies to game after the cyan and blue rectangles for (var i = 0; i < enemies.length; i++) { game.addChild(enemies[i]); } } };
===================================================================
--- original.js
+++ change.js
@@ -152,8 +152,11 @@
// 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
}, {
@@ -184,9 +187,13 @@
scaleX: curScale,
scaleY: curScale
}, {
duration: 250,
- easing: tween.easeInOut
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ self.removeChild(enemyGraphics);
+ enemyGraphics = self.addChild(self.imageDictionary.enemy);
+ }
});
}
});
};
@@ -204,13 +211,8 @@
self.targetReachedTime = null; // Reset targetReachedTime when moving away from target
self.y += self.speed;
self.scaleX += 0.01;
self.scaleY += 0.01;
- // Change back to idle image when moving away
- if (enemyGraphics !== self.imageDictionary.idle) {
- self.removeChild(enemyGraphics);
- enemyGraphics = self.addChild(self.imageDictionary.idle);
- }
} else {
// Reset rotation to zero when reaching target
self.rotation = 0;
self.reachedTarget = true; // Set reachedTarget to true when target is reached
@@ -219,13 +221,8 @@
}
if (Date.now() - self.targetReachedTime >= 1000) {
// Check if 1 second has passed
self.handleTargetReached();
- // Change to attack finish image when reaching player
- if (enemyGraphics !== self.imageDictionary.enemy_attack_finish) {
- self.removeChild(enemyGraphics);
- enemyGraphics = self.addChild(self.imageDictionary.enemy_attack_finish);
- }
}
}
// Pause enemy movement every 0.5 seconds for a duration of 0.25 seconds
if (LK.ticks % 30 == 0) {
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