text: (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
  class Container {
    constructor() {
      this.pos = { x: 0, y: 0 };
      this.children = [];
    }
  
    add(child) {
      this.children.push(child);
      return child;
    }
  
    remove(child) {
      this.children = this.children.filter(c => c !== child);
      return child;
    }
  
    map(f) {
      return this.children.map(f);
    }
  
    update(dt, t) {
      this.children = this.children.filter(child => {
        if (child.update) {
          child.update(dt, t, this);
        }
        return child.dead ? false : true;
      });
    }
  }
  module.exports = Container;
  
  },{}],2:[function(require,module,exports){
  var Container = require("./Container"),
      CanvasRenderer = require('./renderer/CanvasRenderer')
  ;
  
  const STEP = 1 / 60;
  const FRAME_MAX = 5 * STEP;
  
  class Game {
      constructor(w, h, pixelated, parent = "#board") {
          this.w = w;
          this.h = h;
          this.renderer = new CanvasRenderer(w, h);
          document.querySelector(parent).appendChild(this.renderer.view);
  
          if (pixelated) {
              this.renderer.setPixelated();
          }
  
          this.scene = new Container();
      }
  
      run(gameUpdate = () => { }) {
          let dt = 0;
          let last = 0;
          const loop = ms => {
              requestAnimationFrame(loop);
  
              const t = ms / 1000;
              dt = Math.min(t - last, FRAME_MAX);
              last = t;
  
              this.scene.update(dt, t);
              gameUpdate(dt, t);
              this.renderer.render(this.scene);
          };
          requestAnimationFrame(loop);
      }
  }
  
  module.exports = Game;
  },{"./Container":1,"./renderer/CanvasRenderer":14}],3:[function(require,module,exports){
  class Sprite {
    constructor(texture) {
      this.texture = texture;
      this.pos = { x: 0, y: 0 };
      this.anchor = { x: 0, y: 0 };
      this.scale = { x: 1, y: 1 };
      this.rotation = 0;
    }
  }
  module.exports = Sprite;
  
  },{}],4:[function(require,module,exports){
  class SpriteSheetXML {
      constructor(url) {
          this.array = [];
          this.fetchXMLtoArray(url);
      }
  
      fetchXMLtoArray(url) {
          var xhr = new XMLHttpRequest();
          xhr.open('GET', url, false);
          xhr.send(null);
  
          if (xhr.status === 200) {
              var children = xhr.responseXML.children[0].children;
              for (let index = 0; index < children.length; index++) {
                  const element = children[index];
                  this.array.push({
                      name: element.attributes.name.nodeValue,
                      x: element.attributes.x.nodeValue,
                      y: element.attributes.y.nodeValue,
                      width: element.attributes.width.nodeValue,
                      height: element.attributes.height.nodeValue
                  });
              }
          } else {
              console.error('XML file cannot be loaded!')
          }
      }
  
      findIndex(attribute, value) {
          for (let index = 0; index < this.array.length; index++) {
              const element = this.array[index];
              if (element[attribute] == value) {
                  return index;
              }
          }
      }
  }
  
  module.exports = SpriteSheetXML;
  },{}],5:[function(require,module,exports){
  class Text {
    constructor(text = "", style = {}) {
      this.pos = { x: 0, y: 0 };
      this.text = text;
      this.style = style;
    }
  }
  module.exports = Text;
  
  },{}],6:[function(require,module,exports){
  class Texture {
    constructor(url) {
      this.img = new Image();
      this.img.src = url;
    }
  }
  module.exports = Texture;
  
  },{}],7:[function(require,module,exports){
  var Container = require("./Container"),
      TileSprite = require("./TileSprite")
  ;
  
  class TileMap extends Container {
    constructor(tiles, mapW, mapH, tileW, tileH, texture) {
      super();
      this.mapW = mapW;
      this.mapH = mapH;
      this.tileW = tileW;
      this.tileH = tileH;
      this.w = mapW * tileW;
      this.h = mapH * tileH;
  
      this.children = tiles.map((frame, i) => {
        const s = new TileSprite(texture, tileW, tileH);
        s.frame = frame;
        s.pos.x = i % mapW * tileW;
        s.pos.y = Math.floor(i / mapW) * tileH;
        return s;
      });
    }
  }
  
  module.exports = TileMap;
  },{"./Container":1,"./TileSprite":9}],8:[function(require,module,exports){
  var Container = require("./Container"),
      TileSpriteXML = require("./TileSpriteXML")
  ;
  
  class TileMapXML extends Container {
      constructor(tiles, mapW, mapH, texture, xml) {
          super(texture);
          this.mapW = mapW;
          this.mapH = mapH;
          this.tileW = xml.array[tiles[0]].width;
          this.tileH = xml.array[tiles[0]].height;
          this.w = mapW * this.tileW;
          this.h = mapH * this.tileH;
          
          this.children = tiles.map((frame, i) => {
              const s = new TileSpriteXML(texture, xml, frame);
              s.frame = frame;
              s.pos.x = i % mapW * this.tileW;
              s.pos.y = Math.floor(i / mapW) * this.tileH;
              return s;
          });
      }
  }
  
  module.exports = TileMapXML;
  },{"./Container":1,"./TileSpriteXML":10}],9:[function(require,module,exports){
  var Sprite = require("./Sprite");
  
  class TileSprite extends Sprite {
      constructor(texture, w, h) {
          super(texture);
          this.tileW = w;
          this.tileH = h;
          this.frame = { x: 0, y: 0 };
      }
  }
  
  module.exports = TileSprite;
  },{"./Sprite":3}],10:[function(require,module,exports){
  var Sprite = require("./Sprite");
  
  class TileSpriteXML extends Sprite {
      constructor(texture, xml, index) {
          super(texture);
          var src = xml.array[index];
          this.imgPos = { x: src['x'], y: src['y'] };
          this.width = src['width'];
          this.height = src['height'];
      }
  }
  
  module.exports = TileSpriteXML;
  },{"./Sprite":3}],11:[function(require,module,exports){
  class KeyControls {
    
    constructor() {
      this.keys = {};
      // Bind event handlers
      document.addEventListener("keydown", e => {
        if ([37, 38, 39, 40].indexOf(e.which) >= 0) {
          e.preventDefault();
        }
        this.keys[e.which] = true;
      }, false);
      document.addEventListener('keyup', e => {
        this.keys[e.which] = false;
      }, false);
    }
  
    get action() {
      // Spacebar
      return this.keys[32];
    }
  
    get x() {
      // Arrow Left or A (WASD)
      if (this.keys[37] || this.keys[65]) {
        return -1;
      }
      // Arrow Right or D (WASD)
      if (this.keys[39] || this.keys[68]) {
        return 1;
      }
      return 0;
    }
  
    get y() {
      // Arrow Up or W (WASD)
      if (this.keys[38] || this.keys[87]) {
        return -1;
      }
      // Arrow Down or S (WASD)
      if (this.keys[40] || this.keys[83]) {
        return 1;
      }
      return 0;
    }
  
    
    key(key, value) {
      if (value !== undefined) {
        this.keys[key] = value;
      }
      return this.keys[key];
    }
  
    reset() {
      for (let key in this.keys) {
        this.keys[key] = false;
      }
    }
  
  }
  
  module.exports = KeyControls;
  
  },{}],12:[function(require,module,exports){
  class MouseControls {
    constructor(container) {
      this.el = container || document.body;
      // State
      this.pos = { x: 0, y: 0 };
      this.isDown = false;
      this.pressed = false;
      this.released = false;
      // Handlers
      document.addEventListener('mousemove', this.move.bind(this), false);
      document.addEventListener('mousedown', this.down.bind(this), false);
      document.addEventListener('mouseup', this.up.bind(this), false);
    }
  
    mousePosFromEvent({ clientX, clientY }) {
      const { el, pos } = this;
      const rect = el.getBoundingClientRect();
      const xr = el.width / el.clientWidth;
      const yr = el.height / el.clientHeight;
      pos.x = (clientX - rect.left) * xr;
      pos.y = (clientY - rect.top) * yr;
    }
  
    move(e) {
      this.mousePosFromEvent(e);
    }
  
    down(e) {
      this.isDown = true;
      this.pressed = true;
      this.mousePosFromEvent(e);
    }
  
    up() {
      this.isDown = false;
      this.released = true;
    }
  
    update() {
      this.released = false;
      this.pressed = false;
    }
  }
  
  module.exports = MouseControls;
  
  },{}],13:[function(require,module,exports){
  var Container = require("./Container.js"),
      CanvasRenderer = require("./renderer/CanvasRenderer.js"),
      Game = require("./Game.js"),
      math = require("./utilities/math.js"),
      KeyControls = require("./controls/KeyControls.js"),
      MouseControls = require("./controls/MouseControls.js"),
      Sprite = require("./Sprite.js"),
      TileMap = require("./TileMap.js"),
      TileMapXML = require("./TileMapXML.js"),
      TileSprite = require("./TileSprite.js"),
      TileSpriteXML = require("./TileSpriteXML.js"),
      Text = require("./Text.js"),
      Texture = require("./Texture.js"),
      SpriteSheetXML = require("./SpriteSheetXML.js")
  ;
  
  module.exports = {
    CanvasRenderer,
    Container,
    Game,
    math,
    KeyControls,
    MouseControls,
    Sprite,
    TileMap,
    TileMapXML,
    TileSprite,
    SpriteSheetXML,
    TileSpriteXML,
    Text,
    Texture
  };
  
  },{"./Container.js":1,"./Game.js":2,"./Sprite.js":3,"./SpriteSheetXML.js":4,"./Text.js":5,"./Texture.js":6,"./TileMap.js":7,"./TileMapXML.js":8,"./TileSprite.js":9,"./TileSpriteXML.js":10,"./controls/KeyControls.js":11,"./controls/MouseControls.js":12,"./renderer/CanvasRenderer.js":14,"./utilities/math.js":15}],14:[function(require,module,exports){
  class CanvasRenderer {
    
    constructor(w, h) {
      const canvas = document.createElement("canvas");
      this.w = canvas.width = w;
      this.h = canvas.height = h;
      this.view = canvas;
      this.ctx = canvas.getContext("2d");
      this.ctx.textBaseLine = "top";
    }
  
    setPixelated() {
      this.ctx['imageSmoothingEnabled'] = false;       /* standard */
      this.ctx['mozImageSmoothingEnabled'] = false;    /* Firefox */
      this.ctx['oImageSmoothingEnabled'] = false;      /* Opera */
      this.ctx['webkitImageSmoothingEnabled'] = false; /* Safari */
      this.ctx['msImageSmoothingEnabled'] = false;     /* IE */
    }
  
    render(container, clear = true) {
      const { ctx } = this;
      function renderRec(container) {
        // Render container children
        container.children.forEach(child => {
          if (child.visible == false) {
            return;
          }
  
          ctx.save();
  
          if (child.pos) {
            ctx.translate(Math.round(child.pos.x), Math.round(child.pos.y));
          }
  
          if (child.anchor) {
            ctx.translate(child.anchor.x, child.anchor.y);
          }
  
          if (child.scale) {
            ctx.scale(child.scale.x, child.scale.y);
          }
  
          if (child.rotation) {
            const px = child.pivot ? child.pivot.x : 0;
            const py = child.pivot ? child.pivot.y : 0;
            ctx.translate(px, py);
            ctx.rotate(child.rotation);
            ctx.translate(-px, -py);
          }
  
          if (child.text) {
            const { font, fill, align } = child.style;
            if (font) ctx.font = font;
            if (fill) ctx.fillStyle = fill;
            if (align) ctx.textAlign = align;
            ctx.fillText(child.text, 0, 0);
          }
  
          else if (child.texture) {
            const img = child.texture.img;
            if (child.tileW && child.tileH) {
              ctx.drawImage(
                img,
                child.frame.x * child.tileW,
                child.frame.y * child.tileH,
                child.tileW, child.tileH,
                0, 0,
                child.tileW, child.tileH
              );
            } else if (child.imgPos && child.width && child.height) {
              ctx.drawImage(
                img,
                child.imgPos.x,
                child.imgPos.y,
                child.width, child.height,
                0, 0,
                child.width, child.height
              );
            } else {
              ctx.drawImage(img, 0, 0);
            }
          }
  
          // Handle children with children
          if (child.children) {
            renderRec(child);
          }
          ctx.restore();
        })
      }
      if (clear) {
        ctx.clearRect(0, 0, this.w, this.h);
      }
      renderRec(container);
    }
  }
  module.exports = CanvasRenderer;
  
  },{}],15:[function(require,module,exports){
  function rand(min, max) {
    return Math.floor(randf(min, max));
  }
  
  function randf(min, max) {
    if (max == null) {
      max = min || 1;
      min = 0;
    }
    return Math.random() * (max - min) + min;
  }
  
  function randOneFrom(items) {
    return items[rand(items.length)];
  }
  
  function randOneIn(max = 2) {
    return rand(0, max) === 0;
  }
  
  module.exports = {
    rand,
    randf,
    randOneFrom,
    randOneIn
  };
  },{}],16:[function(require,module,exports){
  var asdf = require('../../../asdf/index');
  const { Container, CanvasRenderer, KeyControls, MouseControls, Text, Texture, Sprite } = asdf;
  
  // Board Setup
  const w = 640;
  const h = 300;
  const renderer = new CanvasRenderer(w, h);
  document.querySelector("#board").appendChild(renderer.view);
  
  // Setup game variables
  let dt = 0;
  let last = 0;
  let lastShot = 0;
  let lastSpawn = 0;
  let spawnSpeed = 1.0;
  let scoreAmount = 0;
  let gameOver = false;
  
  // Setup game objects
  const scene = new Container();
  
  // Load game textures
  const textures = {
    background: new Texture("./res/images/bg.png"),
    spaceship: new Texture("./res/images/spaceship.png"),
    bullet: new Texture("./res/images/bullet.png"),
    baddie: new Texture("./res/images/baddie.png")
  }
  
  // Spaceship
  const controls = new KeyControls();
  const ship = new Sprite(textures.spaceship);
  ship.pos.x = 120;
  ship.pos.y = h / 2 - 16;
  ship.update = function (dt, t) {
    const { pos } = this;
    pos.x += controls.x * dt * 300;
    pos.y += controls.y * dt * 300;
  
    if (pos.x < 0) pos.x = 0;
    if (pos.x > w - 32) pos.x = w - 32;
    if (pos.y < 0) pos.y = 0;
    if (pos.y > h - 32) pos.y = h - 32;
  }
  
  // Bullets
  const bullets = new Container();
  function fireBullet(x, y) {
    const bullet = new Sprite(textures.bullet);
    bullet.pos.x = x;
    bullet.pos.y = y;
    bullet.update = function (dt, t) {
      bullet.pos.x += 400 * dt;
    }
    bullets.add(bullet);
  }
  
  // Bad guys
  const baddies = new Container();
  function spawnBaddie(x, y, speed) {
    const baddie = new Sprite(textures.baddie);
    baddie.pos.x = x;
    baddie.pos.y = y;
    baddie.update = function (dt) {
      this.pos.x += speed * dt;
      this.pos.y += Math.sin(this.pos.x / 15) * 1;
    };
    baddies.add(baddie);
  }
  
  // Show score
  const score = new Text(`${scoreAmount}`, {
    font: "15pt Visitor",
    fill: "#000000",
    align: "left"
  });
  score.pos.x = 50;
  score.pos.y = 15;
  score.update = function () {
    if (gameOver) {
      score.pos.x = w / 2;
      score.pos.y = (h / 3) * 2;
      score.text = `Score:  ` + `${scoreAmount}`;
      score.style.align = "center";
      score.style.font = "24pt Visitor"
    } else {
      score.text = `${scoreAmount}`;
    }
  }
  
  // Gameover
  function doGameOver() {
    const gameOverMessage = new Text(`Game Over`, {
      font: "45pt Visitor",
      fill: "#000000",
      align: "center"
    });
    gameOverMessage.pos.x = w / 2;
    gameOverMessage.pos.y = h / 3;
  
    scene.add(gameOverMessage);
    scene.remove(ship);
    scene.remove(baddies);
    scene.remove(bullets);
    gameOver = true;
  }
  
  // Add game objects
  scene.add(new Sprite(textures.background));
  scene.add(ship);
  scene.add(bullets);
  scene.add(baddies);
  scene.add(score);
  
  
  // Looping Code
  function loopme(ms) {
    requestAnimationFrame(loopme);
    const t = ms / 1000;
    dt = t - last;
    last = t;
  
    // Game logic code
    if (controls.action && t - lastShot > 0.15) {
      lastShot = t;
      fireBullet(ship.pos.x + 24, ship.pos.y + 10);
    }
  
    // Spawn bad guys
    if (t - lastSpawn > spawnSpeed) {
      lastSpawn = t;
      const speed = -50 - (Math.random() * Math.random() * 100);
      const position = Math.random() * (h - 24);
      spawnBaddie(w, position, speed);
  
      spawnSpeed = spawnSpeed < 0.05 ? 0.6 : spawnSpeed * 0.97 + 0.001;
    }
  
    // Destroy bullets when they go out of the screen
    baddies.children.forEach(baddie => {
      bullets.children.forEach(bullet => {
        let dx_b = baddie.pos.x + 16 - (bullet.pos.x + 8);
        let dy_b = baddie.pos.y + 16 - (bullet.pos.y + 8);
        if (Math.sqrt(dx_b * dx_b + dy_b * dy_b) < 24) {
          bullet.dead = true;
          baddie.dead = true;
          if (!gameOver) {
            scoreAmount += Math.floor(t);
          }
        }
  
        if (bullet.pos.x > w + 20) {
          bullet.dead = true;
        }
      });
      let dx_s = baddie.pos.x + 16 - (ship.pos.x + 16)
      let dy_s = baddie.pos.y + 16 - (ship.pos.y + 16)
      if (Math.sqrt(dx_s * dx_s + dy_s * dy_s) < 32) {
        if (!gameOver) {
          doGameOver();
        }
        baddie.dead = true;
      }
  
      if (baddie.pos.x < -32) {
        if (!gameOver) {
          doGameOver();
        }
        baddie.dead = true;
      }
    });
  
  
  
    scene.update(dt, t);
    renderer.render(scene);
  }
  requestAnimationFrame(loopme);
  
  },{"../../../asdf/index":13}]},{},[16]);
  