Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'cdCnt')' in or related to this line: 'if (--inst.cdCnt <= 0) {' Line Number: 302
Code edit (5 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'cdCnt')' in or related to this line: 'if (--inst.cdCnt <= 0) {' Line Number: 304
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'update')' in or related to this line: 'BrickProj.parent.update.call(b);' Line Number: 680
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'TypeError: Cannot read properties of undefined (reading 'update')' in or related to this line: 'BrickProj.parent.update.call(p);' Line Number: 754
User prompt
Please fix the bug: 'ReferenceError: fireWeapon is not defined' in or related to this line: 'fireWeapon(key, inst, meta);' Line Number: 223
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: meta is not defined' in or related to this line: 'if (e.intersectsCircle(arc.x, arc.y, meta.range * inst.rngMul) && e.takeDamage(arc.dmg)) {' Line Number: 383
User prompt
Please fix the bug: 'spawnWave is not defined' in or related to this line: 'spawnWave();' Line Number: 1076
Code edit (1 edits merged)
Please save this source code
User prompt
Please fix the bug: 'ReferenceError: dropExpOrb is not defined' in or related to this line: 'dropExpOrb(en.x, en.y, en.expValue);' Line Number: 593
User prompt
Please fix the bug: 'ReferenceError: meta is not defined' in or related to this line: 'if (e.intersectsCircle(arc.x, arc.y, meta.range * inst.rngMul) && e.takeDamage(arc.dmg)) {' Line Number: 383
User prompt
Please fix the bug: 'spawnWave is not defined' in or related to this line: 'spawnWave();' Line Number: 1076
Code edit (1 edits merged)
Please save this source code
User prompt
So let's start writing the code.
User prompt
Let's change the sword's feature. Now the sword is not swinging in the direction my character is looking, but towards the closest enemy. Also, since its range is currently very small, we need to increase its range. We should also change the sword buffs as follows: Sword buffs: 1. Boost) Targets the 2nd closest enemy and swings an additional sword. (Number of swung swords increases from 1 to 2) (If there is no 2nd enemy, targets the 1st enemy) 2. Boost) Targets the 3rd closest enemy and swings an additional sword. (Number of swung swords increases from 2 to 3) (If there is no 3rd enemy, targets the 1st enemy) 3. Boost) Targets the 4th closest enemy and swings an additional sword. (Number of swung swords increases from 3 to 4) (If there is no 4th enemy, targets the 1st enemy)
User prompt
I don't think my character has a sword right now. The sword should be swung in the direction my character is looking at every 2 seconds and if it hits an enemy it should deal damage.
User prompt
We are going to make a huge update now! Read carefully and try to analyze and understand thoroughly. There will be nine different weapon types in the game. Each weapon will have its own unique enchantments and upgrades. Whenever my character levels up (except on the level-5 milestones), three random choices will appear, each containing an enchantment for the weapon currently in hand. Whenever my character reaches a multiple of five levels, three random weapon choices will appear; if my character already owns the weapon shown, that choice will count as an upgrade for the existing weapon. Weapon upgrades unlock sequentially—first Upgrade 1, then Upgrade 2, then Upgrade 3. If all possible enchantments or upgrades for that weapon have already been acquired, then on level-up the character’s health is restored by 30%. In addition, each time the character levels up, maximum health increases by +10. My character starts the game with the sword. Below is more detailed information about weapons, enchantments, and upgrades. Sword: The character swings the sword in the direction they are facing at specific intervals (once every 2 seconds). It has a short range. Enemies struck by the swinging sword take damage. Sword Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Sword Upgrades: Upgrade 1) The character also swings the sword behind themselves at the same intervals. Upgrade 2) The character also swings the sword upwards at the same intervals. Upgrade 3) The character also swings the sword downwards at the same intervals. Boomerang: Throws a boomerang at the nearest enemy. The boomerang follows a circular arc and then returns to the character. As it travels, it damages any enemies it hits. It is thrown once every 3 seconds. It has a long range. Boomerang Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Boomerang Upgrades: Upgrade 1) Throws an additional boomerang targeting the second-closest enemy. (Boomerang count increases from 1 to 2.) (If no second enemy exists, the additional boomerang targets the closest enemy.) Upgrade 2) Throws an additional boomerang targeting the third-closest enemy. (Boomerang count increases from 2 to 3.) (If no third enemy exists, the additional boomerang targets the closest enemy.) Upgrade 3) Throws an additional boomerang targeting the fourth-closest enemy. (Boomerang count increases from 3 to 4.) (If no fourth enemy exists, the additional boomerang targets the closest enemy.) Ball: Every 3 seconds, throws a ball at the nearest enemy within its range. The ball can bounce once and deal damage to an enemy, then disappears once it exits the screen. As it travels, it damages any enemies it collides with. It has a long range. Ball Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Ball Upgrades: Upgrade 1) Throws an additional ball at the second-closest enemy. (Ball count increases from 1 to 2.) (If no second enemy exists, the additional ball targets the closest enemy.) Upgrade 2) Throws an additional ball at the third-closest enemy. (Ball count increases from 2 to 3.) (If no third enemy exists, the additional ball targets the closest enemy.) Upgrade 3) Throws an additional ball at the fourth-closest enemy. (Ball count increases from 3 to 4.) (If no fourth enemy exists, the additional ball targets the closest enemy.) Rocket: Every 3 seconds, launches a rocket at the nearest enemy within its range. Range is moderate. When the rocket hits its target, it deals area damage in a circular radius around that enemy (i.e., it is an AoE rocket). Rocket Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Rocket Upgrades: Upgrade 1) Launches an additional rocket at the second-closest enemy. (Rocket count increases from 1 to 2.) (If no second enemy exists, that additional rocket targets the closest enemy.) Upgrade 2) Launches an additional rocket at the third-closest enemy. (Rocket count increases from 2 to 3.) (If no third enemy exists, that additional rocket targets the closest enemy.) Upgrade 3) Launches an additional rocket at the fourth-closest enemy. (Rocket count increases from 3 to 4.) (If no fourth enemy exists, that additional rocket targets the closest enemy.) Brick: Throws a brick at a 75° angle in the direction the character is facing. After the brick is thrown, it falls downward as if affected by gravity, and disappears once it leaves the screen. As it travels, it damages any enemies it collides with. Bricks are thrown once every 3 seconds. Brick Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Brick Upgrades: Upgrade 1) Also throws a second brick at a 75° angle behind the direction the character is facing. (Total of 2 bricks per throw.) Upgrade 2) Also throws a second brick at a 45° angle in the same direction the character is facing. (Total of 3 bricks per throw.) Upgrade 3) Also throws a second brick at a 45° angle behind the direction the character is facing. (Total of 4 bricks per throw.) Lightning: Summons a lightning strike on a random enemy on the screen. Lightning strikes once every 3 seconds. Lightning Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Lightning Upgrades: Upgrade 1) Increases the number of lightning strikes from 1 to 2. (Multiple strikes can hit the same enemy.) Upgrade 2) Increases the number of lightning strikes from 2 to 3. (Multiple strikes can hit the same enemy.) Upgrade 3) Increases the number of lightning strikes from 3 to 4. (Multiple strikes can hit the same enemy.) Aura: Creates a small circular aura that constantly surrounds the character. Any enemy that touches this aura takes damage. Aura Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Aura Upgrades: Upgrade 1) Enemies that enter the aura’s range are slowed by 25%. Upgrade 2) Enemies that enter the aura’s range are slowed by 50%. Upgrade 3) Enemies that enter the aura’s range are slowed by 75%. Molotov: Randomly throws a Molotov cocktail into a circular area. There is a 3-second cooldown. When Molotovs hit the ground, they shatter and ignite a small circular area on fire for 1 second. Any enemy that enters this burning area takes damage. Molotov Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Molotov Upgrades: Upgrade 1) Increases the number of Molotovs thrown from 1 to 2. Upgrade 2) Increases the number of Molotovs thrown from 2 to 3. Upgrade 3) Increases the number of Molotovs thrown from 3 to 4. Shuriken: Within a short radius around the character, two regular-speed shurikens spin for 3 seconds at a time (each shuriken positioned at equal angular separation—if there are two, they are 180° apart). These shurikens rotate around the character and deal damage to any enemy they hit. Shuriken Enchantments: Option 1) +10% Damage Increase Option 2) +10% Attack Speed Increase Option 3) +10% Range Increase Option 4) +10% Size Increase Shuriken Upgrades: Upgrade 1) Increases the shuriken count from 2 to 3. (Shurikens should be evenly spaced—120° apart when there are three.) Upgrade 2) Increases the shuriken count from 3 to 4. (Shurikens should be evenly spaced—90° apart when there are four.) Upgrade 3) Increases the shuriken count from 4 to 5. (Shurikens should be evenly spaced—72° apart when there are five.) I want you to revise the code according to what I explained above. Think carefully.
User prompt
Currently when I level up and choose a upgrade (while choosing a upgrade) the enemies don't stop and keep moving, so when I choose my buff late the enemies get too close to my character and I die. While my character chooses a buff the enemies shouldn't move and shouldn't attack. After my character chooses his buff the enemies can move and attack. Also the magnet and bomb should be much rarer to be created.
User prompt
There should be a bomb that appears randomly on the map and when my character picks up that bomb, all enemies on the current screen (except bosses) should die by eating them one by one. Also, a magnet should appear randomly on the map and when my character picks up that magnet, it should quickly pull all XPs on the current screen towards itself. Also, right now, the game doesn't stop when my character is choosing a power-up and the enemies continue to advance towards my character. Also, don't allow the same power-up to appear more than once when choosing a power-up, I mean when I'm going to choose one of the three power-ups, sometimes two of the three power-ups are the same and I don't want that, each power-up should be different.
User prompt
Do not allow more than 30 enemies on screen at once. There cannot be more than 30 enemies on screen at once.
User prompt
Enemies are currently spawning very close to my character. Enemies should spawn slightly off screen and come towards me. Also enemies are currently spawning very frequently, enemies should spawn less frequently. Also my joystick button is currently too low, I need to move it up a bit.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ /* Lightning, Aura effect, Molotov flame can be lightweight containers */ var AuraField = Container.expand(function () { var self = Container.call(this); var gfx = self.attachAsset('aura', { anchorX: 0.5, anchorY: 0.5, alpha: 0.35 }); self.radius = 150; self.dmg = 5; self.slow = 0; self.update = function () {/* position follows player by external binding */}; return self; }); /****----------------------------------------------------------------- * 4. Enemy hierarchy (unchanged aside from helper intersectsCircle) *------------------------------------------------------------------*/ var Enemy = Container.expand(function () { var self = Container.call(this); self.hp = 20; self.maxHp = 20; self.damage = 10; self.speed = 2; self.expValue = 5; self.type = 'normal'; self.attachAsset('zombie', { anchorX: 0.5, anchorY: 0.5 }); self.takeDamage = function (a) { self.hp -= a; LK.effects.flashObject(self, 0xffffff, 100); return self.hp <= 0; }; self.update = function () { if (!player || skillSelectionActive) { return; } var dx = player.x - self.x, dy = player.y - self.y, d = Math.sqrt(dx * dx + dy * dy); if (d > 0) { self.x += dx / d * self.speed; self.y += dy / d * self.speed; } }; self.intersectsCircle = function (cx, cy, r) { var dx = self.x - cx, dy = self.y - cy; return dx * dx + dy * dy <= r * r; }; return self; }); var TankZombie = Enemy.expand(function () { var self = Enemy.call(this); var s = Enemy.call(this); s.hp = 60; s.damage = 20; s.speed = 1; s.expValue = 15; s.attachAsset('tankZombie', { anchorX: 0.5, anchorY: 0.5 }); return s; }); var FastZombie = Enemy.expand(function () { var self = Enemy.call(this); var s = Enemy.call(this); s.hp = 15; s.speed = 4; s.expValue = 8; s.attachAsset('fastZombie', { anchorX: 0.5, anchorY: 0.5 }); return s; }); var Boss = Enemy.expand(function () { var self = Enemy.call(this); var s = Enemy.call(this); s.hp = 500; s.damage = 30; s.speed = 1.5; s.expValue = 100; s.type = 'boss'; s.attachAsset('boss', { anchorX: 0.5, anchorY: 0.5 }); return s; }); /****----------------------------------------------------------------- * 5. Exp orb / pickups (unchanged except helper magnetSpeed) *------------------------------------------------------------------*/ var ExpOrb = Container.expand(function () { var self = Container.call(this); self.value = 5; self.magnetSpeed = 0; self.attachAsset('expOrb', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { if (!player || !self.magnetSpeed) { return; } var dx = player.x - self.x, dy = player.y - self.y, d = Math.sqrt(dx * dx + dy * dy); if (d > 0) { self.x += dx / d * self.magnetSpeed; self.y += dy / d * self.magnetSpeed; } }; return self; }); var FlameField = Container.expand(function () { var self = Container.call(this); var gfx = self.attachAsset('molotov', { anchorX: 0.5, anchorY: 0.5, alpha: 0.4 }); self.life = 60; self.dmg = 12; self.radius = 70; self.update = function () { if (--self.life <= 0) { self.destroy(); } }; return self; }); /****----------------------------------------------------------------- * 6. Joystick (same as before) *------------------------------------------------------------------*/ var Joystick = Container.expand(function () { var self = Container.call(this); self.active = false; self.dirX = 0; self.dirY = 0; var base = self.attachAsset('joystickBase', { anchorX: 0.5, anchorY: 0.5 }); base.alpha = 0.5; var knob = self.attachAsset('joystickKnob', { anchorX: 0.5, anchorY: 0.5 }); knob.alpha = 0.7; self.setKnobPosition = function (x, y) { var dx = x - base.x, dy = y - base.y, d = Math.sqrt(dx * dx + dy * dy), m = 60; if (d > m) { dx = dx / d * m; dy = dy / d * m; } knob.x = dx; knob.y = dy; self.dirX = dx / m; self.dirY = dy / m; }; self.reset = function () { knob.x = 0; knob.y = 0; self.dirX = self.dirY = 0; self.active = false; }; return self; }); var LightningStrike = Container.expand(function () { var self = Container.call(this); self.attachAsset('lightning', { anchorX: 0.5, anchorY: 1 }); self.life = 30; self.dmg = 30; self.update = function () { if (--self.life <= 0) { self.destroy(); } }; return self; }); /****----------------------------------------------------------------- * 7. Player (now supports weapons / ench / upgrades) *------------------------------------------------------------------*/ var Player = Container.expand(function () { var self = Container.call(this); self.level = 1; self.exp = 0; self.expToNext = 10; self.hp = 100; self.maxHp = 100; self.moveSpeed = 5; self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); /* ---- WEAPON INVENTORY ---- */ self.weapons = {}; // key→data per weapon instance addWeapon('sword'); // starts with sword function addWeapon(k) { if (self.weapons[k]) { return false; } var d = WEAPONS[k]; self.weapons[k] = { lvl: 1, cd: d.baseCooldown, cdCounter: 0, dmgMul: 1, rngMul: 1, sizeMul: 1, amount: 1, upgradesGot: 0, enchGot: [] }; return true; } /* ---- Level / EXP ---- */ self.gainExp = function (v) { self.exp += v; if (self.exp >= self.expToNext) { levelUp(); } }; function levelUp() { self.level++; self.exp = 0; self.expToNext = self.level * 15; self.maxHp += 10; self.hp = Math.min(self.maxHp, self.hp + self.maxHp * 0.3); // auto-heal 30% after check below LK.getSound('levelup').play(); openChoiceUI(); } /* ---- Combat Tick ---- */ self.update = function () { // traverse owned weapons, fire if CD ready for (var w in self.weapons) { var inst = self.weapons[w], meta = WEAPONS[w]; inst.cdCounter--; if (inst.cdCounter <= 0) { fireWeapon(w, inst, meta); inst.cdCounter = inst.cd | 0; } } }; /* ---- Weapon Firing Logic (very lean) ---- */ function fireWeapon(k, inst, meta) { if (Object.keys(enemies).length === 0) { return; } switch (meta.type) { case 'melee': swingSword(inst); break; case 'boomerang': throwBoomerang(inst); break; case 'ball': throwBall(inst); break; case 'rocket': fireRocket(inst); break; case 'brick': throwBrick(inst, 75); if (inst.upgradesGot > 0) throwBrick(inst, -75); if (inst.upgradesGot > 1) throwBrick(inst, 45); if (inst.upgradesGot > 2) throwBrick(inst, -45); break; case 'lightning': for (var i = 0; i < inst.amount; i++) { strikeLightning(inst); } break; case 'aura': /* aura handled by passive field following player */break; case 'molotov': for (var i = 0; i < inst.amount; i++) { throwMolotov(inst); } break; case 'shuriken': /* spinning handled elsewhere */break; } } /* ----- individual weapon helpers (compact) ----- */ function nearestEnemy() { var n = null, d = 1e9; for (var i = 0; i < enemies.length; i++) { var e = enemies[i], dx = e.x - self.x, dy = e.y - self.y, di = dx * dx + dy * dy; if (di < d) { d = di; n = e; } } return n; } function directionTo(e) { var dx = e.x - self.x, dy = e.y - self.y, d = Math.sqrt(dx * dx + dy * dy); return { dx: dx / d, dy: dy / d }; } function swingSword(inst) { var arc = new Container(); arc.x = self.x; arc.y = self.y; arc.attachAsset('swordHit', { anchorX: 0, anchorY: 0.5, rotation: self.rotation, scaleX: inst.sizeMul, scaleY: inst.sizeMul }); arc.life = 10; arc.dmg = 10 * inst.dmgMul; arc.update = function () { if (--arc.life <= 0) { arc.destroy(); return; } for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; if (e.intersectsCircle(arc.x, arc.y, meta.range * inst.rngMul) && e.takeDamage(arc.dmg)) { killEnemy(i); } } }; gameContainer.addChild(arc); } function throwBoomerang(inst) { var e = nearestEnemy(); if (!e) return; var dir = directionTo(e); for (var i = 0; i < inst.amount; i++) { var p = new BoomerangProj(); p.x = self.x; p.y = self.y; p.speed = 12; p.dirX = dir.dx; p.dirY = dir.dy; p.dmg = 10 * inst.dmgMul; p.returnPhase = false; p.life = 240; p.update = function () { if (!p.returnPhase && --p.life < 180) { p.returnPhase = true; } if (p.returnPhase) { var dx = self.x - p.x, dy = self.y - p.y, d = Math.sqrt(dx * dx + dy * dy); p.dirX = dx / d; p.dirY = dy / d; } BoomerangProj.parent.update.call(p); for (var i = enemies.length - 1; i >= 0; i--) { var en = enemies[i]; if (p.intersects(en) && en.takeDamage(p.dmg)) { killEnemy(i); } } }; bullets.push(p); gameContainer.addChild(p); } } function throwBall(inst) { var e = nearestEnemy(); if (!e) return; var dir = directionTo(e); for (var i = 0; i < inst.amount; i++) { var b = new BallProj(); b.x = self.x; b.y = self.y; b.dirX = dir.dx; b.dirY = dir.dy; b.dmg = 12 * inst.dmgMul; b.bounced = false; b.update = function () { BallProj.parent.update.call(b); if (!b.bounced && (Math.abs(b.x - self.x) > 1150 || Math.abs(b.y - self.y) > 1550)) { b.dirX *= -1; b.dirY *= -1; b.bounced = true; } for (var i = enemies.length - 1; i >= 0; i--) { var en = enemies[i]; if (b.intersects(en) && en.takeDamage(b.dmg)) { killEnemy(i); } } }; bullets.push(b); gameContainer.addChild(b); } } function fireRocket(inst) { var e = nearestEnemy(); if (!e) return; var dir = directionTo(e); for (var i = 0; i < inst.amount; i++) { var r = new RocketProj(); r.x = self.x; r.y = self.y; r.dirX = dir.dx; r.dirY = dir.dy; r.dmg = 20 * inst.dmgMul; r.update = function () { RocketProj.parent.update.call(r); for (var i = enemies.length - 1; i >= 0; i--) { var en = enemies[i]; if (r.intersects(en)) { rocketAoE(r.x, r.y, 120 * inst.rngMul, r.dmg); r.destroy(); bullets.splice(bullets.indexOf(r), 1); break; } } }; bullets.push(r); gameContainer.addChild(r); } } function rocketAoE(cx, cy, rad, dmg) { for (var i = enemies.length - 1; i >= 0; i--) { var en = enemies[i]; if (en.intersectsCircle(cx, cy, rad) && en.takeDamage(dmg)) { killEnemy(i); } } LK.effects.flashScreen(0xff6622, 100); } function throwBrick(inst, angle) { var rad = self.rotation + angle * Math.PI / 180; var dirX = Math.cos(rad), dirY = Math.sin(rad); var br = new BrickProj(); br.x = self.x; br.y = self.y; br.dirX = dirX; br.dirY = dirY; br.gravity = 0.4; br.speed = 14; br.dmg = 15 * inst.dmgMul; br.update = function () { br.y += br.gravity; BrickProj.parent.update.call(br); if (Math.abs(br.x - self.x) > 1200 || br.y > self.y + 1400) { br.destroy(); bullets.splice(bullets.indexOf(br), 1); return; } for (var i = enemies.length - 1; i >= 0; i--) { var en = enemies[i]; if (br.intersects(en) && en.takeDamage(br.dmg)) { killEnemy(i); } } }; bullets.push(br); gameContainer.addChild(br); } function strikeLightning(inst) { var e = enemies[Math.floor(Math.random() * enemies.length)]; if (!e) return; var l = new LightningStrike(); l.x = e.x; l.y = e.y; bullets.push(l); gameContainer.addChild(l); for (var i = enemies.length - 1; i >= 0; i--) { var en = enemies[i]; if (en.x === e.x && en.y === e.y && en.takeDamage(25 * inst.dmgMul)) { killEnemy(i); } } } function throwMolotov(inst) { var angle = Math.random() * Math.PI * 2, dist = 200 + Math.random() * 500, tx = self.x + Math.cos(angle) * dist, ty = self.y + Math.sin(angle) * dist; var m = new MolotovProjectile(tx, ty, inst); bullets.push(m); gameContainer.addChild(m); } function MolotovProjectile(tx, ty, inst) { var mp = new BrickProj(); mp.x = self.x; mp.y = self.y; var dx = tx - mp.x, dy = ty - mp.y, d = Math.sqrt(dx * dx + dy * dy); mp.dirX = dx / d; mp.dirY = dy / d; mp.speed = 15; mp.update = function () { BrickProj.parent.update.call(mp); if (Math.sqrt(Math.pow(mp.x - tx, 2) + Math.pow(mp.y - ty, 2)) < 20) { spawnFlame(mp.x, mp.y, inst); mp.destroy(); bullets.splice(bullets.indexOf(mp), 1); } }; return mp; } function spawnFlame(x, y, inst) { var f = new FlameField(); f.x = x; f.y = y; bullets.push(f); gameContainer.addChild(f); f.update = function () { FlameField.parent.update.call(f); for (var i = enemies.length - 1; i >= 0; i--) { var en = enemies[i]; if (en.intersectsCircle(f.x, f.y, f.radius) && en.takeDamage(f.dmg * inst.dmgMul)) { killEnemy(i); } } }; } function killEnemy(idx) { var en = enemies[idx]; dropExpOrb(en.x, en.y, en.expValue); en.destroy(); enemies.splice(idx, 1); } /* --------------------------------------------------------------*/ /* ---- Choice UI (enchant vs weapon selection) ---- */ function openChoiceUI() { skillSelectionActive = true; var overlay = game.addChild(new Container()); overlay.x = 1024; overlay.y = 1366; var cards = []; var choices = []; if (self.level % 5 === 0) { // weapon choices var pool = Object.keys(WEAPONS); while (choices.length < 3 && pool.length) { var pick = pool.splice(Math.random() * pool.length | 0, 1)[0]; choices.push(pick); } choices.forEach(function (wKey, i) { var data = WEAPONS[wKey]; var already = !!self.weapons[wKey]; var bg = addCard(i, data.display + (already ? " Upgrade" : " Unlock")); bg.effect = function () { if (already) { var inst = self.weapons[wKey]; var upArr = data.upgrades; if (inst.upgradesGot < 3) { applyUpgrade(inst, data); } else { self.hp = Math.min(self.maxHp, self.hp + self.maxHp * 0.3); } // full upgrades → heal 30 % } else { addWeapon(wKey); } }; }); } else { // enchantments for current weapon in hand (sword if only one) var currentKey = Object.keys(self.weapons)[0]; var inst = self.weapons[currentKey], meta = WEAPONS[currentKey]; var pool = meta.ench.filter(function (e) { return inst.enchGot.indexOf(e.label) === -1; }); if (pool.length === 0) { self.hp = Math.min(self.maxHp, self.hp + self.maxHp * 0.3); skillSelectionActive = false; overlay.destroy(); return; } while (choices.length < 3 && pool.length) { var pick = pool.splice(Math.random() * pool.length | 0, 1)[0]; choices.push(pick); } choices.forEach(function (e, i) { var bg = addCard(i, e.label); bg.effect = function () { applyEnchant(inst, e); }; }); } function addCard(idx, text) { var card = overlay.addChild(new Container()); card.attachAsset('skillCard', { anchorX: 0.5, anchorY: 0.5 }); card.x = (idx - 1) * 450; card.y = 0; var t = new Text2(text, { size: 38, fill: 0xffffff }); t.anchor.set(0.5); card.addChild(t); card.down = function () { this.effect(); overlay.destroy(); skillSelectionActive = false; levelText.setText('Level ' + self.level); }; return card; } } function applyEnchant(inst, e) { inst.enchGot.push(e.label); if (e.k === 'dmg') inst.dmgMul *= e.v; if (e.k === 'cd') inst.cd *= e.v; if (e.k === 'rng') inst.rngMul *= e.v; if (e.k === 'size') inst.sizeMul *= e.v; } function applyUpgrade(inst, meta) { inst.upgradesGot++; if (meta.type !== 'sword') inst.amount++; } return self; }); /**** * Initialize Game ****/ /****----------------------------------------------------------------- * 8. Game bootstrap (everything else from your original file) *------------------------------------------------------------------*/ var game = new LK.Game({ backgroundColor: 0x111111 }); /**** * Game Code ****/ /****----------------------------------------------------------------- * 2. Weapon / Enchant / Upgrade data tables (single source of truth) *------------------------------------------------------------------*/ /****----------------------------------------------------------------- * 1. Plugins *------------------------------------------------------------------*/ /*— existing assets you already had —*/ /****----------------------------------------------------------------- * 0. Assets *------------------------------------------------------------------*/ /******************************************************************** * SURVIVOR-LIKE — HUGE UPDATE (nine weapons, enchants, upgrades) * ********************************************************************/ var WEAPONS = { sword: { display: "Sword", baseCooldown: 120, range: 90, type: 'melee', ench: [{ k: 'dmg', v: 1.10, label: "+10% Damage" }, { k: 'cd', v: 0.90, label: "+10% Attack Speed" }, { k: 'rng', v: 1.10, label: "+10% Range" }, { k: 'size', v: 1.10, label: "+10% Size" }], upgrades: [{ id: 1, label: "Back Swing" }, { id: 2, label: "Up Swing" }, { id: 3, label: "Down Swing" }] }, boomerang: { display: "Boomerang", baseCooldown: 180, range: 900, type: 'boomerang', ench: [{ k: 'dmg', v: 1.10, label: "+10% Damage" }, { k: 'cd', v: 0.90, label: "+10% Attack Speed" }, { k: 'rng', v: 1.10, label: "+10% Range" }, { k: 'size', v: 1.10, label: "+10% Size" }], upgrades: [{ id: 1, label: "+1 Boomerang" }, { id: 2, label: "+1 Boomerang" }, { id: 3, label: "+1 Boomerang" }] }, ball: { display: "Rebound Ball", baseCooldown: 180, range: 900, type: 'ball', ench: [/*same four*/], upgrades: [{ id: 1, label: "+1 Ball" }, { id: 2, label: "+1 Ball" }, { id: 3, label: "+1 Ball" }] }, rocket: { display: "Rocket", baseCooldown: 180, range: 650, type: 'rocket', ench: [/*same four*/], upgrades: [{ id: 1, label: "+1 Rocket" }, { id: 2, label: "+1 Rocket" }, { id: 3, label: "+1 Rocket" }] }, brick: { display: "Brick", baseCooldown: 180, range: 800, type: 'brick', ench: [/*same four*/], upgrades: [{ id: 1, label: "Back 75° Brick" }, { id: 2, label: "Front 45° Brick" }, { id: 3, label: "Back 45° Brick" }] }, lightning: { display: "Lightning", baseCooldown: 180, range: 9999, type: 'lightning', ench: [/*same four*/], upgrades: [{ id: 1, label: "+1 Lightning" }, { id: 2, label: "+1 Lightning" }, { id: 3, label: "+1 Lightning" }] }, aura: { display: "Aura", baseCooldown: 60, range: 150, type: 'aura', ench: [/*same four*/], upgrades: [{ id: 1, label: "Slow 25%" }, { id: 2, label: "Slow 50%" }, { id: 3, label: "Slow 75%" }] }, molotov: { display: "Molotov", baseCooldown: 180, range: 850, type: 'molotov', ench: [/*same four*/], upgrades: [{ id: 1, label: "+1 Molotov" }, { id: 2, label: "+1 Molotov" }, { id: 3, label: "+1 Molotov" }] }, shuriken: { display: "Shuriken", baseCooldown: 180, range: 250, type: 'shuriken', ench: [/*same four*/], upgrades: [{ id: 1, label: "+1 Shuriken" }, { id: 2, label: "+1 Shuriken" }, { id: 3, label: "+1 Shuriken" }] } }; // copy generic ench array where needed for (var w in WEAPONS) { if (!WEAPONS[w].ench.length) { WEAPONS[w].ench = [{ k: 'dmg', v: 1.10, label: "+10% Damage" }, { k: 'cd', v: 0.90, label: "+10% Attack Speed" }, { k: 'rng', v: 1.10, label: "+10% Range" }, { k: 'size', v: 1.10, label: "+10% Size" }]; } } /****----------------------------------------------------------------- * 3. Base projectile / area containers * (Boomerang, Ball, Rocket, Brick, Lightning, Shuriken, Aura, Molotov Flame) *------------------------------------------------------------------*/ function makeSimpleProj(shapeKey) { // generic projectile helper return Container.expand(function () { var self = Container.call(this); self.speed = 10; self.dirX = 0; self.dirY = 0; self.dmg = 10; self.life = 600; self.attachAsset(shapeKey, { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { self.x += self.dirX * self.speed; self.y += self.dirY * self.speed; if (--self.life <= 0) { self.destroy(); } }; return self; }); } var Bullet = makeSimpleProj('bullet'); // kept for pickup-bomb etc. var BallProj = makeSimpleProj('ball'); var RocketProj = makeSimpleProj('rocket'); var BrickProj = makeSimpleProj('brick'); var BoomerangProj = makeSimpleProj('boomerang'); var ShurikenProj = makeSimpleProj('shuriken'); var player, enemies = [], bullets = [], expOrbs = [], joystick, gameTime = 0, waveNumber = 1, bossSpawned = false; var skillSelectionActive = false, gameContainer, camera = { x: 0, y: 0 }; /* — create world, player, joystick, UI — */ gameContainer = game.addChild(new Container()); player = gameContainer.addChild(new Player()); player.x = 1024; player.y = 1366; joystick = new Joystick(); joystick.x = 0; joystick.y = -200; LK.gui.bottom.addChild(joystick); /* timer / hp / level text (unchanged) … (keep your original UI init code) */ /* — wave spawn / exp orb / helper funcs remain mostly identical — */ /* ... (you can keep your original spawnEnemy, spawnWave, dropExpOrb, etc.) */ /* ----------------------------------------------------------------- * 9. Input handlers (same as before) * ----------------------------------------------------------------*/ game.down = function (x, y) { if (skillSelectionActive) return; var loc = game.toLocal({ x: x, y: y }); if (loc.y > 2000) { joystick.active = true; joystick.setKnobPosition(0, 0); } }; game.move = function (x, y) { if (!joystick.active || skillSelectionActive) return; var loc = LK.gui.bottom.toLocal({ x: x, y: y }); var dx = loc.x - joystick.x, dy = loc.y - joystick.y; joystick.setKnobPosition(dx, dy); }; game.up = function () { joystick.reset(); }; /* ----------------------------------------------------------------- * 10. Update loop (integrates new player & weapon logic) * ----------------------------------------------------------------*/ game.update = function () { if (skillSelectionActive) { return; } gameTime++; /* --- player movement --- */ if (joystick.active) { player.x += joystick.dirX * player.moveSpeed; player.y += joystick.dirY * player.moveSpeed; } /* --- camera follow --- */ camera.x = player.x - 1024; camera.y = player.y - 1366; gameContainer.x = -camera.x; gameContainer.y = -camera.y; /* --- spawn waves / boss exactly like before (copy your original logic) --- */ /* --- update containers (player already inside its own update) --- */ for (var i = enemies.length - 1; i >= 0; i--) { var e = enemies[i]; if (e.intersects(player)) { player.hp -= e.damage; e.destroy(); enemies.splice(i, 1); } } bullets.forEach(function (b) { if (b.update) b.update(); }); expOrbs.forEach(function (o) { if (o.update) o.update(); }); for (var i = expOrbs.length - 1; i >= 0; i--) { var o = expOrbs[i]; if (o.intersects(player)) { player.gainExp(o.value); o.destroy(); expOrbs.splice(i, 1); } } }; /* initial wave */ function spawnWave() { // Only allow up to 30 enemies at once if (enemies.length >= 30) return; // Spawn a wave of enemies off-screen, coming toward the player var numToSpawn = Math.min(5 + waveNumber, 30 - enemies.length); for (var i = 0; i < numToSpawn; i++) { // Pick a random angle around the player var angle = Math.random() * Math.PI * 2; // Spawn distance: just off screen (300px outside the visible area) var dist = Math.max(1100, 1500) + 300; var ex = player.x + Math.cos(angle) * dist; var ey = player.y + Math.sin(angle) * dist; // Randomly pick enemy type var e; var r = Math.random(); if (r < 0.7) { e = new Enemy(); } else if (r < 0.85) { e = new FastZombie(); } else { e = new TankZombie(); } e.x = ex; e.y = ey; enemies.push(e); gameContainer.addChild(e); } waveNumber++; // Boss spawn every 10 waves, only if not already present and under 30 enemies if (waveNumber % 10 === 0 && !bossSpawned && enemies.length < 30) { var boss = new Boss(); var bossAngle = Math.random() * Math.PI * 2; var bossDist = Math.max(1100, 1500) + 400; boss.x = player.x + Math.cos(bossAngle) * bossDist; boss.y = player.y + Math.sin(bossAngle) * bossDist; enemies.push(boss); gameContainer.addChild(boss); bossSpawned = true; } } spawnWave(); /******************************************************************** * END OF HUGE UPDATE ********************************************************************/
===================================================================
--- original.js
+++ change.js
@@ -1012,8 +1012,48 @@
}
}
};
/* initial wave */
+function spawnWave() {
+ // Only allow up to 30 enemies at once
+ if (enemies.length >= 30) return;
+ // Spawn a wave of enemies off-screen, coming toward the player
+ var numToSpawn = Math.min(5 + waveNumber, 30 - enemies.length);
+ for (var i = 0; i < numToSpawn; i++) {
+ // Pick a random angle around the player
+ var angle = Math.random() * Math.PI * 2;
+ // Spawn distance: just off screen (300px outside the visible area)
+ var dist = Math.max(1100, 1500) + 300;
+ var ex = player.x + Math.cos(angle) * dist;
+ var ey = player.y + Math.sin(angle) * dist;
+ // Randomly pick enemy type
+ var e;
+ var r = Math.random();
+ if (r < 0.7) {
+ e = new Enemy();
+ } else if (r < 0.85) {
+ e = new FastZombie();
+ } else {
+ e = new TankZombie();
+ }
+ e.x = ex;
+ e.y = ey;
+ enemies.push(e);
+ gameContainer.addChild(e);
+ }
+ waveNumber++;
+ // Boss spawn every 10 waves, only if not already present and under 30 enemies
+ if (waveNumber % 10 === 0 && !bossSpawned && enemies.length < 30) {
+ var boss = new Boss();
+ var bossAngle = Math.random() * Math.PI * 2;
+ var bossDist = Math.max(1100, 1500) + 400;
+ boss.x = player.x + Math.cos(bossAngle) * bossDist;
+ boss.y = player.y + Math.sin(bossAngle) * bossDist;
+ enemies.push(boss);
+ gameContainer.addChild(boss);
+ bossSpawned = true;
+ }
+}
spawnWave();
/********************************************************************
* END OF HUGE UPDATE
********************************************************************/
\ No newline at end of file
Survivor.io style 2D sword swing effect made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows. It should only have a slash effect, no swords. The slash effect should also be in the shape of a half moon.
Survivor.io style 2D round soccer ball made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A 2D Survivor.io style lightning strike from a cloud in the sky to the ground, made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A red and blue Survivor.io style 2D U-shaped (with N and S) magnet made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D shuriken made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D brick made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D missile rocket made by HABBY PTE. LTD.
A 2D green radiating circular aura in the Survivor.io style made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A 2D bomb in the style of Survivor.io, made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
A 2D circular burning effect in Survivor.io style made by HABBY PTE. LTD. (not only the surroundings but also the inside burns) In-Game asset. 2d. High contrast. No shadows
A 2D molotov in the Survivor.io style made by HABBY PTE. LTD.. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D greenish exp sphere made by HABBY PTE. LTD. No exp written on it. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D half-moon orange boomerang made by HABBY PTE. LTD. In-Game asset. 2d. High contrast. No shadows
Survivor.io style 2D 1 chicken leg.. In-Game asset. 2d. High contrast. No shadows
2D survivor.io game style atomic boom effect front view. No text written on it.
2D. Ranged zombie. attacks with poisonous saliva. In-Game asset. 2d. High contrast. No shadows
2D. Child (small) zombie. He has a small saw in his hand.. In-Game asset. 2d. High contrast. No shadows
2D. Fat zombie. His hands are too big.. In-Game asset. 2d. High contrast. No shadows
Poisonous green circular saliva. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Small green claw slash effect. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Giant boss angry reddish zombie. 2D.. In-Game asset. 2d. High contrast. No shadows
Small saw slash effect. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Big red fist slash effect. 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
Kanlı kemik 2D. Top View.. In-Game asset. 2d. High contrast. No shadows
2D character that looks like a prophet and holds a holy book in his hand.. In-Game asset. 2d. High contrast. No shadows
A background image (wallpaper) representing an old prophet-like man with white hair and beard, wearing a priest's robe (hooded) and holding a holy book (christianity, cross) in his hand, fighting against zombies.. In-Game asset. 2d. High contrast. No shadows
Zombie flesh and bone themed 2D cardboard hollow (without text) horizontal rectangular button.. In-Game asset. 2d. High contrast. No shadows
2D. Healer zombie. Like a female zombie in a healer costume.. In-Game asset. 2d. High contrast. No shadows
2D. Brain illustrated healing potion.. In-Game asset. 2d. High contrast. No shadows
A healing blood pool with circular zombie brain and bone particles. Green + (healing) symbols on top. 2D.. In-Game asset. 2d. High contrast. No shadows
2D. Survivor.io game style skill card. No text written on it. No symbols on it. Just the blank card. Green.. In-Game asset. 2d. High contrast. No shadows
2D. Cartoon. The rise of the zombie ghost spirit from the ground.. In-Game asset. 2d. High contrast. No shadows
levelup
Sound effect
hit
Sound effect
rocketBoom
Sound effect
pickup
Sound effect
backGroundMusic
Music
death
Sound effect
damageTaken
Sound effect
mainMenuMusic
Music
deathScreenMusic
Music
swordSoundEffect
Sound effect
bumerangSoundEffect
Sound effect
brickSoundEffect
Sound effect
lightningSoundEffect
Sound effect
ballSoundEffect
Sound effect
rocketSoundEffect
Sound effect
auraSoundEffect
Sound effect
molotovSoundEffect
Sound effect
molotovBoom
Sound effect
introSpeech
Sound effect
bombBoomSound
Sound effect