craters.js
Advanced tools
Comparing version 1.0.8 to 1.0.9
// Rect collision tests the edges of each rect to | ||
// test whether the objects are overlapping the other | ||
class Collision { | ||
static detector (collider, collidee) { | ||
static detect (collider, collidee) { | ||
// Store the collider and collidee edges | ||
@@ -6,0 +6,0 @@ var l1 = collider.state.pos.x; |
@@ -1,161 +0,1 @@ | ||
/******/ (function(modules) { // webpackBootstrap | ||
/******/ // The module cache | ||
/******/ var installedModules = {}; | ||
/******/ | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
/******/ | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) { | ||
/******/ return installedModules[moduleId].exports; | ||
/******/ } | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ i: moduleId, | ||
/******/ l: false, | ||
/******/ exports: {} | ||
/******/ }; | ||
/******/ | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
/******/ | ||
/******/ // Flag the module as loaded | ||
/******/ module.l = true; | ||
/******/ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
/******/ | ||
/******/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
/******/ | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
/******/ | ||
/******/ // define getter function for harmony exports | ||
/******/ __webpack_require__.d = function(exports, name, getter) { | ||
/******/ if(!__webpack_require__.o(exports, name)) { | ||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); | ||
/******/ } | ||
/******/ }; | ||
/******/ | ||
/******/ // define __esModule on exports | ||
/******/ __webpack_require__.r = function(exports) { | ||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | ||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | ||
/******/ } | ||
/******/ Object.defineProperty(exports, '__esModule', { value: true }); | ||
/******/ }; | ||
/******/ | ||
/******/ // create a fake namespace object | ||
/******/ // mode & 1: value is a module id, require it | ||
/******/ // mode & 2: merge all properties of value into the ns | ||
/******/ // mode & 4: return value when already ns object | ||
/******/ // mode & 8|1: behave like require | ||
/******/ __webpack_require__.t = function(value, mode) { | ||
/******/ if(mode & 1) value = __webpack_require__(value); | ||
/******/ if(mode & 8) return value; | ||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; | ||
/******/ var ns = Object.create(null); | ||
/******/ __webpack_require__.r(ns); | ||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); | ||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); | ||
/******/ return ns; | ||
/******/ }; | ||
/******/ | ||
/******/ // getDefaultExport function for compatibility with non-harmony modules | ||
/******/ __webpack_require__.n = function(module) { | ||
/******/ var getter = module && module.__esModule ? | ||
/******/ function getDefault() { return module['default']; } : | ||
/******/ function getModuleExports() { return module; }; | ||
/******/ __webpack_require__.d(getter, 'a', getter); | ||
/******/ return getter; | ||
/******/ }; | ||
/******/ | ||
/******/ // Object.prototype.hasOwnProperty.call | ||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | ||
/******/ | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
/******/ | ||
/******/ | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(__webpack_require__.s = "./app/game.js"); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ({ | ||
/***/ "./app/craters/craters.js": | ||
/*!********************************!*\ | ||
!*** ./app/craters/craters.js ***! | ||
\********************************/ | ||
/*! exports provided: Craters, Loader, Game, Canvas, Loop, Entity, Sprite, Collision, Sound */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
"use strict"; | ||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Craters\", function() { return Craters; });\n/* harmony import */ var _system_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./system.js */ \"./app/craters/system.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Canvas\", function() { return _system_js__WEBPACK_IMPORTED_MODULE_0__[\"Canvas\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Loop\", function() { return _system_js__WEBPACK_IMPORTED_MODULE_0__[\"Loop\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Collision\", function() { return _system_js__WEBPACK_IMPORTED_MODULE_0__[\"Collision\"]; });\n\n/* harmony import */ var _entity_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./entity.js */ \"./app/craters/entity.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Game\", function() { return _entity_js__WEBPACK_IMPORTED_MODULE_1__[\"Game\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Entity\", function() { return _entity_js__WEBPACK_IMPORTED_MODULE_1__[\"Entity\"]; });\n\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Sprite\", function() { return _entity_js__WEBPACK_IMPORTED_MODULE_1__[\"Sprite\"]; });\n\n/* harmony import */ var _loader_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./loader.js */ \"./app/craters/loader.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Loader\", function() { return _loader_js__WEBPACK_IMPORTED_MODULE_2__[\"Loader\"]; });\n\n/* harmony import */ var _sound_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sound.js */ \"./app/craters/sound.js\");\n/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, \"Sound\", function() { return _sound_js__WEBPACK_IMPORTED_MODULE_3__[\"Sound\"]; });\n\n// Craters.js micro game framework\n// This module contains the basics fundamental starting point calling game loop, which handles\n// updating the game state and re-rendering the canvas\n// (using the updated state) at the configured FPS.\n\n\n\n\n\n\nconst boundary = function numberboundary (min, max) {\n return Math.min(Math.max(this, min), max)\n}\n// Expose methods\nNumber.prototype.boundary = boundary\n\nclass Craters {\n static version () {\n return '0.0.0.5'\n }\n}\n\n\n\n//# sourceURL=webpack:///./app/craters/craters.js?"); | ||
/***/ }), | ||
/***/ "./app/craters/entity.js": | ||
/*!*******************************!*\ | ||
!*** ./app/craters/entity.js ***! | ||
\*******************************/ | ||
/*! exports provided: Entity, Game, Sprite */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
"use strict"; | ||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Entity\", function() { return Entity; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Game\", function() { return Game; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Sprite\", function() { return Sprite; });\nclass Game {\n constructor (container, width, height, fps, debug) {\n this.entities = []\n this.state = {\n container: container,\n size: {\n\t x: 10,\n\t y: 10\n },\n \n bgcolor: 'rgba(0,0,0,0)',\n color: '#ff0',\n font: '1em Arial'\n }\n }\n\n update () {\n for (var entity = 0; entity < this.entities.length; entity++) {\n // Fire off each active entities `render` method\n this.entities[entity].update()\n }\n }\n \n render () {\n\tfor (var entity = 0; entity < this.entities.length; entity++) {\n // Fire off each active entities `render` method\n this.entities[entity].render() }\n }\n \n clearContext (context, size) {\n\t context.clearRect(0, 0, size.x, size.y)\n }\n}\n\nclass Entity extends Game {\n constructor () {\n super();\n this.state = {\n size: {\n x: 10,\n y: 10\n },\n pos: {\n x: 0,\n y: 0\n },\n vel: {\n x: 0,\n y: 0\n },\n accel: {\n x: 0,\n y: 0\n },\n radius: 10,\n angle: 0\n }\n }\n\n update () {\n super.update ();\n \n this.state.vel.x += this.state.accel.x\n this.state.vel.y += this.state.accel.y\n this.state.pos.x += this.state.vel.x\n this.state.pos.y += this.state.vel.y\n }\n}\n\nclass Sprite extends Entity {\n constructor (scope, args) {\n super()\n\n this.scope = scope\n this.state.pos = args.pos || {\n x: 0,\n y: 0\n }\n this.state.crop = {\n x: 0,\n y: 0\n }\n this.state.size = args.size || {\n x: 0,\n y: 0\n }\n \n this.state.frames = args.frames || []\n this.state.angle = args.angle || 0\n this.state.image = args.image || new Image()\n this.state.delay = args.delay || 5\n this.state.tick = args.tick || 0\n this.state.orientation = args.orientation || 'horizontal'\n }\n\n update () {\n super.update ();\n \n if (this.state.tick <= 0) {\n if (this.orientation === 'vertical') {\n this.state.crop.y = this.state.frames.shift()\n this.state.frames.push(this.state.crop.y)\n } else {\n this.state.crop.x = this.state.frames.shift()\n this.state.frames.push(this.state.crop.x)\n }\n\n this.state.tick = this.state.delay\n }\n\n this.state.tick--\n }\n\n render () {\n super.render()\n\n this.scope.context.save()\n this.scope.context.translate(this.state.crop.x + (this.state.size.x / 2), this.state.crop.y + (this.state.size.y / 2))\n this.scope.context.rotate((this.state.angle) * (Math.PI / 180))\n this.scope.context.translate(-(this.state.crop.x + (this.state.size.x / 2)), -(this.state.crop.y + (this.state.size.y / 2)))\n\n this.scope.context.drawImage(this.state.image,\n (this.state.crop.x * this.state.size.x), (this.state.crop.y * this.state.size.y), this.state.size.x, this.state.size.y,\n this.state.pos.x, this.state.pos.y, this.state.size.x, this.state.size.y)\n\n this.scope.context.restore()\n }\n}\n\n\n\n//# sourceURL=webpack:///./app/craters/entity.js?"); | ||
/***/ }), | ||
/***/ "./app/craters/loader.js": | ||
/*!*******************************!*\ | ||
!*** ./app/craters/loader.js ***! | ||
\*******************************/ | ||
/*! exports provided: Loader */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
"use strict"; | ||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Loader\", function() { return Loader; });\nclass Loader {\n constructor () {\n this.rescache = {}\n };\n\n load (res, cbk) {\n var that = this\n if (res instanceof Array) {\n res.forEach(function (i) {\n that.rescache[i] = false\n that.fetch(i, cbk)\n })\n } else {\n that.rescache[res] = false\n that.fetch(res, cbk)\n }\n }\n\n fetch (url, cbk) {\n var that = this\n if (that.rescache[url]) {\n return that.rescache[url]\n } else {\n var img = new Image()\n img.onload = function () {\n that.rescache[url] = img\n that.ready(cbk)\n }\n\n img.src = url\n }\n }\n\n ready (cbk) {\n var that = this\n if (typeof cbk === 'function') {\n var ready = true\n for (var item in that.rescache) {\n if (Object.prototype.hasOwnProperty.call(that.rescache, item) && !that.rescache[item]) {\n ready = false\n }\n }\n\n if (ready) cbk()\n }\n }\n}\n\n\n\n\n//# sourceURL=webpack:///./app/craters/loader.js?"); | ||
/***/ }), | ||
/***/ "./app/craters/sound.js": | ||
/*!******************************!*\ | ||
!*** ./app/craters/sound.js ***! | ||
\******************************/ | ||
/*! exports provided: Sound */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
"use strict"; | ||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Sound\", function() { return Sound; });\n// modified soundbox.js lib\nclass Sound {\n constructor () {\n this.sounds = {} // The loaded sounds and their instances\n this.instances = [] // Sounds that are currently playing\n this.defaultVolume = 1\n };\n\n load (name, path, callback) {\n this.sounds[name] = new Audio(path)\n if (typeof callback === 'function') {\n this.sounds[name].addEventListener('canplaythrough', callback)\n } else {\n return new Promise((resolve, reject) => {\n this.sounds[name].addEventListener('canplaythrough', resolve)\n this.sounds[name].addEventListener('error', reject)\n })\n }\n };\n\n remove (name) {\n if (typeof this.sounds !== 'undefined') {\n delete this.sounds[name]\n }\n };\n\n unlock (name, callback, volume, loop) {\n var that = this\n var events = ['touchstart', 'touchend', 'mousedown', 'keydown']\n var unlock = function unlock () {\n events.forEach(function (event) {\n document.body.removeEventListener(event, unlock)\n })\n that.play(name, callback, volume, loop)\n }\n\n events.forEach(function (event) {\n document.body.addEventListener(event, unlock, false)\n })\n };\n\n play (name, callback, volume, loop) {\n loop = loop || false\n\n if (typeof this.sounds[name] === 'undefined') {\n console.error(\"Can't find sound called '\" + name + \"'.\")\n return false\n };\n\n var soundInstance = this.sounds[name].cloneNode(true)\n soundInstance.volume = typeof volume === 'number' ? volume : this.defaultVolume\n soundInstance.loop = loop\n soundInstance.play()\n this.instances.push(soundInstance)\n\n // Don't forget to remove the instance from the instances array\n soundInstance.addEventListener('ended', () => {\n var index = this.instances.indexOf(soundInstance)\n if (index !== -1) this.instances.splice(index, 1)\n })\n\n // Attach the callback / promise\n if (typeof callback === 'function') {\n soundInstance.addEventListener('ended', callback)\n return true\n };\n\n return new Promise((resolve, reject) => soundInstance.addEventListener('ended', resolve))\n };\n\n stopAll () {\n // Pause all currently playing sounds\n\n // Shallow clone the array to avoid issues with instances auto-removing themselves\n var instancesToStop = this.instances.slice()\n for (var instance of instancesToStop) {\n instance.pause()\n instance.dispatchEvent(new Event('ended'))\n }\n }\n};\n\n\n\n\n//# sourceURL=webpack:///./app/craters/sound.js?"); | ||
/***/ }), | ||
/***/ "./app/craters/system.js": | ||
/*!*******************************!*\ | ||
!*** ./app/craters/system.js ***! | ||
\*******************************/ | ||
/*! exports provided: Canvas, Loop, Collision */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
"use strict"; | ||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Canvas\", function() { return Canvas; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Loop\", function() { return Loop; });\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"Collision\", function() { return Collision; });\n// Rect collision tests the edges of each rect to\n// test whether the objects are overlapping the other\nclass Collision {\n\tstatic detector (collider, collidee) {\n\t // Store the collider and collidee edges\n\t var l1 = collider.state.pos.x;\n\t var t1 = collider.state.pos.y;\n\t var r1 = l1 + collider.state.size.x;\n\t var b1 = t1 + collider.state.size.y;\n\t \n\t var l2 = collidee.state.pos.x;\n\t var t2 = collidee.state.pos.y;\n\t var r2 = l2 + collidee.state.size.x;\n\t var b2 = t2 + collidee.state.size.y;\n\t \n\t // If the any of the edges are beyond any of the\n\t // others, then we know that the box cannot be\n\t // colliding\n\t if (b1 < t2 || t1 > b2 || r1 < l2 || l1 > r2) {\n\t return false;\n\t }\n\t \n\t // If the algorithm made it here, it had to collide\n\t return true;\n }\n}\n\n// Game Loop Module\n// This module contains the game loop, which handles\n// updating the game state and re-rendering the canvas\n// (using the updated state) at the configured FPS.\nclass Loop {\n constructor (scope, fps) {\n var loop = {}\n // Initialize timer variables so we can calculate FPS\n var fpsInterval = 1000 / fps\n var before = window.performance.now()\n // Set up an object to contain our alternating FPS calculations\n var cycles = {\n new: {\n frameCount: 0,\n startTime: before,\n sinceStart: 0\n },\n old: {\n frameCount: 0,\n startTime: before,\n sineStart: 0\n }\n }\n\n // Alternating Frame Rate vars\n var resetInterval = 5\n var resetState = 'new'\n\n loop.fps = 0\n\n // Main game rendering loop\n loop.main = function mainLoop (tframe) {\n // Request a new Animation Frame\n // setting to `stopLoop` so animation can be stopped via\n // `window.cancelAnimationFrame( loop.stopLoop )`\n loop.stopLoop = window.requestAnimationFrame(loop.main)\n\n // How long ago since last loop?\n var now = tframe\n var elapsed = now - before\n var activeCycle\n var targetResetInterval\n\n // If it's been at least our desired interval, render\n if (elapsed > fpsInterval) {\n // Set before = now for next frame, also adjust for\n // specified fpsInterval not being a multiple of rAF's interval (16.7ms)\n // ( http://stackoverflow.com/a/19772220 )\n before = now - (elapsed % fpsInterval)\n\n // Increment the vals for both the active and the alternate FPS calculations\n for (var calc in cycles) {\n ++cycles[calc].frameCount\n cycles[calc].sinceStart = now - cycles[calc].startTime\n }\n\n // Choose the correct FPS calculation, then update the exposed fps value\n activeCycle = cycles[resetState]\n loop.fps = Math.round(1000 / (activeCycle.sinceStart / activeCycle.frameCount) * 100) / 100\n\n // If our frame counts are equal....\n targetResetInterval = (cycles.new.frameCount === cycles.old.frameCount\n ? resetInterval * fps // Wait our interval\n : (resetInterval * 2) * fps) // Wait double our interval\n\n // If the active calculation goes over our specified interval,\n // reset it to 0 and flag our alternate calculation to be active\n // for the next series of animations.\n if (activeCycle.frameCount > targetResetInterval) {\n cycles[resetState].frameCount = 0\n cycles[resetState].startTime = now\n cycles[resetState].sinceStart = 0\n\n resetState = (resetState === 'new' ? 'old' : 'new')\n }\n\n // Update the game state\n scope.update(scope, now)\n // Render the next frame\n scope.render(scope, now)\n }\n }\n\n // Start off main loop\n loop.main()\n return loop\n }\n}\n\nclass Canvas {\n\tconstructor (width, height, container) {\n\t\tvar container = document.querySelector(container || 'body');\n\t\t// Generate a canvas and store it as our viewport\n\t var canvas = document.createElement('canvas')\n\t var context = canvas.getContext('2d')\n\t // Pass our canvas' context to our getPixelRatio method\n\t var backingStores = ['webkitBackingStorePixelRatio', 'mozBackingStorePixelRatio', 'msBackingStorePixelRatio', 'oBackingStorePixelRatio', 'backingStorePixelRatio']\n\t var deviceRatio = window.devicePixelRatio\n\t // Iterate through our backing store props and determine the proper backing ratio.\n\t var backingRatio = backingStores.reduce(function (prev, curr) {\n\t return (Object.prototype.hasOwnProperty.call(context, curr) ? context[curr] : 1)\n\t })\n\t // Return the proper pixel ratio by dividing the device ratio by the backing ratio\n\t var ratio = deviceRatio / backingRatio\n\t\n\t // Set the canvas' width then downscale via CSS\n\t canvas.width = Math.round(width * ratio)\n\t canvas.height = Math.round(height * ratio)\n\t canvas.style.width = width + 'px'\n\t canvas.style.height = height + 'px'\n\t // Scale the context so we get accurate pixel density\n\t context.setTransform(ratio, 0, 0, ratio, 0, 0)\n\t // Append viewport into our game within the dom\n\t container.insertBefore(canvas, container.firstChild)\n\t \n\t return canvas // return the canvas\n\t}\n}\n\n\n\n//# sourceURL=webpack:///./app/craters/system.js?"); | ||
/***/ }), | ||
/***/ "./app/game.js": | ||
/*!*********************!*\ | ||
!*** ./app/game.js ***! | ||
\*********************/ | ||
/*! no exports provided */ | ||
/***/ (function(module, __webpack_exports__, __webpack_require__) { | ||
"use strict"; | ||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _craters_craters_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./craters/craters.js */ \"./app/craters/craters.js\");\n\n\n\nclass mygame extends _craters_craters_js__WEBPACK_IMPORTED_MODULE_0__[\"Game\"] {\n\tconstructor (container, width, height){\n\t\tsuper ();\n\t\t\n\t\tthis.state.size = {x: width, y: height}\n\t\tthis.viewport = new _craters_craters_js__WEBPACK_IMPORTED_MODULE_0__[\"Canvas\"](this.state.size.x, this.state.size.y, container);\n\t\tthis.context = this.viewport.getContext('2d')\n\t\tthis.loop = new _craters_craters_js__WEBPACK_IMPORTED_MODULE_0__[\"Loop\"](this, 60)\n\t}\n\t\n render () {\n super.render()\n this.clearContext(this.context, this.state.size)\n \n this.context.font = '2em Arial'\n this.context.fillText('It\\'s working.️', 65, (this.state.size.y / 2), (this.state.size.x))\n }\n}\n\nwindow.game = new mygame('#container', window.innerWidth, window.innerHeight, 60, true)\n\n//# sourceURL=webpack:///./app/game.js?"); | ||
/***/ }) | ||
/******/ }); | ||
!function(t){var e={};function r(n){if(e[n])return e[n].exports;var i=e[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,r),i.l=!0,i.exports}r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)r.d(n,i,function(e){return t[e]}.bind(null,i));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=2)}({2:function(t,e,r){"use strict";r.r(e);class n{constructor(t,e){var r={},n=1e3/e,i=window.performance.now(),o={new:{frameCount:0,startTime:i,sinceStart:0},old:{frameCount:0,startTime:i,sineStart:0}},a="new";return r.fps=0,r.main=function(s){r.stopLoop=window.requestAnimationFrame(r.main);var u,c,l=s,f=l-i;if(f>n){for(var d in i=l-f%n,o)++o[d].frameCount,o[d].sinceStart=l-o[d].startTime;u=o[a],r.fps=Math.round(1e3/(u.sinceStart/u.frameCount)*100)/100,c=o.new.frameCount===o.old.frameCount?5*e:10*e,u.frameCount>c&&(o[a].frameCount=0,o[a].startTime=l,o[a].sinceStart=0,a="new"===a?"old":"new"),t.update(t,l),t.render(t,l)}},r.main(),r}}class i{constructor(t,e,r){r=document.querySelector(r||"body");var n=document.createElement("canvas"),i=n.getContext("2d"),o=window.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return Object.prototype.hasOwnProperty.call(i,e)?i[e]:1});return n.width=Math.round(t*o),n.height=Math.round(e*o),n.style.width=t+"px",n.style.height=e+"px",i.setTransform(o,0,0,o,0,0),r.insertBefore(n,r.firstChild),n}}class o{constructor(t,e,r,n,i){this.entities=[],this.state={container:t,size:{x:10,y:10},bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"}}update(){for(var t=0;t<this.entities.length;t++)this.entities[t].update()}render(){for(var t=0;t<this.entities.length;t++)this.entities[t].render()}clearContext(t,e){t.clearRect(0,0,e.x,e.y)}}Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)};window.game=new class extends o{constructor(t,e,r){super(),this.state.size={x:e,y:r},this.viewport=new i(this.state.size.x,this.state.size.y,t),this.context=this.viewport.getContext("2d"),this.loop=new n(this,60)}render(){super.render(),this.clearContext(this.context,this.state.size),this.context.font="2em Arial",this.context.fillText("It's working.️",65,this.state.size.y/2,this.state.size.x)}}("#container",window.innerWidth,window.innerHeight,60,!0)}}); |
@@ -26,2 +26,4 @@ #### v0.0.0.1 | ||
it can be used to create an entity quick and fast | ||
i.e ladybug extends sprite | ||
i.e ladybug extends sprite | ||
#### v0.0.0.5 | ||
* separation of the canvas and loop from the game class |
@@ -7,3 +7,3 @@ var Craters = (function (exports) { | ||
class Collision { | ||
static detector (collider, collidee) { | ||
static detect (collider, collidee) { | ||
// Store the collider and collidee edges | ||
@@ -10,0 +10,0 @@ var l1 = collider.state.pos.x; |
@@ -1,100 +0,1 @@ | ||
/******/ (function(modules) { // webpackBootstrap | ||
/******/ // The module cache | ||
/******/ var installedModules = {}; | ||
/******/ | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
/******/ | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) { | ||
/******/ return installedModules[moduleId].exports; | ||
/******/ } | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ i: moduleId, | ||
/******/ l: false, | ||
/******/ exports: {} | ||
/******/ }; | ||
/******/ | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
/******/ | ||
/******/ // Flag the module as loaded | ||
/******/ module.l = true; | ||
/******/ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
/******/ | ||
/******/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
/******/ | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
/******/ | ||
/******/ // define getter function for harmony exports | ||
/******/ __webpack_require__.d = function(exports, name, getter) { | ||
/******/ if(!__webpack_require__.o(exports, name)) { | ||
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); | ||
/******/ } | ||
/******/ }; | ||
/******/ | ||
/******/ // define __esModule on exports | ||
/******/ __webpack_require__.r = function(exports) { | ||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { | ||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); | ||
/******/ } | ||
/******/ Object.defineProperty(exports, '__esModule', { value: true }); | ||
/******/ }; | ||
/******/ | ||
/******/ // create a fake namespace object | ||
/******/ // mode & 1: value is a module id, require it | ||
/******/ // mode & 2: merge all properties of value into the ns | ||
/******/ // mode & 4: return value when already ns object | ||
/******/ // mode & 8|1: behave like require | ||
/******/ __webpack_require__.t = function(value, mode) { | ||
/******/ if(mode & 1) value = __webpack_require__(value); | ||
/******/ if(mode & 8) return value; | ||
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; | ||
/******/ var ns = Object.create(null); | ||
/******/ __webpack_require__.r(ns); | ||
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); | ||
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); | ||
/******/ return ns; | ||
/******/ }; | ||
/******/ | ||
/******/ // getDefaultExport function for compatibility with non-harmony modules | ||
/******/ __webpack_require__.n = function(module) { | ||
/******/ var getter = module && module.__esModule ? | ||
/******/ function getDefault() { return module['default']; } : | ||
/******/ function getModuleExports() { return module; }; | ||
/******/ __webpack_require__.d(getter, 'a', getter); | ||
/******/ return getter; | ||
/******/ }; | ||
/******/ | ||
/******/ // Object.prototype.hasOwnProperty.call | ||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | ||
/******/ | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
/******/ | ||
/******/ | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(__webpack_require__.s = "./dist/craters.js"); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ({ | ||
/***/ "./dist/craters.js": | ||
/*!*************************!*\ | ||
!*** ./dist/craters.js ***! | ||
\*************************/ | ||
/*! no static exports found */ | ||
/***/ (function(module, exports) { | ||
eval("var Craters = (function (exports) {\n 'use strict';\n\n // Rect collision tests the edges of each rect to\n // test whether the objects are overlapping the other\n class Collision {\n \tstatic detector (collider, collidee) {\n \t // Store the collider and collidee edges\n \t var l1 = collider.state.pos.x;\n \t var t1 = collider.state.pos.y;\n \t var r1 = l1 + collider.state.size.x;\n \t var b1 = t1 + collider.state.size.y;\n \t \n \t var l2 = collidee.state.pos.x;\n \t var t2 = collidee.state.pos.y;\n \t var r2 = l2 + collidee.state.size.x;\n \t var b2 = t2 + collidee.state.size.y;\n \t \n \t // If the any of the edges are beyond any of the\n \t // others, then we know that the box cannot be\n \t // colliding\n \t if (b1 < t2 || t1 > b2 || r1 < l2 || l1 > r2) {\n \t return false;\n \t }\n \t \n \t // If the algorithm made it here, it had to collide\n \t return true;\n }\n }\n\n // Game Loop Module\n // This module contains the game loop, which handles\n // updating the game state and re-rendering the canvas\n // (using the updated state) at the configured FPS.\n class Loop {\n constructor (scope, fps) {\n var loop = {};\n // Initialize timer variables so we can calculate FPS\n var fpsInterval = 1000 / fps;\n var before = window.performance.now();\n // Set up an object to contain our alternating FPS calculations\n var cycles = {\n new: {\n frameCount: 0,\n startTime: before,\n sinceStart: 0\n },\n old: {\n frameCount: 0,\n startTime: before,\n sineStart: 0\n }\n };\n\n // Alternating Frame Rate vars\n var resetInterval = 5;\n var resetState = 'new';\n\n loop.fps = 0;\n\n // Main game rendering loop\n loop.main = function mainLoop (tframe) {\n // Request a new Animation Frame\n // setting to `stopLoop` so animation can be stopped via\n // `window.cancelAnimationFrame( loop.stopLoop )`\n loop.stopLoop = window.requestAnimationFrame(loop.main);\n\n // How long ago since last loop?\n var now = tframe;\n var elapsed = now - before;\n var activeCycle;\n var targetResetInterval;\n\n // If it's been at least our desired interval, render\n if (elapsed > fpsInterval) {\n // Set before = now for next frame, also adjust for\n // specified fpsInterval not being a multiple of rAF's interval (16.7ms)\n // ( http://stackoverflow.com/a/19772220 )\n before = now - (elapsed % fpsInterval);\n\n // Increment the vals for both the active and the alternate FPS calculations\n for (var calc in cycles) {\n ++cycles[calc].frameCount;\n cycles[calc].sinceStart = now - cycles[calc].startTime;\n }\n\n // Choose the correct FPS calculation, then update the exposed fps value\n activeCycle = cycles[resetState];\n loop.fps = Math.round(1000 / (activeCycle.sinceStart / activeCycle.frameCount) * 100) / 100;\n\n // If our frame counts are equal....\n targetResetInterval = (cycles.new.frameCount === cycles.old.frameCount\n ? resetInterval * fps // Wait our interval\n : (resetInterval * 2) * fps); // Wait double our interval\n\n // If the active calculation goes over our specified interval,\n // reset it to 0 and flag our alternate calculation to be active\n // for the next series of animations.\n if (activeCycle.frameCount > targetResetInterval) {\n cycles[resetState].frameCount = 0;\n cycles[resetState].startTime = now;\n cycles[resetState].sinceStart = 0;\n\n resetState = (resetState === 'new' ? 'old' : 'new');\n }\n\n // Update the game state\n scope.update(scope, now);\n // Render the next frame\n scope.render(scope, now);\n }\n };\n\n // Start off main loop\n loop.main();\n return loop\n }\n }\n\n class Canvas {\n \tconstructor (width, height, container) {\n \t\tvar container = document.querySelector(container || 'body');\n \t\t// Generate a canvas and store it as our viewport\n \t var canvas = document.createElement('canvas');\n \t var context = canvas.getContext('2d');\n \t // Pass our canvas' context to our getPixelRatio method\n \t var backingStores = ['webkitBackingStorePixelRatio', 'mozBackingStorePixelRatio', 'msBackingStorePixelRatio', 'oBackingStorePixelRatio', 'backingStorePixelRatio'];\n \t var deviceRatio = window.devicePixelRatio;\n \t // Iterate through our backing store props and determine the proper backing ratio.\n \t var backingRatio = backingStores.reduce(function (prev, curr) {\n \t return (Object.prototype.hasOwnProperty.call(context, curr) ? context[curr] : 1)\n \t });\n \t // Return the proper pixel ratio by dividing the device ratio by the backing ratio\n \t var ratio = deviceRatio / backingRatio;\n \t\n \t // Set the canvas' width then downscale via CSS\n \t canvas.width = Math.round(width * ratio);\n \t canvas.height = Math.round(height * ratio);\n \t canvas.style.width = width + 'px';\n \t canvas.style.height = height + 'px';\n \t // Scale the context so we get accurate pixel density\n \t context.setTransform(ratio, 0, 0, ratio, 0, 0);\n \t // Append viewport into our game within the dom\n \t container.insertBefore(canvas, container.firstChild);\n \t \n \t return canvas // return the canvas\n \t}\n }\n\n class Game {\n constructor (container, width, height, fps, debug) {\n this.entities = [];\n this.state = {\n container: container,\n size: {\n \t x: 10,\n \t y: 10\n },\n \n bgcolor: 'rgba(0,0,0,0)',\n color: '#ff0',\n font: '1em Arial'\n };\n }\n\n update () {\n for (var entity = 0; entity < this.entities.length; entity++) {\n // Fire off each active entities `render` method\n this.entities[entity].update();\n }\n }\n \n render () {\n \tfor (var entity = 0; entity < this.entities.length; entity++) {\n // Fire off each active entities `render` method\n this.entities[entity].render(); }\n }\n \n clearContext (context, size) {\n \t context.clearRect(0, 0, size.x, size.y);\n }\n }\n\n class Entity extends Game {\n constructor () {\n super();\n this.state = {\n size: {\n x: 10,\n y: 10\n },\n pos: {\n x: 0,\n y: 0\n },\n vel: {\n x: 0,\n y: 0\n },\n accel: {\n x: 0,\n y: 0\n },\n radius: 10,\n angle: 0\n };\n }\n\n update () {\n super.update ();\n \n this.state.vel.x += this.state.accel.x;\n this.state.vel.y += this.state.accel.y;\n this.state.pos.x += this.state.vel.x;\n this.state.pos.y += this.state.vel.y;\n }\n }\n\n class Sprite extends Entity {\n constructor (scope, args) {\n super();\n\n this.scope = scope;\n this.state.pos = args.pos || {\n x: 0,\n y: 0\n };\n this.state.crop = {\n x: 0,\n y: 0\n };\n this.state.size = args.size || {\n x: 0,\n y: 0\n };\n \n this.state.frames = args.frames || [];\n this.state.angle = args.angle || 0;\n this.state.image = args.image || new Image();\n this.state.delay = args.delay || 5;\n this.state.tick = args.tick || 0;\n this.state.orientation = args.orientation || 'horizontal';\n }\n\n update () {\n super.update ();\n \n if (this.state.tick <= 0) {\n if (this.orientation === 'vertical') {\n this.state.crop.y = this.state.frames.shift();\n this.state.frames.push(this.state.crop.y);\n } else {\n this.state.crop.x = this.state.frames.shift();\n this.state.frames.push(this.state.crop.x);\n }\n\n this.state.tick = this.state.delay;\n }\n\n this.state.tick--;\n }\n\n render () {\n super.render();\n\n this.scope.context.save();\n this.scope.context.translate(this.state.crop.x + (this.state.size.x / 2), this.state.crop.y + (this.state.size.y / 2));\n this.scope.context.rotate((this.state.angle) * (Math.PI / 180));\n this.scope.context.translate(-(this.state.crop.x + (this.state.size.x / 2)), -(this.state.crop.y + (this.state.size.y / 2)));\n\n this.scope.context.drawImage(this.state.image,\n (this.state.crop.x * this.state.size.x), (this.state.crop.y * this.state.size.y), this.state.size.x, this.state.size.y,\n this.state.pos.x, this.state.pos.y, this.state.size.x, this.state.size.y);\n\n this.scope.context.restore();\n }\n }\n\n class Loader {\n constructor () {\n this.rescache = {};\n };\n\n load (res, cbk) {\n var that = this;\n if (res instanceof Array) {\n res.forEach(function (i) {\n that.rescache[i] = false;\n that.fetch(i, cbk);\n });\n } else {\n that.rescache[res] = false;\n that.fetch(res, cbk);\n }\n }\n\n fetch (url, cbk) {\n var that = this;\n if (that.rescache[url]) {\n return that.rescache[url]\n } else {\n var img = new Image();\n img.onload = function () {\n that.rescache[url] = img;\n that.ready(cbk);\n };\n\n img.src = url;\n }\n }\n\n ready (cbk) {\n var that = this;\n if (typeof cbk === 'function') {\n var ready = true;\n for (var item in that.rescache) {\n if (Object.prototype.hasOwnProperty.call(that.rescache, item) && !that.rescache[item]) {\n ready = false;\n }\n }\n\n if (ready) cbk();\n }\n }\n }\n\n // modified soundbox.js lib\n class Sound {\n constructor () {\n this.sounds = {}; // The loaded sounds and their instances\n this.instances = []; // Sounds that are currently playing\n this.defaultVolume = 1;\n };\n\n load (name, path, callback) {\n this.sounds[name] = new Audio(path);\n if (typeof callback === 'function') {\n this.sounds[name].addEventListener('canplaythrough', callback);\n } else {\n return new Promise((resolve, reject) => {\n this.sounds[name].addEventListener('canplaythrough', resolve);\n this.sounds[name].addEventListener('error', reject);\n })\n }\n };\n\n remove (name) {\n if (typeof this.sounds !== 'undefined') {\n delete this.sounds[name];\n }\n };\n\n unlock (name, callback, volume, loop) {\n var that = this;\n var events = ['touchstart', 'touchend', 'mousedown', 'keydown'];\n var unlock = function unlock () {\n events.forEach(function (event) {\n document.body.removeEventListener(event, unlock);\n });\n that.play(name, callback, volume, loop);\n };\n\n events.forEach(function (event) {\n document.body.addEventListener(event, unlock, false);\n });\n };\n\n play (name, callback, volume, loop) {\n loop = loop || false;\n\n if (typeof this.sounds[name] === 'undefined') {\n console.error(\"Can't find sound called '\" + name + \"'.\");\n return false\n }\n var soundInstance = this.sounds[name].cloneNode(true);\n soundInstance.volume = typeof volume === 'number' ? volume : this.defaultVolume;\n soundInstance.loop = loop;\n soundInstance.play();\n this.instances.push(soundInstance);\n\n // Don't forget to remove the instance from the instances array\n soundInstance.addEventListener('ended', () => {\n var index = this.instances.indexOf(soundInstance);\n if (index !== -1) this.instances.splice(index, 1);\n });\n\n // Attach the callback / promise\n if (typeof callback === 'function') {\n soundInstance.addEventListener('ended', callback);\n return true\n }\n return new Promise((resolve, reject) => soundInstance.addEventListener('ended', resolve))\n };\n\n stopAll () {\n // Pause all currently playing sounds\n\n // Shallow clone the array to avoid issues with instances auto-removing themselves\n var instancesToStop = this.instances.slice();\n for (var instance of instancesToStop) {\n instance.pause();\n instance.dispatchEvent(new Event('ended'));\n }\n }\n }\n\n // Craters.js micro game framework\n\n const boundary = function numberboundary (min, max) {\n return Math.min(Math.max(this, min), max)\n };\n // Expose methods\n Number.prototype.boundary = boundary;\n\n class Craters {\n static version () {\n return '0.0.0.5'\n }\n }\n\n exports.Canvas = Canvas;\n exports.Collision = Collision;\n exports.Craters = Craters;\n exports.Entity = Entity;\n exports.Game = Game;\n exports.Loader = Loader;\n exports.Loop = Loop;\n exports.Sound = Sound;\n exports.Sprite = Sprite;\n\n return exports;\n\n}({}));\n\n\n//# sourceURL=webpack:///./dist/craters.js?"); | ||
/***/ }) | ||
/******/ }); | ||
!function(t){var e={};function s(i){if(e[i])return e[i].exports;var a=e[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,s),a.l=!0,a.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)s.d(i,a,function(e){return t[e]}.bind(null,a));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=0)}([function(t,e){!function(t){"use strict";class e{constructor(t,e,s,i,a){this.entities=[],this.state={container:t,size:{x:10,y:10},bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"}}update(){for(var t=0;t<this.entities.length;t++)this.entities[t].update()}render(){for(var t=0;t<this.entities.length;t++)this.entities[t].render()}clearContext(t,e){t.clearRect(0,0,e.x,e.y)}}class s extends e{constructor(){super(),this.state={size:{x:10,y:10},pos:{x:0,y:0},vel:{x:0,y:0},accel:{x:0,y:0},radius:10,angle:0}}update(){super.update(),this.state.vel.x+=this.state.accel.x,this.state.vel.y+=this.state.accel.y,this.state.pos.x+=this.state.vel.x,this.state.pos.y+=this.state.vel.y}}Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)};t.Canvas=class{constructor(t,e,s){s=document.querySelector(s||"body");var i=document.createElement("canvas"),a=i.getContext("2d"),r=window.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return Object.prototype.hasOwnProperty.call(a,e)?a[e]:1});return i.width=Math.round(t*r),i.height=Math.round(e*r),i.style.width=t+"px",i.style.height=e+"px",a.setTransform(r,0,0,r,0,0),s.insertBefore(i,s.firstChild),i}},t.Collision=class{static detect(t,e){var s=t.state.pos.x,i=t.state.pos.y,a=s+t.state.size.x,r=i+t.state.size.y,n=e.state.pos.x,o=e.state.pos.y,c=n+e.state.size.x,h=o+e.state.size.y;return!(r<o||i>h||a<n||s>c)}},t.Craters=class{static version(){return"0.0.0.5"}},t.Entity=s,t.Game=e,t.Loader=class{constructor(){this.rescache={}}load(t,e){var s=this;t instanceof Array?t.forEach(function(t){s.rescache[t]=!1,s.fetch(t,e)}):(s.rescache[t]=!1,s.fetch(t,e))}fetch(t,e){var s=this;if(s.rescache[t])return s.rescache[t];var i=new Image;i.onload=function(){s.rescache[t]=i,s.ready(e)},i.src=t}ready(t){if("function"==typeof t){var e=!0;for(var s in this.rescache)Object.prototype.hasOwnProperty.call(this.rescache,s)&&!this.rescache[s]&&(e=!1);e&&t()}}},t.Loop=class{constructor(t,e){var s={},i=1e3/e,a=window.performance.now(),r={new:{frameCount:0,startTime:a,sinceStart:0},old:{frameCount:0,startTime:a,sineStart:0}},n="new";return s.fps=0,s.main=function(o){s.stopLoop=window.requestAnimationFrame(s.main);var c,h,u=o,d=u-a;if(d>i){for(var l in a=u-d%i,r)++r[l].frameCount,r[l].sinceStart=u-r[l].startTime;c=r[n],s.fps=Math.round(1e3/(c.sinceStart/c.frameCount)*100)/100,h=r.new.frameCount===r.old.frameCount?5*e:10*e,c.frameCount>h&&(r[n].frameCount=0,r[n].startTime=u,r[n].sinceStart=0,n="new"===n?"old":"new"),t.update(t,u),t.render(t,u)}},s.main(),s}},t.Sound=class{constructor(){this.sounds={},this.instances=[],this.defaultVolume=1}load(t,e,s){if(this.sounds[t]=new Audio(e),"function"!=typeof s)return new Promise((e,s)=>{this.sounds[t].addEventListener("canplaythrough",e),this.sounds[t].addEventListener("error",s)});this.sounds[t].addEventListener("canplaythrough",s)}remove(t){void 0!==this.sounds&&delete this.sounds[t]}unlock(t,e,s,i){var a=this,r=["touchstart","touchend","mousedown","keydown"],n=function n(){r.forEach(function(t){document.body.removeEventListener(t,n)}),a.play(t,e,s,i)};r.forEach(function(t){document.body.addEventListener(t,n,!1)})}play(t,e,s,i){if(i=i||!1,void 0===this.sounds[t])return console.error("Can't find sound called '"+t+"'."),!1;var a=this.sounds[t].cloneNode(!0);return a.volume="number"==typeof s?s:this.defaultVolume,a.loop=i,a.play(),this.instances.push(a),a.addEventListener("ended",()=>{var t=this.instances.indexOf(a);-1!==t&&this.instances.splice(t,1)}),"function"==typeof e?(a.addEventListener("ended",e),!0):new Promise((t,e)=>a.addEventListener("ended",t))}stopAll(){var t=this.instances.slice();for(var e of t)e.pause(),e.dispatchEvent(new Event("ended"))}},t.Sprite=class extends s{constructor(t,e){super(),this.scope=t,this.state.pos=e.pos||{x:0,y:0},this.state.crop={x:0,y:0},this.state.size=e.size||{x:0,y:0},this.state.frames=e.frames||[],this.state.angle=e.angle||0,this.state.image=e.image||new Image,this.state.delay=e.delay||5,this.state.tick=e.tick||0,this.state.orientation=e.orientation||"horizontal"}update(){super.update(),this.state.tick<=0&&("vertical"===this.orientation?(this.state.crop.y=this.state.frames.shift(),this.state.frames.push(this.state.crop.y)):(this.state.crop.x=this.state.frames.shift(),this.state.frames.push(this.state.crop.x)),this.state.tick=this.state.delay),this.state.tick--}render(){super.render(),this.scope.context.save(),this.scope.context.translate(this.state.crop.x+this.state.size.x/2,this.state.crop.y+this.state.size.y/2),this.scope.context.rotate(this.state.angle*(Math.PI/180)),this.scope.context.translate(-(this.state.crop.x+this.state.size.x/2),-(this.state.crop.y+this.state.size.y/2)),this.scope.context.drawImage(this.state.image,this.state.crop.x*this.state.size.x,this.state.crop.y*this.state.size.y,this.state.size.x,this.state.size.y,this.state.pos.x,this.state.pos.y,this.state.size.x,this.state.size.y),this.scope.context.restore()}}}({})}]); |
@@ -1,1 +0,1 @@ | ||
!function(t){var e={};function s(i){if(e[i])return e[i].exports;var a=e[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,s),a.l=!0,a.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)s.d(i,a,function(e){return t[e]}.bind(null,a));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=0)}([function(t,e,s){"use strict";s.r(e);class i{constructor(t,e,s,i,o){this.container=t||"body",this.state={width:e,height:s,fps:i,debug:o,bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"},this.entities=[],this.viewport=r.create(this.state.width,this.state.height,this.container),this.context=this.viewport.getContext("2d"),this.loop=new a(this,this.state.fps)}update(t,e){for(var s=0;s<this.entities.length;s++)this.entities[s].update()}render(t,e){t.context.font=t.state.font,t.context.clearRect(0,0,t.state.width,t.state.height),t.context.fillStyle=t.state.bgcolor,t.context.fillRect(0,0,t.state.width,t.state.height),t.context.fillStyle=t.state.color,t.state.debug&&t.context.fillText("fps : "+t.loop.fps,t.state.width-100,50);for(var s=0;s<this.entities.length;s++)this.entities[s].render()}}class a{constructor(t,e){var s={},i=1e3/e,a=window.performance.now(),r={new:{frameCount:0,startTime:a,sinceStart:0},old:{frameCount:0,startTime:a,sineStart:0}},o="new";return s.fps=0,s.main=function(n){s.stopLoop=window.requestAnimationFrame(s.main);var h,c,p=n,l=p-a;if(l>i){for(var u in a=p-l%i,r)++r[u].frameCount,r[u].sinceStart=p-r[u].startTime;h=r[o],s.fps=Math.round(1e3/(h.sinceStart/h.frameCount)*100)/100,c=r.new.frameCount===r.old.frameCount?5*e:10*e,h.frameCount>c&&(r[o].frameCount=0,r[o].startTime=p,r[o].sinceStart=0,o="new"===o?"old":"new"),t.update(t,p),t.render(t,p)}},s.main(),s}}class r{static create(t,e,s){s=document.querySelector(s||"body");var i=document.createElement("canvas"),a=i.getContext("2d"),r=window.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return Object.prototype.hasOwnProperty.call(a,e)?a[e]:1});return i.width=Math.round(t*r),i.height=Math.round(e*r),i.style.width=t+"px",i.style.height=e+"px",a.setTransform(r,0,0,r,0,0),s.insertBefore(i,s.firstChild),i}}class o{constructor(){this.state={size:{x:10,y:10},pos:{x:0,y:0},vel:{x:0,y:0},accel:{x:0,y:0},radius:10,angle:0},this.entities=[]}update(){for(var t=0;t<this.entities.length;t++)this.entities[t].update();this.state.vel.x+=this.state.accel.x,this.state.vel.y+=this.state.accel.y,this.state.pos.x+=this.state.vel.x,this.state.pos.y+=this.state.vel.y}render(){for(var t=0;t<this.entities.length;t++)this.entities[t].render()}}class n extends o{constructor(t,e){super(),this.scope=t,this.state.pos=e.pos||{x:0,y:0},this.state.crop={x:0,y:0},this.state.size=e.size||{x:0,y:0},this.state.frames=e.frames||[],this.state.angle=e.angle||0,this.state.image=e.image||new Image,this.state.delay=e.delay||5,this.state.tick=e.tick||0,this.state.orientation=e.orientation||"horizontal"}update(){super.update(),this.state.tick<=0&&("vertical"===this.orientation?(this.state.crop.y=this.state.frames.shift(),this.state.frames.push(this.state.crop.y)):(this.state.crop.x=this.state.frames.shift(),this.state.frames.push(this.state.crop.x)),this.state.tick=this.state.delay),this.state.tick--}render(){super.render(),this.scope.context.save(),this.scope.context.translate(this.state.crop.x+this.state.size.x/2,this.state.crop.y+this.state.size.y/2),this.scope.context.rotate(this.state.angle*(Math.PI/180)),this.scope.context.translate(-(this.state.crop.x+this.state.size.x/2),-(this.state.crop.y+this.state.size.y/2)),this.scope.context.drawImage(this.state.image,this.state.crop.x*this.state.size.x,this.state.crop.y*this.state.size.y,this.state.size.x,this.state.size.y,this.state.pos.x,this.state.pos.y,this.state.size.x,this.state.size.y),this.scope.context.restore()}}class h{static detector(t,e){var s=t.state.pos.x,i=t.state.pos.y,a=s+t.state.size.x,r=i+t.state.size.y,o=e.state.pos.x,n=e.state.pos.y,h=o+e.state.size.x,c=n+e.state.size.y;return!(r<n||i>c||a<o||s>h)}}Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)};class c extends i{constructor(){super("#container",window.innerWidth,window.innerHeight,60,!1),this.score=0,this.state.color="rgba(255,255,255,1)",this.state.bgcolor="rgba(0,0,0,0.001)",this.state.font="1.5em Arial",this.ball=this.entities.push(new p(this))-1,this.entities.push(new u(this));for(var t=0;t<3;t++)for(var e=0;e<this.state.width/138;e++){var s=this.entities.push(new l(this,{x:138*e,y:53*t}));this.entities[s-1].id=s-1}}render(){super.render(this),this.context.fillText("score: "+this.score,16,50)}}class p extends n{constructor(t){super(t,{frames:[0],image:d.fetch("./media/ball@3x.png")}),this.state.vel={x:5,y:5},this.state.size={x:48,y:48},this.state.pos={x:t.state.width/2-this.state.size.x/2,y:t.state.height/2-this.state.size.y}}update(){super.update(),this.state.pos.y<0&&(this.state.vel.y*=-1),this.state.pos.y+this.state.size.y+69>this.scope.state.height&&(this.state.vel.y*=-1),this.state.pos.x<0&&(this.state.vel.x*=-1),this.state.pos.x+this.state.size.x>this.scope.state.width&&(this.state.vel.x*=-1)}}class l extends n{constructor(t,e){super(t,{frames:[0],image:d.fetch("./media/block@3x.png")}),this.scope=t,this.state.size={x:138,y:53},this.state.pos={x:e.x,y:e.y}}update(){super.update(),h.detector(this.scope.entities[this.scope.ball],this)&&(this.scope.score+=10,this.state.image=new Image,this.state.pos=this.state.size={x:0,y:0})}}class u extends n{constructor(t){super(t,{frames:[0],image:d.fetch("./media/paddle@3x.png")}),this.scope=t,this.state.size={x:180,y:69}}update(){super.update(),this.state.pos={x:this.scope.entities[this.scope.ball].state.pos.x+25-this.state.size.x/2,y:this.scope.state.height-this.state.size.y}}}var d=new class{constructor(){this.rescache={}}load(t,e){var s=this;t instanceof Array?t.forEach(function(t){s.rescache[t]=!1,s.fetch(t,e)}):(s.rescache[t]=!1,s.fetch(t,e))}fetch(t,e){var s=this;if(s.rescache[t])return s.rescache[t];var i=new Image;i.onload=function(){s.rescache[t]=i,s.ready(e)},i.src=t}ready(t){if("function"==typeof t){var e=!0;for(var s in this.rescache)Object.prototype.hasOwnProperty.call(this.rescache,s)&&!this.rescache[s]&&(e=!1);e&&t()}}};d.load(["./media/ball@3x.png","./media/paddle@3x.png","./media/block@3x.png"],function(){window.game=new c})}]); | ||
!function(t){var e={};function s(i){if(e[i])return e[i].exports;var a=e[i]={i:i,l:!1,exports:{}};return t[i].call(a.exports,a,a.exports,s),a.l=!0,a.exports}s.m=t,s.c=e,s.d=function(t,e,i){s.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,e){if(1&e&&(t=s(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(s.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)s.d(i,a,function(e){return t[e]}.bind(null,a));return i},s.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(e,"a",e),e},s.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},s.p="",s(s.s=0)}([function(t,e,s){"use strict";s.r(e);class i{static detect(t,e){var s=t.state.pos.x,i=t.state.pos.y,a=s+t.state.size.x,o=i+t.state.size.y,n=e.state.pos.x,r=e.state.pos.y,h=n+e.state.size.x,c=r+e.state.size.y;return!(o<r||i>c||a<n||s>h)}}class a{constructor(t,e){var s={},i=1e3/e,a=window.performance.now(),o={new:{frameCount:0,startTime:a,sinceStart:0},old:{frameCount:0,startTime:a,sineStart:0}},n="new";return s.fps=0,s.main=function(r){s.stopLoop=window.requestAnimationFrame(s.main);var h,c,p=r,d=p-a;if(d>i){for(var u in a=p-d%i,o)++o[u].frameCount,o[u].sinceStart=p-o[u].startTime;h=o[n],s.fps=Math.round(1e3/(h.sinceStart/h.frameCount)*100)/100,c=o.new.frameCount===o.old.frameCount?5*e:10*e,h.frameCount>c&&(o[n].frameCount=0,o[n].startTime=p,o[n].sinceStart=0,n="new"===n?"old":"new"),t.update(t,p),t.render(t,p)}},s.main(),s}}class o{constructor(t,e,s){s=document.querySelector(s||"body");var i=document.createElement("canvas"),a=i.getContext("2d"),o=window.devicePixelRatio/["webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","backingStorePixelRatio"].reduce(function(t,e){return Object.prototype.hasOwnProperty.call(a,e)?a[e]:1});return i.width=Math.round(t*o),i.height=Math.round(e*o),i.style.width=t+"px",i.style.height=e+"px",a.setTransform(o,0,0,o,0,0),s.insertBefore(i,s.firstChild),i}}class n{constructor(t,e,s,i,a){this.entities=[],this.state={container:t,size:{x:10,y:10},bgcolor:"rgba(0,0,0,0)",color:"#ff0",font:"1em Arial"}}update(){for(var t=0;t<this.entities.length;t++)this.entities[t].update()}render(){for(var t=0;t<this.entities.length;t++)this.entities[t].render()}clearContext(t,e){t.clearRect(0,0,e.x,e.y)}}class r extends n{constructor(){super(),this.state={size:{x:10,y:10},pos:{x:0,y:0},vel:{x:0,y:0},accel:{x:0,y:0},radius:10,angle:0}}update(){super.update(),this.state.vel.x+=this.state.accel.x,this.state.vel.y+=this.state.accel.y,this.state.pos.x+=this.state.vel.x,this.state.pos.y+=this.state.vel.y}}class h extends r{constructor(t,e){super(),this.scope=t,this.state.pos=e.pos||{x:0,y:0},this.state.crop={x:0,y:0},this.state.size=e.size||{x:0,y:0},this.state.frames=e.frames||[],this.state.angle=e.angle||0,this.state.image=e.image||new Image,this.state.delay=e.delay||5,this.state.tick=e.tick||0,this.state.orientation=e.orientation||"horizontal"}update(){super.update(),this.state.tick<=0&&("vertical"===this.orientation?(this.state.crop.y=this.state.frames.shift(),this.state.frames.push(this.state.crop.y)):(this.state.crop.x=this.state.frames.shift(),this.state.frames.push(this.state.crop.x)),this.state.tick=this.state.delay),this.state.tick--}render(){super.render(),this.scope.context.save(),this.scope.context.translate(this.state.crop.x+this.state.size.x/2,this.state.crop.y+this.state.size.y/2),this.scope.context.rotate(this.state.angle*(Math.PI/180)),this.scope.context.translate(-(this.state.crop.x+this.state.size.x/2),-(this.state.crop.y+this.state.size.y/2)),this.scope.context.drawImage(this.state.image,this.state.crop.x*this.state.size.x,this.state.crop.y*this.state.size.y,this.state.size.x,this.state.size.y,this.state.pos.x,this.state.pos.y,this.state.size.x,this.state.size.y),this.scope.context.restore()}}Number.prototype.boundary=function(t,e){return Math.min(Math.max(this,t),e)};var c=new class{constructor(){this.rescache={}}load(t,e){var s=this;t instanceof Array?t.forEach(function(t){s.rescache[t]=!1,s.fetch(t,e)}):(s.rescache[t]=!1,s.fetch(t,e))}fetch(t,e){var s=this;if(s.rescache[t])return s.rescache[t];var i=new Image;i.onload=function(){s.rescache[t]=i,s.ready(e)},i.src=t}ready(t){if("function"==typeof t){var e=!0;for(var s in this.rescache)Object.prototype.hasOwnProperty.call(this.rescache,s)&&!this.rescache[s]&&(e=!1);e&&t()}}},p=new class{constructor(){this.sounds={},this.instances=[],this.defaultVolume=1}load(t,e,s){if(this.sounds[t]=new Audio(e),"function"!=typeof s)return new Promise((e,s)=>{this.sounds[t].addEventListener("canplaythrough",e),this.sounds[t].addEventListener("error",s)});this.sounds[t].addEventListener("canplaythrough",s)}remove(t){void 0!==this.sounds&&delete this.sounds[t]}unlock(t,e,s,i){var a=this,o=["touchstart","touchend","mousedown","keydown"],n=function n(){o.forEach(function(t){document.body.removeEventListener(t,n)}),a.play(t,e,s,i)};o.forEach(function(t){document.body.addEventListener(t,n,!1)})}play(t,e,s,i){if(i=i||!1,void 0===this.sounds[t])return console.error("Can't find sound called '"+t+"'."),!1;var a=this.sounds[t].cloneNode(!0);return a.volume="number"==typeof s?s:this.defaultVolume,a.loop=i,a.play(),this.instances.push(a),a.addEventListener("ended",()=>{var t=this.instances.indexOf(a);-1!==t&&this.instances.splice(t,1)}),"function"==typeof e?(a.addEventListener("ended",e),!0):new Promise((t,e)=>a.addEventListener("ended",t))}stopAll(){var t=this.instances.slice();for(var e of t)e.pause(),e.dispatchEvent(new Event("ended"))}};class d extends n{constructor(t,e,s){super(),this.score=0,this.state.size={x:e,y:s},this.state.pos={x:0,y:0},this.deleted=[],this.viewport=new o(this.state.size.x,this.state.size.y,t),this.context=this.viewport.getContext("2d"),this.context.fillStyle="#fff",this.loop=new a(this,60),this.ball=this.entities.push(new u(this))-1,this.paddle=this.entities.push(new x(this))-1,this.bamboos=0}update(){this.bamboos<=1&&this.newgame(this.state.size.y/2/53,this.state.size.x/138),super.update()}render(){this.clearContext(this.context,this.state.size),this.context.font="2em Arial",this.context.fillText("SCORE: ️"+this.score,16,50,this.state.size.x),super.render()}newgame(t,e){for(var s=0;s<t;s++)for(var i=0;i<e;i++){var a=this.entities.push(new l(this,{x:138*i,y:53*s}))-1;this.entities[a].id=a,this.bamboos++}}}class u extends h{constructor(t){super(t,{frames:[0],image:c.fetch("./media/ball@3x.png")}),this.scope=t,this.state.vel={x:5,y:-2},this.state.size={x:48,y:48},this.state.pos={x:t.state.size.x/2-this.state.size.x/2,y:t.state.size.y/2-this.state.size.y}}update(){super.update(),(this.state.pos.x+this.state.size.x>this.scope.state.size.x||this.state.pos.x<0)&&(this.state.vel.x*=-1),(this.state.pos.y+this.state.size.y>this.scope.state.size.y||this.state.pos.y<0)&&(this.state.vel.y*=-1),i.detect(this.scope.entities[this.scope.paddle],this)&&(this.state.vel.y*=-1)}}class l extends h{constructor(t,e){super(t,{frames:[0],image:c.fetch("./media/block@3x.png")}),this.scope=t,this.state.size={x:138,y:53},this.state.pos={x:e.x,y:e.y}}update(){if(super.update(),!this.state.collided&&i.detect(this.scope.entities[this.scope.ball],this)){this.scope.score+=10,this.scope.bamboos--,p.play("pop");for(var t=0;t<10;t++){var e=this.scope.entities.push(new f(this.scope,{x:this.state.pos.x+50*(Math.random()-.5),y:this.state.pos.y+25*(Math.random()-.5)}))-1;this.scope.entities[e].id=e}e=this.id;this.scope.entities=this.scope.entities.filter(function(t){return t.id!=e})}}}class f extends h{constructor(t,e){super(t,{frames:[0]}),this.scope=t,this.state.image=c.fetch("./media/block_break01@3x.png"),this.state.size={x:45,y:35},this.state.pos=e,this.state.accel.y=1.25*Math.random(),this.state.accel.x=1.25*(Math.random()-.5)}update(){super.update(),i.detect(this.scope,this)||(this.state.vel.x=this.state.vel.y=this.state.accel.x=this.state.accel.y=0)}}class x extends h{constructor(t){super(t,{frames:[0],image:c.fetch("./media/paddle@3x.png")}),this.scope=t,this.state.size={x:180,y:69}}update(){super.update(),this.state.pos={x:this.scope.entities[this.scope.ball].state.pos.x+25-this.state.size.x/2,y:this.scope.state.size.y-this.state.size.y}}}p.load("pop","./media/music/pop.ogg");c.load(["./media/ball@3x.png","./media/paddle@3x.png","./media/block@3x.png","./media/block_break01@3x.png"],function(){window.game=new d("#container",window.innerWidth,window.innerHeight,60,!0)})}]); |
@@ -1,2 +0,2 @@ | ||
import { Game, Entity, Sprite, Loader } from './../../../app/craters/craters.js' | ||
import { Game, Entity, Sprite, Loader } from './../../app/craters/craters.js' | ||
@@ -3,0 +3,0 @@ 'use strict' |
{ | ||
"name": "craters.js", | ||
"version": "1.0.8", | ||
"version": "1.0.9", | ||
"description": "A Compact Game Engine that helps you build fast, modern HTML5 Games", | ||
@@ -19,6 +19,6 @@ "main": "./index.js", | ||
"keywords": [ | ||
"node", | ||
"nodejs", | ||
"javascript", | ||
"library", | ||
"html5-game-engine", | ||
"game-library", | ||
"js13kgames", | ||
"html5-game-development", | ||
"game-engine" | ||
@@ -34,2 +34,2 @@ ], | ||
} | ||
} | ||
} |
@@ -9,33 +9,28 @@ # craters.js ☄️ | ||
#### Short description | ||
craters.js is a simple to use micro game engine both lightweight and portable so minimal that it's just 1.5kb in size! zipped and minified. | ||
in it, it includes all basics you need to get a game up and running in a few lines of code | ||
leaving enough room for the game logic. suitable for [js13kgames](https://js13kgames.com) competition | ||
A Compact html5 Game Engine that helps you build fast, modern HTML5 Games | ||
* [Buggame sprite sample game](https://swashvirus.github.io/craters.js/examples/sprites-demo/index.html) | ||
* [Panda Breakout sample game](https://swashvirus.github.io/craters.js/examples/breakout-game/index.html) | ||
[Buggame sprite sample game](https://swashvirus.github.io/craters.js/examples/sprites-demo/index.html) | ||
[Panda Breakout sample game](https://swashvirus.github.io/craters.js/examples/breakout-game/index.html) | ||
#### features ✨ | ||
- Changelog | ||
[Read changelog](CHANGELOG.md) | ||
- Changelog outlines more features [Read changelog](CHANGELOG.md) | ||
- ES modules | ||
reduces bundle size | ||
* reduces bundle size you only import what you need | ||
- Sound | ||
sound system loads sounds methods | ||
* a sound system used for loading and playing sound effects | ||
- Sprite | ||
a sprite system | ||
* a sprite system it draws and animates images and sprites | ||
- Loader | ||
file loading utility | ||
* a file loading utility used for pre-loading image files and caching them so that they can be used by i.e the sprite system | ||
- Entity | ||
Entity base class | ||
* a base class for deriving your game entities from it cones with update and render methods as well as the state object with predefined variables namely velocity, acceleration, position and size | ||
- Game | ||
Game base class | ||
* a base class for deriving your games from it has a state object just like the entity it also has methods update and render. | ||
#### structure | ||
game is a method which creates an instance of a game world | ||
game is a method used to create an instance of game world | ||
the game and entities both have methods update and render | ||
the games instance can have entities and entities can also have their own entities as long as they inherit the craters.entity class | ||
@@ -42,0 +37,0 @@ #### let's make a game 🚀 |
const path = require('path') | ||
module.exports = { | ||
mode: 'development', | ||
entry: { | ||
@@ -6,0 +5,0 @@ './build/game.min.js': './app/game.js', |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
78
1824917
1580
78