Browse files

Added inital talk interface

  • Loading branch information...
1 parent e258031 commit 36e2a9acf7d750f5205a34ff36bd897c5cdaeb54 @robrighter committed Jan 7, 2012
Showing with 1,682 additions and 8 deletions.
  1. +0 −3 .gitmodules
  2. +27 −0 static/css/style.css
  3. BIN static/images/.DS_Store
  4. +20 −4 static/js/script.js
  5. +1,634 −0 static/js/sprite.js
  6. +1 −1 views/layout.jade
View
3 .gitmodules
@@ -1,3 +0,0 @@
-[submodule "deps/sprite"]
- path = deps/sprite
- url = https://github.com/batiste/sprite.js.git
View
27 static/css/style.css
@@ -279,6 +279,7 @@ body {
#controlbox .instructions a{
color: #eee;
+ z-index: 999999999;
}
#controlbox #oauthbutt {
@@ -292,6 +293,32 @@ body {
float: left;
}
+#controlbox #talkbox {
+ border: 1px solid rgb(130,130,130);
+ width: 320px;
+ height: 15px;
+ font-size: 11px;
+ color: rgb(55,93,116);
+}
+
+#controlbox #saybutt {
+ font-size: 11px;
+ border: 1px solid rgb(130,130,130);
+ border-radius: 3px;
+ background-color: #dddddd;
+ height: 19px;
+ margin-left: 5px;
+}
+
+#controlbox #saybutt:hover {
+ background-color: #fff;
+}
+
+#controlbox .username {
+ font-size: 10px;
+ color: #444;
+}
+
View
BIN static/images/.DS_Store
Binary file not shown.
View
24 static/js/script.js
@@ -6,22 +6,27 @@ $(document).ready(function() {
var scene = sjs.Scene({w:$(window).width(), h:$(window).height(), autoPause: false});
var sps = {};
var input = sjs.Input(scene);
+ var keyPressed = function(name){
+ console.log('KEY PRESSED');
+ console.log(name);
+ }
+ window.inputer = input;
var inmotion = false;
var socket;
var requestkey = '';
//setup the oauth button
$('#oauthbutt').click(function(){
- openEasyOAuthBox('twitter',function(oauth){
- //var oauth = {user: {username: 'robrighter'} };
+ //openEasyOAuthBox('twitter',function(oauth){
+ var oauth = {user: {username: 'robrighter'} };
$.post("/ajax/initiate-character", {
handle: oauth.user.username,
image: '/images/sprites/weddingguy02.png'
}, function(data){
requestkey = data.requestkey;
});
setupTalkInterface(oauth.user.username);
- });
+ //});
});
//load up the characters
@@ -127,8 +132,19 @@ $(document).ready(function() {
function setupTalkInterface(user){
$('#controlbox').slideUp('slow', function(){
- $('#controlbox').html("<div class='username'>@"+user+"</div>"+"<input type='text' id='talkbox'><button id='#saybutt'>say it.</button>").slideDown('slow');
+ $('#controlbox').html("<form id='talkform'><span class='username'>@"+user+": </span>"+"<input type='text' id='talkbox'><button id='saybutt'>say it.</button></form>").slideDown('slow');
+ $('#talkform').submit(function(e){
+ e.preventDefault();
+ sendMessage($('#talkbox').val());
+ $('#talkbox').val('')
+
+ });
});
}
+
+ function sendMessage(texttosend){
+ console.log('Need to send this:');
+ console.log(texttosend);
+ }
});
View
1,634 static/js/sprite.js
@@ -0,0 +1,1634 @@
+/*
+Copyright (c) 2011 Batiste Bieler and contributors,
+https://github.com/batiste/sprite.js
+
+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.
+*/
+
+/*jslint bitwise: true, undef: true, white: true, maxerr: 50, indent: 4 */
+
+/* Sprite.js v1.2.0
+ *
+ * coding guideline
+ *
+ * CamelCase everywhere (I don't like it but it seems to the standard these days).
+ * Tabs have to be 4 spaces (python style).
+ * If you contribute don't forget to add your name in the AUTHORS file.
+ */
+
+(function (global) {
+
+"use strict";
+var sjs, Sprite, Scene, Layer, Ticker, Ticker_, Cycle, Input, _Input, List,
+doc = global.document,
+// number of sprites
+nb_sprite = 0,
+// number of scenes
+nb_scene = 0,
+// number of cycle
+nb_cycle = 0,
+browser_specific_runned = false,
+// global z-index
+zindex = 1;
+
+function error(msg) {
+ console.log("Sprite.js error: " + msg);
+}
+
+function warning(msg) {
+ console.log("Sprite.js warning: " + msg);
+}
+
+// math functions
+function mod(n, base) {
+ // strictly positive modulo
+ return ((n % base) + base) % base;
+}
+
+function hypo(x, y) {
+ return Math.sqrt(x * x + y * y);
+}
+
+function normalVector(vx, vy, intensity) {
+ var n = hypo(vx, vy);
+ if (n === 0) {
+ return {x: vx, y: vy};
+ }
+ if (intensity) {
+ return {x: ((vx / n) * intensity), y: ((vy / n) * intensity)};
+ }
+ return {x: vx / n, y: vy / n};
+}
+
+function lineSide(ax, ay, bx, by, cx, cy) {
+ // return true if the point C is on the right of the line (A, B)
+ var v = (bx - ax) * (cy - ay) - (by - ay) * (cx - ax);
+ if (v === 0) {
+ return null;
+ }
+ return v > 0;
+}
+
+// browser specific feature detection
+function has(el, propList) {
+ var prop = propList.shift();
+ while (prop) {
+ if (typeof el[prop] !== 'undefined') {
+ return prop;
+ }
+ prop = propList.shift();
+ }
+}
+
+function initBrowserSpecific() {
+ sjs.tproperty = has(doc.body.style, ['transform',
+ 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform']);
+ sjs.animationFrame = has(global, ['mozRequestAnimationFrame',
+ 'webkitRequestAnimationFrame', 'oRequestAnimationFrame',
+ 'msRequestAnimationFrame']);
+ browser_specific_runned = true;
+}
+
+function optionValue(options, name, default_value, type) {
+ if (options && options[name] !== undefined) {
+ if (type === 'int') {
+ return options[name] | 0;
+ }
+ return options[name];
+ }
+ return default_value;
+}
+
+function overlay(x, y, w, h) {
+ var div = doc.createElement('div'),
+ s = div.style;
+ s.top = y + 'px';
+ s.left = x + 'px';
+ s.width = w + 'px';
+ s.height = h + 'px';
+ s.color = '#fff';
+ s.zIndex = 100;
+ s.position = 'absolute';
+ s.backgroundColor = '#000';
+ s.opacity = 0.7;
+ return div;
+}
+
+Scene = function Scene(options) {
+
+ if (this.constructor !== Scene) {
+ return new Scene(options);
+ }
+
+ if (!browser_specific_runned) {
+ initBrowserSpecific();
+ }
+
+ this.autoPause = optionValue(options, 'autoPause', true);
+ // main function
+ this.main = optionValue(options, 'main', function () {});
+
+ var div = doc.createElement('div'), parent;
+ div.style.overflow = 'hidden';
+ // TODO: detect those features
+ // image-rendering: -moz-crisp-edges;
+ // ms-interpolation-mode: nearest-neighbor;
+ div.style.imageRendering = '-webkit-optimize-contrast';
+ div.style.position = 'relative';
+ div.className = 'sjs';
+ div.id = 'sjs' + nb_scene;
+ this.id = nb_scene;
+ nb_scene = nb_scene + 1;
+ parent = optionValue(options, 'parent', doc.body);
+ parent.appendChild(div);
+ this.w = optionValue(options, 'w', 480, 'int');
+ this.h = optionValue(options, 'h', 320, 'int');
+ this.dom = div;
+ this.dom.style.width = this.w + 'px';
+ this.dom.style.height = this.h + 'px';
+ this.layers = {};
+ this.ticker = null;
+ this.useCanvas = optionValue(options, "useCanvas",
+ global.location.href.indexOf('canvas') !== -1);
+
+ this.xscale = 1;
+ this.yscale = 1;
+
+ // needs to be done after this.useCanvas
+ this.Layer("default");
+ sjs.scenes.push(this);
+ return this;
+};
+
+Scene.prototype.constructor = Scene;
+
+Scene.prototype.Sprite = function SceneSprite(src, layer) {
+ // A shortcut for sjs.Sprite
+ return new Sprite(this, src, layer);
+};
+
+Scene.prototype.Layer = function SceneLayer(name, options) {
+ return new Layer(this, name, options);
+};
+
+// just for convenience
+Scene.prototype.Cycle = function SceneCycle(triplets) {
+ return new Cycle(triplets);
+};
+
+Scene.prototype.Input = function SceneInput() {
+ this.input = new Input(this);
+ return this.input;
+};
+
+Scene.prototype.scale = function SceneScale(x, y) {
+ this.xscale = x;
+ this.yscale = y;
+ this.dom.style[sjs.tproperty+"Origin"] = "0 0";
+ this.dom.style[sjs.tproperty] = "scale(" + x + "," + y + ")";
+};
+
+Scene.prototype.toString = function () {
+ return "Scene(" + String(this.id) + ")";
+};
+
+Scene.prototype.reset = function reset() {
+ var l;
+ if (this.ticker) {
+ this.ticker.pause();
+ }
+ for (l in this.layers) {
+ if (this.layers.hasOwnProperty(l)) {
+ this.layers[l].dom.parentNode.removeChild(this.layers[l].dom);
+ delete this.layers[l];
+ }
+ }
+ // remove remaining children
+ while (this.dom.childNodes.length >= 1) {
+ this.dom.removeChild(this.dom.firstChild);
+ }
+ this.layers = {};
+ this.Layer("default");
+};
+
+Scene.prototype.Ticker = function Ticker(paint, options) {
+ if (this.ticker) {
+ this.ticker.pause();
+ this.ticker.paint = function () {};
+ }
+ this.ticker = new Ticker_(this, paint, options);
+ return this.ticker;
+};
+
+Scene.prototype.dialogEvent = function dialogEvent(div, el, event, callback) {
+ var that = this, ev;
+ ev = function () {
+ el.removeEventListener("click", event, false);
+ that.dom.removeChild(div);
+ callback();
+ };
+ el.addEventListener("click", ev, false);
+};
+
+Scene.prototype.dialog = function dialog(options) {
+ var div = doc.createElement("div"), html, buttons, b, button, callback, i, dummy;
+ div.className = "dialog " + optionValue(options, "class", "");
+ optionValue(options, "html");
+ div.innerHTML = html;
+ dummy = function () {};
+ buttons = optionValue(options, "buttons", []);
+ for (i = 0; i < buttons.length; i++) {
+ b = buttons[i];
+ button = doc.createElement("button");
+ button.innerHTML = optionValue(b, "text", "Ok");
+ div.appendChild(button);
+ callback = optionValue(b, "callback", dummy);
+ this.dialogEvent(div, button, "click", callback);
+ }
+ div.style.position = "absolute";
+ zindex += 1;
+ div.style.zIndex = String(zindex);
+ this.dom.appendChild(div);
+};
+
+Scene.prototype.loadImages = function loadImages(images, callback) {
+ // function used to preload the sprite images
+ if (!callback) {
+ callback = this.main;
+ }
+
+ var toLoad = 0, total, div, img, src, error, scene, i;
+ for (i = 0; i < images.length; i++) {
+ if (!sjs.spriteCache[images[i]]) {
+ toLoad += 1;
+ sjs.spriteCache[images[i]] = {src: images[i], loaded: false, loading: false};
+ }
+ }
+
+ if (toLoad === 0) {
+ return callback();
+ }
+
+ total = toLoad;
+ div = overlay(0, 0, this.w, this.h);
+ div.style.textAlign = 'center';
+ div.style.paddingTop = (this.h / 2 - 16) + 'px';
+
+ div.innerHTML = 'Loading';
+ this.dom.appendChild(div);
+ scene = this;
+ error = false;
+
+ function _loadImg(src) {
+ sjs.spriteCache[src].loading = true;
+ img = doc.createElement('img');
+ sjs.spriteCache[src].img = img;
+ img.addEventListener('load', function () {
+ sjs.spriteCache[src].loaded = true;
+ toLoad -= 1;
+ if (error === false) {
+ if (toLoad === 0) {
+ scene.dom.removeChild(div);
+ callback();
+ } else {
+ div.innerHTML = 'Loading ' + ((total - toLoad) / total * 100 | 0) + '%';
+ }
+ }
+ }, false);
+
+ img.addEventListener('error', function () {
+ error = true;
+ div.innerHTML = 'Error loading image ' + src;
+ }, false);
+
+ img.src = src;
+ }
+
+ for (src in sjs.spriteCache) {
+ if (sjs.spriteCache.hasOwnProperty(src)) {
+ if (!sjs.spriteCache[src].loading) {
+ _loadImg(src);
+ }
+ }
+ }
+};
+
+Sprite = function Sprite(scene, src, layer) {
+
+ this.scene = scene;
+ this._dirty = {};
+ this.changed = false;
+
+ // positions
+ this.y = 0;
+ this.x = 0;
+ this._x_before = 0;
+ this._x_rounded = 0;
+ this._y_before = 0;
+ this._y_rounded = 0;
+
+ //velocity
+ this.xv = 0;
+ this.yv = 0;
+ this.rv = 0;
+
+ // shape: rectangle, circle
+ this.type = "rectangle";
+
+ // newton
+ this.mass = 1;
+ this.friction = 0.05;
+ // forces
+ this.xf = 0;
+ this.yf = 0;
+
+ // image
+ this.src = null;
+ this.img = null;
+ this.imgNaturalWidth = null;
+ this.imgNaturalHeight = null;
+
+ // width and height of the sprite view port
+ this.w = null;
+ this.h = null;
+
+ // offsets of the image within the viewport
+ this.xoffset = 0;
+ this.yoffset = 0;
+
+ this.dom = null;
+ this.cycle = null;
+
+ this.xscale = 1;
+ this.yscale = 1;
+ this.angle = 0;
+
+ this.xTransformOrigin = null;
+ this.yTransformOrigin = null;
+
+ this.backgroundRepeat = null;
+
+ this.opacity = 1;
+ this.color = false;
+
+ this.id = ++nb_sprite;
+
+ // necessary to get set
+ this.layer = null;
+
+ var value, target, setF, first_char, d, p, properties;
+
+ // if it doesn't seems to kouak like a Layer object
+ if (layer) {
+ // this is a layer object
+ if (layer.sprites) {
+ this.layer = layer;
+ } else {
+ // we can receive things like this
+ // {x: 10, y: 10, w: 10, h: 50, size: [20, 30], layer: var}
+ properties = layer;
+
+ // this is the messy magic options initializer code
+ for (p in properties) {
+ if (properties.hasOwnProperty(p)) {
+ value = properties[p];
+ target = this[p];
+ if (typeof target === "function") {
+ this[p].apply(this, value);
+ }
+ else if (target !== undefined) {
+ // this is necessary to set cache value properly
+ first_char = p.charAt(0);
+ if ((first_char === 'x' || first_char === 'y') && p.length > 1) {
+ setF = 'set' + first_char.toUpperCase() + p.charAt(1).toUpperCase() + p.slice(2);
+ } else {
+ setF = 'set' + first_char.toUpperCase() + p.slice(1);
+ }
+ if (this[setF]) {
+ this[setF].apply(this, [value]);
+ } else {
+ // necessary for layer option
+ this[p] = value;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // can be set by the properties
+ if (this.layer === undefined || layer === undefined) {
+ this.layer = scene.layers['default'];
+ }
+
+ if (this.layer && !this.layer.useCanvas) {
+ d = doc.createElement('div');
+ d.style.position = 'absolute';
+ this.dom = d;
+ this.layer.dom.appendChild(d);
+ }
+ if (src) {
+ this.loadImg(src);
+ }
+ return this;
+};
+
+Sprite.prototype.constructor = Sprite;
+
+/* boilerplate setter functions */
+
+Sprite.prototype.setX = function setX(value) {
+ this.x = value;
+ // this secessary for the physic
+ this._x_rounded = value | 0;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setY = function setY(value) {
+ this.y = value;
+ this._y_rounded = value | 0;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setW = function setW(value) {
+ this.w = value;
+ this._dirty.w = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setH = function setH(value) {
+ this.h = value;
+ this._dirty.h = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setXOffset = function setXoffset(value) {
+ this.xoffset = value;
+ this._dirty.xoffset = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setYOffset = function setYoffset(value) {
+ this.yoffset = value;
+ this._dirty.yoffset = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setAngle = function setAngle(value) {
+ this.angle = value;
+ this._dirty.angle = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setColor = function setColor(value) {
+ this.color = value;
+ this._dirty.color = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setOpacity = function setOpacity(value) {
+ this.opacity = value;
+ this._dirty.opacity = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setXScale = function setXscale(value) {
+ this.xscale = value;
+ this._dirty.xscale = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setYScale = function setYscale(value) {
+ this.yscale = value;
+ this._dirty.yscale = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.transformOrigin = function transformOrigin(x, y) {
+ this.xTransformOrigin = x;
+ this.yTransformOrigin = y;
+ this._dirty.transform = true;
+ this.changed = true;
+ return this;
+};
+
+Sprite.prototype.setBackgroundRepeat = function setBackgroundRepeat(value) {
+ this._dirty.backgroundRepeat = true;
+ this.backgroundRepeat = value;
+ return this;
+};
+
+// End of boilerplate setters, start of helpers
+
+Sprite.prototype.rotate = function (v) {
+ this.setAngle(this.angle + v);
+ return this;
+};
+
+Sprite.prototype.orient = function orient(x, y) {
+ var a = Math.atan2(y, x);
+ this.setAngle(a);
+};
+
+Sprite.prototype.scale = function (x, y) {
+ if (this.xscale !== x) {
+ this.setXScale(x);
+ }
+ if (y === undefined) {
+ y = x;
+ }
+ if (this.yscale !== y) {
+ this.setYScale(y);
+ }
+ return this;
+};
+
+Sprite.prototype.move = function (x, y) {
+ this.setX(this.x + x);
+ this.setY(this.y + y);
+ return this;
+};
+
+Sprite.prototype.position = function (x, y) {
+ this.setX(x);
+ this.setY(y);
+ return this;
+};
+
+Sprite.prototype.offset = function (x, y) {
+ this.setXOffset(x);
+ this.setYOffset(y);
+ return this;
+};
+
+Sprite.prototype.size = function (w, h) {
+ this.setW(w);
+ this.setH(h);
+ return this;
+};
+
+// Physic
+
+Sprite.prototype.setForce = function setForce(xf, yf) {
+ this.xf = xf;
+ this.yf = yf;
+};
+
+Sprite.prototype.addForce = function addForce(xf, yf) {
+ this.xf += xf;
+ this.yf += yf;
+};
+
+Sprite.prototype.applyForce = function applyForce(ticks) {
+ if (ticks === undefined) {
+ ticks = 1;
+ }
+ // Integrate newton's laws of motion F = ma => a = F / m
+ this.xv -= this.friction * this.xv * this.mass * ticks;
+ this.xv += (this.xf / this.mass) * ticks;
+ this.yv -= this.friction * this.yv * this.mass * ticks;
+ this.yv += (this.yf / this.mass) * ticks;
+};
+
+Sprite.prototype.velocity = function () {
+ return hypo(this.xv, this.yv);
+};
+
+Sprite.prototype.setVelocity = function (xv, yv) {
+ this.xv = xv;
+ this.yv = yv;
+};
+
+Sprite.prototype.addVelocity = function (xv, yv) {
+ this.xv += xv;
+ this.yv += yv;
+};
+
+Sprite.prototype.applyVelocity = function (ticks) {
+ if (ticks === undefined)
+ ticks = 1;
+ if (this.xv !== 0)
+ this.setX(this.x + this.xv * ticks);
+ if (this.yv !== 0)
+ this.setY(this.y + this.yv * ticks);
+ if (this.rv !== 0)
+ this.setAngle(this.angle + this.rv * ticks);
+ return this;
+};
+
+Sprite.prototype.reverseVelocity = function (ticks) {
+ if (ticks === undefined)
+ ticks = 1;
+ if (this.xv !== 0)
+ this.setX(this.x - this.xv * ticks);
+ if (this.yv !== 0)
+ this.setY(this.y - this.yv * ticks);
+ if (this.rv !== 0)
+ this.setAngle(this.angle - this.rv * ticks);
+ return this;
+};
+
+Sprite.prototype.applyXVelocity = function (ticks) {
+ if (ticks === undefined)
+ ticks = 1;
+ if (this.xv !== 0)
+ this.setX(this.x + this.xv * ticks);
+};
+
+Sprite.prototype.reverseXVelocity = function (ticks) {
+ if (ticks === undefined)
+ ticks = 1;
+ if (this.xv !== 0)
+ this.setX(this.x-this.xv * ticks);
+};
+
+Sprite.prototype.applyYVelocity = function (ticks) {
+ if (ticks === undefined)
+ ticks = 1;
+ if (this.yv !== 0)
+ this.setY(this.y+this.yv * ticks);
+};
+
+Sprite.prototype.reverseYVelocity = function (ticks) {
+ if (ticks === undefined)
+ ticks = 1;
+ if (this.yv !== 0)
+ this.setY(this.y-this.yv * ticks);
+};
+
+Sprite.prototype.rotateVelocity = function (a) {
+ var x = this.xv * Math.cos(a) - this.yv * Math.sin(a);
+ this.yv = this.xv * Math.sin(a) + this.yv * Math.cos(a);
+ this.xv = x;
+};
+
+Sprite.prototype.orientVelocity = function (x, y) {
+ var intensity = hypo(this.xv, this.yv), v;
+ v = normalVector(x, y, intensity);
+ this.xv = v.x;
+ this.yv = v.y;
+};
+
+Sprite.prototype.remove = function remove() {
+ if (this.cycle)
+ this.cycle.removeSprite(this);
+ if (this.layer && !this.layer.useCanvas) {
+ this.layer.dom.removeChild(this.dom);
+ this.dom = null;
+ }
+ if (this.texture)
+ this.texture.remove();
+ this.texture = null;
+ //delete this.layer.sprites[this.layerIndex];
+ this.layer = null;
+ this.img = null;
+};
+
+// Update methods
+
+Sprite.prototype.webGLUpdate = function webGLUpdate () {
+ if (!this.texture) {
+ this.texture = new webgl.Texture(this);
+ }
+ this.texture.render(this.x, this.y);
+ return this;
+};
+
+Sprite.prototype.update = function updateDomProperties () {
+ // This is the CPU heavy function.
+
+ if (this.layer.useWebGL) {
+ return this.webGLUpdate();
+ }
+
+ if (this.layer.useCanvas) {
+ return this.canvasUpdate();
+ }
+
+ var style = this.dom.style, trans;
+ // using Math.round to round integers before changing seems to improve a bit performances
+ if (this._x_before !== this._x_rounded)
+ style.left=(this.x | 0) + 'px';
+ if (this._y_before !== this._y_rounded)
+ style.top=(this.y | 0) + 'px';
+
+ // cache rounded positions, it's used to avoid unecessary update
+ this._x_before = this._x_rounded;
+ this._y_before = this._y_rounded;
+
+ if (!this.changed)
+ return this;
+
+ if (this._dirty.w)
+ style.width=(this.w | 0) +'px';
+ if (this._dirty.h)
+ style.height=(this.h | 0) + 'px';
+ // translate and translate3d doesn't seems to offer any speedup
+ // in my tests.
+ if (this._dirty.xoffset || this._dirty.yoffset)
+ style.backgroundPosition=-(this.xoffset | 0) + 'px ' + -(this.yoffset | 0) + 'px';
+
+ if (this._dirty.opacity)
+ style.opacity = this.opacity;
+
+ if (this._dirty.color)
+ style.backgroundColor = this.color;
+
+
+ if(this._dirty.transform) {
+ style[sjs.tproperty + 'Origin'] = this.xTransformOrigin + " " + this.yTransformOrigin;
+ }
+
+ if(this._dirty.backgroundRepeat) {
+ style.backgroundRepeat = this.backgroundRepeat;
+ }
+
+ // those transformation have pretty bad perfs implication on Opera,
+ // don't update those values if nothing changed
+ if (this._dirty.xscale || this._dirty.yscale || this._dirty.angle) {
+ trans = "";
+ if (this.angle !== 0)
+ trans += 'rotate(' + this.angle + 'rad) ';
+ if (this.xscale !== 1 || this.yscale !== 1) {
+ trans += ' scale(' + this.xscale + ', ' + this.yscale + ')';
+ }
+ style[sjs.tproperty] = trans;
+ }
+ // reset
+ this.changed = false;
+ this._dirty = {};
+ return this;
+};
+
+Sprite.prototype.canvasUpdate = function canvasUpdate(layer) {
+ var ctx, transx, transy, repeat_w, repeat_y;
+ if (layer)
+ ctx = layer.ctx;
+ else
+ ctx = this.layer.ctx;
+ ctx.save();
+
+ if (this.xTransformOrigin === null) {
+ // 50% 505 in CSS
+ transx = this.w / 2 | 0;
+ transy = this.h / 2 | 0;
+ } else {
+ transx = this.xTransformOrigin;
+ transy = this.yTransformOrigin;
+ }
+
+ // rounding the coordinates yield a big performance improvement
+ ctx.translate(this.x + transx, this.y + transy);
+ ctx.rotate(this.angle);
+ if (this.xscale !== 1 || this.yscale !== 1)
+ ctx.scale(this.xscale, this.yscale);
+ ctx.globalAlpha = this.opacity;
+ ctx.translate(-transx, -transy);
+ // handle background colors.
+ if (this.color) {
+ ctx.fillStyle = this.color;
+ ctx.fillRect(0, 0, this.w, this.h);
+ }
+ // handle repeating images, a way to implement repeating background in canvas
+ if (this.imgLoaded && this.img) {
+ if (this.imgNaturalWidth < this.w || this.imgNaturalHeight < this.h) {
+ repeat_w = Math.floor(this.w / this.imgNaturalWidth);
+ while(repeat_w > 0) {
+ repeat_w = repeat_w-1;
+ repeat_y = Math.floor(this.h / this.imgNaturalHeight);
+ while(repeat_y > 0) {
+ repeat_y = repeat_y-1;
+ ctx.drawImage(this.img, this.xoffset, this.yoffset,
+ this.imgNaturalWidth,
+ this.imgNaturalHeight,
+ repeat_w * this.imgNaturalWidth,
+ repeat_y * this.imgNaturalHeight,
+ this.imgNaturalWidth,
+ this.imgNaturalHeight);
+ }
+
+ }
+ } else {
+ // image with normal size or with
+ ctx.drawImage(this.img, this.xoffset, this.yoffset, this.w, this.h, 0, 0, this.w, this.h);
+ }
+ }
+ ctx.restore();
+ return this;
+};
+
+// Other methods
+
+Sprite.prototype.toString = function () {
+ return "Sprite(" + String(this.id) + ")";
+};
+
+Sprite.prototype.onload = function (callback) {
+ if (this.imgLoaded && this._callback) {
+ this._callback = callback;
+ }
+};
+
+Sprite.prototype.loadImg = function (src, resetSize) {
+ // the image exact source value will change according to the
+ // hostname, this is useful to retain the original source value here.
+ var _loaded, there = this, img;
+ this.src = src;
+ // check if the image is already in the cache
+ if (!sjs.spriteCache[src]) {
+ // if not we create the image in the cache
+ this.img = doc.createElement('img');
+ sjs.spriteCache[src] = {src: src, img: this.img, loaded: false, loading: true};
+ _loaded = false;
+ } else {
+ // if it's already there, we set img object and check if it's loaded
+ this.img = sjs.spriteCache[src].img;
+ _loaded = sjs.spriteCache[src].loaded;
+ }
+
+ // actions to perform when the image is loaded
+ function imageReady(e) {
+ img = there.img;
+ sjs.spriteCache[src].loaded = true;
+ there.imgLoaded = true;
+ if (there.layer && !there.layer.useCanvas)
+ there.dom.style.backgroundImage = 'url(' + src + ')';
+ there.imgNaturalWidth = img.width;
+ there.imgNaturalHeight = img.height;
+ if (there.w === null || resetSize)
+ there.setW(img.width);
+ if (there.h === null || resetSize)
+ there.setH(img.height);
+ there.onload();
+ }
+ if (_loaded)
+ imageReady();
+ else {
+ this.img.addEventListener('load', imageReady, false);
+ this.img.src = src;
+ }
+ return this;
+};
+
+Sprite.prototype.distance = function distance(x, y) {
+ // Return the distance between this sprite and the point (x, y) or a Sprite
+ if (typeof x === "number") {
+ return Math.sqrt(Math.pow(this.x + this.w / 2 - x, 2) +
+ Math.pow(this.y + this.h / 2 - y, 2));
+ } else {
+ return Math.sqrt(Math.pow(this.x + (this.w / 2) - (x.x + (x.w / 2)), 2) +
+ Math.pow(this.y + (this.h / 2) - (x.y + (x.h / 2)), 2));
+ }
+};
+
+Sprite.prototype.center = function center() {
+ return {x: this.x + this.w / 2, y: this.y + this.h / 2};
+};
+
+// Fx
+
+Sprite.prototype.explode2 = function explode(v, horizontal, layer) {
+ if (!layer)
+ layer = this.layer;
+ if (v === undefined) {
+ if (horizontal)
+ v = this.h / 2;
+ else
+ v = this.w / 2;
+ }
+ v = v | 0;
+ var s1 = layer.scene.Sprite(this.src, layer);
+ var s2 = layer.scene.Sprite(this.src, layer);
+ if (horizontal) {
+ s1.size(this.w, v);
+ s1.position(this.x, this.y);
+ s2.size(this.w, this.h - v);
+ s2.position(this.x, this.y + v);
+ s2.setYOffset(v);
+ } else {
+ s1.size(v, this.h);
+ s1.position(this.x, this.y);
+ s2.size(this.w - v, this.h);
+ s2.position(this.x + v, this.y);
+ s2.setXOffset(v);
+ }
+ return [s1, s2];
+};
+
+Sprite.prototype.explode4 = function explode(x, y, layer) {
+ if (x === undefined)
+ x = this.w / 2;
+ if (y === undefined)
+ y = this.h / 2;
+ x = x | 0;
+ y = y | 0;
+ if (!layer)
+ layer = this.layer;
+ // top left sprite, going counterclockwise
+ var s1 = layer.scene.Sprite(this.src, layer),
+ s2 = layer.scene.Sprite(this.src, layer),
+ s3 = layer.scene.Sprite(this.src, layer),
+ s4 = layer.scene.Sprite(this.src, layer);
+
+ s1.size(x, y);
+ s1.position(this.x, this.y);
+
+ s2.size(this.w - x, y);
+ s2.position(this.x + x, this.y);
+ s2.offset(x, 0);
+
+ s3.size(this.w - x, this.h - y);
+ s3.position(this.x + x, this.y + y);
+ s3.offset(x, y);
+
+ s4.size(x, this.h - y);
+ s4.position(this.x, this.y + y);
+ s4.offset(0, y);
+
+ return [s1, s2, s3, s4];
+};
+
+Cycle = function Cycle(triplets) {
+
+ if (this.constructor !== Cycle) {
+ return new Cycle(triplets);
+ }
+
+ var i, triplet;
+
+ // Cycle for the Sprite image.
+ // A cycle is a list of triplet (x offset, y offset, game tick duration)
+ this.triplets = triplets;
+ // total duration of the animation in ticks
+ this.cycleDuration = 0;
+ // this array knows on which ticks in the animation
+ // an image change is needed
+ this.changingTicks = [0];
+ for (i = 0; triplet=triplets[i]; i++) {
+ this.cycleDuration = this.cycleDuration + triplet[2];
+ this.changingTicks.push(this.cycleDuration);
+ }
+ this.currentTripletIndex = undefined;
+ // suppose to be private
+ this.sprites = [];
+ // if set to false, the animation will stop automaticaly after one run
+ this.repeat = true;
+ this.tick = 0;
+ this.done = false;
+ this.id = ++nb_cycle;
+};
+
+Cycle.prototype.addSprite = function addSprite(sprite) {
+ this.sprites.push(sprite);
+ sprite.cycle = this;
+ return this;
+};
+
+Cycle.prototype.toString = function () {
+ return "Cycle(" + String(this.id) + ")";
+};
+
+Cycle.prototype.update = function update() {
+ var sprites = this.sprites, i, sp;
+ for (i = 0; sp = sprites[i]; i++) {
+ sp.update();
+ }
+ return this;
+};
+
+Cycle.prototype.addSprites = function addSprites(sprites) {
+ this.sprites = this.sprites.concat(sprites);
+ var j, sp;
+ for (j = 0; sp = sprites[j]; j++) {
+ sp.cycle = this;
+ }
+ return this;
+};
+
+Cycle.prototype.removeSprite = function removeSprite(sprite) {
+ var j, sp;
+ for (j = 0; sp = this.sprites[j]; j++) {
+ if (sprite == sp) {
+ sp.cycle = null;
+ this.sprites.splice(j, 1);
+ }
+ }
+ return this;
+};
+
+Cycle.prototype.next = function (ticks, update) {
+ if (this.tick > this.cycleDuration) {
+ if (this.repeat)
+ this.tick = 0;
+ else {
+ this.done = true;
+ return this;
+ }
+ }
+ // search if we are in a new triplet
+ var newTripletIndex, i, j, sprite;
+ for (i = 0; i < this.changingTicks.length - 1; i++) {
+ if (this.tick >= this.changingTicks[i] && this.tick <= this.changingTicks[i+1]) {
+ newTripletIndex = i;
+ break;
+ }
+ }
+ if (newTripletIndex !== undefined && newTripletIndex !== this.currentTickIndex) {
+ for (j = 0; sprite = this.sprites[j]; j++) {
+ sprite.setXOffset(this.triplets[i][0]);
+ sprite.setYOffset(this.triplets[i][1]);
+ if (update)
+ sprite.update();
+ }
+ this.currentTripletIndex = newTripletIndex;
+ }
+
+ ticks = ticks || 1; // default tick: 1
+ this.tick = this.tick + ticks;
+ return this;
+};
+
+Cycle.prototype.reset = function resetCycle(update) {
+ var j, sprite;
+ this.tick = 0;
+ this.done = false;
+ for (j = 0; sprite = this.sprites[j]; j++) {
+ sprite.setXOffset(this.triplets[0][0]);
+ sprite.setYOffset(this.triplets[0][1]);
+ if (update)
+ sprite.update();
+ }
+ return this;
+};
+
+Cycle.prototype.go = function gotoCycle(n) {
+ var j, sprite;
+ for (j = 0; sprite = this.sprites[j]; j++) {
+ sprite.setXOffset(this.triplets[n][0]);
+ sprite.setYOffset(this.triplets[n][1]);
+ }
+ return this;
+};
+
+Ticker_ = function Ticker_(scene, paint, options) {
+
+ // backward compatiblity from the 1.1.1 API
+ if (typeof paint == "number") {
+ var buf = paint;
+ paint = options;
+ options = {tickDuration: buf}
+ }
+
+ this.scene = scene;
+
+ if (this.constructor !== Ticker_)
+ return new Ticker_(tickDuration, paint);
+
+ this.tickDuration = optionValue(options, 'tickDuration', 16);
+ this.useAnimationFrame = optionValue(options, 'useAnimationFrame', false);
+ if (!sjs.animationFrame)
+ this.useAnimationFrame = false;
+ this.paint = paint;
+
+ this.start = new Date().getTime();
+ this.now = this.start;
+ this.ticksElapsed = 0;
+ // absolute number of ticks that have been played ever
+ this.currentTick = 0;
+ this.ticksSinceLastStart = 0;
+ this.droppedFrames = 0;
+};
+
+Ticker_.prototype.next = function () {
+ var now = new Date().getTime();
+ this.diff = now - this.now;
+ this.now = now;
+ // number of ticks that have elapsed since the last start
+ this.lastTicksElapsed = Math.round(this.diff / this.tickDuration);
+ this.droppedFrames += Math.max(0, this.lastTicksElapsed - 1);
+ this.ticksSinceLastStart += this.lastTicksElapsed;
+ // add the diff to the current ticks
+ this.currentTick += this.lastTicksElapsed;
+ return this.lastTicksElapsed;
+};
+
+Ticker_.prototype.run = function () {
+ if (this.paused)
+ return;
+ var t = this;
+ var ticksElapsed = this.next();
+ // no update needed, this happen on the first run
+ if (ticksElapsed == 0) {
+ // this is not a cheap operation
+ setTimeout(function () {t.run()}, this.tickDuration);
+ return;
+ }
+
+ for (var name in this.scene.layers) {
+ var layer = this.scene.layers[name];
+ if (layer.useCanvas && layer.autoClear) {
+ layer.clear();
+ }
+ }
+
+ this.paint(this);
+ // reset the keyboard change
+ if (this.scene.input)
+ this.scene.input.next();
+
+ this.timeToPaint = (new Date().getTime()) - this.now;
+ // spread the load value on 2 frames so the value is more stable
+ this.load = ((this.timeToPaint / this.tickDuration * 100) + this.load) / 2 | 0;
+
+ this.fps = Math.round(1000 / (this.now - (this.lastPaintAt || 0)));
+ this.lastPaintAt = this.now;
+ if (this.useAnimationFrame) {
+ this.tickDuration = 16;
+ global[sjs.animationFrame](function () {t.run()});
+ } else {
+ var _nextPaint = Math.max(this.tickDuration - this.timeToPaint, 6);
+ this.timeout = setTimeout(function () {t.run()}, _nextPaint);
+ }
+};
+
+Ticker_.prototype.pause = function () {
+ global.clearTimeout(this.timeout);
+ global[sjs.animationFrame] = undefined;
+ this.paused = true;
+};
+
+Ticker_.prototype.resume = function () {
+ this.start = new Date().getTime();
+ this.ticksElapsed = 0;
+ this.ticksSinceLastStart = 0;
+ this.paused = false;
+ this.run();
+};
+
+
+var inputSingleton = false;
+function Input(scene){
+ if (!inputSingleton)
+ inputSingleton = new _Input(scene);
+ return inputSingleton
+};
+
+_Input = function _Input(scene) {
+
+ if (scene)
+ this.dom = scene.dom;
+ else
+ this.dom = doc.body;
+
+ var that = this;
+
+ // record the current keyboard state
+ this.keyboard = {};
+ this.mouse = {position: {}, click: undefined};
+ // record the keyboard changes since the last call
+ this.keyboardChange = {};
+ this.mousedown = false;
+ that.mousepressed = false;
+ this.mousereleased = false;
+ this.keydown = false;
+
+ this.touchable = 'ontouchstart' in global;
+
+ this.next = function () {
+ that.keyboardChange = {};
+ that.mousepressed = false;
+ that.mouse.click = undefined;
+ that.mousereleased = false;
+ }
+
+ this.keyPressed = function (name) {
+ return that.keyboardChange[name] !== undefined && that.keyboardChange[name];
+ };
+
+ this.keyReleased = function (name) {
+ return that.keyboardChange[name] !== undefined && !that.keyboardChange[name];
+ };
+
+ function updateKeyChange(name, val) {
+ if (that.keyboard[name] !== val) {
+ that.keyboard[name] = val;
+ that.keyboardChange[name] = val;
+ }
+ }
+
+ // this is handling WASD, and arrows keys
+ function updateKeyboard(e, val) {
+ if (e.keyCode == 40 || e.keyCode == 83) {
+ updateKeyChange('down', val);
+ }
+ if (e.keyCode == 38 || e.keyCode == 87) {
+ updateKeyChange('up', val);
+ }
+ if (e.keyCode == 39 || e.keyCode == 68) {
+ updateKeyChange('right', val);
+ }
+ if (e.keyCode == 37 || e.keyCode == 65) {
+ updateKeyChange('left', val);
+ }
+ if (e.keyCode == 32) {
+ updateKeyChange('space', val);
+ }
+ if (e.keyCode == 17) {
+ updateKeyChange('ctrl', val);
+ }
+ if (e.keyCode == 13) {
+ updateKeyChange('enter', val);
+ }
+ if (e.keyCode == 27) {
+ updateKeyChange('esc', val);
+ }
+ // 0..9, a-z
+ if (e.keyCode >= 48 && e.keyCode <= 90) {
+ var keyStr = String.fromCharCode(e.keyCode);
+ updateKeyChange(keyStr.toLowerCase(), val);
+ }
+ }
+
+ var addEvent = function (name, fct) {
+ global.addEventListener(name, fct, false);
+ }
+
+
+ // Mouse like events
+ function clickEvent(event) {
+ that.mouse.click = {
+ x: (event.clientX - that.dom.offsetLeft) / scene.xscale,
+ y: (event.clientY - that.dom.offsetTop) / scene.yscale
+ };
+ }
+
+ function mouseDownEvent(event) {
+ that.mousedown = true;
+ that.mouse.down = true;
+ that.mousepressed = true;
+ // prevent unwanted browser drag and drop behavior
+ //event.preventDefault();
+ }
+
+ function mouseUpEvent(event) {
+ that.mousedown = false;
+ that.mouse.down = false;
+ that.mousereleased = true;
+ that.mouse.click = {
+ x: (event.clientX - that.dom.offsetLeft) / scene.xscale,
+ y: (event.clientY - that.dom.offsetTop) / scene.yscale
+ };
+ }
+
+ function mouseMoveEvent(event) {
+ that.mouse.position = {
+ x: (event.clientX - that.dom.offsetLeft) / scene.xscale,
+ y: (event.clientY - that.dom.offsetTop) / scene.yscale
+ };
+ }
+
+ function reduceTapEvent(e) {
+ // To simplify I ignore multiple touch events and only return the first event
+ if (e.touches && e.touches.length) { e = e.touches[0]; }
+ else if (e.changedTouches && e.changedTouches.length) { e = e.changedTouches[0];}
+ return e
+ }
+
+ if (this.touchable) {
+ addEvent("touchstart", function (e) {
+ e = reduceTapEvent(e);
+ updateKeyChange('space', true); // tap imitates space
+ // simulate the click
+ clickEvent(e);
+ //store initial coordinates to find out swipe directions later
+ that.touchStart = {"x" : e.clientX, "y": e.clientY};
+
+ });
+
+ addEvent("touchend", function (e) {
+ mouseUpEvent(e);
+ that.keyboard = {}
+ that.touchStart = null;
+ });
+
+ addEvent("touchmove", function (e) {
+ e.preventDefault(); // avoid scrolling the page
+ e = reduceTapEvent(e);
+ updateKeyChange('space', false); // if it moves: it is not a tap
+ mouseMoveEvent(e);
+ if (that.touchStart) {
+ var deltaX = e.clientX - that.touchStart.x;
+ var deltaY = e.clientY - that.touchStart.y;
+ // limit of 3 pixels
+ if (deltaY < 0) {
+ updateKeyChange('up', true);
+ updateKeyChange('down', false);
+ } else {
+ updateKeyChange('down', true);
+ updateKeyChange('up', false);
+ };
+ if (deltaX < 0) {
+ updateKeyChange('left', true);
+ updateKeyChange('right', false);
+ } else {
+ updateKeyChange('right', true);
+ updateKeyChange('left', false);
+ };
+ // increase the control of the swipe in
+ // the long run.
+ that.touchStart.x += (deltaX / 10);
+ that.touchStart.y += (deltaY / 10);
+ }
+ });
+
+ addEvent("touchmove", function (e) {
+ e = reduceTapEvent(e);
+ mouseMoveEvent(e);
+ });
+ };
+
+ addEvent("mousedown", mouseDownEvent);
+ addEvent("mouseup", mouseUpEvent);
+ addEvent("click", clickEvent);
+ addEvent("mousemove", mouseMoveEvent);
+
+ addEvent("keydown", function (e) {
+ that.keydown = true;
+ updateKeyboard(e, true);
+ });
+
+ addEvent("keyup", function (e) {
+ that.keydown = false;
+ updateKeyboard(e, false);
+ });
+
+ // can be used to avoid key jamming
+ addEvent("keypress", function (e) {});
+ if (!sjs.debug)
+ addEvent("contextmenu", function (e) {e.preventDefault()});
+};
+
+_Input.prototype.arrows = function arrows() {
+ /* Return true if any arrow key is pressed */
+ return this.keyboard.right || this.keyboard.left || this.keyboard.up || this.keyboard.down;
+};
+
+// Add an automatic pause to all the scenes when the user
+// quit the current window.
+global.addEventListener("blur", function (e) {
+ for (var i = 0; i < sjs.scenes.length; i++) {
+ var scene = sjs.scenes[i];
+ if (!scene.autoPause)
+ continue;
+ var anon = function (scene) {
+ inputSingleton.keyboard = {};
+ inputSingleton.keydown = false;
+ inputSingleton.mousedown = false;
+ // create a semi transparent layer on the game
+ if (scene.ticker && !scene.ticker.paused) {
+ scene.ticker.pause();
+ var div = overlay(0, 0, scene.w, scene.h);
+ div.innerHTML = '<h1>Paused</h1><p>Click or press any key to resume.</p>';
+ div.style.textAlign = 'center';
+ div.style.paddingTop = ((scene.h / 2) - 32) + 'px';
+ var listener = function (e) {
+ e.stopPropagation();
+ e.preventDefault();
+ scene.dom.removeChild(div);
+ doc.removeEventListener('click', listener, false);
+ doc.removeEventListener('keyup', listener, false);
+ scene.ticker.resume();
+ }
+ doc.addEventListener('click', listener, false);
+ doc.addEventListener('keyup', listener, false);
+ scene.dom.appendChild(div);
+ }
+ }
+ anon(scene);
+ }
+}, false);
+
+Layer = function Layer(scene, name, options) {
+
+ var domElement, needToCreate, domH, domW;
+
+ if (!this || this.constructor !== Layer)
+ return new Layer(scene, name, options);
+
+ this.sprites = {};
+ this.scene = scene;
+
+ if (options === undefined)
+ options = {useCanvas: scene.useCanvas, autoClear: true}
+
+ if (options.useWebGL)
+ options.useCanvas = true;
+
+ if (options.autoClear === undefined)
+ this.autoClear = true;
+ else
+ this.autoClear = options.autoClear;
+
+ if (options.useCanvas === undefined)
+ this.useCanvas = this.scene.useCanvas;
+ else
+ this.useCanvas = options.useCanvas;
+
+ this.useWebGL = options.useWebGL;
+
+ this.name = name;
+ if (this.scene.layers[name] === undefined) {
+ this.scene.layers[name] = this;
+ } else {
+ if (sjs.debug)
+ warning("A layer named " + name + " already exist.");
+ // if the user try to create a Layer that already exists,
+ // we send back the same.
+ return this.scene.layers[name];
+ }
+
+ domElement = doc.getElementById(name);
+ if (!domElement)
+ needToCreate = true;
+ else
+ needToCreate = false;
+
+ if (this.useCanvas) {
+ if (domElement && domElement.nodeName.toLowerCase() !== "canvas") {
+ error("Cannot use HTMLElement " + domElement.nodeName + " with canvas renderer.");
+ }
+ if (needToCreate) {
+ domElement = doc.createElement('canvas');
+ }
+ } else {
+ if (needToCreate) {
+ domElement = doc.createElement('div');
+ }
+ }
+
+ if (!needToCreate) {
+ domH = domElement.height || domElement.style.height;
+ domW = domElement.width || domElement.style.width;
+ } else {
+ domH = false;
+ domW = false;
+ }
+
+ if (options.parent)
+ this.parent = options.parent;
+ else
+ this.parent = this.scene.dom;
+ this.parent.appendChild(domElement);
+ domElement.id = domElement.id || 'sjs' + scene.id + '-' + name;
+ if (!options.disableAutoZIndex) {
+ zindex += 1;
+ domElement.style.zIndex = String(zindex);
+ }
+ domElement.style.backgroundColor = options.color || domElement.style.backgroundColor;
+ this.h = options.h || domH || scene.h;
+ this.w = options.w || domW || scene.w;
+ if (domElement.nodeName == "CANVAS") {
+ domElement.height = this.h;
+ domElement.width = this.w;
+ } else {
+ domElement.style.height = this.h + 'px';
+ domElement.style.width = this.w +'px';
+ };
+ domElement.style.position = 'absolute';
+ domElement.style.top = domElement.style.top || '0px';
+ domElement.style.left = domElement.style.left || '0px';
+
+ this.dom = domElement;
+
+ // webgl needs to be set after the size
+ if (this.useCanvas) {
+ if (options.useWebGL) {
+ this.ctx = webgl.init(domElement);
+ } else {
+ this.ctx = domElement.getContext('2d');
+ }
+ }
+};
+
+Layer.prototype.constructor = Layer;
+
+Layer.prototype.clear = function clear() {
+ if (this.useWebGL)
+ this.ctx.clear(this.ctx.COLOR_BUFFER_BIT | this.ctx.DEPTH_BUFFER_BIT);
+ else
+ this.ctx.clearRect(0, 0, this.dom.width, this.dom.height);
+};
+
+Layer.prototype.Sprite = function (src, options) {
+ if (options)
+ options.layer = this;
+ else
+ options = this;
+ return new Sprite(this.scene, src, options);
+};
+
+Layer.prototype.remove = function remove() {
+ this.parent.removeChild(this.dom);
+ delete this.scene.layers[this.name];
+};
+
+Layer.prototype.addSprite = function addSprite(sprite) {
+ var index = Math.random() * 11;
+ this.sprites[index] = sprite;
+ return index
+};
+
+Layer.prototype.setColor = function setColor(color) {
+ this.dom.style.backgroundColor = color;
+};
+
+Layer.prototype.onTop = function onTop(color) {
+ zindex += 1;
+ this.dom.style.zIndex = String(zindex);
+};
+
+List = function List(list) {
+ if (this.constructor !== List)
+ return new List(list);
+ this.list = list || [];
+ this.length = this.list.length;
+ this.index = -1;
+};
+
+List.prototype.add = function add(sprite) {
+ if (sprite.length)
+ this.list.push.apply(this.list, sprite);
+ else
+ this.list.push(sprite);
+ this.length = this.list.length;
+};
+
+List.prototype.remove = function remove(toRemove) {
+ for (var i = 0, el; el = this.list[i]; i++) {
+ if (el == toRemove) {
+ this.list.splice(i, 1);
+ // delete during the iteration is possible
+ if (this.index > -1)
+ this.index = this.index - 1;
+ this.length = this.list.length;
+ return true;
+ }
+ }
+};
+
+List.prototype.iterate = function iterate() {
+ this.index += 1;
+ if (this.index >= this.list.length) {
+ this.index = -1;
+ return false;
+ }
+ return this.list[this.index];
+};
+
+var sjs = {
+ // a global cache to load each sprite only one time.
+ spriteCache: {},
+ debug: false,
+ Cycle: Cycle,
+ Input: Input,
+ Scene: Scene,
+ SpriteList: List, // backward compatibility 1.1.1
+ List: List,
+ Sprite: Sprite,
+ overlay: overlay,
+ scenes: [],
+ math: {hypo: hypo, mod: mod, normalVector: normalVector, lineSide: lineSide}
+};
+
+global.sjs = sjs;
+
+})(this);
+
View
2 views/layout.jade
@@ -25,7 +25,7 @@ html.no-js(lang='en')
script
window.jQuery || document.write('<script src="js/jquery-1.4.2.js"><\\/script>')
//-script(defer, src='js/plugins.js')
- script(src='/js/sprite/sprite.js')
+ script(src='/js/sprite.js')
script(src='/js/underscore.js')
script(src='/js/script.js')
script

0 comments on commit 36e2a9a

Please sign in to comment.