Fixed spacing on some files and added comments

This commit is contained in:
Arne van Iterson 2020-01-17 21:11:15 +01:00
parent 0d1ee32fd8
commit 3264ae157e
16 changed files with 379 additions and 165 deletions

View File

@ -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;

View File

@ -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 => {

View File

@ -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 };

View File

@ -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];

View File

@ -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;
} }

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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'] };

View File

@ -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;

View File

@ -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;

View File

@ -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>

View File

@ -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);
} }

View File

@ -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
};

View File

@ -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