forked from arne/asdf-games
Fixed spacing on some files and added comments
This commit is contained in:
parent
0d1ee32fd8
commit
3264ae157e
@ -1,31 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Container class
|
||||||
|
*/
|
||||||
class Container {
|
class Container {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.pos = { x: 0, y: 0};
|
this.pos = { x: 0, y: 0 };
|
||||||
this.children = [];
|
this.children = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Contrainer methods
|
/**
|
||||||
add (child) {
|
* Adds child to container
|
||||||
this.children.push(child);
|
* @param {*} child Child to add
|
||||||
return child;
|
* @returns {any} Added child
|
||||||
}
|
*/
|
||||||
|
add(child) {
|
||||||
|
this.children.push(child);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
remove (child) {
|
/**
|
||||||
this.children = this.children.filter(c => c !== child);
|
* Removes child from container
|
||||||
return child;
|
* @param {*} child Child to remove
|
||||||
}
|
* @returns {any} Removed child
|
||||||
|
*/
|
||||||
|
remove(child) {
|
||||||
|
this.children = this.children.filter(c => c !== child);
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
map (f) {
|
/**
|
||||||
return this.children.map(f);
|
* Preforms a function on all children
|
||||||
}
|
* @param {function} f Function to preform on children
|
||||||
|
* @returns {any} Function altered array
|
||||||
|
*/
|
||||||
|
map(f) {
|
||||||
|
return this.children.map(f);
|
||||||
|
}
|
||||||
|
|
||||||
update(dt, t) {
|
/**
|
||||||
this.children = this.children.filter(child => {
|
* Updates all children when called
|
||||||
if (child.update) {
|
* @param {number} dt Delta time
|
||||||
child.update(dt, t, this);
|
* @param {number} t Total time
|
||||||
}
|
* @returns {boolean} Returns if the child is dead or not
|
||||||
return child.dead ? false : true;
|
*/
|
||||||
});
|
update(dt, t) {
|
||||||
}
|
this.children = this.children.filter(child => {
|
||||||
|
if (child.update) {
|
||||||
|
child.update(dt, t, this);
|
||||||
|
}
|
||||||
|
return child.dead ? false : true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
export default Container;
|
export default Container;
|
||||||
|
18
asdf/Game.js
18
asdf/Game.js
@ -4,8 +4,18 @@ import CanvasRenderer from "./renderer/CanvasRenderer.js";
|
|||||||
const STEP = 1 / 60;
|
const STEP = 1 / 60;
|
||||||
const FRAME_MAX = 5 * STEP;
|
const FRAME_MAX = 5 * STEP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Game class
|
||||||
|
*/
|
||||||
class Game {
|
class Game {
|
||||||
constructor (w, h, pixelated, parent = "#board") {
|
/**
|
||||||
|
* Set the games parameters
|
||||||
|
* @param {number} w Width of canvas
|
||||||
|
* @param {number} h Height of canvas
|
||||||
|
* @param {boolean} pixelated Turns canvas smoothening on or off
|
||||||
|
* @param {String} [parent="#board"] HTML id of element to push the canvas element too
|
||||||
|
*/
|
||||||
|
constructor(w, h, pixelated, parent = "#board") {
|
||||||
this.w = w;
|
this.w = w;
|
||||||
this.h = h;
|
this.h = h;
|
||||||
this.renderer = new CanvasRenderer(w, h);
|
this.renderer = new CanvasRenderer(w, h);
|
||||||
@ -18,7 +28,11 @@ class Game {
|
|||||||
this.scene = new Container();
|
this.scene = new Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
run(gameUpdate = () => {}) {
|
/**
|
||||||
|
* Start game loop
|
||||||
|
* @param {Function} gameUpdate Function to run next to scene updates such as debug logging, etc.
|
||||||
|
*/
|
||||||
|
run(gameUpdate = () => { }) {
|
||||||
let dt = 0;
|
let dt = 0;
|
||||||
let last = 0;
|
let last = 0;
|
||||||
const loop = ms => {
|
const loop = ms => {
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Sprite class
|
||||||
|
*/
|
||||||
class Sprite {
|
class Sprite {
|
||||||
|
/**
|
||||||
|
* Draw sprite on canvas
|
||||||
|
* @param {*} texture Sprite image
|
||||||
|
*/
|
||||||
constructor(texture) {
|
constructor(texture) {
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
this.pos = { x: 0, y: 0 };
|
this.pos = { x: 0, y: 0 };
|
||||||
|
@ -1,15 +1,29 @@
|
|||||||
// XML format must be:
|
|
||||||
// <TextureAlias imagePath="">
|
|
||||||
// <SubTexture x="" y="" width="" height=""></SubTexture>
|
|
||||||
// ...
|
|
||||||
// </TextureAlias>
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SpriteSheetXML - Reads XML files to get texture data
|
||||||
|
*
|
||||||
|
* **XML format must be:**
|
||||||
|
*
|
||||||
|
* <TextureAlias imagePath="">
|
||||||
|
*
|
||||||
|
* <SubTexture x="" y="" width="" height=""></SubTexture>
|
||||||
|
* ...
|
||||||
|
* </TextureAlias>
|
||||||
|
*/
|
||||||
class SpriteSheetXML {
|
class SpriteSheetXML {
|
||||||
|
/**
|
||||||
|
* Set url of XML file
|
||||||
|
* @param {String} url Url to XML file
|
||||||
|
*/
|
||||||
constructor(url) {
|
constructor(url) {
|
||||||
this.array = [];
|
this.array = [];
|
||||||
this.fetchXMLtoArray(url);
|
this.fetchXMLtoArray(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch XML file and put contents in a JS array
|
||||||
|
* @param {String} url Url to XML file
|
||||||
|
*/
|
||||||
fetchXMLtoArray(url) {
|
fetchXMLtoArray(url) {
|
||||||
var xhr = new XMLHttpRequest();
|
var xhr = new XMLHttpRequest();
|
||||||
xhr.open('GET', url, false);
|
xhr.open('GET', url, false);
|
||||||
@ -32,6 +46,12 @@ class SpriteSheetXML {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find index of XML element with attribute == value
|
||||||
|
* @param {String} attribute XML element attribute
|
||||||
|
* @param {String} value Value of XML element attribute
|
||||||
|
* @returns {number} Index of XML element
|
||||||
|
*/
|
||||||
findIndex(attribute, value) {
|
findIndex(attribute, value) {
|
||||||
for (let index = 0; index < this.array.length; index++) {
|
for (let index = 0; index < this.array.length; index++) {
|
||||||
const element = this.array[index];
|
const element = this.array[index];
|
||||||
|
10
asdf/Text.js
10
asdf/Text.js
@ -1,6 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Text class
|
||||||
|
*/
|
||||||
class Text {
|
class Text {
|
||||||
|
/**
|
||||||
|
* Prints styled text on canvas
|
||||||
|
* @param {String} text Text to print
|
||||||
|
* @param {String} style Styles to apply to text
|
||||||
|
*/
|
||||||
constructor(text = "", style = {}) {
|
constructor(text = "", style = {}) {
|
||||||
this.pos = { x: 0, y: 0};
|
this.pos = { x: 0, y: 0 };
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.style = style;
|
this.style = style;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
|
/**
|
||||||
|
* Texture class
|
||||||
|
*/
|
||||||
class Texture {
|
class Texture {
|
||||||
|
/**
|
||||||
|
* Sets url of source image and creates an instance of Image()
|
||||||
|
* @param {*} url
|
||||||
|
*/
|
||||||
constructor(url) {
|
constructor(url) {
|
||||||
this.img = new Image();
|
this.img = new Image();
|
||||||
this.img.src = url;
|
this.img.src = url;
|
||||||
|
@ -1,7 +1,19 @@
|
|||||||
import Container from "./Container.js";
|
import Container from "./Container.js";
|
||||||
import TileSprite from "./TileSprite.js";
|
import TileSprite from "./TileSprite.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tilemap class
|
||||||
|
*/
|
||||||
class TileMap extends Container {
|
class TileMap extends Container {
|
||||||
|
/**
|
||||||
|
* Draws array of tiles from unindexed spritesheet
|
||||||
|
* @param {[ { x: number, y: number} ]} tiles Array of x and y values of the source tile on an unindexed Spritesheet
|
||||||
|
* @param {number} mapW Amount of tiles over the width of the map
|
||||||
|
* @param {number} mapH Amount of tiles over the height of the map
|
||||||
|
* @param {number} tileW Width of source tile(s) in pixels
|
||||||
|
* @param {number} tileH Height of source tile(s) in pixels
|
||||||
|
* @param {*} texture Texture instance of source image file
|
||||||
|
*/
|
||||||
constructor(tiles, mapW, mapH, tileW, tileH, texture) {
|
constructor(tiles, mapW, mapH, tileW, tileH, texture) {
|
||||||
super();
|
super();
|
||||||
this.mapW = mapW;
|
this.mapW = mapW;
|
||||||
@ -11,7 +23,6 @@ class TileMap extends Container {
|
|||||||
this.w = mapW * tileW;
|
this.w = mapW * tileW;
|
||||||
this.h = mapH * tileH;
|
this.h = mapH * tileH;
|
||||||
|
|
||||||
// Add all tile sprites
|
|
||||||
this.children = tiles.map((frame, i) => {
|
this.children = tiles.map((frame, i) => {
|
||||||
const s = new TileSprite(texture, tileW, tileH);
|
const s = new TileSprite(texture, tileW, tileH);
|
||||||
s.frame = frame;
|
s.frame = frame;
|
||||||
|
@ -1,8 +1,19 @@
|
|||||||
import Container from "./Container.js";
|
import Container from "./Container.js";
|
||||||
import TileSpriteXML from "./TileSpriteXML.js";
|
import TileSpriteXML from "./TileSpriteXML.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TileMapXML class
|
||||||
|
*/
|
||||||
class TileMapXML extends Container {
|
class TileMapXML extends Container {
|
||||||
constructor (tiles, mapW, mapH, texture, xml) {
|
/**
|
||||||
|
* Draws array of tiles from XML indexed spritesheet
|
||||||
|
* @param {number[]} tiles Array of XML indexes
|
||||||
|
* @param {*} mapW Amount of tiles over the width of the map
|
||||||
|
* @param {*} mapH Amount of tiles over the height of the map
|
||||||
|
* @param {*} texture Texture instance of source image file
|
||||||
|
* @param {*} xml SpriteSheetXML instance of source xml file
|
||||||
|
*/
|
||||||
|
constructor(tiles, mapW, mapH, texture, xml) {
|
||||||
super(texture);
|
super(texture);
|
||||||
this.mapW = mapW;
|
this.mapW = mapW;
|
||||||
this.mapH = mapH;
|
this.mapH = mapH;
|
||||||
@ -10,8 +21,7 @@ class TileMapXML extends Container {
|
|||||||
this.tileH = xml.array[tiles[0]].height;
|
this.tileH = xml.array[tiles[0]].height;
|
||||||
this.w = mapW * this.tileW;
|
this.w = mapW * this.tileW;
|
||||||
this.h = mapH * this.tileH;
|
this.h = mapH * this.tileH;
|
||||||
|
|
||||||
// Add all tile sprites
|
|
||||||
this.children = tiles.map((frame, i) => {
|
this.children = tiles.map((frame, i) => {
|
||||||
const s = new TileSpriteXML(texture, xml, frame);
|
const s = new TileSpriteXML(texture, xml, frame);
|
||||||
s.frame = frame;
|
s.frame = frame;
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
import Sprite from "./Sprite.js";
|
import Sprite from "./Sprite.js";
|
||||||
|
/**
|
||||||
|
* TileSprite class
|
||||||
|
*/
|
||||||
class TileSprite extends Sprite {
|
class TileSprite extends Sprite {
|
||||||
constructor (texture, w, h) {
|
/**
|
||||||
|
* Creates sprite instance from unindexed spritesheet
|
||||||
|
* @param {*} texture Instance of Texture with source image
|
||||||
|
* @param {number} w Width of sprite on source image
|
||||||
|
* @param {number} h Height of spirte on source image
|
||||||
|
*/
|
||||||
|
constructor(texture, w, h) {
|
||||||
super(texture);
|
super(texture);
|
||||||
this.tileW = w;
|
this.tileW = w;
|
||||||
this.tileH = h;
|
this.tileH = h;
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
import Sprite from "./Sprite.js";
|
import Sprite from "./Sprite.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TileSpriteXML class
|
||||||
|
*/
|
||||||
class TileSpriteXML extends Sprite {
|
class TileSpriteXML extends Sprite {
|
||||||
constructor (texture, xml, index) {
|
/**
|
||||||
|
* Creates sprite instance from XML indexed spritesheet
|
||||||
|
* @param {*} texture Instance of Texture with source image
|
||||||
|
* @param {*} xml Instance of SpriteSheetXML with xml index
|
||||||
|
* @param {number} index Index of XML element
|
||||||
|
*/
|
||||||
|
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'] };
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* KeyControls class
|
||||||
|
*/
|
||||||
class KeyControls {
|
class KeyControls {
|
||||||
|
/**
|
||||||
|
* Listens for keypresses and prevents default actions
|
||||||
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.keys = {};
|
this.keys = {};
|
||||||
// Bind event handlers
|
// Bind event handlers
|
||||||
document.addEventListener("keydown", e => {
|
document.addEventListener("keydown", e => {
|
||||||
if ([37,38,39,40].indexOf(e.which) >= 0) {
|
if ([37, 38, 39, 40].indexOf(e.which) >= 0) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
this.keys[e.which] = true;
|
this.keys[e.which] = true;
|
||||||
@ -12,13 +18,23 @@ class KeyControls {
|
|||||||
this.keys[e.which] = false;
|
this.keys[e.which] = false;
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
// Handle key actions
|
|
||||||
|
/**
|
||||||
|
* Returns value of action key (spacebar)
|
||||||
|
* @returns {boolean} Key value
|
||||||
|
*/
|
||||||
get action() {
|
get action() {
|
||||||
// Spacebar
|
// Spacebar
|
||||||
return this.keys[32];
|
return this.keys[32];
|
||||||
}
|
}
|
||||||
|
|
||||||
get x () {
|
/**
|
||||||
|
* Returns -1 on Arrow Left or A
|
||||||
|
*
|
||||||
|
* Returns 1 on Arrow Right or D
|
||||||
|
* @returns {number} Key Value
|
||||||
|
*/
|
||||||
|
get x() {
|
||||||
// Arrow Left or A (WASD)
|
// Arrow Left or A (WASD)
|
||||||
if (this.keys[37] || this.keys[65]) {
|
if (this.keys[37] || this.keys[65]) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -30,7 +46,13 @@ class KeyControls {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get y () {
|
/**
|
||||||
|
* Returns -1 on Arrow Up or W
|
||||||
|
*
|
||||||
|
* Returns 1 on Arrow Down or S
|
||||||
|
* @returns {number} Key value
|
||||||
|
*/
|
||||||
|
get y() {
|
||||||
// Arrow Up or W (WASD)
|
// Arrow Up or W (WASD)
|
||||||
if (this.keys[38] || this.keys[87]) {
|
if (this.keys[38] || this.keys[87]) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -42,6 +64,12 @@ class KeyControls {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read or write value of any key
|
||||||
|
* @param {number} key Keycode for targetted key
|
||||||
|
* @param {*} [value] Value to set to key
|
||||||
|
* @return {*} Value of key
|
||||||
|
*/
|
||||||
key(key, value) {
|
key(key, value) {
|
||||||
if (value !== undefined) {
|
if (value !== undefined) {
|
||||||
this.keys[key] = value;
|
this.keys[key] = value;
|
||||||
@ -49,6 +77,9 @@ class KeyControls {
|
|||||||
return this.keys[key];
|
return this.keys[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets default value to all keys
|
||||||
|
*/
|
||||||
reset() {
|
reset() {
|
||||||
for (let key in this.keys) {
|
for (let key in this.keys) {
|
||||||
this.keys[key] = false;
|
this.keys[key] = false;
|
||||||
|
@ -1,17 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* MouseControls class
|
||||||
|
*/
|
||||||
class MouseControls {
|
class MouseControls {
|
||||||
|
/**
|
||||||
|
* Sets container element where handlers will listen
|
||||||
|
* @param {*} [container] Container element, defaults to document.body
|
||||||
|
*/
|
||||||
constructor(container) {
|
constructor(container) {
|
||||||
this.el = container || document.body;
|
this.el = container || document.body;
|
||||||
// State
|
// State
|
||||||
this.pos = {x: 0, y: 0};
|
this.pos = { x: 0, y: 0 };
|
||||||
this.isDown = false;
|
this.isDown = false;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recalculates mouse position based on the position of the container
|
||||||
|
* @param {{ clientX: number, clientY: number}} param0 Native mouse event x and y values
|
||||||
|
*/
|
||||||
mousePosFromEvent({ clientX, clientY }) {
|
mousePosFromEvent({ clientX, clientY }) {
|
||||||
const { el, pos } = this;
|
const { el, pos } = this;
|
||||||
const rect = el.getBoundingClientRect();
|
const rect = el.getBoundingClientRect();
|
||||||
@ -21,26 +32,40 @@ class MouseControls {
|
|||||||
pos.y = (clientY - rect.top) * yr;
|
pos.y = (clientY - rect.top) * yr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls mousePosFromEvent() on mouse move
|
||||||
|
* @param {*} e Event
|
||||||
|
*/
|
||||||
move(e) {
|
move(e) {
|
||||||
this.mousePosFromEvent(e);
|
this.mousePosFromEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles mouseDown event and calls mousePosFromEvent() to determine the exact pixel
|
||||||
|
* @param {*} e Event
|
||||||
|
*/
|
||||||
down(e) {
|
down(e) {
|
||||||
this.isDown = true;
|
this.isDown = true;
|
||||||
this.pressed = true;
|
this.pressed = true;
|
||||||
this.mousePosFromEvent(e);
|
this.mousePosFromEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles mouseUp event and calls mousePosFromEvent() to determine the exact pixel
|
||||||
|
* @param {*} e Event
|
||||||
|
*/
|
||||||
up() {
|
up() {
|
||||||
this.isDown = false;
|
this.isDown = false;
|
||||||
this.released = true;
|
this.released = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets pressed and released values to make sure they are only true on a press or release
|
||||||
|
*/
|
||||||
update() {
|
update() {
|
||||||
this.released = false;
|
this.released = false;
|
||||||
this.pressed = false;
|
this.pressed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default MouseControls;
|
export default MouseControls;
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<title>ASDF Framework</title>
|
<title>ASDF Framework</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<h2>ASDF JS Framework</h2>
|
<h2>ASDF JS Framework</h2>
|
||||||
<p>Nothing to browse here, just some shared files to make these games work.</p>
|
<p>Nothing to browse here, just some shared files to make these games work.</p>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -1,4 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* CanvasRenderer class
|
||||||
|
*/
|
||||||
class CanvasRenderer {
|
class CanvasRenderer {
|
||||||
|
/**
|
||||||
|
* Renderer for CanvasJS, defines width and height for the canvas element
|
||||||
|
* @param {*} w Width for canvas element
|
||||||
|
* @param {*} h Height for canvas element
|
||||||
|
*/
|
||||||
constructor(w, h) {
|
constructor(w, h) {
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
this.w = canvas.width = w;
|
this.w = canvas.width = w;
|
||||||
@ -8,7 +16,10 @@ class CanvasRenderer {
|
|||||||
this.ctx.textBaseLine = "top";
|
this.ctx.textBaseLine = "top";
|
||||||
}
|
}
|
||||||
|
|
||||||
setPixelated(){
|
/**
|
||||||
|
* Turns off image smoothening on the canvas element
|
||||||
|
*/
|
||||||
|
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 */
|
||||||
@ -16,6 +27,12 @@ class CanvasRenderer {
|
|||||||
this.ctx['msImageSmoothingEnabled'] = false; /* IE */
|
this.ctx['msImageSmoothingEnabled'] = false; /* IE */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render all children on the canvas element
|
||||||
|
* @param {*} container Containing element of the canvas element
|
||||||
|
* @param {boolean} [clear=true] Defines if the canvas element needs to be cleared for the next render
|
||||||
|
*/
|
||||||
render(container, clear = true) {
|
render(container, clear = true) {
|
||||||
const { ctx } = this;
|
const { ctx } = this;
|
||||||
function renderRec(container) {
|
function renderRec(container) {
|
||||||
@ -27,7 +44,6 @@ class CanvasRenderer {
|
|||||||
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
|
|
||||||
// Draw the leaf node
|
|
||||||
if (child.pos) {
|
if (child.pos) {
|
||||||
ctx.translate(Math.round(child.pos.x), Math.round(child.pos.y));
|
ctx.translate(Math.round(child.pos.x), Math.round(child.pos.y));
|
||||||
}
|
}
|
||||||
@ -53,7 +69,7 @@ class CanvasRenderer {
|
|||||||
if (font) ctx.font = font;
|
if (font) ctx.font = font;
|
||||||
if (fill) ctx.fillStyle = fill;
|
if (fill) ctx.fillStyle = fill;
|
||||||
if (align) ctx.textAlign = align;
|
if (align) ctx.textAlign = align;
|
||||||
ctx.fillText(child.text, 0,0);
|
ctx.fillText(child.text, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (child.texture) {
|
else if (child.texture) {
|
||||||
@ -64,7 +80,7 @@ class CanvasRenderer {
|
|||||||
child.frame.x * child.tileW,
|
child.frame.x * child.tileW,
|
||||||
child.frame.y * child.tileH,
|
child.frame.y * child.tileH,
|
||||||
child.tileW, child.tileH,
|
child.tileW, child.tileH,
|
||||||
0,0,
|
0, 0,
|
||||||
child.tileW, child.tileH
|
child.tileW, child.tileH
|
||||||
);
|
);
|
||||||
} else if (child.imgPos && child.width && child.height) {
|
} else if (child.imgPos && child.width && child.height) {
|
||||||
@ -73,7 +89,7 @@ class CanvasRenderer {
|
|||||||
child.imgPos.x,
|
child.imgPos.x,
|
||||||
child.imgPos.y,
|
child.imgPos.y,
|
||||||
child.width, child.height,
|
child.width, child.height,
|
||||||
0,0,
|
0, 0,
|
||||||
child.width, child.height
|
child.width, child.height
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -81,7 +97,7 @@ class CanvasRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the child types
|
// Handle children with children
|
||||||
if (child.children) {
|
if (child.children) {
|
||||||
renderRec(child);
|
renderRec(child);
|
||||||
}
|
}
|
||||||
@ -89,7 +105,7 @@ class CanvasRenderer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (clear) {
|
if (clear) {
|
||||||
ctx.clearRect(0,0,this.w,this.h);
|
ctx.clearRect(0, 0, this.w, this.h);
|
||||||
}
|
}
|
||||||
renderRec(container);
|
renderRec(container);
|
||||||
}
|
}
|
||||||
|
@ -1,26 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Returns random integer between min and max
|
||||||
|
* @param {number} min Minimum value
|
||||||
|
* @param {number} max Maximum value
|
||||||
|
* @returns {number} Random integer
|
||||||
|
*/
|
||||||
function rand(min, max) {
|
function rand(min, max) {
|
||||||
return Math.floor(randf(min, max));
|
return Math.floor(randf(min, max));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns random float between min and max
|
||||||
|
* @param {number} min Minimum value
|
||||||
|
* @param {number} max Maximum value
|
||||||
|
* @returns {number} Random value
|
||||||
|
*/
|
||||||
|
function randf(min, max) {
|
||||||
|
if (max == null) {
|
||||||
|
max = min || 1;
|
||||||
|
min = 0;
|
||||||
}
|
}
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
function randf(min, max) {
|
}
|
||||||
if (max == null) {
|
|
||||||
max = min || 1;
|
/**
|
||||||
min = 0;
|
* Returns random item from items array
|
||||||
}
|
* @param {*[]} items Array of anything
|
||||||
return Math.random() * (max - min) + min;
|
* @returns {any} Item from items array
|
||||||
}
|
*/
|
||||||
|
function randOneFrom(items) {
|
||||||
function randOneFrom(items) {
|
return items[rand(items.length)];
|
||||||
return items[rand(items.length)];
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
function randOneIn(max = 2) {
|
* Returns true one out of max times
|
||||||
return rand(0, max) === 0;
|
* @param {number} [max=2] Maximum value
|
||||||
}
|
* @returns {boolean} Outcome
|
||||||
|
*/
|
||||||
export default {
|
function randOneIn(max = 2) {
|
||||||
rand,
|
return rand(0, max) === 0;
|
||||||
randf,
|
}
|
||||||
randOneFrom,
|
|
||||||
randOneIn
|
export default {
|
||||||
};
|
rand,
|
||||||
|
randf,
|
||||||
|
randOneFrom,
|
||||||
|
randOneIn
|
||||||
|
};
|
@ -2,115 +2,115 @@ import asdf from "../../../asdf/index.js";
|
|||||||
const { Container, CanvasRenderer, KeyControls, MouseControls, Text, Texture, Sprite } = asdf;
|
const { Container, CanvasRenderer, KeyControls, MouseControls, Text, Texture, Sprite } = asdf;
|
||||||
|
|
||||||
// Board Setup
|
// Board Setup
|
||||||
const w = 640;
|
const w = 640;
|
||||||
const h = 300;
|
const h = 300;
|
||||||
const renderer = new CanvasRenderer(w, h);
|
const renderer = new CanvasRenderer(w, h);
|
||||||
document.querySelector("#board").appendChild(renderer.view);
|
document.querySelector("#board").appendChild(renderer.view);
|
||||||
|
|
||||||
// Setup game variables
|
// Setup game variables
|
||||||
let dt = 0;
|
let dt = 0;
|
||||||
let last = 0;
|
let last = 0;
|
||||||
let lastShot = 0;
|
let lastShot = 0;
|
||||||
let lastSpawn = 0;
|
let lastSpawn = 0;
|
||||||
let spawnSpeed = 1.0;
|
let spawnSpeed = 1.0;
|
||||||
let scoreAmount = 0;
|
let scoreAmount = 0;
|
||||||
let gameOver = false;
|
let gameOver = false;
|
||||||
|
|
||||||
// Setup game objects
|
// Setup game objects
|
||||||
const scene = new Container();
|
const scene = new Container();
|
||||||
|
|
||||||
// Load game textures
|
// Load game textures
|
||||||
const textures = {
|
const textures = {
|
||||||
background: new Texture("./res/images/bg.png"),
|
background: new Texture("./res/images/bg.png"),
|
||||||
spaceship: new Texture("./res/images/spaceship.png"),
|
spaceship: new Texture("./res/images/spaceship.png"),
|
||||||
bullet: new Texture("./res/images/bullet.png"),
|
bullet: new Texture("./res/images/bullet.png"),
|
||||||
baddie: new Texture("./res/images/baddie.png")
|
baddie: new Texture("./res/images/baddie.png")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spaceship
|
// Spaceship
|
||||||
const controls = new KeyControls();
|
const controls = new KeyControls();
|
||||||
const ship = new Sprite(textures.spaceship);
|
const ship = new Sprite(textures.spaceship);
|
||||||
ship.pos.x = 120;
|
ship.pos.x = 120;
|
||||||
ship.pos.y = h / 2 - 16;
|
ship.pos.y = h / 2 - 16;
|
||||||
ship.update = function(dt, t) {
|
ship.update = function (dt, t) {
|
||||||
const { pos } = this;
|
const { pos } = this;
|
||||||
pos.x += controls.x * dt * 300;
|
pos.x += controls.x * dt * 300;
|
||||||
pos.y += controls.y * dt * 300;
|
pos.y += controls.y * dt * 300;
|
||||||
|
|
||||||
if (pos.x < 0) pos.x = 0;
|
if (pos.x < 0) pos.x = 0;
|
||||||
if (pos.x > w - 32) pos.x = w - 32;
|
if (pos.x > w - 32) pos.x = w - 32;
|
||||||
if (pos.y < 0) pos.y = 0;
|
if (pos.y < 0) pos.y = 0;
|
||||||
if (pos.y > h - 32) pos.y = h - 32;
|
if (pos.y > h - 32) pos.y = h - 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bullets
|
// Bullets
|
||||||
const bullets = new Container();
|
const bullets = new Container();
|
||||||
function fireBullet(x, y) {
|
function fireBullet(x, y) {
|
||||||
const bullet = new Sprite(textures.bullet);
|
const bullet = new Sprite(textures.bullet);
|
||||||
bullet.pos.x = x;
|
bullet.pos.x = x;
|
||||||
bullet.pos.y = y;
|
bullet.pos.y = y;
|
||||||
bullet.update = function(dt, t) {
|
bullet.update = function (dt, t) {
|
||||||
bullet.pos.x += 400 * dt;
|
bullet.pos.x += 400 * dt;
|
||||||
}
|
}
|
||||||
bullets.add(bullet);
|
bullets.add(bullet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad guys
|
// Bad guys
|
||||||
const baddies = new Container();
|
const baddies = new Container();
|
||||||
function spawnBaddie(x, y, speed) {
|
function spawnBaddie(x, y, speed) {
|
||||||
const baddie = new Sprite(textures.baddie);
|
const baddie = new Sprite(textures.baddie);
|
||||||
baddie.pos.x = x;
|
baddie.pos.x = x;
|
||||||
baddie.pos.y = y;
|
baddie.pos.y = y;
|
||||||
baddie.update = function(dt) {
|
baddie.update = function (dt) {
|
||||||
this.pos.x += speed * dt;
|
this.pos.x += speed * dt;
|
||||||
this.pos.y += Math.sin(this.pos.x / 15) * 1;
|
this.pos.y += Math.sin(this.pos.x / 15) * 1;
|
||||||
};
|
};
|
||||||
baddies.add(baddie);
|
baddies.add(baddie);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show score
|
// Show score
|
||||||
const score = new Text(`${scoreAmount}`, {
|
const score = new Text(`${scoreAmount}`, {
|
||||||
font: "15pt Visitor",
|
font: "15pt Visitor",
|
||||||
fill: "#000000",
|
fill: "#000000",
|
||||||
align: "left"
|
align: "left"
|
||||||
});
|
});
|
||||||
score.pos.x = 50;
|
score.pos.x = 50;
|
||||||
score.pos.y = 15;
|
score.pos.y = 15;
|
||||||
score.update = function() {
|
score.update = function () {
|
||||||
if (gameOver) {
|
if (gameOver) {
|
||||||
score.pos.x = w / 2;
|
score.pos.x = w / 2;
|
||||||
score.pos.y = (h / 3) * 2;
|
score.pos.y = (h / 3) * 2;
|
||||||
score.text = `Score: ` + `${scoreAmount}`;
|
score.text = `Score: ` + `${scoreAmount}`;
|
||||||
score.style.align = "center";
|
score.style.align = "center";
|
||||||
score.style.font = "24pt Visitor"
|
score.style.font = "24pt Visitor"
|
||||||
} else {
|
} else {
|
||||||
score.text = `${scoreAmount}`;
|
score.text = `${scoreAmount}`;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Gameover
|
// Gameover
|
||||||
function doGameOver() {
|
function doGameOver() {
|
||||||
const gameOverMessage = new Text(`Game Over`, {
|
const gameOverMessage = new Text(`Game Over`, {
|
||||||
font: "45pt Visitor",
|
font: "45pt Visitor",
|
||||||
fill: "#000000",
|
fill: "#000000",
|
||||||
align: "center"
|
align: "center"
|
||||||
});
|
});
|
||||||
gameOverMessage.pos.x = w / 2;
|
gameOverMessage.pos.x = w / 2;
|
||||||
gameOverMessage.pos.y = h / 3;
|
gameOverMessage.pos.y = h / 3;
|
||||||
|
|
||||||
scene.add(gameOverMessage);
|
scene.add(gameOverMessage);
|
||||||
scene.remove(ship);
|
scene.remove(ship);
|
||||||
scene.remove(baddies);
|
scene.remove(baddies);
|
||||||
scene.remove(bullets);
|
scene.remove(bullets);
|
||||||
gameOver = true;
|
gameOver = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add game objects
|
// Add game objects
|
||||||
scene.add(new Sprite(textures.background));
|
scene.add(new Sprite(textures.background));
|
||||||
scene.add(ship);
|
scene.add(ship);
|
||||||
scene.add(bullets);
|
scene.add(bullets);
|
||||||
scene.add(baddies);
|
scene.add(baddies);
|
||||||
scene.add(score);
|
scene.add(score);
|
||||||
|
|
||||||
|
|
||||||
// Looping Code
|
// Looping Code
|
||||||
|
Loading…
Reference in New Issue
Block a user