From edd005cb4d901477f01a31b21172c44b4a5cdcb2 Mon Sep 17 00:00:00 2001 From: biglyderv Date: Mon, 25 Nov 2024 14:14:21 -0500 Subject: [PATCH] add enemy --- common/entity.js | 6 ++++ common/player.js | 5 ++++ common/shooter.js | 38 ++++++++++++++++++++++++ game.js | 5 ++++ static/assets/npc.svg | 14 ++++----- static/assets/shooter.svg | 62 +++++++++++++++++++++++++++++++++++++++ static/js/index.js | 17 +++++++++-- 7 files changed, 137 insertions(+), 10 deletions(-) create mode 100644 common/shooter.js create mode 100644 static/assets/shooter.svg diff --git a/common/entity.js b/common/entity.js index e532aef..d8a3eca 100644 --- a/common/entity.js +++ b/common/entity.js @@ -10,13 +10,19 @@ class Entity { let ent = this; let { width, height } = game; + let bounced = false; + if (Math.abs(ent.pos.x) >= width / 2) { ent.vel.x = (Math.abs(ent.vel.x) + 10) * -Math.sign(ent.pos.x); + bounced = true; } if (Math.abs(ent.pos.y) >= height / 2) { ent.vel.y = (Math.abs(ent.vel.y) + 10) * -Math.sign(ent.pos.y); + bounced = true; } + + return bounced; } } diff --git a/common/player.js b/common/player.js index 6acf3a8..c30d341 100644 --- a/common/player.js +++ b/common/player.js @@ -93,6 +93,11 @@ class Player extends Entity { ent.isMenu = true; ent.rot = 1.2; } + + if (target.type == 'Shooter') { + this.health = 0; + } + if (target.immortal) continue; let oldHealth = target.health diff --git a/common/shooter.js b/common/shooter.js new file mode 100644 index 0000000..4bfdedd --- /dev/null +++ b/common/shooter.js @@ -0,0 +1,38 @@ +import { distF, uuidv4 } from './util.js' +import Entity from "./entity.js"; + +class Shooter extends Entity { + constructor(you, game = false) { + super(game); + + this.you = you || uuidv4(); + + this.type = 'Shooter'; + + this.immortal = true; + + this.serverProps = [ + 'type', 'pos', 'vel', 'you', 'immortal', 'dir' + ]; + + this.dir = Math.random() * 696969; + } + handleTick(game) { + this.ticks++; + + this.vel.x += Math.sin(this.dir) * 1; + this.vel.y += Math.cos(this.dir) * 1; + + this.vel.x *= 0.9; + this.vel.y *= 0.9; + + this.pos.x += this.vel.x; + this.pos.y += this.vel.y; + + if (this.bounce(game)) { + this.dir = Math.random() * 696969; + } + } +} + +export default Shooter; \ No newline at end of file diff --git a/game.js b/game.js index 5e5fd01..875b658 100644 --- a/game.js +++ b/game.js @@ -1,5 +1,6 @@ import GameBasic from "./common/game_basic.js"; import NPC from "./common/npc.js"; +import Shooter from "./common/shooter.js"; import initDb from './db.js'; @@ -102,6 +103,10 @@ class Game extends GameBasic { that.entities.push(new NPC(false,that)) } + for (let i = 0; i < 30; i++) { + that.entities.push(new Shooter(false,that)) + } + setInterval(function () { that.sync(false) }, 1000 / 10); setInterval(function () { that.sync(true) }, 1000); } diff --git a/static/assets/npc.svg b/static/assets/npc.svg index 70fc43d..a5cd34a 100644 --- a/static/assets/npc.svg +++ b/static/assets/npc.svg @@ -7,7 +7,7 @@ viewBox="0 0 110 110" version="1.1" id="svg1" - inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)" + inkscape:version="1.4 (e7c3feb100, 2024-10-09)" sodipodi:docname="npc.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" @@ -24,12 +24,12 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="px" inkscape:zoom="4.1121712" - inkscape:cx="61.403085" - inkscape:cy="49.608829" - inkscape:window-width="1860" - inkscape:window-height="1004" - inkscape:window-x="30" - inkscape:window-y="46" + inkscape:cx="61.403086" + inkscape:cy="49.487239" + inkscape:window-width="1918" + inkscape:window-height="1056" + inkscape:window-x="0" + inkscape:window-y="22" inkscape:window-maximized="1" inkscape:current-layer="layer1" showgrid="false" /> diff --git a/static/assets/shooter.svg b/static/assets/shooter.svg new file mode 100644 index 0000000..6510aec --- /dev/null +++ b/static/assets/shooter.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + diff --git a/static/js/index.js b/static/js/index.js index e64ca71..994bcef 100644 --- a/static/js/index.js +++ b/static/js/index.js @@ -1,18 +1,28 @@ import Player from "./player.js"; import GameBasic from "./game_basic.js"; import NPC from "./npc.js"; +import Shooter from "./shooter.js"; const cs = 1024; const assets = [ 'assets/player.svg', 'assets/head.svg', 'assets/map.svg', - 'assets/npc.svg' + 'assets/npc.svg', + 'assets/shooter.svg' ]; const legalTypes = { Player, - NPC + NPC, + Shooter } + +const bodies = { + 'Player': 0, + 'NPC': 3, + 'Shooter': 4 +}; + const emojis = [ 'Troll', 'Exit', @@ -79,7 +89,8 @@ class Game extends GameBasic { ctx.fill(); } - ctx.drawImage((ent.type == 'NPC') ? assetsIn[3] : assetsIn[0], ent.pos.x - 64 / 2, ent.pos.y - 64 / 2, 64, 64); + let a = assetsIn[bodies[ent.type]] + ctx.drawImage(a, ent.pos.x - 64 / 2, ent.pos.y - 64 / 2, 64, 64); if (ent.type != 'Player') continue;