forked from arne/asdf-games
Added everything from chapter 4 and set up ESlint
This commit is contained in:
parent
3490dd07ae
commit
72633d8c0f
2
.eslintignore
Normal file
2
.eslintignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
projects
|
||||||
|
examples
|
33
.eslintrc.js
Normal file
33
.eslintrc.js
Normal 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
63
lib/AnimManager.js
Normal 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
54
lib/Camera.js
Normal 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;
|
@ -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;
|
||||||
|
@ -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!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
@ -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"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 }) {
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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 || [];
|
||||||
|
@ -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
1096
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -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"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user