add enemy
This commit is contained in:
parent
a1156f1f8e
commit
758f574f10
7 changed files with 137 additions and 10 deletions
|
@ -10,13 +10,19 @@ class Entity {
|
||||||
let ent = this;
|
let ent = this;
|
||||||
let { width, height } = game;
|
let { width, height } = game;
|
||||||
|
|
||||||
|
let bounced = false;
|
||||||
|
|
||||||
if (Math.abs(ent.pos.x) >= width / 2) {
|
if (Math.abs(ent.pos.x) >= width / 2) {
|
||||||
ent.vel.x = (Math.abs(ent.vel.x) + 10) * -Math.sign(ent.pos.x);
|
ent.vel.x = (Math.abs(ent.vel.x) + 10) * -Math.sign(ent.pos.x);
|
||||||
|
bounced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Math.abs(ent.pos.y) >= height / 2) {
|
if (Math.abs(ent.pos.y) >= height / 2) {
|
||||||
ent.vel.y = (Math.abs(ent.vel.y) + 10) * -Math.sign(ent.pos.y);
|
ent.vel.y = (Math.abs(ent.vel.y) + 10) * -Math.sign(ent.pos.y);
|
||||||
|
bounced = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bounced;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,11 @@ class Player extends Entity {
|
||||||
ent.isMenu = true;
|
ent.isMenu = true;
|
||||||
ent.rot = 1.2;
|
ent.rot = 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target.type == 'Shooter') {
|
||||||
|
this.health = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (target.immortal) continue;
|
if (target.immortal) continue;
|
||||||
|
|
||||||
let oldHealth = target.health
|
let oldHealth = target.health
|
||||||
|
|
38
common/shooter.js
Normal file
38
common/shooter.js
Normal file
|
@ -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;
|
5
game.js
5
game.js
|
@ -1,5 +1,6 @@
|
||||||
import GameBasic from "./common/game_basic.js";
|
import GameBasic from "./common/game_basic.js";
|
||||||
import NPC from "./common/npc.js";
|
import NPC from "./common/npc.js";
|
||||||
|
import Shooter from "./common/shooter.js";
|
||||||
|
|
||||||
import initDb from './db.js';
|
import initDb from './db.js';
|
||||||
|
|
||||||
|
@ -102,6 +103,10 @@ class Game extends GameBasic {
|
||||||
that.entities.push(new NPC(false,that))
|
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(false) }, 1000 / 10);
|
||||||
setInterval(function () { that.sync(true) }, 1000);
|
setInterval(function () { that.sync(true) }, 1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
viewBox="0 0 110 110"
|
viewBox="0 0 110 110"
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="svg1"
|
id="svg1"
|
||||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25, custom)"
|
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||||
sodipodi:docname="npc.svg"
|
sodipodi:docname="npc.svg"
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
@ -24,12 +24,12 @@
|
||||||
inkscape:deskcolor="#d1d1d1"
|
inkscape:deskcolor="#d1d1d1"
|
||||||
inkscape:document-units="px"
|
inkscape:document-units="px"
|
||||||
inkscape:zoom="4.1121712"
|
inkscape:zoom="4.1121712"
|
||||||
inkscape:cx="61.403085"
|
inkscape:cx="61.403086"
|
||||||
inkscape:cy="49.608829"
|
inkscape:cy="49.487239"
|
||||||
inkscape:window-width="1860"
|
inkscape:window-width="1918"
|
||||||
inkscape:window-height="1004"
|
inkscape:window-height="1056"
|
||||||
inkscape:window-x="30"
|
inkscape:window-x="0"
|
||||||
inkscape:window-y="46"
|
inkscape:window-y="22"
|
||||||
inkscape:window-maximized="1"
|
inkscape:window-maximized="1"
|
||||||
inkscape:current-layer="layer1"
|
inkscape:current-layer="layer1"
|
||||||
showgrid="false" />
|
showgrid="false" />
|
||||||
|
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
62
static/assets/shooter.svg
Normal file
62
static/assets/shooter.svg
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="110"
|
||||||
|
height="110"
|
||||||
|
viewBox="0 0 110 110"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||||
|
sodipodi:docname="shooter.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#000000"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:zoom="4.1121712"
|
||||||
|
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" />
|
||||||
|
<defs
|
||||||
|
id="defs1" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(5,5)">
|
||||||
|
<circle
|
||||||
|
style="fill:#834141;fill-opacity:1;stroke:#fcf9f9;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
|
||||||
|
id="path1"
|
||||||
|
cx="50"
|
||||||
|
cy="50"
|
||||||
|
r="50" />
|
||||||
|
<path
|
||||||
|
id="circle4"
|
||||||
|
style="fill:#582b2b;stroke-width:10;stroke-linecap:round;stroke-linejoin:round;paint-order:stroke fill markers;fill-opacity:1"
|
||||||
|
d="M 50 0 A 50 50 0 0 0 4.5566406 29.15625 C 2.0495143 38.07249 0.46754838 45.280484 0.095703125 48.669922 A 50 50 0 0 0 0 50 C 0 59.3151 34.053758 47.505859 61.667969 47.505859 C 89.282178 47.505859 93.717713 56.877787 100 50 A 50 50 0 0 0 50 0 z " />
|
||||||
|
<path
|
||||||
|
id="rect1"
|
||||||
|
style="fill:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.38;paint-order:stroke fill markers"
|
||||||
|
d="m 75.271741,24.808649 c 1.762363,1.762363 1.762363,4.599958 -1e-6,6.362321 L 31.251359,75.191351 c -1.762362,1.762363 -4.599956,1.762363 -6.36232,-10e-7 -1.762362,-1.762362 -1.762362,-4.599956 0,-6.362319 L 68.90942,24.80865 c 1.762364,-1.762363 4.599958,-1.762364 6.362321,-1e-6 z" />
|
||||||
|
<path
|
||||||
|
id="path2"
|
||||||
|
style="fill:#ffffff;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.38;paint-order:stroke fill markers"
|
||||||
|
d="m 24.88904,24.808649 c -1.762363,1.762363 -1.762363,4.599958 10e-7,6.362321 l 44.020381,44.020381 c 1.762362,1.762363 4.599956,1.762363 6.36232,-10e-7 1.762362,-1.762362 1.762362,-4.599956 0,-6.362319 L 31.251361,24.80865 c -1.762364,-1.762363 -4.599958,-1.762364 -6.362321,-1e-6 z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.8 KiB |
|
@ -1,18 +1,28 @@
|
||||||
import Player from "./player.js";
|
import Player from "./player.js";
|
||||||
import GameBasic from "./game_basic.js";
|
import GameBasic from "./game_basic.js";
|
||||||
import NPC from "./npc.js";
|
import NPC from "./npc.js";
|
||||||
|
import Shooter from "./shooter.js";
|
||||||
|
|
||||||
const cs = 1024;
|
const cs = 1024;
|
||||||
const assets = [
|
const assets = [
|
||||||
'assets/player.svg',
|
'assets/player.svg',
|
||||||
'assets/head.svg',
|
'assets/head.svg',
|
||||||
'assets/map.svg',
|
'assets/map.svg',
|
||||||
'assets/npc.svg'
|
'assets/npc.svg',
|
||||||
|
'assets/shooter.svg'
|
||||||
];
|
];
|
||||||
const legalTypes = {
|
const legalTypes = {
|
||||||
Player,
|
Player,
|
||||||
NPC
|
NPC,
|
||||||
|
Shooter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bodies = {
|
||||||
|
'Player': 0,
|
||||||
|
'NPC': 3,
|
||||||
|
'Shooter': 4
|
||||||
|
};
|
||||||
|
|
||||||
const emojis = [
|
const emojis = [
|
||||||
'Troll',
|
'Troll',
|
||||||
'Exit',
|
'Exit',
|
||||||
|
@ -79,7 +89,8 @@ class Game extends GameBasic {
|
||||||
ctx.fill();
|
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;
|
if (ent.type != 'Player') continue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue