User prompt
enemy fall out to bottom after hit ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
more enemy appear
User prompt
enemy loop
User prompt
fix game
User prompt
fix enemy spawn
User prompt
boss escape out to upper screen after hit by player
User prompt
make enemy fall out to bottom screen after hit
User prompt
make enemy fall after hit ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Please fix the bug: 'ReferenceError: currentWave is not defined' in or related to this line: 'currentWave++;' Line Number: 75
User prompt
bullet change to white color
User prompt
delete wave asset. make loop game logic
User prompt
fix wave
User prompt
fix collor bullet to yellow
User prompt
add background asset
User prompt
enemy are spider. make animation enemy the spider walking to player ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
enemy one shoot dead. boss 5x shoot dead
User prompt
change rule. no dash attack. make be a shooter game
User prompt
delete auto shoot
User prompt
delete hazzard asset
User prompt
fix auto shoot
User prompt
add new logic. player can auto shoot
User prompt
player get more strenght
User prompt
reduce enemy appear
User prompt
more speed dash ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphic = self.attachAsset('boss', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 1.5;
self.health = 10;
self.attackCooldown = 0;
self.attackPattern = 0;
self.scoreValue = 2000;
self.active = true;
self.init = function (x, y) {
self.x = x;
self.y = y;
return self;
};
self.takeDamage = function () {
if (!self.active) {
return;
}
// Boss takes 1 damage per hit, dies after 5 hits
self.health -= 1;
// Flash boss
LK.effects.flashObject(self, 0xffffff, 300);
LK.getSound('hit').play();
if (self.health <= 0) {
self.die();
} else {
// Speed up as health decreases
self.speed = 1.5 + (5 - self.health) * 0.2;
}
};
self.die = function () {
if (!self.active) {
return;
}
self.active = false;
LK.getSound('bossDeath').play();
// Flash and fade out
LK.effects.flashObject(self, 0xffff00, 500);
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
currentWave++;
bossDefeated = true;
nextWaveTimer = 180; // 3 seconds until next wave
return self.scoreValue;
};
self.update = function () {
if (!self.active) {
return;
}
// Move toward hero but more intelligently
if (hero) {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
// Different movement patterns
if (self.attackPattern === 0) {
// Direct approach
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
}
} else if (self.attackPattern === 1) {
// Circle around
var angle = Math.atan2(dy, dx) + Math.PI / 4;
self.x += Math.cos(angle) * self.speed * 1.5;
self.y += Math.sin(angle) * self.speed * 1.5;
} else if (self.attackPattern === 2) {
// Charge attack
if (self.attackCooldown > 30) {
self.x += dx / dist * self.speed * 2.5;
self.y += dy / dist * self.speed * 2.5;
} else {
// Wait
}
}
if (hero.invulnerable <= 0 && !hero.isDashing) {
if (self.intersects(hero)) {
hero.takeDamage();
}
}
}
// Attack pattern cooldown
self.attackCooldown--;
if (self.attackCooldown <= 0) {
self.attackPattern = (self.attackPattern + 1) % 3;
self.attackCooldown = 120; // 2 seconds per pattern
}
// Keep within screen bounds
self.x = Math.max(100, Math.min(2048 - 100, self.x));
self.y = Math.max(100, Math.min(2732 - 100, self.y));
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphic = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphic.tint = 0xffffff; // White bullet for the hero
self.speed = 15;
self.damage = 1;
self.active = true;
self.init = function (x, y, direction) {
self.x = x;
self.y = y;
self.direction = direction || {
x: 0,
y: -1
}; // Default direction is up
return self;
};
self.update = function () {
if (!self.active) {
return;
}
// Move in the specified direction
self.x += self.direction.x * self.speed;
self.y += self.direction.y * self.speed;
// Remove if off-screen
if (self.x < -50 || self.x > 2048 + 50 || self.y < -50 || self.y > 2732 + 50) {
self.destroy();
}
};
return self;
});
var DashTrail = Container.expand(function () {
var self = Container.call(this);
var trailGraphic = self.attachAsset('dashTrail', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7
});
self.init = function (x, y) {
self.x = x;
self.y = y;
self.lifetime = 20; // frames the trail will live
return self;
};
self.update = function () {
self.lifetime--;
trailGraphic.alpha = self.lifetime / 20 * 0.7;
if (self.lifetime <= 0) {
self.destroy();
}
};
return self;
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphic = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.health = 1;
self.scoreValue = 100;
self.active = true;
self.init = function (x, y) {
self.x = x;
self.y = y;
// Initialize last position for rotation tracking
self.lastX = x;
self.lastY = y;
// Set initial rotation
if (hero) {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
enemyGraphic.rotation = Math.atan2(dy, dx);
}
return self;
};
self.takeDamage = function () {
if (!self.active) {
return;
}
// Enemies die from one hit
self.health = 0;
self.die();
};
self.die = function () {
if (!self.active) {
return;
}
self.active = false;
LK.getSound('hit').play();
// Flash, fade out, and fall animation
tween(self, {
alpha: 0,
y: self.y + 300,
// Fall down animation
rotation: Math.random() * Math.PI * 2,
// Random rotation
scaleX: 0.5,
scaleY: 0.5
}, {
duration: 800,
easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
return self.scoreValue;
};
self.update = function () {
if (!self.active) {
return;
}
// Move toward hero
if (hero && !hero.isDashing) {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
self.x += dx / dist * self.speed;
self.y += dy / dist * self.speed;
// Spider walking animation
if (LK.ticks % 10 === 0) {
// Spider leg movement animation
tween(enemyGraphic, {
scaleX: 1.1,
scaleY: 0.9,
rotation: Math.atan2(dy, dx) + (Math.random() * 0.2 - 0.1)
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemyGraphic, {
scaleX: 1,
scaleY: 1,
rotation: Math.atan2(dy, dx)
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
}
}
// Check for collision with hero
if (hero && !hero.isDashing && hero.invulnerable <= 0) {
if (self.intersects(hero)) {
hero.takeDamage();
}
}
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphic = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
// Simple click handler that does nothing (placeholder)
self.down = function (x, y, obj) {
// No auto-shoot toggle functionality
};
self.shootSpeed = 15; // Bullet speed
self.fireRate = 15; // Frames between shots
self.shootCooldown = 0;
self.health = 3;
self.invulnerable = 0;
self.combo = 0;
self.score = 0;
self.powerBoost = 1; // Base power multiplier
self.shootBullet = function (targetX, targetY) {
if (self.shootCooldown > 0) {
return;
}
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize direction
var dirX = dx / distance;
var dirY = dy / distance;
// Create bullet
var bullet = new Bullet().init(self.x, self.y, {
x: dirX,
y: dirY
});
bullet.damage = self.powerBoost; // Apply power boost to bullet damage
// Visual shooting effect
tween(heroGraphic, {
scaleX: 1.2,
scaleY: 0.9
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(heroGraphic, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.elasticOut
});
}
});
// Set cooldown
self.shootCooldown = self.fireRate;
// Add bullet to game
game.addChild(bullet);
if (!bullets) {
bullets = [];
}
bullets.push(bullet);
// Play shoot sound
LK.getSound('hit').play();
};
self.takeDamage = function () {
if (self.invulnerable > 0) {
return;
}
self.health--;
self.invulnerable = 60; // invulnerable for 1 second
self.combo = 0; // Reset combo
// Flash hero red
LK.effects.flashObject(self, 0xff0000, 500);
// Play damage sound
LK.getSound('damage').play();
if (self.health <= 0) {
LK.showGameOver();
}
};
self.addScore = function (points) {
self.combo++;
var comboMultiplier = Math.min(4, 1 + self.combo * 0.1);
var scoreToAdd = Math.floor(points * comboMultiplier);
self.score += scoreToAdd;
LK.setScore(self.score);
};
self.update = function () {
// Keep within screen bounds
self.x = Math.max(50, Math.min(2048 - 50, self.x));
self.y = Math.max(50, Math.min(2732 - 50, self.y));
// Cooldowns
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
if (self.invulnerable > 0) {
self.invulnerable--;
// Flicker effect during invulnerability
heroGraphic.alpha = LK.ticks % 6 < 3 ? 0.4 : 1;
} else {
// Normal appearance when not invulnerable
heroGraphic.alpha = 1;
heroGraphic.tint = 0xFFFFFF; // Normal color
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerUpGraphic = self.attachAsset('powerUp', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'health'; // Default type
self.active = true;
self.lifetime = 300; // 5 seconds
self.init = function (x, y, type) {
self.x = x;
self.y = y;
self.type = type || self.type;
// Set color based on type
if (self.type === 'health') {
powerUpGraphic.tint = 0x2ecc71; // Green
} else if (self.type === 'speed') {
powerUpGraphic.tint = 0x3498db; // Blue
} else if (self.type === 'power') {
powerUpGraphic.tint = 0xe74c3c; // Red
} else if (self.type === 'strength') {
powerUpGraphic.tint = 0x9b59b6; // Purple
}
return self;
};
self.collect = function () {
if (!self.active) {
return;
}
self.active = false;
LK.getSound('powerup').play();
if (self.type === 'health' && hero.health < 3) {
hero.health++;
} else if (self.type === 'speed') {
hero.dashSpeed = 80; // Even faster dash
hero.dashDistance = 900; // Even longer dash
// Visual indicator of speed boost
tween(hero, {
alpha: 0.7
}, {
duration: 200,
onFinish: function onFinish() {
tween(hero, {
alpha: 1
}, {
duration: 200
});
}
});
// Reset after 10 seconds
LK.setTimeout(function () {
if (hero) {
hero.dashSpeed = 60;
hero.dashDistance = 700;
}
}, 10000);
} else if (self.type === 'strength') {
// Increase hero's attack strength more permanently
hero.powerBoost = Math.min(5, hero.powerBoost + 1);
// Visual indicator of strength boost
tween(hero, {
tint: 0x9b59b6
}, {
duration: 500,
onFinish: function onFinish() {
tween(hero, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
});
// Show strength level
var strengthTxt = new Text2('STRENGTH +' + hero.powerBoost + '!', {
size: 80,
fill: 0x9b59b6
});
strengthTxt.anchor.set(0.5, 0.5);
strengthTxt.x = 2048 / 2;
strengthTxt.y = 2732 / 2;
game.addChild(strengthTxt);
// Fade out the text
tween(strengthTxt, {
alpha: 0,
y: strengthTxt.y - 100
}, {
duration: 1500,
onFinish: function onFinish() {
strengthTxt.destroy();
}
});
} else if (self.type === 'power') {
// Clear all enemies
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i].active) {
var points = enemies[i].die();
hero.addScore(points);
}
}
// Increase hero's attack strength
hero.powerBoost = 3;
// Visual indicator of power boost
tween(hero, {
tint: 0xFF0000
}, {
duration: 300
});
// Reset after 10 seconds
LK.setTimeout(function () {
if (hero) {
hero.powerBoost = 1;
tween(hero, {
tint: 0xFFFFFF
}, {
duration: 500
});
}
}, 10000);
}
// Flash and fade out
tween(self, {
alpha: 0,
scaleX: 2,
scaleY: 2
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
};
self.update = function () {
if (!self.active) {
return;
}
// Floating animation
self.y += Math.sin(LK.ticks * 0.1) * 0.5;
// Rotate slowly
powerUpGraphic.rotation += 0.02;
// Check for collision with hero
if (hero && (hero.intersects(self) || hero.isDashing && self.distanceTo(hero) < 100)) {
self.collect();
}
// Expire after lifetime
self.lifetime--;
if (self.lifetime <= 0) {
tween(self, {
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
self.destroy();
}
});
self.active = false;
}
};
self.distanceTo = function (target) {
var dx = target.x - self.x;
var dy = target.y - self.y;
return Math.sqrt(dx * dx + dy * dy);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000022
});
/****
* Game Code
****/
// Game state variables
var hero;
var enemies = [];
var bullets = [];
var powerUps = [];
var trails = [];
var gameTime = 0;
var spawnTimer = 0;
var bossTimer = 0;
var currentWave = 0;
var bossDefeated = false;
var nextWaveTimer = 0;
var swipeStart = {
x: 0,
y: 0
};
var isSwipeActive = false;
// UI elements
var scoreTxt;
var timeTxt;
var healthTxt;
var comboTxt;
// Game constants
var SPAWN_INTERVAL = 90; // Frames between enemy spawns
var POWER_UP_CHANCE = 0.15; // Chance to spawn power-up on enemy defeat
var BOSS_INTERVAL = 1800; // Spawn boss every 30 seconds (60fps * 30)
var MAX_ENEMIES = 15; // Maximum enemies on screen at once
// Initialize game elements
function initGame() {
// Add background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Create hero
hero = new Hero();
hero.x = 2048 / 2;
hero.y = 2732 / 2;
game.addChild(hero);
// Auto-shoot indicator removed
// Create UI elements
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
timeTxt = new Text2('Time: 0s', {
size: 60,
fill: 0xFFFFFF
});
timeTxt.anchor.set(1, 0);
LK.gui.top.addChild(timeTxt);
healthTxt = new Text2('❤️❤️❤️', {
size: 60,
fill: 0xFFFFFF
});
healthTxt.anchor.set(0, 0);
LK.gui.bottom.addChild(healthTxt);
comboTxt = new Text2('Combo: 0x', {
size: 60,
fill: 0xFFFFFF
});
comboTxt.anchor.set(1, 0);
LK.gui.bottom.addChild(comboTxt);
// Initialize game timers
gameTime = 0;
spawnTimer = 0;
bossTimer = BOSS_INTERVAL;
// Play background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.5,
duration: 1000
}
});
}
// This function is no longer needed in endless mode
// Spawn a regular enemy
function spawnEnemy() {
// Enforce a maximum number of enemies
if (enemies.length >= MAX_ENEMIES) {
return;
}
var edge = Math.floor(Math.random() * 4); // 0: top, 1: right, 2: bottom, 3: left
var x, y;
switch (edge) {
case 0:
// Top
x = Math.random() * 2048;
y = -50;
break;
case 1:
// Right
x = 2048 + 50;
y = Math.random() * 2732;
break;
case 2:
// Bottom
x = Math.random() * 2048;
y = 2732 + 50;
break;
case 3:
// Left
x = -50;
y = Math.random() * 2732;
break;
}
var enemy = new Enemy().init(x, y);
var seconds = Math.floor(gameTime / 60);
// Speed increases with game time
enemy.speed = 2 + Math.min(3, seconds / 30);
enemy.health = 1; // Enemies always have 1 health
// Scale score value based on time played
enemy.scoreValue = 100 + Math.floor(seconds / 30) * 20;
game.addChild(enemy);
enemies.push(enemy);
}
// Spawn a boss
function spawnBoss() {
var boss = new Boss().init(2048 / 2, -200);
var seconds = Math.floor(gameTime / 60);
// Boss health and score scale with game time
boss.health = 5 + Math.floor(seconds / 60);
boss.scoreValue = 2000 + seconds * 50;
game.addChild(boss);
enemies.push(boss);
// Make a dramatic entrance
tween(boss, {
y: 400
}, {
duration: 2000,
easing: tween.bounceOut
});
}
// Spawn a power-up
function spawnPowerUp(x, y) {
var types = ['health', 'speed', 'power', 'strength'];
var type = types[Math.floor(Math.random() * types.length)];
var powerUp = new PowerUp().init(x, y, type);
game.addChild(powerUp);
powerUps.push(powerUp);
}
// Handle touch/mouse down
game.down = function (x, y, obj) {
isSwipeActive = true;
swipeStart.x = x;
swipeStart.y = y;
};
// Handle touch/mouse up
game.up = function (x, y, obj) {
if (isSwipeActive) {
// Instead of dashing, shoot in the direction of the swipe
var dx = x - swipeStart.x;
var dy = y - swipeStart.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If it's a significant swipe, shoot in that direction
if (distance > 20) {
// Calculate target point to shoot towards
var targetX = hero.x + dx * 10;
var targetY = hero.y + dy * 10;
hero.shootBullet(targetX, targetY);
} else {
// If it's just a tap, shoot upward
hero.shootBullet(hero.x, hero.y - 100);
}
isSwipeActive = false;
}
};
// Handle touch/mouse move
game.move = function (x, y, obj) {
// We'll use swipe up/down instead of tracking movement
};
// Main game update loop
game.update = function () {
// Update game time (in seconds)
gameTime++;
var seconds = Math.floor(gameTime / 60);
timeTxt.setText('Time: ' + seconds + 's');
// Update UI
scoreTxt.setText('Score: ' + LK.getScore());
comboTxt.setText('Combo: ' + hero.combo + 'x');
// Update health display
var healthStr = '';
for (var i = 0; i < hero.health; i++) {
healthStr += '❤️';
}
healthTxt.setText(healthStr);
// Spawn enemies - continuous spawn
spawnTimer++;
if (spawnTimer >= SPAWN_INTERVAL && enemies.length < MAX_ENEMIES) {
// Spawn rate increases over time
var difficulty = Math.min(0.9, 0.4 + seconds / 120);
// Higher chance to spawn as time goes on
if (Math.random() < difficulty) {
spawnEnemy();
}
spawnTimer = 0;
}
// Boss timer
bossTimer--;
if (bossTimer <= 0) {
spawnBoss();
bossTimer = BOSS_INTERVAL;
}
// Increase difficulty based on time
var speedIncrease = Math.min(3, seconds / 60);
var enemySpeedModifier = 1 + speedIncrease * 0.5;
// Update game objects
updateGameObjects();
// Detect collisions between bullets and enemies
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
if (!bullet.active) {
continue;
}
var hitEnemy = false;
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
if (!enemy.active) {
continue;
}
if (bullet.intersects(enemy)) {
// Bullet hit enemy
hitEnemy = true;
// Call enemy's takeDamage method
enemy.takeDamage();
// Visual feedback
LK.effects.flashObject(enemy, 0xFFFFFF, 100);
// Award points if enemy dead
if (!enemy.active) {
hero.addScore(enemy.scoreValue);
// Maybe spawn a power-up
if (Math.random() < POWER_UP_CHANCE) {
spawnPowerUp(enemy.x, enemy.y);
}
}
break;
}
}
// Remove bullet if it hit something
if (hitEnemy) {
bullet.destroy();
bullets.splice(b, 1);
}
}
// Clean up destroyed objects
cleanupDestroyedObjects();
};
// Update all game objects
function updateGameObjects() {
// Update hero
if (hero) {
hero.update();
}
// Update enemies
for (var i = 0; i < enemies.length; i++) {
if (enemies[i]) {
enemies[i].update();
}
}
// Update power-ups
for (var i = 0; i < powerUps.length; i++) {
if (powerUps[i]) {
powerUps[i].update();
}
}
// Update bullets
for (var i = 0; i < bullets.length; i++) {
if (bullets[i]) {
bullets[i].update();
}
}
// Update trails
for (var i = 0; i < trails.length; i++) {
if (trails[i]) {
trails[i].update();
}
}
}
// Clean up destroyed objects
function cleanupDestroyedObjects() {
// Clean up destroyed enemies
for (var i = enemies.length - 1; i >= 0; i--) {
if (!enemies[i] || !enemies[i].parent) {
enemies.splice(i, 1);
}
}
// Clean up destroyed power-ups
for (var i = powerUps.length - 1; i >= 0; i--) {
if (!powerUps[i] || !powerUps[i].parent) {
powerUps.splice(i, 1);
}
}
// Clean up destroyed trails
for (var i = trails.length - 1; i >= 0; i--) {
if (!trails[i] || !trails[i].parent) {
trails.splice(i, 1);
}
}
// Clean up destroyed bullets
for (var i = bullets.length - 1; i >= 0; i--) {
if (!bullets[i] || !bullets[i].parent) {
bullets.splice(i, 1);
}
}
}
// Initialize the game
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -35,28 +35,8 @@
LK.getSound('hit').play();
if (self.health <= 0) {
self.die();
} else {
- // Make boss escape to top of screen briefly after being hit
- tween(self, {
- y: -200
- }, {
- duration: 1000,
- easing: tween.easeOut,
- onFinish: function onFinish() {
- // Return after a delay
- LK.setTimeout(function () {
- if (self.active) {
- tween(self, {
- y: 400
- }, {
- duration: 1500,
- easing: tween.bounceOut
- });
- }
- }, 1500);
- }
- });
// Speed up as health decreases
self.speed = 1.5 + (5 - self.health) * 0.2;
}
};
@@ -213,38 +193,28 @@
return;
}
// Enemies die from one hit
self.health = 0;
- // Add falling animation before dying
- self.active = false; // Prevent multiple hits
- LK.getSound('hit').play();
- // Flash and add falling animation
- LK.effects.flashObject(self, 0xffffff, 300);
- // Make enemy fall down with rotation to bottom of screen
- tween(self, {
- y: 2732 + 100,
- // Fall beyond bottom of screen
- rotation: Math.PI * 2,
- alpha: 0.7
- }, {
- duration: 1500,
- easing: tween.easeIn,
- onFinish: function onFinish() {
- self.die();
- }
- });
+ self.die();
};
self.die = function () {
if (!self.active) {
return;
}
self.active = false;
LK.getSound('hit').play();
- // Flash and fade out
+ // Flash, fade out, and fall animation
tween(self, {
- alpha: 0
+ alpha: 0,
+ y: self.y + 300,
+ // Fall down animation
+ rotation: Math.random() * Math.PI * 2,
+ // Random rotation
+ scaleX: 0.5,
+ scaleY: 0.5
}, {
- duration: 300,
+ duration: 800,
+ easing: tween.easeIn,
onFinish: function onFinish() {
self.destroy();
}
});
@@ -253,37 +223,31 @@
self.update = function () {
if (!self.active) {
return;
}
- // Move toward hero with looping pattern
+ // Move toward hero
if (hero && !hero.isDashing) {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist > 0) {
- // Calculate angle to player
- var angle = Math.atan2(dy, dx);
- // Add sinusoidal variation to create looping motion
- var loopFactor = Math.sin(LK.ticks * 0.05) * 0.8;
- var adjustedAngle = angle + loopFactor;
- // Move with adjusted angle
- self.x += Math.cos(adjustedAngle) * self.speed;
- self.y += Math.sin(adjustedAngle) * self.speed;
+ self.x += dx / dist * self.speed;
+ self.y += dy / dist * self.speed;
// Spider walking animation
if (LK.ticks % 10 === 0) {
// Spider leg movement animation
tween(enemyGraphic, {
scaleX: 1.1,
scaleY: 0.9,
- rotation: adjustedAngle + (Math.random() * 0.2 - 0.1)
+ rotation: Math.atan2(dy, dx) + (Math.random() * 0.2 - 0.1)
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(enemyGraphic, {
scaleX: 1,
scaleY: 1,
- rotation: adjustedAngle
+ rotation: Math.atan2(dy, dx)
}, {
duration: 200,
easing: tween.easeOut
});
@@ -588,9 +552,9 @@
var trails = [];
var gameTime = 0;
var spawnTimer = 0;
var bossTimer = 0;
-var currentWave = 1;
+var currentWave = 0;
var bossDefeated = false;
var nextWaveTimer = 0;
var swipeStart = {
x: 0,
@@ -622,9 +586,9 @@
hero.y = 2732 / 2;
game.addChild(hero);
// Auto-shoot indicator removed
// Create UI elements
- scoreTxt = new Text2('Score: 0 - Wave: 1', {
+ scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
@@ -650,39 +614,16 @@
// Initialize game timers
gameTime = 0;
spawnTimer = 0;
bossTimer = BOSS_INTERVAL;
- // Initialize wave variables
- currentWave = 1;
- bossDefeated = false;
- nextWaveTimer = 0;
// Play background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.5,
duration: 1000
}
});
- // Announce first wave
- var waveTxt = new Text2('WAVE 1!', {
- size: 120,
- fill: 0xFFFF00
- });
- waveTxt.anchor.set(0.5, 0.5);
- waveTxt.x = 2048 / 2;
- waveTxt.y = 2732 / 2;
- game.addChild(waveTxt);
- // Fade out wave text
- tween(waveTxt, {
- alpha: 0,
- y: waveTxt.y - 100
- }, {
- duration: 1500,
- onFinish: function onFinish() {
- waveTxt.destroy();
- }
- });
}
// This function is no longer needed in endless mode
// Spawn a regular enemy
function spawnEnemy() {
@@ -695,44 +636,35 @@
switch (edge) {
case 0:
// Top
x = Math.random() * 2048;
- y = -100; // Move further off-screen
+ y = -50;
break;
case 1:
// Right
- x = 2048 + 100; // Move further off-screen
+ x = 2048 + 50;
y = Math.random() * 2732;
break;
case 2:
// Bottom
x = Math.random() * 2048;
- y = 2732 + 100; // Move further off-screen
+ y = 2732 + 50;
break;
case 3:
// Left
- x = -100; // Move further off-screen
+ x = -50;
y = Math.random() * 2732;
break;
}
- // Calculate how many enemies to spawn based on current wave
- var enemiesToSpawn = Math.min(3, currentWave);
- for (var i = 0; i < enemiesToSpawn; i++) {
- // Add slight variation to position for multiple spawns
- var spawnX = x + (Math.random() * 100 - 50);
- var spawnY = y + (Math.random() * 100 - 50);
- // Create and initialize the enemy
- var enemy = new Enemy().init(spawnX, spawnY);
- var seconds = Math.floor(gameTime / 60);
- // Speed increases with game time and wave
- enemy.speed = 2 + Math.min(3, seconds / 30) + currentWave * 0.2;
- enemy.health = 1; // Enemies always have 1 health
- // Scale score value based on time played and wave
- enemy.scoreValue = 100 + Math.floor(seconds / 30) * 20 + currentWave * 10;
- // Add to game and enemy array
- game.addChild(enemy);
- enemies.push(enemy);
- }
+ var enemy = new Enemy().init(x, y);
+ var seconds = Math.floor(gameTime / 60);
+ // Speed increases with game time
+ enemy.speed = 2 + Math.min(3, seconds / 30);
+ enemy.health = 1; // Enemies always have 1 health
+ // Scale score value based on time played
+ enemy.scoreValue = 100 + Math.floor(seconds / 30) * 20;
+ game.addChild(enemy);
+ enemies.push(enemy);
}
// Spawn a boss
function spawnBoss() {
var boss = new Boss().init(2048 / 2, -200);
@@ -794,49 +726,22 @@
gameTime++;
var seconds = Math.floor(gameTime / 60);
timeTxt.setText('Time: ' + seconds + 's');
// Update UI
- scoreTxt.setText('Score: ' + LK.getScore() + ' - Wave: ' + currentWave);
+ scoreTxt.setText('Score: ' + LK.getScore());
comboTxt.setText('Combo: ' + hero.combo + 'x');
// Update health display
var healthStr = '';
for (var i = 0; i < hero.health; i++) {
healthStr += '❤️';
}
healthTxt.setText(healthStr);
- // Handle advancing to next wave
- if (bossDefeated && nextWaveTimer > 0) {
- nextWaveTimer--;
- if (nextWaveTimer <= 0) {
- // Announce new wave
- var waveTxt = new Text2('WAVE ' + currentWave + '!', {
- size: 120,
- fill: 0xFFFF00
- });
- waveTxt.anchor.set(0.5, 0.5);
- waveTxt.x = 2048 / 2;
- waveTxt.y = 2732 / 2;
- game.addChild(waveTxt);
- // Fade out wave text
- tween(waveTxt, {
- alpha: 0,
- y: waveTxt.y - 100
- }, {
- duration: 1500,
- onFinish: function onFinish() {
- waveTxt.destroy();
- }
- });
- bossDefeated = false;
- }
- }
- // Spawn enemies - continuous spawn with wave-based adjustments
+ // Spawn enemies - continuous spawn
spawnTimer++;
- var waveSpawnInterval = Math.max(30, SPAWN_INTERVAL - currentWave * 10); // Faster spawns in higher waves
- if (spawnTimer >= waveSpawnInterval && enemies.length < MAX_ENEMIES) {
- // Spawn rate increases over time and with wave number
- var difficulty = Math.min(0.9, 0.4 + seconds / 120 + currentWave * 0.1);
- // Higher chance to spawn as time goes on and wave increases
+ if (spawnTimer >= SPAWN_INTERVAL && enemies.length < MAX_ENEMIES) {
+ // Spawn rate increases over time
+ var difficulty = Math.min(0.9, 0.4 + seconds / 120);
+ // Higher chance to spawn as time goes on
if (Math.random() < difficulty) {
spawnEnemy();
}
spawnTimer = 0;
@@ -846,10 +751,10 @@
if (bossTimer <= 0) {
spawnBoss();
bossTimer = BOSS_INTERVAL;
}
- // Increase difficulty based on time and wave
- var speedIncrease = Math.min(3, seconds / 60 + currentWave * 0.2);
+ // Increase difficulty based on time
+ var speedIncrease = Math.min(3, seconds / 60);
var enemySpeedModifier = 1 + speedIncrease * 0.5;
// Update game objects
updateGameObjects();
// Detect collisions between bullets and enemies
@@ -873,10 +778,10 @@
LK.effects.flashObject(enemy, 0xFFFFFF, 100);
// Award points if enemy dead
if (!enemy.active) {
hero.addScore(enemy.scoreValue);
- // Maybe spawn a power-up, higher chance in higher waves
- if (Math.random() < POWER_UP_CHANCE + currentWave * 0.02) {
+ // Maybe spawn a power-up
+ if (Math.random() < POWER_UP_CHANCE) {
spawnPowerUp(enemy.x, enemy.y);
}
}
break;
colored spider. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
white silk web. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
amazing spider web on tree branch. anime image. green landscape Single Game Texture. In-Game asset. 2d.
flyn lady bug 2d cartoon objek. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
flyin evil woodpecker bird. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows