(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && this._events[type].length > m) { this._events[type].warned = true; console.error('(node) warning: possible EventEmitter memory ' + 'leak detected. %d listeners added. ' + 'Use emitter.setMaxListeners() to increase limit.', this._events[type].length); if (typeof console.trace === 'function') { // not supported in IE 10 console.trace(); } } } return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!isFunction(listener)) throw TypeError('listener must be a function'); var fired = false; function g() { this.removeListener(type, g); if (!fired) { fired = true; listener.apply(this, arguments); } } g.listener = listener; this.on(type, g); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function(type, listener) { var list, position, length, i; if (!isFunction(listener)) throw TypeError('listener must be a function'); if (!this._events || !this._events[type]) return this; list = this._events[type]; length = list.length; position = -1; if (list === listener || (isFunction(list.listener) && list.listener === listener)) { delete this._events[type]; if (this._events.removeListener) this.emit('removeListener', type, listener); } else if (isObject(list)) { for (i = length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { position = i; break; } } if (position < 0) return this; if (list.length === 1) { list.length = 0; delete this._events[type]; } else { list.splice(position, 1); } if (this._events.removeListener) this.emit('removeListener', type, listener); } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { var key, listeners; if (!this._events) return this; // not listening for removeListener, no need to emit if (!this._events.removeListener) { if (arguments.length === 0) this._events = {}; else if (this._events[type]) delete this._events[type]; return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { for (key in this._events) { if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = {}; return this; } listeners = this._events[type]; if (isFunction(listeners)) { this.removeListener(type, listeners); } else { // LIFO order while (listeners.length) this.removeListener(type, listeners[listeners.length - 1]); } delete this._events[type]; return this; }; EventEmitter.prototype.listeners = function(type) { var ret; if (!this._events || !this._events[type]) ret = []; else if (isFunction(this._events[type])) ret = [this._events[type]]; else ret = this._events[type].slice(); return ret; }; EventEmitter.listenerCount = function(emitter, type) { var ret; if (!emitter._events || !emitter._events[type]) ret = 0; else if (isFunction(emitter._events[type])) ret = 1; else ret = emitter._events[type].length; return ret; }; function isFunction(arg) { return typeof arg === 'function'; } function isNumber(arg) { return typeof arg === 'number'; } function isObject(arg) { return typeof arg === 'object' && arg !== null; } function isUndefined(arg) { return arg === void 0; } },{}],"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/inherits/inherits_browser.js":[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; } else { // old school shim for old browsers module.exports = function inherits(ctor, superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } },{}],"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/process/browser.js":[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; process.nextTick = (function () { var canSetImmediate = typeof window !== 'undefined' && window.setImmediate; var canPost = typeof window !== 'undefined' && window.postMessage && window.addEventListener ; if (canSetImmediate) { return function (f) { return window.setImmediate(f) }; } if (canPost) { var queue = []; window.addEventListener('message', function (ev) { var source = ev.source; if ((source === window || source === null) && ev.data === 'process-tick') { ev.stopPropagation(); if (queue.length > 0) { var fn = queue.shift(); fn(); } } }, true); return function nextTick(fn) { queue.push(fn); window.postMessage('process-tick', '*'); }; } return function nextTick(fn) { setTimeout(fn, 0); }; })(); process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); } // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; },{}],"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/util/support/isBufferBrowser.js":[function(require,module,exports){ module.exports = function isBuffer(arg) { return arg && typeof arg === 'object' && typeof arg.copy === 'function' && typeof arg.fill === 'function' && typeof arg.readUInt8 === 'function'; } },{}],"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/util/util.js":[function(require,module,exports){ (function (process,global){ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. var formatRegExp = /%[sdj%]/g; exports.format = function(f) { if (!isString(f)) { var objects = []; for (var i = 0; i < arguments.length; i++) { objects.push(inspect(arguments[i])); } return objects.join(' '); } var i = 1; var args = arguments; var len = args.length; var str = String(f).replace(formatRegExp, function(x) { if (x === '%%') return '%'; if (i >= len) return x; switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); case '%j': try { return JSON.stringify(args[i++]); } catch (_) { return '[Circular]'; } default: return x; } }); for (var x = args[i]; i < len; x = args[++i]) { if (isNull(x) || !isObject(x)) { str += ' ' + x; } else { str += ' ' + inspect(x); } } return str; }; // Mark that a method should not be used. // Returns a modified function which warns once by default. // If --no-deprecation is set, then it is a no-op. exports.deprecate = function(fn, msg) { // Allow for deprecating things in the process of starting up. if (isUndefined(global.process)) { return function() { return exports.deprecate(fn, msg).apply(this, arguments); }; } if (process.noDeprecation === true) { return fn; } var warned = false; function deprecated() { if (!warned) { if (process.throwDeprecation) { throw new Error(msg); } else if (process.traceDeprecation) { console.trace(msg); } else { console.error(msg); } warned = true; } return fn.apply(this, arguments); } return deprecated; }; var debugs = {}; var debugEnviron; exports.debuglog = function(set) { if (isUndefined(debugEnviron)) debugEnviron = process.env.NODE_DEBUG || ''; set = set.toUpperCase(); if (!debugs[set]) { if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { var pid = process.pid; debugs[set] = function() { var msg = exports.format.apply(exports, arguments); console.error('%s %d: %s', set, pid, msg); }; } else { debugs[set] = function() {}; } } return debugs[set]; }; /** * Echos the value of a value. Trys to print the value out * in the best way possible given the different types. * * @param {Object} obj The object to print out. * @param {Object} opts Optional options object that alters the output. */ /* legacy: obj, showHidden, depth, colors*/ function inspect(obj, opts) { // default options var ctx = { seen: [], stylize: stylizeNoColor }; // legacy... if (arguments.length >= 3) ctx.depth = arguments[2]; if (arguments.length >= 4) ctx.colors = arguments[3]; if (isBoolean(opts)) { // legacy... ctx.showHidden = opts; } else if (opts) { // got an "options" object exports._extend(ctx, opts); } // set default options if (isUndefined(ctx.showHidden)) ctx.showHidden = false; if (isUndefined(ctx.depth)) ctx.depth = 2; if (isUndefined(ctx.colors)) ctx.colors = false; if (isUndefined(ctx.customInspect)) ctx.customInspect = true; if (ctx.colors) ctx.stylize = stylizeWithColor; return formatValue(ctx, obj, ctx.depth); } exports.inspect = inspect; // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics inspect.colors = { 'bold' : [1, 22], 'italic' : [3, 23], 'underline' : [4, 24], 'inverse' : [7, 27], 'white' : [37, 39], 'grey' : [90, 39], 'black' : [30, 39], 'blue' : [34, 39], 'cyan' : [36, 39], 'green' : [32, 39], 'magenta' : [35, 39], 'red' : [31, 39], 'yellow' : [33, 39] }; // Don't use 'blue' not visible on cmd.exe inspect.styles = { 'special': 'cyan', 'number': 'yellow', 'boolean': 'yellow', 'undefined': 'grey', 'null': 'bold', 'string': 'green', 'date': 'magenta', // "name": intentionally not styling 'regexp': 'red' }; function stylizeWithColor(str, styleType) { var style = inspect.styles[styleType]; if (style) { return '\u001b[' + inspect.colors[style][0] + 'm' + str + '\u001b[' + inspect.colors[style][1] + 'm'; } else { return str; } } function stylizeNoColor(str, styleType) { return str; } function arrayToHash(array) { var hash = {}; array.forEach(function(val, idx) { hash[val] = true; }); return hash; } function formatValue(ctx, value, recurseTimes) { // Provide a hook for user-specified inspect functions. // Check that value is an object with an inspect function on it if (ctx.customInspect && value && isFunction(value.inspect) && // Filter out the util module, it's inspect function is special value.inspect !== exports.inspect && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { var ret = value.inspect(recurseTimes, ctx); if (!isString(ret)) { ret = formatValue(ctx, ret, recurseTimes); } return ret; } // Primitive types cannot have properties var primitive = formatPrimitive(ctx, value); if (primitive) { return primitive; } // Look up the keys of the object. var keys = Object.keys(value); var visibleKeys = arrayToHash(keys); if (ctx.showHidden) { keys = Object.getOwnPropertyNames(value); } // IE doesn't make error fields non-enumerable // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx if (isError(value) && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { return formatError(value); } // Some type of object without properties can be shortcutted. if (keys.length === 0) { if (isFunction(value)) { var name = value.name ? ': ' + value.name : ''; return ctx.stylize('[Function' + name + ']', 'special'); } if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } if (isDate(value)) { return ctx.stylize(Date.prototype.toString.call(value), 'date'); } if (isError(value)) { return formatError(value); } } var base = '', array = false, braces = ['{', '}']; // Make Array say that they are Array if (isArray(value)) { array = true; braces = ['[', ']']; } // Make functions say that they are functions if (isFunction(value)) { var n = value.name ? ': ' + value.name : ''; base = ' [Function' + n + ']'; } // Make RegExps say that they are RegExps if (isRegExp(value)) { base = ' ' + RegExp.prototype.toString.call(value); } // Make dates with properties first say the date if (isDate(value)) { base = ' ' + Date.prototype.toUTCString.call(value); } // Make error with message first say the error if (isError(value)) { base = ' ' + formatError(value); } if (keys.length === 0 && (!array || value.length == 0)) { return braces[0] + base + braces[1]; } if (recurseTimes < 0) { if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { return ctx.stylize('[Object]', 'special'); } } ctx.seen.push(value); var output; if (array) { output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); } else { output = keys.map(function(key) { return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); } ctx.seen.pop(); return reduceToSingleString(output, base, braces); } function formatPrimitive(ctx, value) { if (isUndefined(value)) return ctx.stylize('undefined', 'undefined'); if (isString(value)) { var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') .replace(/'/g, "\\'") .replace(/\\"/g, '"') + '\''; return ctx.stylize(simple, 'string'); } if (isNumber(value)) return ctx.stylize('' + value, 'number'); if (isBoolean(value)) return ctx.stylize('' + value, 'boolean'); // For some reason typeof null is "object", so special case here. if (isNull(value)) return ctx.stylize('null', 'null'); } function formatError(value) { return '[' + Error.prototype.toString.call(value) + ']'; } function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { var output = []; for (var i = 0, l = value.length; i < l; ++i) { if (hasOwnProperty(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true)); } else { output.push(''); } } keys.forEach(function(key) { if (!key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); } }); return output; } function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { var name, str, desc; desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; if (desc.get) { if (desc.set) { str = ctx.stylize('[Getter/Setter]', 'special'); } else { str = ctx.stylize('[Getter]', 'special'); } } else { if (desc.set) { str = ctx.stylize('[Setter]', 'special'); } } if (!hasOwnProperty(visibleKeys, key)) { name = '[' + key + ']'; } if (!str) { if (ctx.seen.indexOf(desc.value) < 0) { if (isNull(recurseTimes)) { str = formatValue(ctx, desc.value, null); } else { str = formatValue(ctx, desc.value, recurseTimes - 1); } if (str.indexOf('\n') > -1) { if (array) { str = str.split('\n').map(function(line) { return ' ' + line; }).join('\n').substr(2); } else { str = '\n' + str.split('\n').map(function(line) { return ' ' + line; }).join('\n'); } } } else { str = ctx.stylize('[Circular]', 'special'); } } if (isUndefined(name)) { if (array && key.match(/^\d+$/)) { return str; } name = JSON.stringify('' + key); if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { name = name.substr(1, name.length - 2); name = ctx.stylize(name, 'name'); } else { name = name.replace(/'/g, "\\'") .replace(/\\"/g, '"') .replace(/(^"|"$)/g, "'"); name = ctx.stylize(name, 'string'); } } return name + ': ' + str; } function reduceToSingleString(output, base, braces) { var numLinesEst = 0; var length = output.reduce(function(prev, cur) { numLinesEst++; if (cur.indexOf('\n') >= 0) numLinesEst++; return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; }, 0); if (length > 60) { return braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n ') + ' ' + braces[1]; } return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; } // NOTE: These type checking functions intentionally don't use `instanceof` // because it is fragile and can be easily faked with `Object.create()`. function isArray(ar) { return Array.isArray(ar); } exports.isArray = isArray; function isBoolean(arg) { return typeof arg === 'boolean'; } exports.isBoolean = isBoolean; function isNull(arg) { return arg === null; } exports.isNull = isNull; function isNullOrUndefined(arg) { return arg == null; } exports.isNullOrUndefined = isNullOrUndefined; function isNumber(arg) { return typeof arg === 'number'; } exports.isNumber = isNumber; function isString(arg) { return typeof arg === 'string'; } exports.isString = isString; function isSymbol(arg) { return typeof arg === 'symbol'; } exports.isSymbol = isSymbol; function isUndefined(arg) { return arg === void 0; } exports.isUndefined = isUndefined; function isRegExp(re) { return isObject(re) && objectToString(re) === '[object RegExp]'; } exports.isRegExp = isRegExp; function isObject(arg) { return typeof arg === 'object' && arg !== null; } exports.isObject = isObject; function isDate(d) { return isObject(d) && objectToString(d) === '[object Date]'; } exports.isDate = isDate; function isError(e) { return isObject(e) && (objectToString(e) === '[object Error]' || e instanceof Error); } exports.isError = isError; function isFunction(arg) { return typeof arg === 'function'; } exports.isFunction = isFunction; function isPrimitive(arg) { return arg === null || typeof arg === 'boolean' || typeof arg === 'number' || typeof arg === 'string' || typeof arg === 'symbol' || // ES6 symbol typeof arg === 'undefined'; } exports.isPrimitive = isPrimitive; exports.isBuffer = require('./support/isBuffer'); function objectToString(o) { return Object.prototype.toString.call(o); } function pad(n) { return n < 10 ? '0' + n.toString(10) : n.toString(10); } var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; // 26 Feb 16:19:34 function timestamp() { var d = new Date(); var time = [pad(d.getHours()), pad(d.getMinutes()), pad(d.getSeconds())].join(':'); return [d.getDate(), months[d.getMonth()], time].join(' '); } // log is just a thin wrapper to console.log that prepends a timestamp exports.log = function() { console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); }; /** * Inherit the prototype methods from one constructor into another. * * The Function.prototype.inherits from lang.js rewritten as a standalone * function (not on Function.prototype). NOTE: If this file is to be loaded * during bootstrapping this function needs to be rewritten using some native * functions as prototype setup using normal JavaScript does not work as * expected during bootstrapping (see mirror.js in r114903). * * @param {function} ctor Constructor function which needs to inherit the * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ exports.inherits = require('inherits'); exports._extend = function(origin, add) { // Don't do anything if add isn't an object if (!add || !isObject(add)) return origin; var keys = Object.keys(add); var i = keys.length; while (i--) { origin[keys[i]] = add[keys[i]]; } return origin; }; function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./support/isBuffer":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/util/support/isBufferBrowser.js","_process":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/process/browser.js","inherits":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/inherits/inherits_browser.js"}],"/home/josh/dev/vapor/node_modules/chem/index.js":[function(require,module,exports){ var resources = require('./lib/resources'); module.exports = { vec2d: require('vec2d'), button: require('./lib/button'), resources: resources, Engine: require('./lib/engine'), Sound: require('./lib/sound'), Sprite: require('./lib/sprite'), Label: require('./lib/label'), Batch: require('./lib/batch'), Animation: require('./lib/animation'), }; },{"./lib/animation":"/home/josh/dev/vapor/node_modules/chem/lib/animation.js","./lib/batch":"/home/josh/dev/vapor/node_modules/chem/lib/batch.js","./lib/button":"/home/josh/dev/vapor/node_modules/chem/lib/button.js","./lib/engine":"/home/josh/dev/vapor/node_modules/chem/lib/engine.js","./lib/label":"/home/josh/dev/vapor/node_modules/chem/lib/label.js","./lib/resources":"/home/josh/dev/vapor/node_modules/chem/lib/resources.js","./lib/sound":"/home/josh/dev/vapor/node_modules/chem/lib/sound.js","./lib/sprite":"/home/josh/dev/vapor/node_modules/chem/lib/sprite.js","vec2d":"/home/josh/dev/vapor/node_modules/chem/node_modules/vec2d/index.js"}],"/home/josh/dev/vapor/node_modules/chem/lib/animation.js":[function(require,module,exports){ var vec2d = require('vec2d'); module.exports = Animation; function Animation() { this.delay = 0.1; this.loop = true; this.spritesheet = null; this.duration = 0; this.anchor = vec2d(0, 0); this.frames = []; } Animation.fromImage = function(image, o) { o = o || {}; var anim = new Animation(); anim.spritesheet = image; anim.anchor = vec2d(o.anchor); anim.loop = false; anim.addFrame(vec2d(0, 0), vec2d(image.width, image.height)); return anim; }; Animation.fromJson = function(o) { var anim = new Animation(); anim.delay = o.delay; anim.spritesheet = o.spritesheet; anim.anchor = vec2d(o.anchor); anim.loop = !!o.loop; anim.frames = []; var frames = o.frames || []; for (var i = 0; i < frames.length; ++i) { var frame = frames[i]; anim.addFrame(vec2d(frame.pos), vec2d(frame.size)); } return anim; }; Animation.prototype.addFrame = function(pos, size) { this.frames.push(new Frame(pos, size)); this.calcDuration(); }; Animation.prototype.removeFrame = function(index) { this.frames.splice(index, 1); this.calcDuration(); }; Animation.prototype.clearFrames = function() { this.frames = []; this.calcDuration(); }; Animation.prototype.calcDuration = function() { this.duration = this.delay * this.frames.length; } Animation.prototype.setDelay = function(delay) { this.delay = delay; this.calcDuration(); }; // extract an image from the spritesheet Animation.prototype.getImage = function(frameIndex) { if (frameIndex == null) frameIndex = 0; var buffer = document.createElement('canvas'); var frame = this.frames[frameIndex]; buffer.width = frame.size.x; buffer.height = frame.size.y; var context = buffer.getContext('2d'); context.drawImage(this.spritesheet, frame.pos.x, frame.pos.y, frame.size.x, frame.size.y, 0, 0, frame.size.x, frame.size.y); return buffer; }; function Frame(pos, size) { this.pos = pos; this.size = size; } },{"vec2d":"/home/josh/dev/vapor/node_modules/chem/node_modules/vec2d/index.js"}],"/home/josh/dev/vapor/node_modules/chem/lib/batch.js":[function(require,module,exports){ module.exports = Batch; function Batch() { // indexed by zOrder this.layers = []; } Batch.prototype.add = function(item) { if (item.batch) item.batch.remove(item); item.batch = this; if (item.visible) { var layer = this.layers[item.zOrder]; if (! layer) layer = this.layers[item.zOrder] = []; layer.push(item); } }; Batch.prototype.remove = function(item) { var layer = this.layers[item.zOrder]; if (!layer) return; var index = layer.indexOf(item); if (index >= 0) layer.splice(index, 1); }; Batch.prototype.draw = function(context) { for (var i = 0; i < this.layers.length; ++i) { var layer = this.layers[i]; if (!layer) continue; for (var spriteIndex = 0; spriteIndex < layer.length; spriteIndex += 1) { layer[spriteIndex].draw(context); } } }; Batch.prototype.clear = function(context) { for (var i = 0; i < this.layers.length; ++i) { var layer = this.layers[i]; if (!layer) continue; for (var spriteIndex = 0; spriteIndex < layer.length; spriteIndex += 1) { var sprite = layer[spriteIndex]; sprite.batch = null; sprite['delete'](); } } this.layers = []; }; },{}],"/home/josh/dev/vapor/node_modules/chem/lib/button.js":[function(require,module,exports){ var KEY_OFFSET = 0; var MOUSE_OFFSET = 256; exports.KEY_OFFSET = KEY_OFFSET; exports.MOUSE_OFFSET = MOUSE_OFFSET; var Key = { Backspace: 8, Tab: 9, Enter: 13, Shift: 16, Ctrl: 17, Alt: 18, Pause: 19, Break: 19, CapsLock: 20, Escape: 27, Space: 32, PageUp: 33, PageDown: 34, End: 35, Home: 36, Left: 37, Up: 38, Right: 39, Down: 40, Insert: 45, Delete: 46, 0: 48, 1: 49, 2: 50, 3: 51, 4: 52, 5: 53, 6: 54, 7: 55, 8: 56, 9: 57, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90, MetaLeft: 91, MetaRight: 92, Select: 93, Numpad0: 96, Numpad1: 97, Numpad2: 98, Numpad3: 99, Numpad4: 100, Numpad5: 101, Numpad6: 102, Numpad7: 103, Numpad8: 104, Numpad9: 105, Multiply: 106, Add: 107, Subtract: 109, Decimal: 110, Divide: 111, F1: 112, F2: 113, F3: 114, F4: 115, F5: 116, F6: 117, F7: 118, F8: 119, F9: 120, F10: 121, F11: 122, F12: 123, NumLock: 144, ScrollLock: 145, Semicolon: 186, EqualSign: 187, Comma: 188, Dash: 189, Period: 190, SlashForward: 191, Grave: 192, BracketOpen: 219, SlashBack: 220, BracketClose: 221, Quote: 222 }; var Mouse = { Left: 1, Middle: 2, Right: 3 }; // map both Key and Mouse into Button var btnName, val; for (btnName in Key) { val = Key[btnName]; exports["Key" + btnName] = KEY_OFFSET + val; } for (btnName in Mouse) { val = Mouse[btnName]; exports["Mouse" + btnName] = MOUSE_OFFSET + val; } },{}],"/home/josh/dev/vapor/node_modules/chem/lib/engine.js":[function(require,module,exports){ (function (global){ var Vec2d = require('vec2d').Vec2d; var resources = require('./resources'); var util = require('util'); var EventEmitter = require('events').EventEmitter; var button = require('./button'); var Label = require('./label'); var MOUSE_OFFSET = button.MOUSE_OFFSET; var KEY_OFFSET = button.KEY_OFFSET; var EPSILON = 0.00000001; var MAX_DISPLAY_FPS = 90000; module.exports = Engine; var targetFps = 60; var targetSpf = 1 / targetFps; var fpsSmoothness = 0.9; var fpsOneFrameWeight = 1.0 - fpsSmoothness; var requestAnimationFrame = global.requestAnimationFrame || global.webkitRequestAnimationFrame || global.mozRequestAnimationFrame || global.oRequestAnimationFrame || global.msRequestAnimationFrame || fallbackRequestAnimationFrame; var cancelAnimationFrame = global.cancelAnimationFrame || global.webkitCancelAnimationFrame || global.mozCancelAnimationFrame || global.oCancelAnimationFrame || global.msCancelAnimationFrame || clearTimeout; util.inherits(Engine, EventEmitter); function Engine(canvas) { EventEmitter.call(this); this.canvas = canvas; this.listeners = []; // add tabindex property to canvas so that it can receive keyboard input this.canvas.tabIndex = 0; this.context = this.canvas.getContext("2d"); this.size = new Vec2d(this.canvas.width, this.canvas.height); this.fps = targetFps; this.setMinFps(20); this.buttonCaptureExceptions = {}; } Engine.prototype.setSize = function(size) { this.size = size; this.canvas.width = this.size.x; this.canvas.height = this.size.y; }; Engine.prototype.setMinFps = function(it){ this.maxSpf = 1 / it; }; Engine.prototype.start = function(){ attachListeners(this); startMainLoop(this); }; Engine.prototype.stop = function(){ stopMainLoop(this); removeListeners(this); }; Engine.prototype.buttonState = function(button){ return !!this.buttonStates[button]; }; Engine.prototype.buttonJustPressed = function(button){ return !!this.btnJustPressed[button]; }; Engine.prototype.buttonJustReleased = function(button){ return !!this.btnJustReleased[button]; }; Engine.prototype.showLoadProgressBar = function() { showLoadProgressBar(this); }; Engine.prototype.createFpsLabel = function() { var label = new Label(this.fps, { font: "14px sans-serif", fillStyle: "#ffffff", textAlign: 'left', pos: new Vec2d(0, this.size.y), }); this.on('update', function() { label.text = Math.round(this.fps); }); return label; }; function startMainLoop(self) { var previousUpdate = (new Date()).getTime(); var previousDraw = (new Date()).getTime(); doUpdate(); function doUpdate() { var timestamp = new Date().getTime(); var delta = (timestamp - previousUpdate) / 1000; previousUpdate = timestamp; // make sure dt is never zero // if FPS is too low, lag instead of causing physics glitches var dt = delta; if (dt < EPSILON) dt = EPSILON; if (dt > self.maxSpf) dt = self.maxSpf; var multiplier = dt / targetSpf; self.emit('update', dt, multiplier); self.btnJustPressed = {}; self.btnJustReleased = {}; self.animationFrameId = requestAnimationFrame(doDraw, self.canvas); } function doDraw(timestamp) { var delta = (timestamp - previousDraw) / 1000; previousDraw = timestamp; self.emit('draw', self.context); var fps = 1 / delta; fps = fps < MAX_DISPLAY_FPS ? fps : MAX_DISPLAY_FPS; self.fps = self.fps * fpsSmoothness + fps * fpsOneFrameWeight; self.timeoutId = setTimeout(doUpdate, 0); } } function attachListeners(self) { self.buttonStates = {}; self.btnJustPressed = {}; self.btnJustReleased = {}; // disable right click context menu addListener(self.canvas, 'contextmenu', function(event){ if (self.buttonCaptureExceptions[button.MouseRight]) return true; event.preventDefault(); }); // mouse input self.mousePos = new Vec2d(0, 0); addListener(self.canvas, 'mousemove', onMouseMove); addListener(self.canvas, 'mousedown', function(event){ var buttonId = MOUSE_OFFSET + event.which; self.buttonStates[buttonId] = true; self.btnJustPressed[buttonId] = true; self.emit('buttondown', buttonId); self.canvas.focus(); window.addEventListener('mouseup', onMouseUp, false); window.addEventListener('mousemove', onMouseMove, false); return bubbleEvent(self, event); }); function onMouseUp(event) { var buttonId = MOUSE_OFFSET + event.which; self.buttonStates[buttonId] = false; self.btnJustReleased[buttonId] = true; self.emit('buttonup', buttonId); window.removeEventListener('mouseup', onMouseUp, false); window.removeEventListener('mousemove', onMouseMove, false); return bubbleEvent(self, event); } function onMouseMove(event) { self.mousePos = new Vec2d( event.pageX - self.canvas.offsetLeft, event.pageY - self.canvas.offsetTop); self.emit('mousemove', self.mousePos, MOUSE_OFFSET + event.which); } // keyboard input addListener(self.canvas, 'keydown', function(event){ var buttonId = KEY_OFFSET + event.which; self.btnJustPressed[buttonId] = !self.buttonStates[buttonId]; self.buttonStates[buttonId] = true; self.emit('buttondown', buttonId); return bubbleEvent(self, event); }); addListener(window, 'keyup', function(event){ var buttonId = KEY_OFFSET + event.which; self.btnJustReleased[buttonId] = self.buttonStates[buttonId]; self.buttonStates[buttonId] = false; self.emit('buttonup', buttonId); return bubbleEvent(self, event); }); function addListener(element, eventName, listener){ self.listeners.push([element, eventName, listener]); element.addEventListener(eventName, listener, false); } } function bubbleEvent(self, event) { // we need to figure out whether to bubble this key event up. // if the button is an exception, bubble it up. // also if any other exceptions are pressed, bubble it up. // this allows ctrl+(anything) to work. var buttonId = KEY_OFFSET + event.which; if (self.buttonCaptureExceptions[buttonId] || (event.ctrlKey && self.buttonCaptureExceptions[button.KeyCtrl]) || (event.altKey && self.buttonCaptureExceptions[button.KeyAlt]) || (event.shiftKey && self.buttonCaptureExceptions[button.KeyShift])) { return true; } else { event.preventDefault(); return false; } } function removeListeners(self) { self.listeners.forEach(function(listener) { var element = listener[0]; var eventName = listener[1]; var fn = listener[2]; element.removeEventListener(eventName, fn, false); }); self.listeners = []; } function stopMainLoop(self) { cancelAnimationFrame(self.animationFrameId); clearTimeout(self.timeoutId); } function fallbackRequestAnimationFrame(cb) { return setTimeout(function() { var timestamp = (new Date()).getTime(); cb(timestamp); }, targetSpf * 1000); } function showLoadProgressBar(self) { resources.on('progress', onProgress); resources.on('ready', onReady); self.on('draw', onDraw); var percent = 0; function onProgress(complete, total) { percent = total === 0 ? 1 : complete / total; } function onReady() { resources.removeListener('progress', onProgress); resources.removeListener('ready', onReady); self.removeListener('draw', onDraw); } function onDraw(context) { context.save(); context.setTransform(1, 0, 0, 1, 0, 0); // identity // clear to black context.fillStyle = "#000000"; context.fillRect(0, 0, self.size.x, self.size.y); // draw a progress bar var barRadius = Math.floor(self.size.y / 20); var centerY = Math.floor(self.size.y / 2); var margin = 5; // outline context.strokeStyle = "#ffffff"; context.lineWidth = 2; context.strokeRect(margin, centerY - barRadius, self.size.x - margin * 2, barRadius * 2); // inside context.fillStyle = "#ffffff"; var width = percent * (self.size.x - margin * 4); context.fillRect(margin * 2, centerY - barRadius + margin, width, barRadius * 2 - margin * 2); // text context.font = "18px sans-serif"; context.fillStyle = "#000000"; context.textAlign = "center"; context.textBaseline = "middle"; context.fillText("Loading... " + Math.floor(percent * 100) + "%", margin * 2 + Math.floor(width / 2), centerY); context.restore(); } } }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./button":"/home/josh/dev/vapor/node_modules/chem/lib/button.js","./label":"/home/josh/dev/vapor/node_modules/chem/lib/label.js","./resources":"/home/josh/dev/vapor/node_modules/chem/lib/resources.js","events":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/events/events.js","util":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/util/util.js","vec2d":"/home/josh/dev/vapor/node_modules/chem/node_modules/vec2d/index.js"}],"/home/josh/dev/vapor/node_modules/chem/lib/label.js":[function(require,module,exports){ var Vec2d = require('vec2d').Vec2d; module.exports = Label; function Label(text, params) { this.text = text; params = params || {}; this.pos = params.pos == null ? new Vec2d(0, 0) : params.pos; this.scale = params.scale == null ? new Vec2d(1, 1) : params.scale; this.zOrder = params.zOrder == null ? 0 : params.zOrder; this.batch = params.batch; this.rotation = params.rotation == null ? 0 : params.rotation; this.alpha = params.alpha == null ? 1 : params.alpha; this.font = params.font == null ? "10px sans-serif" : params.font; this.textAlign = params.textAlign == null ? "start" : params.textAlign; this.textBaseline= params.textBaseline == null ? "alphabetic" : params.textBaseline; this.fill = params.fill == null ? true : params.fill; this.fillStyle = params.fillStyle == null ? "#000000" : params.fillStyle; this.stroke = !!params.stroke; this.lineWidth = params.lineWidth == null ? 1 : params.lineWidth; this.strokeStyle = params.strokeStyle == null ? "#000000" : params.strokeStyle; this.setVisible(params.visible == null ? true : params.visible); } Label.prototype.draw = function(context) { context.save(); context.font = this.font; context.textAlign = this.textAlign; context.textBaseline = this.textBaseline; context.translate(this.pos.x, this.pos.y); context.scale(this.scale.x, this.scale.y); context.rotate(this.rotation); context.globalAlpha = this.alpha; if (this.fill) { context.fillStyle = this.fillStyle; context.fillText(this.text, 0, 0); } if (this.stroke) { context.strokeStyle = this.strokeStyle; context.lineWidth = this.lineWidth; context.strokeText(this.text, 0, 0); } context.restore(); }; Label.prototype.setVisible = function(visible){ this.visible = visible; if (this.batch == null) { return; } if (this.visible) { this.batch.add(this); } else { this.batch.remove(this); } }; Label.prototype.setZOrder = function(zOrder){ if (this.batch != null) { this.batch.remove(this); this.zOrder = zOrder; this.batch.add(this); } else { this.zOrder = zOrder; } }; Label.prototype['delete'] = function() { if (this.batch) this.batch.remove(this); this.batch = null; }; },{"vec2d":"/home/josh/dev/vapor/node_modules/chem/node_modules/vec2d/index.js"}],"/home/josh/dev/vapor/node_modules/chem/lib/resources.js":[function(require,module,exports){ var vec2d = require('vec2d'); var Pend = require('pend'); var util = require('util'); var EventEmitter = require('events').EventEmitter; var Animation = require('./animation'); // exports at bottom because we need to set up this class before // creating an instance util.inherits(ResourceLoader, EventEmitter); function ResourceLoader() { EventEmitter.call(this); this.ready = false; this.text = {}; this.images = {}; this.animations = {}; this.spritesheet = null; this.useSpritesheet = true; this.prefix = ""; } ResourceLoader.prototype.bootstrap = function() { bootstrap(this); }; ResourceLoader.prototype.url = function(relativeUrl) { if (this.prefix) { var lastChar = this.prefix[this.prefix.length - 1]; if (lastChar === '/') { return this.prefix + relativeUrl; } else { return this.prefix + '/' + relativeUrl; } } else { return relativeUrl; } }; ResourceLoader.prototype.fetchTextFile = function(path, cb) { var request = new XMLHttpRequest(); request.onreadystatechange = onReadyStateChange; request.open("GET", this.url(path), true); try { request.send(); } catch (err) { cb(err); } function onReadyStateChange() { if (request.readyState !== 4) return; if (Math.floor(request.status / 100) === 2) { cb(null, request.responseText); return; } cb(new Error(request.status + ": " + request.statusText)); } } ResourceLoader.prototype.fetchImage = function (path, cb) { var img = new Image(); img.src = this.url(path); img.onload = function(){ cb(null, img); }; } function bootstrap(self) { var pend = new Pend(); var total = 0; var complete = 0; if (self.useSpritesheet) { addLoader(loadSpritesheet); addLoader(loadAnimationsJson); } var name; for (name in self.text) { addLoader(generateLoadText(name)); } for (name in self.images) { addLoader(generateLoadImage(name)); } // allow the event loop to process one time // so that the user can get their on('ready') hook in setTimeout(executeBatch, 0); function executeBatch() { pend.wait(function(err) { if (err) { self.emit('error', err); return; } for (var name in self.animations) { self.animations[name].spritesheet = self.spritesheet; } self.ready = true; self.emit('ready'); }); } function addLoader(load) { total += 1; pend.go(function(cb) { load(function(err) { complete += 1; self.emit('progress', complete, total); cb(err); }); }); } function loadAnimationsJson(cb) { self.fetchImage("spritesheet.png", function(err, img) { if (err) return cb(err); self.spritesheet = img; cb(); }); } function loadSpritesheet(cb) { self.fetchTextFile("animations.json", function(err, text) { if (err) return cb(err); var animationsJson = JSON.parse(text); for (var name in animationsJson) { self.animations[name] = Animation.fromJson(animationsJson[name]); } cb(); }); } function generateLoadText(name) { var path = self.text[name]; return function(cb) { self.fetchTextFile(path, function(err, contents) { if (err) return cb(err); self.text[name] = contents; cb(); }); }; } function generateLoadImage(name) { var path = self.images[name]; return function(cb) { self.fetchImage(path, function(err, img) { if (err) return cb(err); self.images[name] = img; cb(); }); }; } } module.exports = new ResourceLoader(); },{"./animation":"/home/josh/dev/vapor/node_modules/chem/lib/animation.js","events":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/events/events.js","pend":"/home/josh/dev/vapor/node_modules/chem/node_modules/pend/index.js","util":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/util/util.js","vec2d":"/home/josh/dev/vapor/node_modules/chem/node_modules/vec2d/index.js"}],"/home/josh/dev/vapor/node_modules/chem/lib/sound.js":[function(require,module,exports){ var EventEmitter = require('events').EventEmitter; var util = require('util'); var resources = require('./resources'); module.exports = Sound; function Sound(src) { EventEmitter.call(this); this.currentSrc = src; this.resolvedSrc = resources.url(src); this.audioPool = [new Audio(this.resolvedSrc)]; this.maxPoolSize = 10; this.volume = 1; this.preload = "auto"; this.playbackRate = 1; this.buffered = 0; this.duration = null; applySettings(this); progressHooks(this); } util.inherits(Sound, EventEmitter); Sound.prototype.play = function() { var oldest = null; var oldestCurrentTime = -1; // play a ready one for (var i = 0; i < this.audioPool.length; ++i) { var audio = this.audioPool[i]; if (audioReadyToPlay(audio)) { audio.play(); return audio; } else if (audio.currentTime > oldestCurrentTime) { oldestCurrentTime = audio.currentTime; oldest = audio; } } // add a new one to the pool and play that one if (this.audioPool.length < this.maxPoolSize) { var newAudio = new Audio(this.resolvedSrc); applySettingsToAudio(this, newAudio); newAudio.play(); this.audioPool.push(newAudio); return newAudio; } // recycle the oldest one oldest.currentTime = 0; oldest.play(); return oldest; }; Sound.prototype.stop = function() { for (var i = 0; i < this.audioPool.length; ++i) { var audio = this.audioPool[i]; audio.pause(); audio.currentTime = 0; } }; Sound.prototype.setVolume = function(vol) { this.volume = vol; applySettings(this); }; Sound.prototype.setPreload = function(preload) { this.preload = preload; applySettings(this); }; Sound.prototype.setPlaybackRate = function(rate) { this.playbackRate = rate; applySettings(this); }; function applySettings(self) { for (var i = 0; i < self.audioPool.length; ++i) { applySettingsToAudio(self, self.audioPool[i]); } } function applySettingsToAudio(self, audio) { audio.volume = self.volume; audio.preload = self.preload; audio.playbackRate = self.playbackRate; audio.defaultPlaybackRate = self.playbackRate; } function progressHooks(self) { var audio = self.audioPool[0]; audio.addEventListener("progress", onProgress, false); audio.load(); var complete = false; function onProgress() { try { // sometimes I get Index Size Error: DOM Exception 1 self.buffered = audio.buffered.end(audio.buffered.length - 1); } catch (err) { return; } self.duration = audio.duration; self.emit('progress'); if (! complete && self.buffered >= self.duration) { complete = true; self.emit('ready'); } } } function audioReadyToPlay(audio) { return audio.currentTime === 0 || audio.currentTime === audio.duration; } },{"./resources":"/home/josh/dev/vapor/node_modules/chem/lib/resources.js","events":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/events/events.js","util":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/util/util.js"}],"/home/josh/dev/vapor/node_modules/chem/lib/sprite.js":[function(require,module,exports){ var Vec2d = require('vec2d').Vec2d; var util = require('util'); var EventEmitter = require('events').EventEmitter; var resources = require('./resources'); module.exports = Sprite; util.inherits(Sprite, EventEmitter); function Sprite(animation, params) { EventEmitter.call(this); params = params || {}; // defaults this.pos = params.pos == null ? new Vec2d(0, 0) : params.pos; this.scale = params.scale == null ? new Vec2d(1, 1) : params.scale; this.zOrder = params.zOrder == null ? 0 : params.zOrder; this.batch = params.batch; this.rotation = params.rotation == null ? 0 : params.rotation; this.alpha = params.alpha == null ? 1 : params.alpha; setUpListeners(this); this.setAnimation(animation); this.setLoop(params.loop); this.setVisible(params.visible == null ? true : params.visible); this.setFrameIndex(params.frameIndex == null ? 0 : params.frameIndex); } Sprite.prototype.draw = function(context) { var frame = this.animation.frames[this.getFrameIndex()]; context.save(); context.translate(this.pos.x, this.pos.y); context.scale(this.scale.x, this.scale.y); context.rotate(this.rotation); context.globalAlpha = this.alpha; context.drawImage(this.animation.spritesheet, frame.pos.x, frame.pos.y, frame.size.x, frame.size.y, -this.animation.anchor.x, -this.animation.anchor.y, frame.size.x, frame.size.y); context.restore(); }; Sprite.prototype.setAnimation = function(animation){ this.animation = animation; this._loop = this.loop == null ? this.animation.loop : this.loop; // size of first frame, which does not take scale into account this.size = this.animation.frames[0].size; }; // takes scale and current frame into account Sprite.prototype.getSize = function(){ return this.animation.frames[this.getFrameIndex()].size.times(this.scale.applied(Math.abs)); }; // convenience Sprite.prototype.getAnchor = function(){ return this.animation.anchor.times(this.scale.applied(Math.abs)); }; Sprite.prototype.getTopLeft = function(){ return this.pos.minus(this.getAnchor()); }; Sprite.prototype.getBottomRight = function(){ return this.getTopLeft().plus(this.getSize()); }; Sprite.prototype.getTop = function(){ return this.getTopLeft().y; }; Sprite.prototype.getLeft = function(){ return this.getTopLeft().x; }; Sprite.prototype.getBottom = function(){ return this.getBottomRight().y; }; Sprite.prototype.getRight = function(){ return this.getBottomRight().x; }; Sprite.prototype.setLeft = function(x){ this.pos.x = x + this.animation.anchor.x; }; Sprite.prototype.setRight = function(x){ this.pos.x = x - this.animation.anchor.x; }; Sprite.prototype.setTop = function(y){ this.pos.y = y + this.animation.anchor.y; }; Sprite.prototype.setBottom = function(y){ this.pos.y = y - this.animation.anchor.y; }; Sprite.prototype.isTouching = function(sprite){ var a_tl = this.getTopLeft(); var a_br = this.getBottomRight(); var b_tl = sprite.getTopLeft(); var b_br = sprite.getBottomRight(); var notTouching = a_tl.x >= b_br.x || a_br.x <= b_tl.x || a_tl.y >= b_br.y || a_br.y <= b_tl.y; return !notTouching; }; Sprite.prototype.hitTest = function(pt) { var tl = this.getTopLeft(); var br = this.getBottomRight(); return pt.x >= tl.x && pt.y >= tl.y && pt.x < br.x && pt.y < br.y; }; Sprite.prototype.setVisible = function(visible){ this.visible = visible; if (this.batch == null) { return; } if (this.visible) { this.batch.add(this); } else { this.batch.remove(this); } }; Sprite.prototype.setZOrder = function(zOrder){ if (this.batch != null) { this.batch.remove(this); this.zOrder = zOrder; this.batch.add(this); } else { this.zOrder = zOrder; } }; Sprite.prototype.setFrameIndex = function(frameIndex){ var secondsPassed = frameIndex * this.animation.delay; var date = new Date(); date.setMilliseconds(date.getMilliseconds() - secondsPassed * 1000); this.setAnimationStartDate(date); }; Sprite.prototype.setLoop = function(loop){ this.loop = loop; // this is the actual value we'll use to check if we're going to loop. this._loop = this.loop == null ? this.animation.loop : this.loop; setUpInterval(this); }; Sprite.prototype.setAnimationStartDate = function(animationStartDate){ this.animationStartDate = animationStartDate; setUpInterval(this); }; Sprite.prototype.getFrameIndex = function(){ var now = new Date(); var totalTime = (now - this.animationStartDate) / 1000; if (this._loop) { return Math.floor((totalTime % this.animation.duration) / this.animation.delay); } else { var timeElapsedFrame = Math.floor(totalTime / this.animation.delay); var lastFrame = this.animation.frames.length - 1; return Math.min(timeElapsedFrame, lastFrame); } }; Sprite.prototype['delete'] = function(){ if (this.interval) this.interval(); this.removeAllListeners(); if (this.batch) this.batch.remove(this); this.batch = null; }; function setUpInterval(self) { if (self.interval) self.interval(); self.interval = null; if (self.animationEndListenCount === 0) return; var _schedule = self._loop ? schedule : wait; var now = new Date(); var timeSinceStart = (now - self.animationStartDate) / 1000; var duration = self.animation.duration - timeSinceStart; self.interval = _schedule(duration, function(){ return self.emit('animationend'); }); } function wait(sec, cb) { var interval = setTimeout(cb, sec * 1000); return function(){ clearTimeout(interval); }; } function schedule(sec, cb) { var interval = setInterval(cb, sec * 1000); return function(){ clearInterval(interval); }; } function setUpListeners(self) { self.on('newListener', function(event) { if (event === 'animationend') { self.animationEndListenCount += 1; setUpInterval(self); } }); self.on('removeListener', function(event) { if (event === 'animationend') { self.animationEndListenCount -= 1; setUpInterval(self); } }); } },{"./resources":"/home/josh/dev/vapor/node_modules/chem/lib/resources.js","events":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/events/events.js","util":"/home/josh/dev/vapor/node_modules/chem-cli/node_modules/browserify/node_modules/util/util.js","vec2d":"/home/josh/dev/vapor/node_modules/chem/node_modules/vec2d/index.js"}],"/home/josh/dev/vapor/node_modules/chem/node_modules/pend/index.js":[function(require,module,exports){ module.exports = Pend; function Pend() { this.pending = 0; this.max = Infinity; this.listeners = []; this.waiting = []; this.error = null; } Pend.prototype.go = function(fn) { if (this.pending < this.max) { pendGo(this, fn); } else { this.waiting.push(fn); } }; Pend.prototype.wait = function(cb) { if (this.pending === 0) { cb(this.error); } else { this.listeners.push(cb); } }; function pendGo(self, fn) { self.pending += 1; var called = false; fn(onCb); function onCb(err) { if (called) throw new Error("callback called twice"); called = true; self.error = self.error || err; self.pending -= 1; if (self.waiting.length > 0 && self.pending < self.max) { pendGo(self, self.waiting.shift()); } else if (self.pending === 0) { var listeners = self.listeners; self.listeners = []; listeners.forEach(cbListener); } } function cbListener(listener) { listener(self.error); } } },{}],"/home/josh/dev/vapor/node_modules/chem/node_modules/vec2d/index.js":[function(require,module,exports){ module.exports = v; v.Vec2d = Vec2d; v.unit = unitFromAngle; Vec2d.unit = unitFromAngle; var re = /\((-?[.\d]+), (-?[.\d]+)\)/; function Vec2d(x, y) { this.x = x; this.y = y; } function unitFromAngle(angle) { return new Vec2d(Math.cos(angle), Math.sin(angle)); } function v(xOrPair, y) { if (xOrPair == null) { return new Vec2d(0, 0, 0); } else if (Array.isArray(xOrPair)) { return new Vec2d(parseFloat(xOrPair[0], 10), parseFloat(xOrPair[1], 10)); } else if (typeof xOrPair === 'object') { return new Vec2d(parseFloat(xOrPair.x, 10), parseFloat(xOrPair.y, 10)); } else if (typeof xOrPair === 'string' && y == null) { var match = xOrPair.match(re); if (match) { return new Vec2d(parseFloat(match[1], 10), parseFloat(match[2], 10)); } else { throw new Error("Vec2d: cannot parse: " + xOrPair); } } else { return new Vec2d(parseFloat(xOrPair, 10), parseFloat(y, 10)); } } Vec2d.prototype.offset = function(dx, dy) { return new Vec2d(this.x + dx, this.y + dy); }; Vec2d.prototype.add = function(other) { this.x += other.x; this.y += other.y; return this; }; Vec2d.prototype.sub = function(other) { this.x -= other.x; this.y -= other.y; return this; }; Vec2d.prototype.plus = function(other) { return this.clone().add(other); }; Vec2d.prototype.minus = function(other) { return this.clone().sub(other); }; Vec2d.prototype.neg = function() { this.x = -this.x; this.y = -this.y; return this; }; Vec2d.prototype.mult = function(other) { this.x *= other.x; this.y *= other.y; return this; }; Vec2d.prototype.times = function(other) { return this.clone().mult(other); }; Vec2d.prototype.div = function(other) { this.x /= other.x; this.y /= other.y; return this; }; Vec2d.prototype.divBy = function(other) { return this.clone().div(other); }; Vec2d.prototype.scale = function(scalar) { this.x *= scalar; this.y *= scalar; return this; }; Vec2d.prototype.scaled = function(scalar) { return this.clone().scale(scalar); }; Vec2d.prototype.clone = function() { return new Vec2d(this.x, this.y); }; Vec2d.prototype.apply = function(func) { this.x = func(this.x); this.y = func(this.y); return this; }; Vec2d.prototype.applied = function(func) { return this.clone().apply(func); }; Vec2d.prototype.distanceSqrd = function(other) { var dx = other.x - this.x; var dy = other.y - this.y; return dx * dx + dy * dy; }; Vec2d.prototype.distance = function(other) { return Math.sqrt(this.distanceSqrd(other)); }; Vec2d.prototype.equals = function(other) { return this.x === other.x && this.y === other.y; }; Vec2d.prototype.toString = function() { return "(" + this.x + ", " + this.y + ")"; }; Vec2d.prototype.lengthSqrd = function() { return this.x * this.x + this.y * this.y; }; Vec2d.prototype.length = function() { return Math.sqrt(this.lengthSqrd()); }; Vec2d.prototype.angle = function() { if (this.lengthSqrd() === 0) { return 0; } else { return Math.atan2(this.y, this.x); } }; Vec2d.prototype.normalize = function() { var length = this.length(); if (length === 0) { return this; } else { return this.scale(1 / length); } }; Vec2d.prototype.normalized = function() { return this.clone().normalize(); }; Vec2d.prototype.boundMin = function(other) { if (this.x < other.x) this.x = other.x; if (this.y < other.y) this.y = other.y; return this; }; Vec2d.prototype.boundMax = function(other) { if (this.x > other.x) this.x = other.x; if (this.y > other.y) this.y = other.y; return this; }; Vec2d.prototype.floor = function() { return this.apply(Math.floor); }; Vec2d.prototype.floored = function() { return this.applied(Math.floor); }; Vec2d.prototype.ceil = function() { return this.apply(Math.ceil); }; Vec2d.prototype.ceiled = function() { return this.applied(Math.ceil); }; Vec2d.prototype.project = function(other) { this.scale(this.dot(other) / other.lengthSqrd()); return this; }; Vec2d.prototype.dot = function(other) { return this.x * other.x + this.y * other.y; }; Vec2d.prototype.rotate = function(direction) { var newX = this.x * direction.x - this.y * direction.y; this.y = this.x * direction.y + this.y * direction.x; this.x = newX; return this; }; Vec2d.prototype.rotated = function(direction) { return this.clone().rotate(direction); }; // reflect about axis originating from origin Vec2d.prototype.reflect = function(axis) { return this.reflectAboutLine(new Vec2d(0, 0), axis); }; Vec2d.prototype.reflectAboutLine = function(linePt1, linePt2) { var normal = new Vec2d( linePt2.x - linePt1.x, linePt2.y - linePt1.x); var temp = normal.x; normal.x = -normal.y; normal.y = temp; normal.normalize(); var dot2 = 2 * this.dot(normal); this.x -= dot2 * normal.x; this.y -= dot2 * normal.y; return this; }; Vec2d.prototype.set = Vec2d; },{}],"/home/josh/dev/vapor/public/bootstrap.js":[function(require,module,exports){ // This code is auto-generated based on your chemfile. // `exports.autoBootstrap = false` to disable this file. var chem = require('chem'); chem.resources.bootstrap(); },{"chem":"/home/josh/dev/vapor/node_modules/chem/index.js"}],"/home/josh/dev/vapor/src/main.js":[function(require,module,exports){ (function() { // TODO: use require return value instead of global variables. require("./map"); require("./man"); window.Chem = require("chem"); // TODO: update chem useage to new naming conventions Chem.Vec2d = Chem.vec2d; Chem.Button = Chem.button; var b2Vec2 = Box2D.Common.Math.b2Vec2; var b2BodyDef = Box2D.Dynamics.b2BodyDef; var b2Body = Box2D.Dynamics.b2Body; var b2FixtureDef = Box2D.Dynamics.b2FixtureDef; var b2RevoluteJointDef = Box2D.Dynamics.Joints.b2RevoluteJointDef; var b2World = Box2D.Dynamics.b2World; var b2DebugDraw = Box2D.Dynamics.b2DebugDraw; var b2AABB = Box2D.Collision.b2AABB; var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; var b2CircleShape = Box2D.Collision.Shapes.b2CircleShape; function query_aabb(world, aabb, callback) { var actual_callback; actual_callback = function(fixture) { return !callback(fixture); }; return world.QueryAABB(callback, aabb); } function sign(n) { if (n < 0) return -1; if (n > 0) return 1; return 0; } function aabb_contains_point(aabb, point) { return (aabb.lowerBound.x <= point.x && point.x < aabb.upperBound.x && aabb.lowerBound.y <= point.y && point.y < aabb.upperBound.y); } function make_aabb(x1, y1, x2, y2) { var result = new b2AABB(); result.lowerBound.x = x1; result.lowerBound.y = y1; result.upperBound.x = x2; result.upperBound.y = y2; return result; }; var map = null; (function() { var waiting_events = []; function create_wait_condition(name) { var index = waiting_events.length; waiting_events.push(name); return function() { waiting_events[index] = null; var done = true; var list = document.getElementById("loading-list"); list.innerHTML = ""; for (var i = 0; i < waiting_events.length; i++) { var event_name = waiting_events[i]; if (event_name == null) continue; var item = document.createElement("li"); item.innerHTML = event_name; list.appendChild(item); done = false; } if (done) { document.getElementById("loading").setAttribute("style", "display:none;"); init(); } }; } Chem.resources.on("ready", create_wait_condition("sprites")); var map_is_ready = create_wait_condition("map"); var request = new XMLHttpRequest(); request.onreadystatechange = function() { if (!(request.readyState === 4 && request.status === 200)) { return; } map = Map.parse(request.responseText, create_wait_condition); map_is_ready(); }; request.open("GET", "map.tmx", true); request.send(); })(); function init() { var canvas = document.getElementById("game"); var canvas_center = new Chem.Vec2d(canvas.getAttribute("width") / 2, canvas.getAttribute("height") / 2); var engine = new Chem.Engine(canvas); var standard_gravity = new b2Vec2(0, 30); engine.buttonCaptureExceptions[Chem.button.KeyCtrl] = true; engine.buttonCaptureExceptions[Chem.button.KeyAlt] = true; for (var i = 1; i <= 12; i++) { engine.buttonCaptureExceptions[Chem.button["KeyF" + i]] = true; } var sounds = { bchs: new Chem.Sound("sfx/bchs.ogg") }; var buttons = { left: Chem.Button.KeyA, right: Chem.Button.KeyD, crouch: Chem.Button.KeyS, stand: Chem.Button.KeyW, jump: Chem.Button.KeyK, pew: Chem.Button.KeyJ, debug: Chem.Button.KeyGrave }; var view_scale = map.scale; var world = null; var gravity_zones = []; var debug_drawer = null; var debug_drawing = false; var man = new Man(); window._debug_man = man; (function() { world = new b2World(new b2Vec2(), true); debug_drawer = new b2DebugDraw(); debug_drawer.SetSprite(canvas.getContext("2d")); debug_drawer.SetDrawScale(view_scale); debug_drawer.SetFillAlpha(0.5); debug_drawer.SetLineThickness(1); debug_drawer.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit); world.SetDebugDraw(debug_drawer); var fixture_def = new b2FixtureDef(); fixture_def.density = 1.0; fixture_def.friction = 0.5; fixture_def.restitution = 0; fixture_def.shape = new b2PolygonShape(); var stretch_floor_start = null; var stretch_floor_end = null; function flush_strech_floor() { var body_def; if (stretch_floor_start == null) { return; } body_def = new b2BodyDef(); body_def.type = b2Body.b2_staticBody; body_def.position.x = (stretch_floor_start.x + stretch_floor_end.x) / 2; body_def.position.y = (stretch_floor_start.y + stretch_floor_end.y) / 2; fixture_def.shape.SetAsBox((stretch_floor_end.x - stretch_floor_start.x) / 2, (stretch_floor_end.y - stretch_floor_start.y) / 2); world.CreateBody(body_def).CreateFixture(fixture_def); return stretch_floor_start = null; } for (var y = 0; y < map.physics_layer.length; y++) { var row = map.physics_layer[y]; for (var x = 0; x < row.length; x++) { var value = row[x]; if (value !== 0) { if (stretch_floor_start == null) { stretch_floor_start = new b2Vec2(x, y); } stretch_floor_end = new b2Vec2(x + 1, y + 1); } else { flush_strech_floor(); } } flush_strech_floor(); } for (var i = 0; i < map.objects.length; i++) { var object = map.objects[i]; var gravity_scale = parseFloat(object.properties.gravity_scale); var priority = parseFloat(object.properties.priority); if (!isNaN(gravity_scale) && !isNaN(priority)) { gravity_zones.push({ scale: gravity_scale, priority: priority, aabb: make_aabb(object.x / map.scale, object.y / map.scale, (object.x + object.width) / map.scale, (object.y + object.height) / map.scale) }); } } gravity_zones.sort(function(a, b){ if (a.priority < b.priority) { return -1; } else if (a.priority > b.priority) { return 1; } else { return 0; } }); var body_def = new b2BodyDef(); body_def.type = b2Body.b2_dynamicBody; body_def.position.x = 40; body_def.position.y = 43; body_def.fixedRotation = true; man.body = world.CreateBody(body_def); man.body.SetUserData(man.standing_sprite); var torso_def = new b2FixtureDef(); torso_def.density = 1.0; torso_def.friction = 0; torso_def.shape = man.get_torso_shape(); man.torso_fixture = man.body.CreateFixture(torso_def); var ground_sensor_def = new b2FixtureDef(); ground_sensor_def.density = 0; ground_sensor_def.isSensor = true; ground_sensor_def.shape = man.get_ground_sensor_shape(); man.ground_sensor = man.body.CreateFixture(ground_sensor_def); var ground_fringe_sensor_def = new b2FixtureDef(); ground_fringe_sensor_def.density = 0; ground_fringe_sensor_def.isSensor = true; ground_fringe_sensor_def.shape = man.get_ground_fringe_sensor_shape(); man.ground_fringe_sensor = man.body.CreateFixture(ground_fringe_sensor_def); man.mass = man.body.GetMass(); })(); function is_sensor_in_contact(sensor) { var contact_edge = man.body.GetContactList(); while (contact_edge) { var contact = contact_edge.contact; if (contact.IsTouching()) { if (contact.GetFixtureA() === sensor || contact.GetFixtureB() === sensor) { return true; } } contact_edge = contact_edge.next; } return false; } engine.on('update', function(dt, dx) { if (engine.buttonJustPressed(buttons.debug)) { debug_drawing = !debug_drawing; } var was_grounded = man.is_grounded; man.is_grounded = is_sensor_in_contact(man.ground_sensor); var is_fringe_contact = is_sensor_in_contact(man.ground_fringe_sensor); // input intentions var vertical_intention = 0; if (engine.buttonJustPressed(buttons.crouch)) vertical_intention--; if (engine.buttonJustPressed(buttons.stand)) vertical_intention++; var new_posture = man.posture + vertical_intention; if (new_posture < 0) new_posture = 0; if (new_posture > Man.POSTURE_STANDING) new_posture = Man.POSTURE_STANDING; var horizontal_intention = 0; if (engine.buttonState(buttons.left)) horizontal_intention--; if (engine.buttonState(buttons.right)) horizontal_intention++; var jump_now = engine.buttonJustPressed(buttons.jump); var keep_jumping = engine.buttonState(buttons.jump); if (jump_now && new_posture === Man.POSTURE_CRAWLING) { // can't jump while crawling, but we'll get you one step closer. jump_now = false; new_posture = Man.POSTURE_CROUCHING; } else if (jump_now && new_posture === Man.POSTURE_CROUCHING) { // extend your legs to jump new_posture = Man.POSTURE_STANDING; } if (man.is_grounded && new_posture === Man.POSTURE_CROUCHING && horizontal_intention !== 0) { // can't walk while crouching, so stand up new_posture = Man.POSTURE_STANDING; } if (new_posture === Man.POSTURE_CRAWLING && !man.is_grounded && is_fringe_contact) { // fall off ledge new_posture = Man.POSTURE_CROUCHING; } var old_posture = man.posture; var old_half_height = man.get_half_height(); man.posture = new_posture; if (old_posture !== man.posture) { man.torso_fixture.m_shape = man.get_torso_shape(); man.update_ground_sensor_shape(); if (man.is_grounded) { // anchor your feet to the ground while you change posture var position = man.body.GetPosition().Copy(); position.y += man.gravity_direction * (old_half_height - man.get_half_height()); man.body.SetPosition(position); } } var man_velocity = man.body.GetLinearVelocity(); var max_speed = 10; if (man.is_grounded) { if (man.posture === Man.POSTURE_CROUCHING) max_speed = 0; if (man.posture === Man.POSTURE_CRAWLING) max_speed = 5; } var magic_max_velocity = horizontal_intention * max_speed; var acceleration = max_speed / 5; if (horizontal_intention * man_velocity.x < horizontal_intention * magic_max_velocity) { // let's go man.body.ApplyImpulse(new b2Vec2(acceleration * horizontal_intention, 0), man.body.GetPosition()); } else if (horizontal_intention !== 0) { // you're running too fast man_velocity = man_velocity.Copy(); man_velocity.x = magic_max_velocity; man.body.SetLinearVelocity(man_velocity); } if (man.is_grounded && horizontal_intention === 0) { // please stop if (!was_grounded) { // land abruptly man.body.SetLinearVelocity({ x: 0, y: 0 }); } else { // slide to a stop var direction = sign(man_velocity.x); if (direction !== 0) { man.body.ApplyImpulse(new b2Vec2(-2.0 * direction, 0), man.body.GetPosition()); var new_direction = sign(man_velocity.x); if (new_direction !== 0 && new_direction !== direction) { man.body.SetLinearVelocity({ x: 0, y: 0 }); } } } } var gravity = standard_gravity.Copy(); for (var i = gravity_zones.length - 1; i >= 0; i--) { var gravity_zone = gravity_zones[i]; var scale = gravity_zone.scale; var aabb = gravity_zone.aabb; if (aabb_contains_point(aabb, man.body.GetPosition())) { gravity.Multiply(scale); break; } } gravity.Multiply(man.body.GetMass()); man.body.ApplyForce(gravity, man.body.GetPosition()); var old_gravity_direction = man.gravity_direction; var new_gravity_direction = sign(gravity.y); if (new_gravity_direction === 0) { // i thought this wouldn't happen new_gravity_direction = man.gravity_direction; } if (man.gravity_direction !== new_gravity_direction) { man.is_jumping = false; man.gravity_direction = new_gravity_direction; man.update_ground_sensor_shape(); } // jomp if (man.is_grounded && jump_now) { var jump_impulse = man.jump_impulse.Copy(); jump_impulse.y *= new_gravity_direction; man.body.ApplyImpulse(jump_impulse, man.body.GetPosition()); man.is_jumping = true; } else if (man.is_jumping) { var jump_stop = new_gravity_direction * man.jump_stop; if (new_gravity_direction * man_velocity.y < new_gravity_direction * jump_stop) { if (!keep_jumping) { man_velocity = man_velocity.Copy(); man_velocity.y = jump_stop; man.body.SetLinearVelocity(man_velocity); man.is_jumping = false; } } else { man.is_jumping = false; } } // pew pew if (engine.buttonJustPressed(buttons.pew)) { sounds.bchs.play(); } // sprites if (horizontal_intention !== 0) man.facing_direction = horizontal_intention; var sprite = man.get_sprite(); sprite.scale.x = man.facing_direction; sprite.scale.y = man.gravity_direction; man.body.SetUserData(sprite); // physics world.Step(dt, 10, 10); world.ClearForces(); }); function world_to_canvas(it) { var in_pixels; in_pixels = new Chem.Vec2d(it).scale(view_scale); in_pixels.floor(); return in_pixels; } function get_view_aabb() { var position = man.body.GetPosition(); return make_aabb(position.x - canvas_center.x / view_scale, position.y - canvas_center.y / view_scale, position.x + canvas_center.x / view_scale, position.y + canvas_center.y / view_scale); } var fpsLabel = engine.createFpsLabel(); engine.on('draw', function(context) { context.fillStyle = '#000000'; context.fillRect(0, 0, engine.size.x, engine.size.y); context.save(); var center = world_to_canvas(new Chem.Vec2d(man.body.GetPosition())).sub(canvas_center); context.translate(-center.x, -center.y); if (debug_drawing) { world.DrawDebugData(); } else { var view_aabb = get_view_aabb(); map.draw_tiles(context, view_aabb); var sprite_batch = new Chem.Batch(); query_aabb(world, view_aabb, function(fixture) { var body = fixture.GetBody(); var sprite = body.GetUserData(); if (sprite instanceof Chem.Sprite) { sprite.pos = world_to_canvas(body.GetPosition()); sprite_batch.add(sprite); } return body = body.m_next; }); sprite_batch.draw(context); } context.restore(); context.fillStyle = '#ffffff'; fpsLabel.draw(context); context.fillText("grounded = " + man.is_grounded, 100, canvas_center.y * 2); return context.fillText("jumping = " + man.is_jumping, 200, canvas_center.y * 2); }); engine.start(); return canvas.focus(); } })(); },{"./man":"/home/josh/dev/vapor/src/man.js","./map":"/home/josh/dev/vapor/src/map.js","chem":"/home/josh/dev/vapor/node_modules/chem/index.js"}],"/home/josh/dev/vapor/src/man.js":[function(require,module,exports){ (function() { var b2Vec2 = Box2D.Common.Math.b2Vec2; var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape; var b2MassData = Box2D.Collision.Shapes.b2MassData; window.Man = Man; function Man() { this.standing_sprite = new Chem.Sprite(Chem.resources.animations.man_stand, {z_order:1}); this.crouching_sprite = new Chem.Sprite(Chem.resources.animations.man_crouch, {z_order:1}); this.crawling_sprite = new Chem.Sprite(Chem.resources.animations.man_crawl, {z_order:1}); this.body = null; this.mass = null; this.ground_sensor = null; this.ground_fringe_sensor = null; this.torso_fixture = null; this.is_grounded = null; this.posture = Man.POSTURE_STANDING; this.is_jumping = false; this.gravity_direction = 1; this.facing_direction = 1; return this; } Man.POSTURE_STANDING = 2; Man.POSTURE_CROUCHING = 1; Man.POSTURE_CRAWLING = 0; Man.prototype.standing_half_width = 0.8 / 2; Man.prototype.crawling_half_width = 91/32 / 2; Man.prototype.standing_half_height = 2.6 / 2; Man.prototype.crouching_half_height = 2.0 / 2; Man.prototype.crawling_half_height = 27/32 / 2; Man.prototype.ground_sensor_height = 0.05; Man.prototype.jump_impulse = new b2Vec2(0, -39); Man.prototype.jump_stop = -5; Man.prototype.get_half_height = function() { if (this.posture === Man.POSTURE_STANDING) return this.standing_half_height; if (this.posture === Man.POSTURE_CROUCHING) return this.crouching_half_height; if (this.posture === Man.POSTURE_CRAWLING) return this.crawling_half_height; throw asdf; }; Man.prototype.get_half_width = function() { if (this.posture === Man.POSTURE_STANDING) return this.standing_half_width; if (this.posture === Man.POSTURE_CROUCHING) return this.standing_half_width; if (this.posture === Man.POSTURE_CRAWLING) return this.crawling_half_width; throw asdf; }; Man.prototype.get_sprite = function() { if (this.posture === Man.POSTURE_STANDING) return this.standing_sprite; if (this.posture === Man.POSTURE_CROUCHING) return this.crouching_sprite; if (this.posture === Man.POSTURE_CRAWLING) return this.crawling_sprite; throw asdf; }; Man.prototype.get_torso_shape = function() { return b2PolygonShape.AsBox(this.get_half_width(), this.get_half_height()); }; Man.prototype.get_ground_sensor_shape_with_half_width = function(half_width) { var center = new b2Vec2(0, this.gravity_direction * this.get_half_height()); return b2PolygonShape.AsOrientedBox(half_width, this.ground_sensor_height, center); }; Man.prototype.get_ground_sensor_shape = function() { return this.get_ground_sensor_shape_with_half_width(this.standing_half_width * 0.95); }; Man.prototype.get_ground_fringe_sensor_shape = function() { return this.get_ground_sensor_shape_with_half_width(this.get_half_width() * 0.995); }; Man.prototype.reset_mass = function() { this.body.SetAwake(true); this.body.ResetMassData(); var mass_data = new b2MassData(); this.body.GetMassData(mass_data); mass_data.mass = this.mass; return this.body.SetMassData(mass_data); }; Man.prototype.update_ground_sensor_shape = function() { this.ground_sensor.m_shape = this.get_ground_sensor_shape(); this.ground_fringe_sensor.m_shape = this.get_ground_fringe_sensor_shape(); this.reset_mass(); }; })(); },{}],"/home/josh/dev/vapor/src/map.js":[function(require,module,exports){ (function() { var from_base64 = atob; var flip_horizontal_flag = 0x80000000; var flip_vertical_flag = 0x40000000; var flip_diagonal_flag = 0x20000000; var imageid_mask = 0x1fffffff; window.Map = Map; function Map() { this.tilesets = []; this.layers = []; this.objects = []; } Map.prototype.tile = function(layer, x, y) { var row = this.layers[layer][y]; if (row == null) return 0; var value = row[x]; if (value == null) return 0; return value; }; Map.prototype.draw_tiles = function(context, view_aabb) { var minX = Math.floor(view_aabb.lowerBound.x); var minY = Math.floor(view_aabb.lowerBound.y); var maxX = Math.ceil(view_aabb.upperBound.x); var maxY = Math.ceil(view_aabb.upperBound.y); for (var layer_index = 0; layer_index < this.layers.length; layer_index++) { for (var y = minY; y <= maxY; y++) { for (var x = minX; x <= maxX; x++) { this.draw_tile(context, layer_index, x, y); } } } }; // TODO: silly var non_wall_image_ids = [0, 17, 18]; window._all_image_ids = []; Map.prototype.draw_tile = function(context, layer_index, x, y) { var tile = this.tile(layer_index, x, y); if (tile === 0) return; var width = 32; var height = 32; var half_width = 16; var half_height = 16; var imageid = tile & imageid_mask; if (_all_image_ids.indexOf(imageid) === -1) { _all_image_ids.push(imageid); _all_image_ids.sort(); } if (non_wall_image_ids.indexOf(imageid) === -1) { // special wall drawing logic var edge_width = 6; var neighbors = [ [ non_wall_image_ids.indexOf(this.tile(layer_index, x - 1, y - 1)) === -1, non_wall_image_ids.indexOf(this.tile(layer_index, x + 0, y - 1)) === -1, non_wall_image_ids.indexOf(this.tile(layer_index, x + 1, y - 1)) === -1, ], [ non_wall_image_ids.indexOf(this.tile(layer_index, x - 1, y + 0)) === -1, true, non_wall_image_ids.indexOf(this.tile(layer_index, x + 1, y + 0)) === -1, ], [ non_wall_image_ids.indexOf(this.tile(layer_index, x - 1, y + 1)) === -1, non_wall_image_ids.indexOf(this.tile(layer_index, x + 0, y + 1)) === -1, non_wall_image_ids.indexOf(this.tile(layer_index, x + 1, y + 1)) === -1, ] ]; context.save(); context.translate(x * this.scale + half_width, y * this.scale + half_height); context.fillStyle = "#000080"; context.fillRect(-half_width, -half_height, width, height); context.fillStyle = "#0000ff"; if (!neighbors[0][0] || !neighbors[1][0] || !neighbors[0][1]) { context.fillRect(-half_width, -half_height, edge_width, edge_width); } if (!neighbors[2][0] || !neighbors[1][0] || !neighbors[2][1]) { context.fillRect(-half_width, half_height - edge_width, edge_width, edge_width); } if (!neighbors[0][2] || !neighbors[1][2] || !neighbors[0][1]) { context.fillRect(half_width - edge_width, -half_height, edge_width, edge_width); } if (!neighbors[2][2] || !neighbors[1][2] || !neighbors[2][1]) { context.fillRect(half_width - edge_width, half_height - edge_width, edge_width, edge_width); } if (!neighbors[0][1]) { context.fillRect(-(half_width - edge_width), -half_width, 2 * (half_width - edge_width), edge_width); } if (!neighbors[2][1]) { context.fillRect(-(half_width - edge_width), half_width - edge_width, 2 * (half_width - edge_width), edge_width); } if (!neighbors[1][0]) { context.fillRect(-half_width, -(half_width - edge_width), edge_width, 2 * (half_width - edge_width)); } if (!neighbors[1][2]) { context.fillRect(half_width - edge_width, -(half_width - edge_width), edge_width, 2 * (half_width - edge_width)); } context.restore(); } else { var flip_horizontal = !!(tile & flip_horizontal_flag); var flip_vertical = !!(tile & flip_vertical_flag); var flip_diagonal = !!(tile & flip_diagonal_flag); var rotation = 0; if (flip_diagonal) { rotation += Math.PI / 2; flip_horizontal = !flip_horizontal; } var tileset; var image_bounds; for (var i = 0; i < this.tilesets.length; i++) { tileset = this.tilesets[i]; image_bounds = tileset.image_bounds(imageid); if (image_bounds != null) { break; } } context.save(); context.translate(x * this.scale + half_width, y * this.scale + half_height); context.scale(flip_horizontal ? -1 : 1, flip_vertical ? -1 : 1); context.rotate(rotation); context.drawImage(tileset.image, image_bounds.x, image_bounds.y, image_bounds.width, image_bounds.height, -half_width, -half_height, image_bounds.width, image_bounds.height); context.restore(); } }; function Tileset() { // TODO: assign my properties in here so i know what they are by looking at this function } Tileset.prototype.image_bounds = function(imageid) { var local_id = imageid - this.first_gid; if (local_id < 0) { return null; } var column_count = this.width / this.tilewidth; var row = Math.floor(local_id / column_count); var row_count = this.height / this.tileheight; if (row >= row_count) { return null; } var column = local_id % column_count; return { x: column * this.tilewidth, y: row * this.tileheight, width: this.tilewidth, height: this.tileheight }; }; Map.parse = function(text, create_wait_condition) { var map = new Map(); var xml = new DOMParser().parseFromString(text, "text/xml"); var root = xml.getElementsByTagName("map")[0]; map.scale = parseInt(root.getAttribute("tilewidth")); var tileset_elements = root.getElementsByTagName("tileset"); for (var i = 0; i < tileset_elements.length; i++) { var tileset_element = tileset_elements[i]; var tileset = new Tileset(); tileset.first_gid = parseInt(tileset_element.getAttribute("firstgid")); tileset.tilewidth = parseInt(tileset_element.getAttribute("tilewidth")); tileset.tileheight = parseInt(tileset_element.getAttribute("tileheight")); var image_element = tileset_element.getElementsByTagName("image")[0]; tileset.image = new Image(); tileset.image.src = image_element.getAttribute("source"); tileset.image.onload = create_wait_condition("tileset"); tileset.width = parseInt(image_element.getAttribute("width")); tileset.height = parseInt(image_element.getAttribute("height")); map.tilesets.push(tileset); } var layer_elements = root.getElementsByTagName("layer"); for (var i = 0; i < layer_elements.length; i++) { var layer_element = layer_elements[i]; var name = layer_element.getAttribute("name"); var width = parseInt(layer_element.getAttribute("width")); var height = parseInt(layer_element.getAttribute("height")); var data_element = layer_element.getElementsByTagName("data")[0]; if (data_element.getAttribute("compression")) { alert("can't decompress map. store maps with base64 uncompressed data. sorry."); return; } var data_string = from_base64(data_element.textContent.trim()); var index = 0; var layer = []; for (var y = 0; y < height; y++) { var row = []; for (var x = 0; x < width; x++) { var tile_value = data_string.charCodeAt(index++); tile_value |= data_string.charCodeAt(index++) << 8; tile_value |= data_string.charCodeAt(index++) << 16; tile_value |= data_string.charCodeAt(index++) << 24; row.push(tile_value); } layer.push(row); } map.layers.push(layer); if (name === "physics") { map.physics_layer = layer; } } var objectgroup_elements = root.getElementsByTagName("objectgroup"); for (var i = 0; i < objectgroup_elements.length; i++) { var objectgroup_element = objectgroup_elements[i]; var object_elements = objectgroup_element.getElementsByTagName("object"); for (var j = 0; j < object_elements.length; j++) { var object_element = object_elements[j]; var properties = {}; var properties_elements = object_element.getElementsByTagName("properties"); for (var k = 0; k < properties_elements.length; k++) { var properties_element = properties_elements[k]; var property_elements = properties_element.getElementsByTagName("property"); for (var l = 0; l < property_elements.length; l++) { var property_element = property_elements[l]; properties[property_element.getAttribute("name")] = property_element.getAttribute("value"); } } map.objects.push({ x: parseInt(object_element.getAttribute("x")), y: parseInt(object_element.getAttribute("y")), width: parseInt(object_element.getAttribute("width")), height: parseInt(object_element.getAttribute("height")), properties: properties }); } } return map; }; })(); },{}]},{},["/home/josh/dev/vapor/src/main.js","/home/josh/dev/vapor/public/bootstrap.js"]);