Code edit (2 edits merged)
Please save this source code
User prompt
if the player goes to attack state while in jump state, the player should go to jump state after the attack anim_finish event is recieved.
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'state')' in or related to this line: 'if (enemies[j].state === 'dead') {' Line Number: 776
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'sendEvent')' in or related to this line: 'enemy.sendEvent(GameEvents.BULLET_HIT, self);' Line Number: 786
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'state')' in or related to this line: 'if (typeof enemies[j].state === 'undefined' || enemies[j].state === 'dead') {' Line Number: 784
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'state')' in or related to this line: 'if (enemies[j].state == 'undefined' || enemies[j].state === 'dead') {' Line Number: 780
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'state')' in or related to this line: 'if (enemies[j].state === 'dead') {' Line Number: 780
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'state')' in or related to this line: 'if (enemies[j].state === 'dead') {' Line Number: 780
Code edit (1 edits merged)
Please save this source code
User prompt
when bullet is moving away from the player, it starts spinning and starts collisions with enemies and sends the BULLET_HIT event to them.
Code edit (1 edits merged)
Please save this source code
User prompt
If the player hits the bullet in attack state, the bullet needs to change direction.
User prompt
player goes to dead state when he is hit by bullet in idle or jumping state.
Code edit (1 edits merged)
Please save this source code
Code edit (7 edits merged)
Please save this source code
User prompt
add a new game event called BULLET_HIT to GameEvents. BULLET_HIT event is sent to player when player is hit by the enemy bullet.
User prompt
bullets should be added to bullet container. bullet container is added to game after the enemy container.
User prompt
all the enemies should be added to enemy container.
Code edit (2 edits merged)
Please save this source code
User prompt
Enemy2 plays idle animation when it enters attack state. It then waits for attack timer to reach 0. Once the attack timer reaches 0, we play the attack animation. On ANIMATION_FINISHED event for attack anim, we shoot a bullet at the player using enemy_horn image.
User prompt
the enemy2 spawns only if the player score is greater than or equal to 5
/**** 
* Plugins
****/ 
var tween = LK.import("@upit/tween.v1");
/**** 
* Classes
****/ 
var Bullet = Container.expand(function () {
	var self = Container.call(this);
	var bulletGraphics = self.attachAsset('enemy2_horn', {
		anchorX: 0.5,
		anchorY: 0.5
	});
	self.speed = 10;
	self.update = function () {
		self.x -= self.speed;
		if (self.x < 0) {
			self.destroy();
		}
	};
});
var Enemy = Container.expand(function () {
	var self = Container.call(this);
	self.images = {
		"dead": LK.getAsset('enemy1_dead', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"walk1": LK.getAsset('enemy1_walk1', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"walk2": LK.getAsset('enemy1_walk2', {
			anchorX: 0.5,
			anchorY: 0.5
		})
	};
	//replacing the asset ref with the image added.
	for (var img_name in self.images) {
		var img = self.addChild(self.images[img_name]);
		img.visible = false;
		self.images[img_name] = img;
	}
	//configure the animation frames.
	self.anims = {
		'walk': new FrameAnimation([self.images.walk1, self.images.walk2], 300),
		'dead': new FrameAnimation([self.images.dead], 100)
	};
	var enemyGraphics = {
		height: 300,
		width: 300
	};
	// Add a red rectangle to the enemy's head
	self.headCollider = self.attachAsset('enemyRectangle', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 200,
		height: 100
	});
	self.headCollider.y = -enemyGraphics.height / 4; // Position the rectangle on the enemy's head
	self.headCollider.alpha = 0;
	// Add a bodyCollider rectangle to the bottom part of the enemy
	self.bodyCollider = self.attachAsset('enemyRectangle', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 150,
		height: 150,
		color: 0xffff00
	});
	self.bodyCollider.y = enemyGraphics.height / 4; // Position the rectangle on the enemy's body
	self.bodyCollider.alpha = 0;
	self.speed = 5;
	self.state;
	self.removeFromArray = false;
	self.states = {
		moving: {
			onEnter: function onEnter() {
				console.log('Enemy starts moving');
				self.anims['walk'].play();
			},
			onUpdate: function onUpdate() {
				self.x -= self.speed;
			},
			onExit: function onExit() {
				console.log('Enemy stops moving');
				self.anims['walk'].stop();
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in moving state: ', event, data);
				if (event === GameEvents.COLLISION_ENEMY_HEAD) {
					self.setState('dead');
				}
			}
		},
		dead: {
			onEnter: function onEnter() {
				console.log('Enemy has died');
				self.anims['dead'].play();
				self.speed = 0;
				var y_val = self.y - Math.random() * 150;
				var x_val = self.x + 100 + Math.random() * 200;
				tween(self, {
					x: x_val,
					y: y_val,
					rotation: Math.PI / 6 // 30 degrees in radians
				}, {
					duration: 250,
					easing: tween.expoOut,
					onFinish: function onFinish() {
						tween(self, {
							y: 2732 + 300
						}, {
							duration: 500,
							easing: tween.expoIn,
							onFinish: function onFinish() {
								self.removeFromArray = true;
							}
						});
					}
				});
			},
			onUpdate: function onUpdate() {},
			onExit: function onExit() {
				console.log('Exiting dead state');
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in dead state: ', event, data);
			}
		}
	};
	self.setState = function (state) {
		if (self.state) {
			self.states[self.state].onExit();
		}
		self.state = state;
		self.states[self.state].onEnter();
	};
	self.sendEvent = function (event, data) {
		if (self.state) {
			self.states[self.state].onEvent(event, data);
		}
	};
	self.update = function () {
		self.states[self.state].onUpdate();
	};
	self.setState('moving');
});
var Enemy2 = Container.expand(function () {
	var self = Container.call(this);
	self.images = {
		"dead": LK.getAsset('enemy2_dead', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"walk1": LK.getAsset('enemy2_walk1', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"walk2": LK.getAsset('enemy2_walk2', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"attack1": LK.getAsset('enemy2_attack1', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"attack2": LK.getAsset('enemy2_attack2', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"horn": LK.getAsset('enemy2_horn', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"idle1": LK.getAsset('enemy2_idle1', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"idle2": LK.getAsset('enemy2_idle2', {
			anchorX: 0.5,
			anchorY: 0.5
		})
	};
	for (var img_name in self.images) {
		var img = self.addChild(self.images[img_name]);
		img.visible = false;
		self.images[img_name] = img;
	}
	self.anims = {
		'walk': new FrameAnimation([self.images.walk1, self.images.walk2], 300),
		'dead': new FrameAnimation([self.images.dead], 100),
		'idle': new FrameAnimation([self.images.idle1, self.images.idle2], 300),
		// New idle animation
		'attack': new FrameAnimation([self.images.attack1, self.images.attack2], 300) // New attack animation
	};
	var enemyGraphics = {
		height: 300,
		width: 300
	};
	self.headCollider = self.attachAsset('enemyRectangle', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 200,
		height: 100
	});
	self.headCollider.y = -enemyGraphics.height / 4;
	self.headCollider.alpha = 0;
	self.bodyCollider = self.attachAsset('enemyRectangle', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 150,
		height: 150,
		color: 0xffff00
	});
	self.bodyCollider.y = enemyGraphics.height / 4;
	self.bodyCollider.alpha = 0;
	self.speed = 5;
	self.state;
	self.removeFromArray = false;
	self.states = {
		moving: {
			onEnter: function onEnter() {
				console.log('Enemy2 starts moving');
				self.anims['walk'].play();
			},
			onUpdate: function onUpdate() {
				self.x -= self.speed;
				// Transition to attack state when reaching 2/3rd of the screen
				if (self.lastX > 2048 * (2 / 3) && self.x <= 2048 * (2 / 3)) {
					self.setState('attack');
				}
				self.lastX = self.x;
			},
			onExit: function onExit() {
				console.log('Enemy2 stops moving');
				self.anims['walk'].stop();
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in moving state: ', event, data);
				if (event === GameEvents.COLLISION_ENEMY_HEAD) {
					self.setState('dead');
				}
			}
		},
		attack: {
			// New attack state
			onEnter: function onEnter() {
				console.log('Enemy2 starts attacking');
				self.anims['idle'].play(); // Play idle animation
				self.attackTimer = 500; // Set attack timer
			},
			onUpdate: function onUpdate() {
				if (self.attackTimer > 0) {
					self.attackTimer--; // Decrease attack timer
				} else {
					self.anims['idle'].stop(); // Stop idle animation
					self.anims['attack'].play(); // Play attack animation
					self.attackTimer = 1000;
				}
			},
			onExit: function onExit() {
				console.log('Enemy2 stops attacking');
				self.anims['idle'].stop();
				self.anims['attack'].stop();
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in attack state: ', event, data);
				if (event === GameEvents.ANIM_FINISHED && data == self.anims['attack']) {
					// Shoot a bullet at the player using enemy_horn image
					var bullet = new Bullet(self.images.horn);
					bullet.x = self.x;
					bullet.y = self.y;
					game.addChild(bullet);
					self.anims['attack'].stop();
					self.anims['idle'].play();
					self.attackTimer = 500;
				} else if (event === GameEvents.COLLISION_ENEMY_HEAD) {
					self.setState('dead');
				}
			}
		},
		// End of new attack state
		dead: {
			onEnter: function onEnter() {
				console.log('Enemy2 has died');
				self.anims['dead'].play();
				self.speed = 0;
				var y_val = self.y - Math.random() * 150;
				var x_val = self.x + 100 + Math.random() * 200;
				tween(self, {
					x: x_val,
					y: y_val,
					rotation: Math.PI / 6
				}, {
					duration: 250,
					easing: tween.expoOut,
					onFinish: function onFinish() {
						tween(self, {
							y: 2732 + 300
						}, {
							duration: 500,
							easing: tween.expoIn,
							onFinish: function onFinish() {
								self.removeFromArray = true;
							}
						});
					}
				});
			},
			onUpdate: function onUpdate() {},
			onExit: function onExit() {
				console.log('Exiting dead state');
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in dead state: ', event, data);
			}
		}
	};
	self.setState = function (state) {
		if (self.state) {
			self.states[self.state].onExit();
		}
		self.state = state;
		self.states[self.state].onEnter();
	};
	self.sendEvent = function (event, data) {
		if (self.state) {
			self.states[self.state].onEvent(event, data);
		}
	};
	self.update = function () {
		self.states[self.state].onUpdate();
	};
	self.setState('moving');
});
//<Assets used in the game will automatically appear here>
// Define a class for the player character
var Player = Container.expand(function () {
	var self = Container.call(this);
	self.images = {
		"idle": LK.getAsset('player', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"jump": LK.getAsset('player_jump', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"walk1": LK.getAsset('walk_1', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		"walk2": LK.getAsset('walk_2', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		'dead': LK.getAsset('player_dead', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		'attack1': LK.getAsset('player_attack1', {
			anchorX: 0.5,
			anchorY: 0.5
		}),
		'attack2': LK.getAsset('player_attack2', {
			anchorX: 0.5,
			anchorY: 0.5
		})
	};
	self.speed = 5;
	self.jumpHeight = 40;
	self.isJumping = false;
	self.velocityY = 0;
	self.state;
	//replacing the asset ref with the image added.
	for (var img_name in self.images) {
		var img = self.addChild(self.images[img_name]);
		img.visible = false;
		self.images[img_name] = img;
	}
	// Add a bodyCollider rectangle to the player character
	self.bodyCollider = self.attachAsset('collider', {
		anchorX: 0.5,
		anchorY: 0.5,
		width: 150,
		height: 150,
		color: 0xffff00,
		// Yellow color
		alpha: 0
	});
	self.bodyCollider.y = self.images.idle.height / 4; // Position the rectangle on the player's body
	//configure the animation frames.
	self.anims = {
		'walk': new FrameAnimation([self.images.walk1, self.images.walk2], 300),
		'jump': new FrameAnimation([self.images.jump], 100),
		'idle': [self.images.idle],
		'dead': new FrameAnimation([self.images.dead], 100),
		'attack': new FrameAnimation([self.images.jump, self.images.attack1, self.images.attack2, self.images.idle], 200)
	};
	self.states = {
		idle: {
			onEnter: function onEnter() {
				console.log('Entering idle state');
				self.anims['walk'].play();
			},
			onUpdate: function onUpdate() {},
			onExit: function onExit() {
				console.log('Exiting idle state');
				self.anims['walk'].stop();
			},
			onEvent: function onEvent(event, data) {
				if (event === GameEvents.COLLISION_ENEMY_BODY) {
					self.setState('dead');
				}
			}
		},
		dead: {
			onEnter: function onEnter() {
				console.log('Player has died');
				tween(self, {
					y: self.y - 400,
					rotation: -Math.PI / 6 // 30 degrees in radians
				}, {
					duration: 250,
					easing: tween.expoOut,
					onFinish: function onFinish() {
						tween(self, {
							y: 2732 + 300
						}, {
							duration: 1000,
							easing: tween.expoIn,
							onFinish: function onFinish() {
								LK.showGameOver();
							}
						});
					}
				});
				// Stop all enemies from moving
				for (var j = 0; j < enemies.length; j++) {
					enemies[j].speed = 0;
				}
				self.anims['dead'].play();
				// Additional logic for death state can be added here
			},
			onUpdate: function onUpdate() {},
			onExit: function onExit() {
				console.log('Exiting death state');
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in death state: ', event, data);
			}
		},
		attack: {
			onEnter: function onEnter() {
				console.log('Player is attacking');
				self.anims['attack'].play();
			},
			onUpdate: function onUpdate() {
				// Attack logic can be added here
			},
			onExit: function onExit() {
				console.log('Exiting attack state');
				self.anims['attack'].stop();
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in attack state: ', event, data);
				if (event === GameEvents.ANIM_FINISHED) {
					self.setState('idle');
				} else if (event === GameEvents.COLLISION_ENEMY_HEAD) {
					data.setState('dead');
				} else if (event === GameEvents.COLLISION_ENEMY_BODY) {
					data.setState('dead');
				}
			}
		},
		jumping: {
			onEnter: function onEnter() {
				if (!self.isJumping) {
					self.isJumping = true;
					self.velocityY = -self.jumpHeight;
					self.anims['jump'].play();
					console.log("jump Started");
				}
			},
			onUpdate: function onUpdate() {
				if (self.isJumping) {
					self.y += self.velocityY;
					self.velocityY += 1.4; // Increase gravity effect to make descent twice as fast 
					if (self.y >= 2732 / 2) {
						// Ground level
						self.y = 2732 / 2;
						self.isJumping = false;
						self.velocityY = 0;
						self.setState('idle');
					}
				}
			},
			onExit: function onExit() {
				console.log('Exiting jumping state');
				self.anims['jump'].stop();
			},
			onEvent: function onEvent(event, data) {
				console.log('Event received in jumping state: ', event, data);
				if (event === GameEvents.COLLISION_ENEMY_HEAD) {
					// Add upward velocity to player
					player.velocityY = -player.jumpHeight / 2;
					player.isJumping = true;
				}
				if (event === GameEvents.COLLISION_ENEMY_BODY) {
					self.setState('dead');
				}
			}
		}
	};
	self.setState = function (state) {
		if (self.state) {
			self.states[self.state].onExit();
		}
		self.state = state;
		self.states[self.state].onEnter();
	};
	self.sendEvent = function (event, data) {
		if (self.state) {
			self.states[self.state].onEvent(event, data);
		}
	};
	self.update = function () {
		self.states[self.state].onUpdate();
	};
	self.attack = function () {
		self.setState('attack');
	};
	self.jump = function () {
		self.setState('jumping');
	};
	//call the initial state.
	self.setState('idle');
});
/**** 
* Initialize Game
****/ 
var game = new LK.Game({
	backgroundColor: 0x87CEEB // Sky blue background
});
/**** 
* Game Code
****/ 
// Define an enum for GameEvents
var GameEvents = {
	COLLISION_ENEMY_HEAD: 0,
	COLLISION_ENEMY_BODY: 1,
	COLLISION_PLAYER_BODY: 2,
	ANIM_FINISHED: 3
};
// Define a class for frame animations
var FrameAnimation = function FrameAnimation(assets, frameRate) {
	var self = this;
	self.assets = assets;
	self.frameRate = frameRate;
	self.currentFrame = 0;
	self.isPlaying = false;
	self.interval = null;
	// Function to show the current frame
	self.showFrame = function () {
		for (var i = 0; i < self.assets.length; i++) {
			self.assets[i].visible = false;
		}
		self.assets[self.currentFrame].visible = true;
	};
	// Play the animation
	self.play = function () {
		if (!self.isPlaying) {
			self.isPlaying = true;
			self.showFrame();
			if (self.assets.length > 1) {
				self.interval = LK.setInterval(function () {
					self.currentFrame = (self.currentFrame + 1) % self.assets.length;
					self.showFrame();
					if (self.currentFrame === 0) {
						// Send ANIM_FINISHED event when animation completes a cycle
						self.assets[0].parent.sendEvent(GameEvents.ANIM_FINISHED, self);
					}
				}, self.frameRate);
			}
		}
	};
	// Pause the animation
	self.pause = function () {
		if (self.isPlaying) {
			clearInterval(self.interval);
			self.isPlaying = false;
		}
	};
	// Resume the animation
	self.resume = function () {
		if (!self.isPlaying) {
			self.play();
		}
	};
	// Stop the animation
	self.stop = function () {
		LK.clearInterval(self.interval);
		self.isPlaying = false;
		self.currentFrame = 0;
		for (var i = 0; i < self.assets.length; i++) {
			self.assets[i].visible = false;
		}
	};
};
var background = game.addChild(LK.getAsset('background', {
	anchorX: 0.5,
	anchorY: 0.5
}));
background.x = 2048 / 2;
background.y = 2732 / 2 - 550;
// Initialize player
var player = game.addChild(new Player());
player.x = 150; // Position player on the left side of the screen
player.y = 2732 / 2;
// Initialize enemy container
var enemyContainer = new Container();
game.addChild(enemyContainer);
// Initialize enemies array
var enemies = [];
var enemySpawnInterval = 100;
var enemySpawnCounter = 0;
// Create a new Text2 object to display the score
var scoreText = new Text2('0', {
	size: 100,
	fill: 0xFFFFFF
});
// Create a GUI container
var guiContainer = new Container();
game.addChild(guiContainer);
// Add the score text to the GUI container at the top center of the screen
guiContainer.addChild(scoreText);
scoreText.x = 2048 / 2;
scoreText.y = 0;
// Add a jump button to the bottom of the screen in the GUI container
var jumpButton = LK.getAsset('jump_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 400
});
jumpButton.x = 2048 / 4;
jumpButton.y = 2732 - jumpButton.height / 2 - 300;
guiContainer.addChild(jumpButton);
// Add an attack button to the bottom of the screen in the GUI container
var attackButton = LK.getAsset('attack_button', {
	anchorX: 0.5,
	anchorY: 0.5,
	width: 400,
	height: 400
});
attackButton.x = 3 * 2048 / 4;
attackButton.y = 2732 - attackButton.height / 2 - 300;
guiContainer.addChild(attackButton);
// Add event listeners to flash buttons black on mouse or touch down
jumpButton.down = function (x, y, obj) {
	LK.effects.flashObject(jumpButton, 0x000000, 500);
	player.jump();
};
attackButton.down = function (x, y, obj) {
	LK.effects.flashObject(attackButton, 0x000000, 500);
	player.attack();
};
function addEnemy2(game, enemies) {
	enemy = new Enemy2();
	enemy.x = 2048;
	enemy.y = 2732 / 2;
	enemies.push(enemy);
	enemyContainer.addChild(enemy);
}
// Handle game updates
game.update = function () {
	player.update();
	// Spawn enemies
	if (player.state !== 'dead') {
		enemySpawnCounter++;
		var enemy2Exists = enemies.some(function (e) {
			return e instanceof Enemy2;
		});
		if (!enemy2Exists && LK.getScore() == 5) {
			addEnemy2(game, enemies);
		} else if (!enemy2Exists && LK.getScore() >= 10) {
			addEnemy2(game, enemies);
		}
		if (enemySpawnCounter >= enemySpawnInterval) {
			var enemy;
			enemy = new Enemy();
			enemy.x = 2048;
			enemy.y = 2732 / 2;
			enemies.push(enemy);
			enemyContainer.addChild(enemy);
			// Randomize the spawn interval for the next enemy
			enemySpawnInterval = Math.floor(Math.random() * 150) + 50;
			enemySpawnCounter = 0;
		}
	}
	// Update enemies
	for (var j = enemies.length - 1; j >= 0; j--) {
		enemies[j].update();
		// Skip collision checks if player is in the dead state
		if (player.state === 'dead') {
			continue;
		}
		//remove the enemies marked for removal.
		if (enemies[j].removeFromArray == true) {
			enemies[j].destroy();
			enemies.splice(j, 1);
		}
		//skip collisions if enemy is dead.
		if (enemies[j].state === 'dead') {
			continue;
		}
		// Check collision between player bodyCollider and enemy headCollider
		if (player.bodyCollider.intersects(enemies[j].headCollider)) {
			LK.setScore(LK.getScore() + 1);
			scoreText.setText(LK.getScore());
			// Send COLLISION_ENEMY_HEAD event to player
			player.sendEvent(GameEvents.COLLISION_ENEMY_HEAD, enemies[j]);
			enemies[j].sendEvent(GameEvents.COLLISION_ENEMY_HEAD, player);
			continue;
		}
		// Check collision between enemy bodyCollider and player bodyCollider
		if (enemies[j].bodyCollider.intersects(player.bodyCollider)) {
			// Send COLLISION_ENEMY_BODY event to player
			player.sendEvent(GameEvents.COLLISION_ENEMY_BODY, enemies[j]);
			return;
		}
	}
};
// Handle player jump
game.down = function (x, y, obj) {
	// player.jump();
}; ===================================================================
--- original.js
+++ change.js
@@ -247,21 +247,22 @@
 			// New attack state
 			onEnter: function onEnter() {
 				console.log('Enemy2 starts attacking');
 				self.anims['idle'].play(); // Play idle animation
-				self.attackTimer = 300; // Set attack timer
+				self.attackTimer = 500; // Set attack timer
 			},
 			onUpdate: function onUpdate() {
 				if (self.attackTimer > 0) {
 					self.attackTimer--; // Decrease attack timer
 				} else {
 					self.anims['idle'].stop(); // Stop idle animation
 					self.anims['attack'].play(); // Play attack animation
-					self.attackTimer = 300;
+					self.attackTimer = 1000;
 				}
 			},
 			onExit: function onExit() {
 				console.log('Enemy2 stops attacking');
+				self.anims['idle'].stop();
 				self.anims['attack'].stop();
 			},
 			onEvent: function onEvent(event, data) {
 				console.log('Event received in attack state: ', event, data);
@@ -270,8 +271,11 @@
 					var bullet = new Bullet(self.images.horn);
 					bullet.x = self.x;
 					bullet.y = self.y;
 					game.addChild(bullet);
+					self.anims['attack'].stop();
+					self.anims['idle'].play();
+					self.attackTimer = 500;
 				} else if (event === GameEvents.COLLISION_ENEMY_HEAD) {
 					self.setState('dead');
 				}
 			}
@@ -615,9 +619,12 @@
 // Initialize player
 var player = game.addChild(new Player());
 player.x = 150; // Position player on the left side of the screen
 player.y = 2732 / 2;
-// Initialize enemies
+// Initialize enemy container
+var enemyContainer = new Container();
+game.addChild(enemyContainer);
+// Initialize enemies array
 var enemies = [];
 var enemySpawnInterval = 100;
 var enemySpawnCounter = 0;
 // Create a new Text2 object to display the score
@@ -660,28 +667,36 @@
 attackButton.down = function (x, y, obj) {
 	LK.effects.flashObject(attackButton, 0x000000, 500);
 	player.attack();
 };
+function addEnemy2(game, enemies) {
+	enemy = new Enemy2();
+	enemy.x = 2048;
+	enemy.y = 2732 / 2;
+	enemies.push(enemy);
+	enemyContainer.addChild(enemy);
+}
 // Handle game updates
 game.update = function () {
 	player.update();
 	// Spawn enemies
 	if (player.state !== 'dead') {
 		enemySpawnCounter++;
+		var enemy2Exists = enemies.some(function (e) {
+			return e instanceof Enemy2;
+		});
+		if (!enemy2Exists && LK.getScore() == 5) {
+			addEnemy2(game, enemies);
+		} else if (!enemy2Exists && LK.getScore() >= 10) {
+			addEnemy2(game, enemies);
+		}
 		if (enemySpawnCounter >= enemySpawnInterval) {
 			var enemy;
-			var enemy2Exists = enemies.some(function (e) {
-				return e instanceof Enemy2;
-			});
-			if (!enemy2Exists && LK.getScore() >= 5 && (LK.getScore() === 5 || Math.random() < 0.6 && LK.getScore() % 5 === 0)) {
-				enemy = new Enemy2();
-			} else {
-				enemy = new Enemy();
-			}
+			enemy = new Enemy();
 			enemy.x = 2048;
 			enemy.y = 2732 / 2;
 			enemies.push(enemy);
-			game.addChild(enemy);
+			enemyContainer.addChild(enemy);
 			// Randomize the spawn interval for the next enemy
 			enemySpawnInterval = Math.floor(Math.random() * 150) + 50;
 			enemySpawnCounter = 0;
 		}
 Single 2D Mario Character. In-Game asset. 2d. Blank background.
 
 
 
 
 
 
 
 
 
 
 
 monster in flat shading style. Monster has chopped off horns and has lazy eye with scary teeth. think black borders Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
 
 
 
 
 
 
 
 Sprite sheet of a monster enemy that has crucked teeth and a crazy eye. The sprite sheet has different frames of the enemy doing actions like run , attack , dodge, hurt and die.. High contrast