Added everything from chapter 4 and set up ESlint

This commit is contained in:
Arne van Iterson 2020-03-21 17:22:28 +01:00
parent 3490dd07ae
commit 72633d8c0f
23 changed files with 1727 additions and 416 deletions

2
.eslintignore Normal file
View File

@ -0,0 +1,2 @@
projects
examples

33
.eslintrc.js Normal file
View File

@ -0,0 +1,33 @@
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es6": true
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
]
}
};

63
lib/AnimManager.js Normal file
View File

@ -0,0 +1,63 @@
class Anim {
constructor(frames, rate) {
this.frames = frames;
this.rate = rate;
this.reset();
}
update(dt) {
const { rate, frames } = this;
if ((this.curTime += dt) > rate) {
this.curFrame++;
this.frame = frames[this.curFrame % frames.length];
this.curTime -= rate;
}
}
reset() {
this.frame = this.frames[0];
this.curFrame = 0;
this.curTime = 0;
}
}
class AnimManager {
constructor(e) {
this.anims = {};
this.running = false;
this.frameSource = e.frame || e;
this.currrent = null;
}
add(name, frames, speed) {
this.anims[name] = new Anim(frames, speed);
return this.anims[name];
}
update(dt) {
const { current, anims, frameSource } = this;
if (!current) {
return;
}
const anim = anims[current];
anim.update(dt);
frameSource.x = anim.frame.x;
frameSource.y = anim.frame.y;
}
play(anim) {
const { current, anims } = this;
if (anim === current ) {
return;
}
this.current = anim;
anims[anim].reset();
}
stop() {
this.current = null;
}
}
module.exports = AnimManager;

54
lib/Camera.js Normal file
View File

@ -0,0 +1,54 @@
const Container = require("./Container");
const math = require("./utilities/math");
class Camera extends Container {
constructor(subject, viewport, worldSize = viewport) {
super();
this.w = viewport.w;
this.h = viewport.h;
this.worldSize = worldSize;
this.setSubject(subject);
}
setSubject(e) {
this.subject = e ? e.pos || e : this.pos;
this.offset = { x: 0, y: 0 };
// Center on the entity
if (e && e.w) {
this.offset.x += e.w / 2;
this.offset.y += e.h / 2;
}
if (e && e.anchor) {
this.offset.x -= e.anchor.x;
this.offset.y -= e.anchor.y;
}
this.focus();
}
focus() {
const { pos, w, h, worldSize, subject, offset } = this;
const centeredX = subject.x + offset.x - w / 2;
const maxX = worldSize.w - w;
const x = -math.clamp(centeredX, 0, maxX);
const centeredY = subject.y + offset.y - h / 2;
const maxY = worldSize.h - h;
const y = -math.clamp(centeredY, 0, maxY);
pos.x = x;
pos.y = y;
}
update(dt, t) {
super.update(dt, t);
if (this.subject) {
this.focus();
}
}
}
module.exports = Camera;

View File

@ -1,5 +1,5 @@
var Container = require("./Container"), var Container = require("./Container"),
CanvasRenderer = require('./renderer/CanvasRenderer') CanvasRenderer = require("./renderer/CanvasRenderer")
; ;
const STEP = 1 / 60; const STEP = 1 / 60;

View File

@ -5,6 +5,6 @@ class Rect {
this.h = h; this.h = h;
this.style = style; this.style = style;
} }
} }
module.exports = Rect; module.exports = Rect;

View File

@ -6,7 +6,7 @@ class SpriteSheetXML {
fetchXMLtoArray(url) { fetchXMLtoArray(url) {
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open('GET', url, false); xhr.open("GET", url, false);
xhr.send(null); xhr.send(null);
if (xhr.status === 200) { if (xhr.status === 200) {
@ -22,7 +22,7 @@ class SpriteSheetXML {
}); });
} }
} else { } else {
console.error('XML file cannot be loaded!') console.error("XML file cannot be loaded!");
} }
} }

View File

@ -20,6 +20,40 @@ class TileMap extends Container {
return s; return s;
}); });
} }
pixelToMapPos(pos) {
const { tileW, tileH } = this;
return {
x: Math.floor(pos.x / tileW),
y: Math.floor(pos.y / tileH)
};
}
mapToPixelPos(mapPos) {
const { tileW, tileH } = this;
return {
x: mapPos.x * tileW,
y: mapPos.y * tileH
};
}
tileAtMapPos(mapPos) {
return this.children[mapPos.y * this.mapW + mapPos.x];
}
tileAtPixelPos(pos) {
return this.tileAtMapPos(this.pixelToMapPos(pos));
}
setFrameAtMapPos(mapPos, frame) {
const tile = this.tileAtMapPos(mapPos);
tile.frame = frame;
return tile;
}
setFrameAtPixelPos(pos, frame) {
return this.setFrameAtMapPos(this.pixelToMapPos(pos), frame);
}
} }
module.exports = TileMap; module.exports = TileMap;

View File

@ -4,9 +4,9 @@ class TileSpriteXML extends Sprite {
constructor(texture, xml, index) { constructor(texture, xml, index) {
super(texture); super(texture);
var src = xml.array[index]; var src = xml.array[index];
this.imgPos = { x: src['x'], y: src['y'] }; this.imgPos = { x: src["x"], y: src["y"] };
this.width = src['width']; this.width = src["width"];
this.height = src['height']; this.height = src["height"];
} }
} }

View File

@ -9,7 +9,7 @@ class KeyControls {
} }
this.keys[e.which] = true; this.keys[e.which] = true;
}, false); }, false);
document.addEventListener('keyup', e => { document.addEventListener("keyup", e => {
this.keys[e.which] = false; this.keys[e.which] = false;
}, false); }, false);
} }

View File

@ -7,9 +7,9 @@ class MouseControls {
this.pressed = false; this.pressed = false;
this.released = false; this.released = false;
// Handlers // Handlers
document.addEventListener('mousemove', this.move.bind(this), false); document.addEventListener("mousemove", this.move.bind(this), false);
document.addEventListener('mousedown', this.down.bind(this), false); document.addEventListener("mousedown", this.down.bind(this), false);
document.addEventListener('mouseup', this.up.bind(this), false); document.addEventListener("mouseup", this.up.bind(this), false);
} }
mousePosFromEvent({ clientX, clientY }) { mousePosFromEvent({ clientX, clientY }) {

View File

@ -1,4 +1,6 @@
var Container = require("./Container.js"), var AnimManager = require("./AnimManager.js"),
Camera = require("./Camera.js"),
Container = require("./Container.js"),
CanvasRenderer = require("./renderer/CanvasRenderer.js"), CanvasRenderer = require("./renderer/CanvasRenderer.js"),
Game = require("./Game.js"), Game = require("./Game.js"),
math = require("./utilities/math.js"), math = require("./utilities/math.js"),
@ -17,7 +19,9 @@ var Container = require("./Container.js"),
; ;
module.exports = { module.exports = {
AnimManager,
CanvasRenderer, CanvasRenderer,
Camera,
Container, Container,
Game, Game,
math, math,

View File

@ -10,11 +10,11 @@ class CanvasRenderer {
} }
setPixelated() { setPixelated() {
this.ctx['imageSmoothingEnabled'] = false; /* standard */ this.ctx["imageSmoothingEnabled"] = false; /* standard */
this.ctx['mozImageSmoothingEnabled'] = false; /* Firefox */ this.ctx["mozImageSmoothingEnabled"] = false; /* Firefox */
this.ctx['oImageSmoothingEnabled'] = false; /* Opera */ this.ctx["oImageSmoothingEnabled"] = false; /* Opera */
this.ctx['webkitImageSmoothingEnabled'] = false; /* Safari */ this.ctx["webkitImageSmoothingEnabled"] = false; /* Safari */
this.ctx['msImageSmoothingEnabled'] = false; /* IE */ this.ctx["msImageSmoothingEnabled"] = false; /* IE */
} }
render(container, clear = true) { render(container, clear = true) {
@ -78,7 +78,7 @@ class CanvasRenderer {
); );
} else if (child.style && child.w && child.h) { } else if (child.style && child.w && child.h) {
ctx.fillStyle = child.style.fill; ctx.fillStyle = child.style.fill;
ctx.fillRect(0, 0, child.w, child.h) ctx.fillRect(0, 0, child.w, child.h);
} else { } else {
ctx.drawImage(img, 0, 0); ctx.drawImage(img, 0, 0);
} }
@ -89,7 +89,7 @@ class CanvasRenderer {
renderRec(child); renderRec(child);
} }
ctx.restore(); ctx.restore();
}) });
} }
if (clear) { if (clear) {
ctx.clearRect(0, 0, this.w, this.h); ctx.clearRect(0, 0, this.w, this.h);

View File

@ -1,5 +1,5 @@
const math = require('./math'); const math = require("./math");
const Rect = require('../Rect'); const Rect = require("../Rect");
function addDebug(e) { function addDebug(e) {
e.children = e.children || []; e.children = e.children || [];

View File

@ -1,3 +1,22 @@
function angle(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
const angle = Math.atan2(dy, dx);
return angle;
}
function clamp(x, min, max) {
return Math.max(min, Math.min(x, max));
}
function distance (a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
}
function rand(min, max) { function rand(min, max) {
return Math.floor(randf(min, max)); return Math.floor(randf(min, max));
} }
@ -19,6 +38,9 @@ function randOneIn(max = 2) {
} }
module.exports = { module.exports = {
angle,
clamp,
distance,
rand, rand,
randf, randf,
randOneFrom, randOneFrom,

1096
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -17,5 +17,8 @@
"name": "Arne van Iterson", "name": "Arne van Iterson",
"url": "https://gitea.arnweb.nl/arne/" "url": "https://gitea.arnweb.nl/arne/"
}, },
"license": "ISC" "license": "ISC",
"devDependencies": {
"eslint": "^6.8.0"
}
} }