"
# Pages can be listed multiple times in the nav, but we should only generate them once
- continue if page.flagged is true
+ continue if page.flagged is true
page.flagged = true
# Make page
@@ -246,7 +246,7 @@ saveMd = (data) ->
for page in pages
html = template.replace("CONTENT_DIV", page.content_html).replace("NAV_DIV", nav_html)
writeOut(page.name, html)
-
+
return
@@ -267,7 +267,7 @@ document = (files, output, template, version, callback)->
dirOut = output
versionString = version
for file in files
- parseJS file
+ parseJS file
# Save the data to files
saveMd data
diff --git a/build/template.html b/build/template.html
index e86344c2..c973e7fc 100644
--- a/build/template.html
+++ b/build/template.html
@@ -1,4 +1,4 @@
----
+---
layout: default
---
diff --git a/changelog.txt b/changelog.txt
index 54b3d5a1..bd4751fa 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -140,7 +140,7 @@ v0.3.2
* Fixed a collision bug
-v0.3.1
+v0.3.1
* Window resize even on fullscreen
* Use scrollTop and scrollLeft
diff --git a/src/2D.js b/src/2D.js
index a4c4bf0f..f7fe9777 100644
--- a/src/2D.js
+++ b/src/2D.js
@@ -1,14 +1,14 @@
var Crafty = require('./core.js'),
document = window.document,
HashMap = require('./HashMap.js');
-// Crafty._rectPool
+// Crafty._rectPool
//
// This is a private object used internally by 2D methods
// Cascade and _attr need to keep track of an entity's old position,
// but we want to avoid creating temp objects every time an attribute is set.
// The solution is to have a pool of objects that can be reused.
//
-// The current implementation makes a BIG ASSUMPTION: that if multiple rectangles are requested,
+// The current implementation makes a BIG ASSUMPTION: that if multiple rectangles are requested,
// the later one is recycled before any preceding ones. This matches how they are used in the code.
// Each rect is created by a triggered event, and will be recycled by the time the event is complete.
Crafty._rectPool = (function () {
@@ -940,7 +940,7 @@ Crafty.c("2D", {
y2 = (this._y + this._origin.y - e.o.y) * e.cos - (this._x + this._origin.x - e.o.x) * e.sin + (e.o.y - this._origin.y);
this._attr('_rotation', this._rotation - e.deg);
this._attr('_x', x2 );
- this._attr('_y', y2 );
+ this._attr('_y', y2 );
},
/**@
@@ -1112,7 +1112,7 @@ Crafty.c("Gravity", {
if (hit) { //stop falling if found and player is moving down
if (this._falling && ((this._gy > this._jumpSpeed) || !this._up)){
this.stopFalling(hit);
- }
+ }
} else {
this._falling = true; //keep falling otherwise
}
diff --git a/src/animation.js b/src/animation.js
index 6fc2a912..ab5af2bf 100644
--- a/src/animation.js
+++ b/src/animation.js
@@ -14,13 +14,13 @@ Crafty.easing.prototype = {
steps: null,
complete: false,
paused: false,
-
- // init values
- reset: function(){
+
+ // init values
+ reset: function(){
this.loops = 1;
this.clock = 0;
this.complete = false;
- this.paused = false;
+ this.paused = false;
},
repeat: function(loopCount){
@@ -31,7 +31,7 @@ Crafty.easing.prototype = {
this.clock = this.duration * progress;
if (typeof loopCount !== "undefined")
this.loops = loopCount;
-
+
},
pause: function(){
@@ -61,7 +61,7 @@ Crafty.easing.prototype = {
// same as value for now; with other time value functions would be more useful
time: function(){
return ( Math.min(this.clock/this.duration, 1) );
-
+
},
// Value is where along the tweening curve we are
@@ -89,14 +89,14 @@ Crafty.easing.prototype = {
* Must be applied to an entity that has a sprite-map component.
*
* To define an animation, see the `reel` method. To play an animation, see the `animate` method.
-*
+*
* A reel is an object that contains the animation frames and current state for an animation. The reel object has the following properties:
* @param id: (String) - the name of the reel
* @param frames: (Array) - A list of frames in the format [xpos, ypos]
* @param currentFrame: (Number) - The index of the current frame
-* @param easing: (Crafty.easing object) - The object that handles the internal progress of the animation.
+* @param easing: (Crafty.easing object) - The object that handles the internal progress of the animation.
* @param duration: (Number) - The duration in milliseconds.
-*
+*
* Many animation related events pass a reel object as data. As typical with events, this should be treated as read only data that might be later altered by the entity. If you wish to preserve the data, make a copy of it.
*
* @see crafty.sprite
@@ -119,7 +119,7 @@ Crafty.c("SpriteAnimation", {
/*
* The currently active reel.
- * This value is `null` if no reel is active.
+ * This value is `null` if no reel is active.
*/
_currentReel: null,
@@ -215,7 +215,7 @@ Crafty.c("SpriteAnimation", {
id: reelId,
frames: [],
currentFrame: 0,
- easing: new Crafty.easing(duration),
+ easing: new Crafty.easing(duration),
defaultLoops: 1
};
@@ -265,7 +265,7 @@ Crafty.c("SpriteAnimation", {
*
* Play one of the reels previously defined through `.reel(...)`. Simply pass the name of the reel. If you wish the
* animation to play multiple times in succession, pass in the amount of times as an additional parameter.
- * To have the animation repeat indefinitely, pass in `-1`.
+ * To have the animation repeat indefinitely, pass in `-1`.
*
* If another animation is currently playing, it will be paused.
*
@@ -304,7 +304,7 @@ Crafty.c("SpriteAnimation", {
this.pauseAnimation(); // This will pause the current animation, if one is playing
// Handle repeats; if loopCount is undefined and reelID is a number, calling with that signature
- if (typeof loopCount === "undefined")
+ if (typeof loopCount === "undefined")
if (typeof reelId === "number")
loopCount = reelId;
else
@@ -312,9 +312,9 @@ Crafty.c("SpriteAnimation", {
// set the animation to the beginning
currentReel.easing.reset();
-
- // user provided loop count.
+
+ // user provided loop count.
this.loops(loopCount);
// trigger the necessary events and switch to the first frame
@@ -333,7 +333,7 @@ Crafty.c("SpriteAnimation", {
* @comp SpriteAnimation
* @sign public this .resumeAnimation()
*
- * This will resume animation of the current reel from its current state.
+ * This will resume animation of the current reel from its current state.
* If a reel is already playing, or there is no current reel, there will be no effect.
*/
resumeAnimation: function() {
@@ -342,8 +342,8 @@ Crafty.c("SpriteAnimation", {
this._isPlaying = true;
this._currentReel.easing.resume();
this.trigger("StartAnimation", this._currentReel);
- }
- return this;
+ }
+ return this;
},
/**@
@@ -368,7 +368,7 @@ Crafty.c("SpriteAnimation", {
* @sign public this .resetAnimation()
*
* Resets the current animation to its initial state. Resets the number of loops to the last specified value, which defaults to 1.
- *
+ *
* Neither pauses nor resumes the current animation.
*/
resetAnimation: function(){
@@ -387,7 +387,7 @@ Crafty.c("SpriteAnimation", {
* @sign public this .loops(Number loopCount)
* @param loopCount - The number of times to play the animation
*
- * Sets the number of times the animation will loop for.
+ * Sets the number of times the animation will loop for.
* If called while an animation is in progress, the current state will be considered the first loop.
*
* @sign public Number .loops()
@@ -425,10 +425,10 @@ Crafty.c("SpriteAnimation", {
*
* @sign public this .reelPosition(String position)
* Jumps to the specified position. The only currently accepted value is "end", which will jump to the end of the reel.
- *
+ *
* @sign public Number .reelPosition()
* @returns The current frame number
- *
+ *
*/
reelPosition: function(position) {
if (this._currentReel === null)
@@ -447,7 +447,7 @@ Crafty.c("SpriteAnimation", {
position = Math.floor(l * progress);
} else {
if (position !== Math.floor(position))
- throw("Position " + position + " is invalid.");
+ throw("Position " + position + " is invalid.");
if (position < 0)
position = l - 1 + position;
progress = position / l;
@@ -459,10 +459,10 @@ Crafty.c("SpriteAnimation", {
this._setFrame(position);
return this;
-
+
},
-
+
// Bound to "EnterFrame". Progresses the animation by dt, changing the frame if necessary.
_animationTick: function(frameData) {
var currentReel = this._reels[this._currentReelId];
@@ -480,7 +480,7 @@ Crafty.c("SpriteAnimation", {
-
+
// Set the current frame and update the displayed sprite
// The actual progress for the animation must be set seperately.
@@ -490,7 +490,7 @@ Crafty.c("SpriteAnimation", {
return;
currentReel.currentFrame = frameNumber;
this._updateSprite();
- this.trigger("FrameChange", currentReel);
+ this.trigger("FrameChange", currentReel);
},
// Update the displayed sprite.
@@ -539,9 +539,9 @@ Crafty.c("SpriteAnimation", {
* @comp SpriteAnimation
* @sign public Reel .getReel()
* @returns The current reel, or null if there is no active reel
- *
+ *
* @sign public Reel .getReel(reelId)
- * @param reelId - The id of the reel to fetch.
+ * @param reelId - The id of the reel to fetch.
* @returns The specified reel, or `undefined` if no such reel exists.
*
*/
@@ -626,7 +626,7 @@ Crafty.c("Tween", {
*
*/
tween: function (props, duration) {
-
+
var tween = {
props: props,
easing: new Crafty.easing(duration)
@@ -643,7 +643,7 @@ Crafty.c("Tween", {
this.tweenGroup[propname] = props;
}
this.tweens.push(tween);
-
+
return this;
},
@@ -653,11 +653,11 @@ Crafty.c("Tween", {
* @comp Tween
* @sign public this .cancelTween(String target)
* @param target - The property to cancel
- *
+ *
* @sign public this .cancelTween(Object target)
* @param target - An object containing the properties to cancel.
*
- * Stops tweening the specified property or properties.
+ * Stops tweening the specified property or properties.
* Passing the object used to start the tween might be a typical use of the second signature.
*/
cancelTween: function(target){
@@ -670,7 +670,7 @@ Crafty.c("Tween", {
}
return this;
-
+
},
/*
diff --git a/src/collision.js b/src/collision.js
index bf5aeb17..4d2b1240 100644
--- a/src/collision.js
+++ b/src/collision.js
@@ -86,7 +86,7 @@ Crafty.c("Collision", {
},
- // Change the hitbox when a "Resize" event triggers.
+ // Change the hitbox when a "Resize" event triggers.
_resizeMap: function (e) {
var dx, dy, rot = this.rotation * DEG_TO_RAD,
diff --git a/src/core.js b/src/core.js
index 5bf142c0..bf9417fe 100644
--- a/src/core.js
+++ b/src/core.js
@@ -28,7 +28,7 @@ var version = require('./version');
* ~~~
* Passing an integer will select the entity with that `ID`.
*/
-
+
var Crafty = function (selector) {
return new Crafty.fn.init(selector);
},
@@ -464,7 +464,7 @@ Crafty.fn = Crafty.prototype = {
* @sign public this .timeout(Function callback, Number delay)
* @param callback - Method to execute after given amount of milliseconds
* @param delay - Amount of milliseconds to execute the method
- *
+ *
* The delay method will execute a function after a given amount of time in milliseconds.
*
* Essentially a wrapper for `setTimeout`.
@@ -1339,7 +1339,7 @@ Crafty.extend({
// entity6.trigger('Move')), it causes the execution of fnB() and fnC(). When
// the Move event is triggered globally (i.e. Crafty.trigger('Move')), it
// will execute fnA, fnB, fnC, fnD.
- //
+ //
// In this example, "this" is bound to entity #6 whenever fnB() is executed, and
// "this" is bound to Crafty whenever fnD() is executed.
//
diff --git a/src/diamondiso.js b/src/diamondiso.js
index 246c358f..29579f4d 100644
--- a/src/diamondiso.js
+++ b/src/diamondiso.js
@@ -107,7 +107,7 @@ Crafty.extend({
vp._w += (this._tile.width / 2 + ow);
vp._h += (this._tile.height / 2 + oh);
/* Crafty.viewport.x = -vp._x;
- Crafty.viewport.y = -vp._y;
+ Crafty.viewport.y = -vp._y;
Crafty.viewport.width = vp._w;
Crafty.viewport.height = vp._h; */
diff --git a/src/drawing.js b/src/drawing.js
index dc7cd551..2efb6ddf 100644
--- a/src/drawing.js
+++ b/src/drawing.js
@@ -370,7 +370,7 @@ Crafty.DrawManager = (function () {
target._y = Math.min(a._y, b._y);
target._w -= target._x;
target._h -= target._y;
-
+
return target;
},
diff --git a/src/isometric.js b/src/isometric.js
index 13268014..b3c59199 100644
--- a/src/isometric.js
+++ b/src/isometric.js
@@ -111,7 +111,7 @@ Crafty.extend({
return {
x: -Math.ceil(-left / this._tile.width - (top & 1) * 0.5),
y: top / this._tile.height * 2
- };
+ };
},
/**@
* #Crafty.isometric.centerAt
diff --git a/src/storage.js b/src/storage.js
index 563d4eb8..5cdcebed 100644
--- a/src/storage.js
+++ b/src/storage.js
@@ -53,7 +53,7 @@ var Crafty = require('./core.js'),
* @param key - A unique key to search for
* @param type - 'save' or 'cache'
* @param callback - Do things with the data you get back
- *
+ *
* Loads a piece of data from the database.
* Entities will be reconstructed from the serialized string
diff --git a/src/text.js b/src/text.js
index 89c5540c..21402bff 100644
--- a/src/text.js
+++ b/src/text.js
@@ -77,11 +77,11 @@ Crafty.c("Text", {
"cm": 96/2.54,
"mm": 96/25.4,
"in": 96,
- "em": undefined,
+ "em": undefined,
"ex": undefined
};
return function (font){
- var number = parseFloat(font);
+ var number = parseFloat(font);
var match = re.exec(font);
var unit = match ? match[1] : "px";
if (multipliers[unit] !== undefined)
@@ -206,7 +206,7 @@ Crafty.c("Text", {
if(propertyKey == 'family'){
this._textFont[propertyKey] = "'" + key[propertyKey] + "'";
} else {
- this._textFont[propertyKey] = key[propertyKey];
+ this._textFont[propertyKey] = key[propertyKey];
}
}
}
diff --git a/src/viewport.js b/src/viewport.js
index f9446ee1..875b44fd 100644
--- a/src/viewport.js
+++ b/src/viewport.js
@@ -64,7 +64,7 @@ Crafty.extend({
* @comp Crafty.viewport
*
* A rectangle which defines the bounds of the viewport.
- * It should be an object with two properties, `max` and `min`,
+ * It should be an object with two properties, `max` and `min`,
* which are each an object with `x` and `y` properties.
*
* If this property is null, Crafty uses the bounding box of all the items
diff --git a/tests/animation/animation.html b/tests/animation/animation.html
index f22e5c78..17c022d0 100644
--- a/tests/animation/animation.html
+++ b/tests/animation/animation.html
@@ -25,10 +25,10 @@
Sprite animation playground:
-
+
-
+
@@ -36,11 +36,11 @@
Sprite animation playground:
-
+
-
+
-
+
Crafty: Core
diff --git a/tests/dom.html b/tests/dom.html
index 461efbcc..56414f0d 100644
--- a/tests/dom.html
+++ b/tests/dom.html
@@ -1,4 +1,4 @@
-
@@ -12,7 +12,7 @@
security settings when firefox opens an HTML file saved on your computer; it does
not affect your security when you are browsing the internet.]
* To run the tests in chrome: You need to pass a flag when opening chrome.
- For example, in Linux, you would run this command in a Linux terminal:
+ For example, in Linux, you would run this command in a Linux terminal:
chromium-browser /path/to/core.html --allow-file-access-from-files
-->
@@ -26,14 +26,14 @@
$(document).ready(function() {
Crafty.init(500,500);
-
+
module("DOM");
-
+
test("avoidCss3dTransforms", function() {
var useCss3dTransforms = Crafty.e("2D, DOM")
.attr({x: 10, y: 10})
.draw();
-
+
strictEqual(useCss3dTransforms.avoidCss3dTransforms, false);
strictEqual(useCss3dTransforms._cssStyles.transform, "translate3d(10px,10px,0)");
strictEqual(useCss3dTransforms._cssStyles.top, "");
@@ -52,7 +52,7 @@
});
});
-
+
Crafty: Core
diff --git a/tests/events.html b/tests/events.html
index 73168b37..ef0a4d82 100644
--- a/tests/events.html
+++ b/tests/events.html
@@ -1,4 +1,4 @@
-
@@ -12,7 +12,7 @@
security settings when firefox opens an HTML file saved on your computer; it does
not affect your security when you are browsing the internet.]
* To run the tests in chrome: You need to pass a flag when opening chrome.
- For example, in Linux, you would run this command in a Linux terminal:
+ For example, in Linux, you would run this command in a Linux terminal:
chromium-browser /path/to/core.html --allow-file-access-from-files
-->
@@ -26,9 +26,9 @@
$(document).ready(function() {
Crafty.init(500,500);
-
+
module("EVENTS");
-
+
test("Global binding events", function() {
var x = 0;
function add(){x++}
@@ -36,7 +36,7 @@
Crafty.bind("Increment", add)
Crafty.trigger("Increment")
strictEqual(x, 1, "Crafty.bind fired once");
-
+
x = 0;
Crafty.unbind("Increment", add)
@@ -54,7 +54,7 @@
Crafty.uniqueBind("Increment", add);
Crafty.trigger("Increment");
strictEqual(x, 1, "Event bound twice by Crafty.uniqueBound fires only once");
-
+
x = 0;
Crafty.unbind("Increment", add);
Crafty.trigger("Increment")
@@ -63,7 +63,7 @@
});
test("Entity binding events", function() {
-
+
var x = 0;
function add(){x++}
var e = Crafty.e("Triggerable")
@@ -71,7 +71,7 @@
e.bind("Increment", add)
e.trigger("Increment")
strictEqual(x, 1, ".bind fired once");
-
+
x = 0;
e.unbind("Increment", add)
@@ -89,7 +89,7 @@
e.uniqueBind("Increment", add);
e.trigger("Increment");
strictEqual(x, 1, "Event bound twice by .uniqueBound fires only once");
-
+
x = 0;
e.unbind("Increment", add);
e.trigger("Increment")
@@ -145,13 +145,13 @@
strictEqual(temp.def, 1, "second one() should trigger once");
Crafty.unbind("Event A")
-
+
});
test("Data passing", function(){
var x = 0, e;
function add(data){x+=data.amount}
-
+
x = 0;
e = Crafty.e("Triggerable")
e.bind("Increment", add)
@@ -182,10 +182,10 @@
});
-
+
});
-
+
Crafty: Events
diff --git a/tests/isometric.html b/tests/isometric.html
index 255ba4c4..2c5c789f 100644
--- a/tests/isometric.html
+++ b/tests/isometric.html
@@ -1,4 +1,4 @@
-
@@ -12,7 +12,7 @@
security settings when firefox opens an HTML file saved on your computer; it does
not affect your security when you are browsing the internet.]
* To run the tests in chrome: You need to pass a flag when opening chrome.
- For example, in Linux, you would run this command in a Linux terminal:
+ For example, in Linux, you would run this command in a Linux terminal:
chromium-browser /path/to/core.html --allow-file-access-from-files
-->
@@ -26,83 +26,83 @@
$(document).ready(function() {
Crafty.init(500,500);
-
+
module("ISOMETRIC");
test("place tile", function () {
var iso = Crafty.isometric.size(64,16);
-
+
var tile1 = Crafty.e("2D, DOM, Color").attr({x:0, y:0, w:64, h:16}).color("red");
var tile2 = Crafty.e("2D, DOM, Color").attr({x:100, y:100, z:3, w:64, h:16}).color("blue");
-
+
iso.place(0,0,0,tile1);
iso.place(1,2,5,tile2);
-
+
equal(tile1.attr('x'), 0, "First tile should default to origin");
equal(tile1.attr('y'), 0, "First tile should default to origin");
equal(tile1.attr('z'), 0, "z-index should be transferred unchanged");
-
+
equal(tile2.attr('x'), 64 + Crafty.viewport._x, "Each tile should be offset by the sum of the width of those before it");
equal(tile2.attr('y'), -24 + Crafty.viewport._y, "The row should be offset by one and a half times the height");
equal(tile2.attr('z'), 8, "z-index should be added to existing value");
-
+
// Clean up
Crafty("*").destroy();
});
-
+
test("pos2px", function () {
var iso = Crafty.isometric.size(64,16);
-
+
var origin = iso.pos2px(0,0);
equal(origin.left, 0, "First tile should default to origin");
equal(origin.top, 0, "First tile should default to origin");
-
+
var oddNumberedRow = iso.pos2px(0,1);
equal(oddNumberedRow.left, 32, "Odd numbered rows should be be inset by half the width");
equal(oddNumberedRow.top, 8, "Each row should move down by half the height");
-
+
var evenNumberedRow = iso.pos2px(0,2);
equal(evenNumberedRow.left, 0, "Even numbered rows should not be be inset");
equal(evenNumberedRow.top, 16, "Each row should move down by half the height");
-
+
var numberedColumn = iso.pos2px(3,0);
equal(numberedColumn.left, 64 * 3, "Should be inset by the width times the x position");
});
-
+
test("px2pos", function () {
var iso = Crafty.isometric.size(64,16);
-
+
var origin = iso.px2pos(0,0);
equal(origin.x, 0, "Origin should be the corner of the lowest numbered tile");
equal(origin.y, 0, "Origin should be the corner of the lowest numbered tile");
-
+
var oddNumberedRow = iso.px2pos(32, 8);
equal(oddNumberedRow.x, 0, "Odd numbered rows should be be inset by half the width");
equal(oddNumberedRow.y, 1, "Each row should move down by half the height");
-
+
var evenNumberedRow = iso.px2pos(0,16);
equal(evenNumberedRow.x, 0, "Even numbered rows should not be be inset");
equal(evenNumberedRow.y, 2, "Each row should move down by half the height");
-
+
var numberedColumn = iso.px2pos(128,0);
equal(numberedColumn.x, 2, "Should be inset by the width times the x position");
});
-
+
test("round trip conversions", function () {
var iso = Crafty.isometric.size(64,16);
-
+
var startX = 14;
var startY = 21;
-
+
var startingPoint = iso.pos2px(startX,startY);
var end = iso.px2pos(startingPoint.left, startingPoint.top);
-
+
equal(end.x, startX, "x position should match");
equal(end.y, startY, "y position should match");
});
});
-
+
Crafty: Core
diff --git a/tests/loader.html b/tests/loader.html
index ead04651..04a13615 100644
--- a/tests/loader.html
+++ b/tests/loader.html
@@ -12,7 +12,7 @@
security settings when firefox opens an HTML file saved on your computer; it does
not affect your security when you are browsing the internet.]
* To run the tests in chrome: You need to pass a flag when opening chrome.
- For example, in Linux, you would run this command in a Linux terminal:
+ For example, in Linux, you would run this command in a Linux terminal:
chromium-browser /path/to/core.html --allow-file-access-from-files
-->
diff --git a/tests/stage.html b/tests/stage.html
index cf25c774..43829410 100644
--- a/tests/stage.html
+++ b/tests/stage.html
@@ -1,4 +1,4 @@
-
@@ -62,7 +62,7 @@
Crafty.viewport.follow(e, 0, 0);
equal(Crafty.viewport._x, -100, "Center viewport on entity.x but take clamp into account");
equal(Crafty.viewport._y, -70, "Center viewport on entity.y but take clamp into account");
-
+
//Make large enough so the viewport won't get clamped
Crafty.e("2D, DOM").attr({ x: 0, y: 0, w: Crafty.viewport.width * 2 + 50, h: Crafty.viewport.height*2+35 });
Crafty.viewport.follow(e, 0, 0);
@@ -97,7 +97,7 @@
Crafty.timer.simulateFrames(10);
equal(Crafty.viewport._x, -e.w / 2 + Crafty.viewport.width / 2, "Entity still centered 10 frames later");
- Crafty.viewport.clampToEntities = false;
+ Crafty.viewport.clampToEntities = false;
var e2 = Crafty.e("2D, DOM").attr({ x: 450, y: 450, w: 20, h: 20 });
Crafty.viewport.scroll('x', 1500);
Crafty.viewport.scroll('y', 300);
@@ -105,8 +105,8 @@
Crafty.timer.simulateFrames(1);
equal(Crafty.viewport._x, Math.floor(-(e2.x + e2.w/2 - Crafty.viewport.width / 2)), "Entity centered from non-zero origin");
equal(Crafty.viewport._y, Math.floor(-(e2.y + e2.h/2 - Crafty.viewport.height / 2)), "Entity centered from non-zero origin");
-
- Crafty.viewport.clampToEntities = true;
+
+ Crafty.viewport.clampToEntities = true;
Crafty.viewport.scroll('x', 0);
Crafty.viewport.scroll('y', 0);
});
@@ -122,7 +122,7 @@
lastKnownTime = params.gameTime;
}
});
-
+
setTimeout(function () {
var endTime = lastKnownTime;
ok(endTime > startTime, "EndTime " + endTime + " must be larger than StartTime " + startTime);
@@ -133,7 +133,7 @@
});
-
+
-
-
diff --git a/tests/touchevents.html b/tests/touchevents.html
index 2525e259..ee85c449 100644
--- a/tests/touchevents.html
+++ b/tests/touchevents.html
@@ -1,28 +1,28 @@
-
-
+
+
\ No newline at end of file
diff --git a/tests/tween.html b/tests/tween.html
deleted file mode 100644
index af79d761..00000000
--- a/tests/tween.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Crafty: Tween
-
-
-
-
-
test markup, will be hidden
-
-
From e9e21aa9e389b2d8e7702c93e28dc9a2068859ee Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Thu, 2 Jan 2014 11:08:04 +0100
Subject: [PATCH 43/61] Correct the name of the modules
---
tests/core.js | 2 +-
tests/events.js | 2 +-
tests/isometric.js | 2 +-
tests/loader.js | 2 +-
tests/math.js | 2 +-
tests/sound.js | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/tests/core.js b/tests/core.js
index 80296850..0df8def8 100644
--- a/tests/core.js
+++ b/tests/core.js
@@ -1,4 +1,4 @@
-module("CORE");
+module("Core");
test("getVersion", function() {
diff --git a/tests/events.js b/tests/events.js
index 8d2f5531..629674be 100644
--- a/tests/events.js
+++ b/tests/events.js
@@ -1,4 +1,4 @@
-module("EVENTS");
+module("Events");
test("Global binding events", function() {
var x = 0;
diff --git a/tests/isometric.js b/tests/isometric.js
index bfa01727..59e9cf6a 100644
--- a/tests/isometric.js
+++ b/tests/isometric.js
@@ -1,4 +1,4 @@
-module("ISOMETRIC");
+module("Isometric");
test("place tile", function() {
var iso = Crafty.isometric.size(64, 16);
diff --git a/tests/loader.js b/tests/loader.js
index 928bbd49..33fcd358 100644
--- a/tests/loader.js
+++ b/tests/loader.js
@@ -1,4 +1,4 @@
-module('LOADER');
+module('Loader');
asyncTest('assets loading', function() {
expect(1);
diff --git a/tests/math.js b/tests/math.js
index 21f20351..fa82703e 100644
--- a/tests/math.js
+++ b/tests/math.js
@@ -3,7 +3,7 @@ var Vector2D = Crafty.math.Vector2D;
// tests for general functions should go here (.abs(), .amountOf(), etc)
-module("Vector2D");
+module("Math - Vector2D");
test("constructor", function() {
var v0 = new Vector2D();
diff --git a/tests/sound.js b/tests/sound.js
index 4a870e98..d408eee9 100644
--- a/tests/sound.js
+++ b/tests/sound.js
@@ -1,4 +1,4 @@
-module("Audio");
+module("Sound");
//Set up some test fixtures
function MockAudio() {
From 07a054f2a9a203048be05f756e61fc96cb4eabbb Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Thu, 2 Jan 2014 11:39:18 +0100
Subject: [PATCH 44/61] Makes the module cleanup after themselves instead of
doing it every time in the test manually
---
tests/2d.js | 471 ++++++++++++++++++++++++++++++++++++++
tests/core.js | 556 ++++-----------------------------------------
tests/dom.js | 10 +-
tests/events.js | 10 +-
tests/index.html | 2 +-
tests/isometric.js | 10 +-
tests/loader.js | 10 +-
tests/math.js | 10 +-
tests/sound.js | 11 +-
tests/stage.js | 18 +-
tests/text.js | 16 +-
tests/tween.js | 11 +-
12 files changed, 609 insertions(+), 526 deletions(-)
create mode 100644 tests/2d.js
diff --git a/tests/2d.js b/tests/2d.js
new file mode 100644
index 00000000..9869ece3
--- /dev/null
+++ b/tests/2d.js
@@ -0,0 +1,471 @@
+module("2D", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
+
+test("position", function() {
+ var player = Crafty.e("2D, DOM, Color").attr({
+ w: 50,
+ h: 50
+ }).color("red");
+ player.x += 50;
+ strictEqual(player._x, 50, "X moved");
+
+ player.y += 50;
+ strictEqual(player._y, 50, "Y moved");
+
+ player.w += 50;
+ strictEqual(player._w, 100, "Width increase");
+
+ player.h += 50;
+ strictEqual(player._h, 100, "Height increase");
+
+ strictEqual(player._globalZ, player[0], "Global Z, Before");
+
+ player.z = 1;
+ strictEqual(player._z, 1, "Z index");
+
+ var global_z_guess;
+ if (player[0] < 10) {
+ global_z_guess = parseInt('10000' + player[0], 10);
+ } else {
+ global_z_guess = parseInt('1000' + player[0], 10);
+ }
+ strictEqual(player._globalZ, global_z_guess, "Global Z, After");
+
+});
+
+test("intersect", function() {
+ var player = Crafty.e("2D, DOM, Color").attr({
+ w: 50,
+ h: 50
+ }).color("red");
+ player.x = 0;
+ player.y = 0;
+ player.w = 50;
+ player.h = 50;
+
+ strictEqual(player.intersect(0, 0, 100, 50), true, "Intersected");
+
+ strictEqual(player.intersect({
+ x: 0,
+ y: 0,
+ w: 100,
+ h: 50
+ }), true, "Intersected Again");
+
+ strictEqual(player.intersect(100, 100, 100, 50), false, "Didn't intersect");
+
+});
+
+test("within", function() {
+ var player = Crafty.e("2D, DOM, Color").attr({
+ w: 50,
+ h: 50
+ });
+ player.x = 0;
+ player.y = 0;
+ player.w = 50;
+ player.h = 50;
+
+ strictEqual(player.within(0, 0, 50, 50), true, "Within");
+
+ strictEqual(player.within(-1, -1, 51, 51), true, "Within");
+
+
+ strictEqual(player.within({
+ _x: 0,
+ _y: 0,
+ _w: 50,
+ _h: 50
+ }), true, "Within Again");
+
+ strictEqual(player.within(0, 0, 40, 50), false, "Wasn't within");
+
+ player.rotation = 90; // Once rotated, the entity should no longer be within the rectangle
+
+ strictEqual(player.within(0, 0, 50, 50), false, "Rotated, Not within");
+ strictEqual(player.within(-50, 0, 50, 50), true, "Rotated, within rotated area");
+
+});
+
+test("contains", function() {
+ var player = Crafty.e("2D, DOM, Color").attr({
+ w: 50,
+ h: 50
+ });
+ player.x = 0;
+ player.y = 0;
+ player.w = 50;
+ player.h = 50;
+
+
+ strictEqual(player.contains(0, 0, 50, 50), true, "Contains");
+
+ strictEqual(player.contains(1, 1, 49, 49), true, "Contains");
+
+ strictEqual(player.contains({
+ _x: 0,
+ _y: 0,
+ _w: 50,
+ _h: 50
+ }), true, "Contains");
+
+ strictEqual(player.contains(1, 1, 51, 51), false, "Doesn't contain");
+
+ player.rotation = 90;
+
+ strictEqual(player.contains(0, 0, 50, 50), false, "Rotated, no longer contains");
+ strictEqual(player.within(-50, 0, 50, 50), true, "Rotated, contains rotated area");
+
+});
+
+
+
+test("circle", function() {
+ var player = Crafty.e("2D, DOM, Color").attr({
+ w: 50,
+ h: 50
+ }).color("red");
+ var circle = new Crafty.circle(0, 0, 10);
+
+ strictEqual(circle.containsPoint(1, 2), true, "Contained the point");
+ strictEqual(circle.containsPoint(8, 9), false, "Didn't contain the point");
+
+ circle.shift(1, 0);
+
+ strictEqual(circle.x, 1, "Shifted of one pixel on the x axis");
+ strictEqual(circle.y, 0, "circle.y didn't change");
+ strictEqual(circle.radius, 10, "circle.radius didn't change");
+
+});
+
+test("child", function() {
+ var parent0 = Crafty.e("2D, DOM, Color").attr({
+ x: 0,
+ y: 0,
+ w: 50,
+ h: 50
+ }).color("red");
+ var child0 = Crafty.e("2D, DOM, Color").attr({
+ x: 1,
+ y: 1,
+ w: 50,
+ h: 50
+ }).color("red");
+ var child1 = Crafty.e("2D, DOM, Color").attr({
+ x: 2,
+ y: 2,
+ w: 50,
+ h: 50
+ }).color("red");
+ var child2 = Crafty.e("2D, DOM, Color").attr({
+ x: 3,
+ y: 3,
+ w: 50,
+ h: 50
+ }).color("red");
+ var child3 = Crafty.e("2D, DOM, Color").attr({
+ x: 4,
+ y: 4,
+ w: 50,
+ h: 50
+ }).color("red");
+ var child0_ID = child0[0];
+ var child1_ID = child1[0];
+ var child2_ID = child2[0];
+ var child3_ID = child3[0];
+ parent0.attach(child0);
+ parent0.attach(child1);
+ parent0.attach(child2);
+ parent0.attach(child3);
+ parent0.x += 50;
+ strictEqual(child0._x, 51, 'child0 shifted when parent did');
+ strictEqual(child1._x, 52, 'child1 shifted when parent did');
+ child0.x += 1;
+ child1.x += 1;
+ strictEqual(parent0._x, 50, 'child shifts do not move the parent');
+ child1.destroy();
+ deepEqual(parent0._children, [child0, child2, child3], 'child1 cleared itself from parent0._children when destroyed');
+ parent0.destroy();
+ strictEqual(Crafty(child0_ID).length, 0, 'destruction of parent killed child0');
+ strictEqual(Crafty(child2_ID).length, 0, 'destruction of parent killed child2');
+ strictEqual(Crafty(child3_ID).length, 0, 'destruction of parent killed child3');
+
+});
+
+test("child_rotate", function() {
+ var Round = function(x) {
+ return Math.round(x * 100) / 100
+ };
+ var parent = Crafty.e("2D, DOM, Color")
+ .attr({
+ x: 0,
+ y: 0,
+ w: 50,
+ h: 50,
+ rotation: 10
+ })
+ .color("red");
+ var child = Crafty.e("2D, DOM, Color")
+ .attr({
+ x: 10,
+ y: 10,
+ w: 50,
+ h: 50,
+ rotation: 15
+ })
+ .color("red");
+ parent.attach(child);
+
+ parent.rotation += 20;
+ strictEqual(parent.rotation, 30, 'parent rotates normally');
+ strictEqual(child.rotation, 35, 'child follows parent rotation');
+
+ child.rotation += 22;
+ strictEqual(parent.rotation, 30, 'parent ignores child rotation');
+ strictEqual(child.rotation, 57, 'child rotates normally');
+
+ parent.rotation = 100; // Rotation by 90 degrees from initial position
+ strictEqual(Round(child.x), -10, "Child moved around parent upon rotation (x).")
+ strictEqual(Round(child.y), 10, "Child moved around parent upon rotation (y).")
+
+});
+
+
+
+// This test assumes that the "circles" are really octagons, as per Crafty.circle.
+test("SAT", function() {
+ var e = Crafty.e("2D, Collision");
+ var c1 = new Crafty.circle(100, 100, 10);
+ var c2 = new Crafty.circle(100, 105, 10);
+ strictEqual((e._SAT(c1, c2).overlap < -13.8 && e._SAT(c1, c2).overlap > -13.9), true, "Expected overlap to be about -13.86 ( or 15 cos[pi/8])")
+
+});
+
+
+test("adjustable boundary", function() {
+ e = Crafty.e("2D").attr({
+ x: 10,
+ y: 10,
+ w: 10,
+ h: 10
+ })
+
+ // Four argument version
+ e.offsetBoundary(10, 1, 3, 0);
+ equal(e._bx1, 10, "X1 boundary set");
+ equal(e._bx2, 3, "X2 boundary set");
+ equal(e._by1, 1, "Y1 boundary set");
+ equal(e._by2, 0, "Y2 boundary set");
+
+ e._calculateMBR(10, 10, 0)
+
+ var mbr = e._mbr;
+
+ equal(mbr._h, 11, "MBR height uses boundaries (11)");
+ equal(mbr._w, 23, "MBR width uses boundaries (23)");
+
+ // One argument version
+ e.offsetBoundary(5);
+ equal(e._bx1, 5, "X1 boundary set");
+ equal(e._bx2, 5, "X2 boundary set");
+ equal(e._by1, 5, "Y1 boundary set");
+ equal(e._by2, 5, "Y2 boundary set");
+
+})
+
+
+test("disableControl and enableControl", function() {
+ var e = Crafty.e("2D, Twoway")
+ .attr({
+ x: 0
+ })
+ .twoway(1);
+
+ equal(e._movement.x, 0);
+ equal(e._x, 0);
+ Crafty.trigger('KeyDown', {
+ key: Crafty.keys.D
+ });
+ Crafty.trigger('EnterFrame');
+ equal(e._movement.x, 1);
+ equal(e._x, 1);
+
+ e.disableControl();
+ Crafty.trigger('EnterFrame');
+ equal(e._movement.x, 1);
+ equal(e._x, 1);
+
+ Crafty.trigger('KeyUp', {
+ key: Crafty.keys.D
+ });
+ Crafty.trigger('EnterFrame');
+ equal(e._movement.x, 0);
+ equal(e._x, 1);
+
+ e.enableControl();
+ Crafty.trigger('EnterFrame');
+ equal(e._movement.x, 0);
+ equal(e._x, 1);
+
+ Crafty.trigger('KeyDown', {
+ key: Crafty.keys.D
+ });
+ Crafty.trigger('EnterFrame');
+ equal(e._movement.x, 1);
+ equal(e._x, 2);
+
+ Crafty.trigger('KeyUp', {
+ key: Crafty.keys.D
+ });
+ Crafty.trigger('EnterFrame');
+ equal(e._movement.x, 0);
+ equal(e._x, 2);
+
+ e.destroy();
+});
+
+
+test("Resizing 2D objects & hitboxes", function() {
+ var e = Crafty.e("2D, Collision");
+ e.attr({
+ x: 0,
+ y: 0,
+ w: 40,
+ h: 50
+ })
+
+ equal(e.map.points[0][0], 0, "Before rotation: x_0 is 0")
+ equal(e.map.points[0][1], 0, "y_0 is 0")
+ equal(e.map.points[2][0], 40, "x_2 is 40")
+ equal(e.map.points[2][1], 50, "y_2 is 50")
+
+ e.rotation = 90;
+
+ equal(Math.round(e.map.points[0][0]), 0, "After rotation by 90 deg: x_0 is 0")
+ equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
+ equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
+ equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40")
+
+ // After rotation the MBR will have changed
+ equal(Math.round(e._mbr._w), 50, "_mbr._w is 50");
+ equal(Math.round(e._mbr._h), 40, "_mbr._h is 40");
+ equal(Math.round(e._mbr._x), -50, "_mbr._x is -50");
+ equal(Math.round(e._mbr._y), 0, "_mbr._y is 0");
+
+ e.collision(); // Check that regenerating the hitbox while rotated works correctly
+
+ equal(Math.round(e.map.points[0][0]), 0, "After rotation and hitbox regeneration: x_0 is 0")
+ equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
+ equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
+ equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40")
+
+
+ // Check that changing the width when rotated resizes correctly for both hitbox and MBR
+ // Rotated by 90 degrees, changing the width of the entity should change the height of the hitbox/mbr
+ e.w = 100;
+
+ equal(Math.round(e.map.points[0][0]), 0, "After rotation and increase in width: x_0 is 0")
+ equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
+ equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
+ equal(Math.round(e.map.points[2][1]), 100, "y_2 is 100")
+
+ // After rotation the MBR will have changed
+ equal(Math.round(e._mbr._w), 50, "_mbr._w is 50");
+ equal(Math.round(e._mbr._h), 100, "_mbr._h is 100");
+ equal(Math.round(e._mbr._x), -50, "_mbr._x is -50");
+ equal(Math.round(e._mbr._y), 0, "_mbr._y is 0");
+
+ e.destroy();
+});
+
+test("Hitboxes outside of entities (CBR)", function() {
+ var poly = new Crafty.polygon([
+ [-8, 6],
+ [0, -8],
+ [8, -14],
+ [16, -8],
+ [24, 6]
+ ]);
+
+ var e = Crafty.e("2D, Collision").attr({
+ x: 50,
+ y: 50,
+ w: 16,
+ h: 16
+ }).collision(poly);
+
+ ok(e._cbr !== null, "_cbr exists");
+ var cbr = e._cbr;
+ // Test whether cbr actually bounds hitbox+object
+ ok(cbr._x <= 42, "cbr x position correct");
+ ok(cbr._y <= 36, "cbr y position correct");
+ ok(cbr._x + cbr._w >= 74, "cbr width correct");
+ ok(cbr._y + cbr._h >= 66, "cbr height correct");
+
+ var x0 = cbr._x,
+ y0 = cbr._y;
+
+ e.x += 10;
+ e.y += 15;
+
+ equal(cbr._x, x0 + 10, "cbr x position moves correctly");
+ equal(cbr._y, y0 + 15, "cbr y position moves correctly");
+
+})
+
+test("CBRs on resize", function() {
+ var poly = new Crafty.polygon([
+ [0, 0],
+ [0, 12],
+ [12, 12],
+ [12, 0]
+ ]);
+
+ var e = Crafty.e("2D, Collision").attr({
+ x: 50,
+ y: 50,
+ w: 15,
+ h: 15
+ }).collision(poly);
+
+ ok(e._cbr === null, "_cbr should not exist");
+
+ e.w = 10;
+
+ ok(e._cbr !== null, "_cbr should now exist after entity shrinks");
+
+ e.w = 20;
+
+ ok(e._cbr === null, "_cbr should not exist after entity grows again");
+
+})
+
+test("CBRs should be removed on removal of component", function() {
+ var poly = new Crafty.polygon([
+ [0, 0],
+ [0, 12],
+ [12, 12],
+ [12, 0]
+ ]);
+
+ var e = Crafty.e("2D, Collision").attr({
+ x: 50,
+ y: 50,
+ w: 10,
+ h: 10
+ }).collision(poly);
+
+ ok(e._cbr !== null, "_cbr should exist to begin with");
+
+ e.removeComponent("Collision");
+
+ ok(e._cbr === null, "_cbr should now be removed along with Collision");
+
+});
\ No newline at end of file
diff --git a/tests/core.js b/tests/core.js
index 0df8def8..3e93162d 100644
--- a/tests/core.js
+++ b/tests/core.js
@@ -1,4 +1,12 @@
-module("Core");
+module("Core", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
test("getVersion", function() {
@@ -20,8 +28,7 @@ test("selectors", function() {
strictEqual(Crafty("*").length, 7, "All components - universal selector");
strictEqual(Crafty(first[0]), first, "Get by ID");
- // Clean up
- Crafty("*").destroy();
+
});
test("addComponent and removeComponent", function() {
@@ -46,8 +53,6 @@ test("addComponent and removeComponent", function() {
first.removeComponent("comp", false);
strictEqual(!first.added && !first.has("comp"), true, "hard-removed component (properties are gone)");
- // Clean up
- Crafty("*").destroy();
});
test("remove", function() {
@@ -87,8 +92,7 @@ test("attr", function() {
});
strictEqual(first.prop, "test", "properties from object assigned");
strictEqual(first.another, 56, "properties from object assigned");
- // Clean up
- Crafty("*").destroy();
+
});
test("setter", function() {
@@ -112,8 +116,7 @@ test("setter", function() {
first.p2 = 2;
first.p3 = 3;
strictEqual(first._p2 + first._p3, 10, "two property setters");
- // Clean up
- Crafty("*").destroy();
+
});
test("bind", function() {
@@ -124,8 +127,7 @@ test("bind", function() {
});
first.trigger("myevent");
strictEqual(triggered, true, "custom event triggered");
- // Clean up
- Crafty("*").destroy();
+
});
test("unbind", function() {
@@ -148,8 +150,7 @@ test("unbind", function() {
first.bind("myevent", callback2);
first.unbind("myevent", callback);
first.trigger("myevent");
- // Clean up
- Crafty("*").destroy();
+
});
test("globalBindAndUnbind", function() {
@@ -196,8 +197,7 @@ test("each", function() {
count++;
});
strictEqual(count, 7, "Iterated all elements");
- // Clean up
- Crafty("*").destroy();
+
});
test("Crafty.get() to find an array", function() {
@@ -211,7 +211,6 @@ test("Crafty.get() to find an array", function() {
equal(result[0].has("test"), true, "Result elements should have correct component");
equal(collection[0], result[0].getId(), "First id of result should match first id of Crafty array");
- Crafty("*").destroy();
})
test("Crafty.get(index) to find the indicated entity", function() {
@@ -229,7 +228,6 @@ test("Crafty.get(index) to find the indicated entity", function() {
equal(result.has("test"), true, "Result should have correct component");
equal(result.getId(), collection[2], "result should be last element of collection");
- Crafty("*").destroy();
})
test("Crafty.get(index) error checking", function() {
@@ -246,9 +244,6 @@ test("Crafty.get(index) error checking", function() {
result = collection.get(-4);
equal(typeof result, "undefined", "result of get(-4) should be undefined")
-
-
- Crafty("*").destroy();
})
test("Crafty.get with only one object", function() {
@@ -258,7 +253,7 @@ test("Crafty.get with only one object", function() {
equal(result.getId(), e.getId(), "result of get(0) is correct entity")
result = collection.get();
equal(result.length, 1, "result of get() is array of length 1");
- Crafty("*").destroy();
+
})
test("requires", function() {
@@ -278,8 +273,7 @@ test("requires", function() {
strictEqual(first.already, "already", "Didn't overwrite property");
strictEqual(first.notyet, true, "Assigned if didn't have");
ok(first.has("already") && first.has("notyet"), "Both added");
- // Clean up
- Crafty("*").destroy();
+
});
test("destroy", function() {
@@ -287,11 +281,18 @@ test("destroy", function() {
id = first[0]; //id
first.destroy();
strictEqual(Crafty(id).length, 0, "Not listed");
- // Clean up
- Crafty("*").destroy();
+
});
-module("Scenes");
+module("Scenes", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
test("Scene calling", function() {
var x = 0;
@@ -301,6 +302,7 @@ test("Scene calling", function() {
Crafty.scene("test-call", sceneInit);
Crafty.scene("test-call");
equal(x, 13, "Scene called succesfully.")
+
});
test("Scene parameters", function() {
@@ -321,7 +323,6 @@ test("Calling a scene destroys 2D entities", function() {
var l = Crafty("2D").length;
equal(l, 0, "2D entity destroyed on scene change.");
- Crafty("*").destroy();
});
test("Calling a scene doesn't destroy 2D entities with Persist", function() {
@@ -332,7 +333,6 @@ test("Calling a scene doesn't destroy 2D entities with Persist", function() {
var l = Crafty("2D").length;
equal(l, 1, "Persist entity remains on scene change.");
- Crafty("*").destroy();
});
@@ -353,493 +353,20 @@ test("Scene uninit function called", function() {
Crafty.enterScene("test-uninit");
Crafty.enterScene("game");
equal(x, 20, "Uninit scene called successfully when chanced to another scene");
-});
-
-module("2D");
-
-test("position", function() {
- var player = Crafty.e("2D, DOM, Color").attr({
- w: 50,
- h: 50
- }).color("red");
- player.x += 50;
- strictEqual(player._x, 50, "X moved");
-
- player.y += 50;
- strictEqual(player._y, 50, "Y moved");
-
- player.w += 50;
- strictEqual(player._w, 100, "Width increase");
-
- player.h += 50;
- strictEqual(player._h, 100, "Height increase");
-
- strictEqual(player._globalZ, player[0], "Global Z, Before");
-
- player.z = 1;
- strictEqual(player._z, 1, "Z index");
-
- var global_z_guess;
- if (player[0] < 10) {
- global_z_guess = parseInt('10000' + player[0], 10);
- } else {
- global_z_guess = parseInt('1000' + player[0], 10);
- }
- strictEqual(player._globalZ, global_z_guess, "Global Z, After");
- // Clean up
- Crafty("*").destroy();
-});
-
-test("intersect", function() {
- var player = Crafty.e("2D, DOM, Color").attr({
- w: 50,
- h: 50
- }).color("red");
- player.x = 0;
- player.y = 0;
- player.w = 50;
- player.h = 50;
-
- strictEqual(player.intersect(0, 0, 100, 50), true, "Intersected");
-
- strictEqual(player.intersect({
- x: 0,
- y: 0,
- w: 100,
- h: 50
- }), true, "Intersected Again");
-
- strictEqual(player.intersect(100, 100, 100, 50), false, "Didn't intersect");
- // Clean up
- Crafty("*").destroy();
-});
-
-test("within", function() {
- var player = Crafty.e("2D, DOM, Color").attr({
- w: 50,
- h: 50
- });
- player.x = 0;
- player.y = 0;
- player.w = 50;
- player.h = 50;
-
- strictEqual(player.within(0, 0, 50, 50), true, "Within");
-
- strictEqual(player.within(-1, -1, 51, 51), true, "Within");
-
-
- strictEqual(player.within({
- _x: 0,
- _y: 0,
- _w: 50,
- _h: 50
- }), true, "Within Again");
-
- strictEqual(player.within(0, 0, 40, 50), false, "Wasn't within");
-
- player.rotation = 90; // Once rotated, the entity should no longer be within the rectangle
-
- strictEqual(player.within(0, 0, 50, 50), false, "Rotated, Not within");
- strictEqual(player.within(-50, 0, 50, 50), true, "Rotated, within rotated area");
-
-
-
- // Clean up
- Crafty("*").destroy();
-});
-
-test("contains", function() {
- var player = Crafty.e("2D, DOM, Color").attr({
- w: 50,
- h: 50
- });
- player.x = 0;
- player.y = 0;
- player.w = 50;
- player.h = 50;
-
-
- strictEqual(player.contains(0, 0, 50, 50), true, "Contains");
-
- strictEqual(player.contains(1, 1, 49, 49), true, "Contains");
-
- strictEqual(player.contains({
- _x: 0,
- _y: 0,
- _w: 50,
- _h: 50
- }), true, "Contains");
-
- strictEqual(player.contains(1, 1, 51, 51), false, "Doesn't contain");
-
- player.rotation = 90;
-
- strictEqual(player.contains(0, 0, 50, 50), false, "Rotated, no longer contains");
- strictEqual(player.within(-50, 0, 50, 50), true, "Rotated, contains rotated area");
-
- // Clean up
- Crafty("*").destroy();
-});
-
-
-
-test("circle", function() {
- var player = Crafty.e("2D, DOM, Color").attr({
- w: 50,
- h: 50
- }).color("red");
- var circle = new Crafty.circle(0, 0, 10);
-
- strictEqual(circle.containsPoint(1, 2), true, "Contained the point");
- strictEqual(circle.containsPoint(8, 9), false, "Didn't contain the point");
-
- circle.shift(1, 0);
-
- strictEqual(circle.x, 1, "Shifted of one pixel on the x axis");
- strictEqual(circle.y, 0, "circle.y didn't change");
- strictEqual(circle.radius, 10, "circle.radius didn't change");
- // Clean up
- Crafty("*").destroy();
-});
-
-test("child", function() {
- var parent0 = Crafty.e("2D, DOM, Color").attr({
- x: 0,
- y: 0,
- w: 50,
- h: 50
- }).color("red");
- var child0 = Crafty.e("2D, DOM, Color").attr({
- x: 1,
- y: 1,
- w: 50,
- h: 50
- }).color("red");
- var child1 = Crafty.e("2D, DOM, Color").attr({
- x: 2,
- y: 2,
- w: 50,
- h: 50
- }).color("red");
- var child2 = Crafty.e("2D, DOM, Color").attr({
- x: 3,
- y: 3,
- w: 50,
- h: 50
- }).color("red");
- var child3 = Crafty.e("2D, DOM, Color").attr({
- x: 4,
- y: 4,
- w: 50,
- h: 50
- }).color("red");
- var child0_ID = child0[0];
- var child1_ID = child1[0];
- var child2_ID = child2[0];
- var child3_ID = child3[0];
- parent0.attach(child0);
- parent0.attach(child1);
- parent0.attach(child2);
- parent0.attach(child3);
- parent0.x += 50;
- strictEqual(child0._x, 51, 'child0 shifted when parent did');
- strictEqual(child1._x, 52, 'child1 shifted when parent did');
- child0.x += 1;
- child1.x += 1;
- strictEqual(parent0._x, 50, 'child shifts do not move the parent');
- child1.destroy();
- deepEqual(parent0._children, [child0, child2, child3], 'child1 cleared itself from parent0._children when destroyed');
- parent0.destroy();
- strictEqual(Crafty(child0_ID).length, 0, 'destruction of parent killed child0');
- strictEqual(Crafty(child2_ID).length, 0, 'destruction of parent killed child2');
- strictEqual(Crafty(child3_ID).length, 0, 'destruction of parent killed child3');
- // Clean up
- Crafty("*").destroy();
-});
-
-test("child_rotate", function() {
- var Round = function(x) {
- return Math.round(x * 100) / 100
- };
- var parent = Crafty.e("2D, DOM, Color")
- .attr({
- x: 0,
- y: 0,
- w: 50,
- h: 50,
- rotation: 10
- })
- .color("red");
- var child = Crafty.e("2D, DOM, Color")
- .attr({
- x: 10,
- y: 10,
- w: 50,
- h: 50,
- rotation: 15
- })
- .color("red");
- parent.attach(child);
-
- parent.rotation += 20;
- strictEqual(parent.rotation, 30, 'parent rotates normally');
- strictEqual(child.rotation, 35, 'child follows parent rotation');
-
- child.rotation += 22;
- strictEqual(parent.rotation, 30, 'parent ignores child rotation');
- strictEqual(child.rotation, 57, 'child rotates normally');
-
- parent.rotation = 100; // Rotation by 90 degrees from initial position
- strictEqual(Round(child.x), -10, "Child moved around parent upon rotation (x).")
- strictEqual(Round(child.y), 10, "Child moved around parent upon rotation (y).")
-
- // Clean up
- Crafty("*").destroy();
-});
-
-
-
-// This test assumes that the "circles" are really octagons, as per Crafty.circle.
-test("SAT", function() {
- var e = Crafty.e("2D, Collision");
- var c1 = new Crafty.circle(100, 100, 10);
- var c2 = new Crafty.circle(100, 105, 10);
- strictEqual((e._SAT(c1, c2).overlap < -13.8 && e._SAT(c1, c2).overlap > -13.9), true, "Expected overlap to be about -13.86 ( or 15 cos[pi/8])")
- // Clean up
- Crafty("*").destroy();
-});
-
-
-test("adjustable boundary", function() {
- e = Crafty.e("2D").attr({
- x: 10,
- y: 10,
- w: 10,
- h: 10
- })
-
- // Four argument version
- e.offsetBoundary(10, 1, 3, 0);
- equal(e._bx1, 10, "X1 boundary set");
- equal(e._bx2, 3, "X2 boundary set");
- equal(e._by1, 1, "Y1 boundary set");
- equal(e._by2, 0, "Y2 boundary set");
-
- e._calculateMBR(10, 10, 0)
-
- var mbr = e._mbr;
-
- equal(mbr._h, 11, "MBR height uses boundaries (11)");
- equal(mbr._w, 23, "MBR width uses boundaries (23)");
-
- // One argument version
- e.offsetBoundary(5);
- equal(e._bx1, 5, "X1 boundary set");
- equal(e._bx2, 5, "X2 boundary set");
- equal(e._by1, 5, "Y1 boundary set");
- equal(e._by2, 5, "Y2 boundary set");
-
-
-
- Crafty("*").destroy();
-
-
-})
-
-
-test("disableControl and enableControl", function() {
- var e = Crafty.e("2D, Twoway")
- .attr({
- x: 0
- })
- .twoway(1);
-
- equal(e._movement.x, 0);
- equal(e._x, 0);
- Crafty.trigger('KeyDown', {
- key: Crafty.keys.D
- });
- Crafty.trigger('EnterFrame');
- equal(e._movement.x, 1);
- equal(e._x, 1);
-
- e.disableControl();
- Crafty.trigger('EnterFrame');
- equal(e._movement.x, 1);
- equal(e._x, 1);
-
- Crafty.trigger('KeyUp', {
- key: Crafty.keys.D
- });
- Crafty.trigger('EnterFrame');
- equal(e._movement.x, 0);
- equal(e._x, 1);
-
- e.enableControl();
- Crafty.trigger('EnterFrame');
- equal(e._movement.x, 0);
- equal(e._x, 1);
- Crafty.trigger('KeyDown', {
- key: Crafty.keys.D
- });
- Crafty.trigger('EnterFrame');
- equal(e._movement.x, 1);
- equal(e._x, 2);
-
- Crafty.trigger('KeyUp', {
- key: Crafty.keys.D
- });
- Crafty.trigger('EnterFrame');
- equal(e._movement.x, 0);
- equal(e._x, 2);
-
- e.destroy();
});
-test("Resizing 2D objects & hitboxes", function() {
- var e = Crafty.e("2D, Collision");
- e.attr({
- x: 0,
- y: 0,
- w: 40,
- h: 50
- })
-
- equal(e.map.points[0][0], 0, "Before rotation: x_0 is 0")
- equal(e.map.points[0][1], 0, "y_0 is 0")
- equal(e.map.points[2][0], 40, "x_2 is 40")
- equal(e.map.points[2][1], 50, "y_2 is 50")
-
- e.rotation = 90;
-
- equal(Math.round(e.map.points[0][0]), 0, "After rotation by 90 deg: x_0 is 0")
- equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
- equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
- equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40")
-
- // After rotation the MBR will have changed
- equal(Math.round(e._mbr._w), 50, "_mbr._w is 50");
- equal(Math.round(e._mbr._h), 40, "_mbr._h is 40");
- equal(Math.round(e._mbr._x), -50, "_mbr._x is -50");
- equal(Math.round(e._mbr._y), 0, "_mbr._y is 0");
-
- e.collision(); // Check that regenerating the hitbox while rotated works correctly
-
- equal(Math.round(e.map.points[0][0]), 0, "After rotation and hitbox regeneration: x_0 is 0")
- equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
- equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
- equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40")
-
-
- // Check that changing the width when rotated resizes correctly for both hitbox and MBR
- // Rotated by 90 degrees, changing the width of the entity should change the height of the hitbox/mbr
- e.w = 100;
-
- equal(Math.round(e.map.points[0][0]), 0, "After rotation and increase in width: x_0 is 0")
- equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
- equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
- equal(Math.round(e.map.points[2][1]), 100, "y_2 is 100")
-
- // After rotation the MBR will have changed
- equal(Math.round(e._mbr._w), 50, "_mbr._w is 50");
- equal(Math.round(e._mbr._h), 100, "_mbr._h is 100");
- equal(Math.round(e._mbr._x), -50, "_mbr._x is -50");
- equal(Math.round(e._mbr._y), 0, "_mbr._y is 0");
-
- e.destroy();
+module("DebugLayer", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
});
-test("Hitboxes outside of entities (CBR)", function() {
- var poly = new Crafty.polygon([
- [-8, 6],
- [0, -8],
- [8, -14],
- [16, -8],
- [24, 6]
- ]);
-
- var e = Crafty.e("2D, Collision").attr({
- x: 50,
- y: 50,
- w: 16,
- h: 16
- }).collision(poly);
-
- ok(e._cbr !== null, "_cbr exists");
- var cbr = e._cbr;
- // Test whether cbr actually bounds hitbox+object
- ok(cbr._x <= 42, "cbr x position correct");
- ok(cbr._y <= 36, "cbr y position correct");
- ok(cbr._x + cbr._w >= 74, "cbr width correct");
- ok(cbr._y + cbr._h >= 66, "cbr height correct");
-
- var x0 = cbr._x,
- y0 = cbr._y;
-
- e.x += 10;
- e.y += 15;
-
- equal(cbr._x, x0 + 10, "cbr x position moves correctly");
- equal(cbr._y, y0 + 15, "cbr y position moves correctly");
- Crafty("*").destroy();
-})
-
-test("CBRs on resize", function() {
- var poly = new Crafty.polygon([
- [0, 0],
- [0, 12],
- [12, 12],
- [12, 0]
- ]);
-
- var e = Crafty.e("2D, Collision").attr({
- x: 50,
- y: 50,
- w: 15,
- h: 15
- }).collision(poly);
-
- ok(e._cbr === null, "_cbr should not exist");
-
- e.w = 10;
-
- ok(e._cbr !== null, "_cbr should now exist after entity shrinks");
-
- e.w = 20;
-
- ok(e._cbr === null, "_cbr should not exist after entity grows again");
-
- Crafty("*").destroy();
-})
-
-test("CBRs should be removed on removal of component", function() {
- var poly = new Crafty.polygon([
- [0, 0],
- [0, 12],
- [12, 12],
- [12, 0]
- ]);
-
- var e = Crafty.e("2D, Collision").attr({
- x: 50,
- y: 50,
- w: 10,
- h: 10
- }).collision(poly);
-
- ok(e._cbr !== null, "_cbr should exist to begin with");
-
- e.removeComponent("Collision");
-
- ok(e._cbr === null, "_cbr should now be removed along with Collision");
-
-
-})
-
-module("DebugLayer");
test("DebugCanvas", function() {
if (!(Crafty.support.canvas)) {
expect(0);
@@ -923,7 +450,16 @@ test("Hitbox debugging", function() {
});
-module("Easing");
+module("Easing", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
+
test("Crafty.easing duration", function() {
var e = new Crafty.easing(80); // 4 frames == 80ms by default
equal(e.duration, 80, "Default duration in ms");
diff --git a/tests/dom.js b/tests/dom.js
index 7e9a2fe4..4e597b60 100644
--- a/tests/dom.js
+++ b/tests/dom.js
@@ -1,4 +1,12 @@
-module("DOM");
+module("DOM", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
test("avoidCss3dTransforms", function() {
var useCss3dTransforms = Crafty.e("2D, DOM")
diff --git a/tests/events.js b/tests/events.js
index 629674be..21bc7247 100644
--- a/tests/events.js
+++ b/tests/events.js
@@ -1,4 +1,12 @@
-module("Events");
+module("Events", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
test("Global binding events", function() {
var x = 0;
diff --git a/tests/index.html b/tests/index.html
index 65eba487..2e3f0f1d 100755
--- a/tests/index.html
+++ b/tests/index.html
@@ -43,6 +43,7 @@
+
@@ -50,7 +51,6 @@
-
diff --git a/tests/isometric.js b/tests/isometric.js
index 59e9cf6a..2aadff12 100644
--- a/tests/isometric.js
+++ b/tests/isometric.js
@@ -1,4 +1,12 @@
-module("Isometric");
+module("Isometric", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
test("place tile", function() {
var iso = Crafty.isometric.size(64, 16);
diff --git a/tests/loader.js b/tests/loader.js
index 33fcd358..45e5b971 100644
--- a/tests/loader.js
+++ b/tests/loader.js
@@ -1,4 +1,12 @@
-module('Loader');
+module('Loader', {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
asyncTest('assets loading', function() {
expect(1);
diff --git a/tests/math.js b/tests/math.js
index fa82703e..88b8c2a4 100644
--- a/tests/math.js
+++ b/tests/math.js
@@ -3,7 +3,15 @@ var Vector2D = Crafty.math.Vector2D;
// tests for general functions should go here (.abs(), .amountOf(), etc)
-module("Math - Vector2D");
+module("Math - Vector2D", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
test("constructor", function() {
var v0 = new Vector2D();
diff --git a/tests/sound.js b/tests/sound.js
index d408eee9..b97c123d 100644
--- a/tests/sound.js
+++ b/tests/sound.js
@@ -1,4 +1,12 @@
-module("Sound");
+module("Sound", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
//Set up some test fixtures
function MockAudio() {
@@ -62,7 +70,6 @@ function ChromeBuggedAudio() {
this.ended = false
}
-Crafty.init();
asyncTest("setChannels", function() {
// Test that setChannels doesn't break sound
diff --git a/tests/stage.js b/tests/stage.js
index 3f6975bf..d25f62f3 100644
--- a/tests/stage.js
+++ b/tests/stage.js
@@ -22,7 +22,13 @@ test("simulateFrames", function() {
module("Viewport", {
- setup: reset
+ setup: function() {
+ reset();
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
});
test("scroll using _x, _y", function() {
@@ -188,7 +194,15 @@ test("centerOn", function() {
Crafty.viewport.scroll('y', 0);
});
-module("Crafty.timer")
+module("Crafty.timer", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
test("curTime", 1, function() {
var startTime, lastKnownTime;
Crafty.e("").bind("EnterFrame", function(params) {
diff --git a/tests/text.js b/tests/text.js
index 7caec16b..575cce7f 100644
--- a/tests/text.js
+++ b/tests/text.js
@@ -1,4 +1,13 @@
-module("Text");
+module("Text", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
+
test("fontFamily", function() {
var text = Crafty.e('DOM, Text').textFont({
family: 'Times New Roman 400',
@@ -6,7 +15,6 @@ test("fontFamily", function() {
}).text('Test');
equal(text.attr('_textFont')['family'], "'Times New Roman 400'", 'Expect to have singlequotes arount the family property.');
- Crafty("*").destroy();
});
test("_getFontHeight", function() {
@@ -15,7 +23,6 @@ test("_getFontHeight", function() {
equal(h, 10, "Font height is 10 pixels");
h = e._getFontHeight("10in");
equal(h, 960, "Font height is 960 pixels");
- Crafty("*").destroy();
})
test("Width of canvas element", function() {
@@ -25,7 +32,6 @@ test("Width of canvas element", function() {
e.text("abc");
var w2 = e.w;
ok(w2 > w1, "Entity increases in width when text is changed.")
- Crafty("*").destroy();
})
test("Height of canvas element", function() {
@@ -38,5 +44,5 @@ test("Height of canvas element", function() {
var h2 = e.h;
ok(h2 > 20, "Font height set correctly.")
ok(h2 > h1, "Entity increases in height when font size is increased.")
- Crafty("*").destroy();
+
})
\ No newline at end of file
diff --git a/tests/tween.js b/tests/tween.js
index f25c1722..0e986ea0 100644
--- a/tests/tween.js
+++ b/tests/tween.js
@@ -1,4 +1,13 @@
-module("Tween");
+module("Tween", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
+
test("Tween", function() {
var e = Crafty.e("2D, Tween")
e.x = 0;
From 5517bdac1ab248c42cb6642cb0b06e4a961befcd Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Thu, 2 Jan 2014 11:41:35 +0100
Subject: [PATCH 45/61] Human error (+1 squashed commit) Squashed commits:
[e630496] HelperFunctions
---
Gruntfile.js | 2 +-
tests/index.html | 1 +
tests/lib/helperFunctions.js | 3 +++
3 files changed, 5 insertions(+), 1 deletion(-)
create mode 100644 tests/lib/helperFunctions.js
diff --git a/Gruntfile.js b/Gruntfile.js
index 12779a80..a55ba0e8 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -86,7 +86,7 @@ module.exports = function (grunt) {
qunit: {
all: [
- 'tests/index.js'
+ 'tests/index.html'
]
},
diff --git a/tests/index.html b/tests/index.html
index 2e3f0f1d..06c07d7c 100755
--- a/tests/index.html
+++ b/tests/index.html
@@ -23,6 +23,7 @@
Â
+
diff --git a/tests/lib/helperFunctions.js b/tests/lib/helperFunctions.js
new file mode 100644
index 00000000..b2057ded
--- /dev/null
+++ b/tests/lib/helperFunctions.js
@@ -0,0 +1,3 @@
+Round = function(x){
+ return Math.round(x*100)/100;
+};
\ No newline at end of file
From 8d2cfa5ce260b14624d06bf34a4af15806fcc3d2 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Thu, 2 Jan 2014 12:46:45 +0100
Subject: [PATCH 46/61] Rename sound to Audio as it is named in Crafty and
HTML5 (+1 squashed commit) Squashed commits: [7f79c58] Semicolons in sound.js
---
tests/audio.js | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
tests/sound.js | 109 -------------------------------------------------
2 files changed, 107 insertions(+), 109 deletions(-)
create mode 100644 tests/audio.js
delete mode 100644 tests/sound.js
diff --git a/tests/audio.js b/tests/audio.js
new file mode 100644
index 00000000..7c33fecb
--- /dev/null
+++ b/tests/audio.js
@@ -0,0 +1,107 @@
+module("Audio", {
+ setup: function() {
+ // prepare something for all following tests
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
+});
+
+//Set up some test fixtures
+function MockAudio() {
+ var self = this;
+ this.endedListeners = [];
+ this.canPlayType = function() {
+ return true;
+ };
+ this.addEventListener = function(event, listener) {
+ switch (event) {
+ case "ended":
+ this.endedListeners.push(listener);
+ break;
+ default:
+ throw new Exception("Not implemented");
+ }
+ }
+ this.removeEventListener = function(event, listener) {
+ switch (event) {
+ case "ended":
+ var ind = this.endedListeners.indexOf(listener);
+ if (ind) this.endedListeners.splice(ind, 1);
+ break;
+ default:
+ throw new Exception("Not implemented");
+ }
+ }
+
+ function fireEnded() {
+ setTimeout(function() {
+ self.ended = true;
+ self.endedListeners.forEach(function(f) {
+ f.call(self);
+ })
+ }, 0);
+ }
+ this.play = function() {
+ if (this.src) {
+ fireEnded();
+ }
+ };
+ this.pause = function() {};
+ this.ended = false;
+}
+
+function ChromeBuggedAudio() {
+ var self = this;
+ this.canPlayType = function() {
+ return true;
+ };
+ this.addEventListener = function(event, listener) {};
+ this.removeEventListener = function(event, listener) {};
+ this.play = function() {
+ if (this.src) {
+ self.ended = true;
+ self.src = null;
+ ok(true, "Audio played");
+ }
+ };
+ this.pause = function() {};
+ this.ended = false;
+}
+
+
+asyncTest("setChannels", function() {
+ // Test that setChannels doesn't break sound
+ expect(2);
+ window.Audio = MockAudio;
+ Crafty.support.audio = true;
+ Crafty.audio.setChannels(5);
+ Crafty.audio.add("mockSound", ["sound.ogg"]);
+ var a = Crafty.audio.play("mockSound", 1);
+ ok(typeof a === "object", "Type of a is object: " + a);
+ a.addEventListener("ended", function() {
+ ok(true, "Sound played");
+ delete window.Audio; //reset Audio to platform default
+ Crafty.audio.channels = [];
+ start();
+ })
+});
+
+test("chromeBug", function() {
+ // Test that we don't exhaust our audio channels if Chrome bug 280417
+ // eats our "ended" events
+ expect(10);
+ window.Audio = ChromeBuggedAudio;
+ Crafty.support.audio = true;
+ Crafty.audio.setChannels(1);
+ Crafty.support.audio = true;
+ Crafty.audio.add("mockSound", ["sound.ogg"]);
+
+ var a;
+ for (var i = 0; i < 10; i++) {
+ a = Crafty.audio.play("mockSound", 1); // This will trigger an assertion
+ }
+ delete window.Audio; //reset Audio to platform default
+ Crafty.audio.channels = [];
+});
\ No newline at end of file
diff --git a/tests/sound.js b/tests/sound.js
deleted file mode 100644
index b97c123d..00000000
--- a/tests/sound.js
+++ /dev/null
@@ -1,109 +0,0 @@
-module("Sound", {
- setup: function() {
- // prepare something for all following tests
- },
- teardown: function() {
- // clean up after each test
- Crafty("*").destroy();
- }
-});
-
-//Set up some test fixtures
-function MockAudio() {
- var self = this
- this.endedListeners = []
- this.canPlayType = function() {
- return true
- }
- this.addEventListener = function(event, listener) {
- switch (event) {
- case "ended":
- this.endedListeners.push(listener)
- break
- default:
- throw new Exception("Not implemented")
- }
- }
- this.removeEventListener = function(event, listener) {
- switch (event) {
- case "ended":
- var ind = this.endedListeners.indexOf(listener)
- if (ind) this.endedListeners.splice(ind, 1);
- break
- default:
- throw new Exception("Not implemented")
- }
- }
-
- function fireEnded() {
- setTimeout(function() {
- self.ended = true
- self.endedListeners.forEach(function(f) {
- f.call(self)
- })
- }, 0)
- }
- this.play = function() {
- if (this.src) {
- fireEnded()
- }
- }
- this.pause = function() {}
- this.ended = false
-}
-
-function ChromeBuggedAudio() {
- var self = this
- this.canPlayType = function() {
- return true
- }
- this.addEventListener = function(event, listener) {}
- this.removeEventListener = function(event, listener) {}
- this.play = function() {
- if (this.src) {
- self.ended = true
- self.src = null
- ok(true, "Audio played")
- }
- }
- this.pause = function() {}
- this.ended = false
-}
-
-
-asyncTest("setChannels", function() {
- // Test that setChannels doesn't break sound
- expect(2)
- window.Audio = MockAudio
- Crafty.support.audio = true
- Crafty.audio.setChannels(5)
- Crafty.audio.add("mockSound", ["sound.ogg"])
- var a = Crafty.audio.play("mockSound", 1)
- ok(typeof a === "object", "Type of a is object: " + a)
- a.addEventListener("ended", function() {
- ok(true, "Sound played")
- delete window.Audio //reset Audio to platform default
- Crafty.audio.channels = []
- Crafty("*").destroy();
- start()
- })
-});
-
-test("chromeBug", function() {
- // Test that we don't exhaust our audio channels if Chrome bug 280417
- // eats our "ended" events
- expect(10)
- window.Audio = ChromeBuggedAudio
- Crafty.support.audio = true
- Crafty.audio.setChannels(1)
- Crafty.support.audio = true
- Crafty.audio.add("mockSound", ["sound.ogg"])
-
- var a
- for (var i = 0; i < 10; i++) {
- a = Crafty.audio.play("mockSound", 1) // This will trigger an assertion
- }
- delete window.Audio //reset Audio to platform default
- Crafty.audio.channels = []
- Crafty("*").destroy();
-});
\ No newline at end of file
From e7b1fe0df9eb2714da7ae942fa262868fdf6cf18 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Thu, 2 Jan 2014 13:03:07 +0100
Subject: [PATCH 47/61] JSValidate and JSHint on the test also to ensure
quality
---
Gruntfile.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Gruntfile.js b/Gruntfile.js
index a55ba0e8..391ceb01 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -76,7 +76,7 @@ module.exports = function (grunt) {
},
jshint: {
- files: ['Gruntfile.js', 'src/**/*.js'],
+ files: ['Gruntfile.js', 'src/**/*.js', 'tests/*.js'],
options: {
trailing: true,
globals: {
@@ -91,7 +91,7 @@ module.exports = function (grunt) {
},
jsvalidate: {
- files: "crafty.js"
+ files: ["crafty.js", 'tests/*.js']
},
});
From 742294b4601feadbc230ada3a502e7f25669b0bb Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Thu, 2 Jan 2014 13:19:22 +0100
Subject: [PATCH 48/61] JSHint fixes on the test files
---
tests/2d.js | 53 ++++++++++++++++++-------------------
tests/audio.js | 8 +++---
tests/core.js | 69 ++++++++++++++++++++++++------------------------
tests/events.js | 66 ++++++++++++++++++++++-----------------------
tests/stage.js | 13 ++++-----
tests/storage.js | 12 ++++-----
tests/text.js | 16 +++++------
tests/tween.js | 2 +-
8 files changed, 117 insertions(+), 122 deletions(-)
diff --git a/tests/2d.js b/tests/2d.js
index 9869ece3..065bd1bb 100644
--- a/tests/2d.js
+++ b/tests/2d.js
@@ -200,9 +200,6 @@ test("child", function() {
});
test("child_rotate", function() {
- var Round = function(x) {
- return Math.round(x * 100) / 100
- };
var parent = Crafty.e("2D, DOM, Color")
.attr({
x: 0,
@@ -232,8 +229,8 @@ test("child_rotate", function() {
strictEqual(child.rotation, 57, 'child rotates normally');
parent.rotation = 100; // Rotation by 90 degrees from initial position
- strictEqual(Round(child.x), -10, "Child moved around parent upon rotation (x).")
- strictEqual(Round(child.y), 10, "Child moved around parent upon rotation (y).")
+ strictEqual(Round(child.x), -10, "Child moved around parent upon rotation (x).");
+ strictEqual(Round(child.y), 10, "Child moved around parent upon rotation (y).");
});
@@ -244,7 +241,7 @@ test("SAT", function() {
var e = Crafty.e("2D, Collision");
var c1 = new Crafty.circle(100, 100, 10);
var c2 = new Crafty.circle(100, 105, 10);
- strictEqual((e._SAT(c1, c2).overlap < -13.8 && e._SAT(c1, c2).overlap > -13.9), true, "Expected overlap to be about -13.86 ( or 15 cos[pi/8])")
+ strictEqual((e._SAT(c1, c2).overlap < -13.8 && e._SAT(c1, c2).overlap > -13.9), true, "Expected overlap to be about -13.86 ( or 15 cos[pi/8])");
});
@@ -255,7 +252,7 @@ test("adjustable boundary", function() {
y: 10,
w: 10,
h: 10
- })
+ });
// Four argument version
e.offsetBoundary(10, 1, 3, 0);
@@ -264,7 +261,7 @@ test("adjustable boundary", function() {
equal(e._by1, 1, "Y1 boundary set");
equal(e._by2, 0, "Y2 boundary set");
- e._calculateMBR(10, 10, 0)
+ e._calculateMBR(10, 10, 0);
var mbr = e._mbr;
@@ -278,7 +275,7 @@ test("adjustable boundary", function() {
equal(e._by1, 5, "Y1 boundary set");
equal(e._by2, 5, "Y2 boundary set");
-})
+});
test("disableControl and enableControl", function() {
@@ -339,19 +336,19 @@ test("Resizing 2D objects & hitboxes", function() {
y: 0,
w: 40,
h: 50
- })
+ });
- equal(e.map.points[0][0], 0, "Before rotation: x_0 is 0")
- equal(e.map.points[0][1], 0, "y_0 is 0")
- equal(e.map.points[2][0], 40, "x_2 is 40")
- equal(e.map.points[2][1], 50, "y_2 is 50")
+ equal(e.map.points[0][0], 0, "Before rotation: x_0 is 0");
+ equal(e.map.points[0][1], 0, "y_0 is 0");
+ equal(e.map.points[2][0], 40, "x_2 is 40");
+ equal(e.map.points[2][1], 50, "y_2 is 50");
e.rotation = 90;
- equal(Math.round(e.map.points[0][0]), 0, "After rotation by 90 deg: x_0 is 0")
- equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
- equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
- equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40")
+ equal(Math.round(e.map.points[0][0]), 0, "After rotation by 90 deg: x_0 is 0");
+ equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0");
+ equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50");
+ equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40");
// After rotation the MBR will have changed
equal(Math.round(e._mbr._w), 50, "_mbr._w is 50");
@@ -361,20 +358,20 @@ test("Resizing 2D objects & hitboxes", function() {
e.collision(); // Check that regenerating the hitbox while rotated works correctly
- equal(Math.round(e.map.points[0][0]), 0, "After rotation and hitbox regeneration: x_0 is 0")
- equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
- equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
- equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40")
+ equal(Math.round(e.map.points[0][0]), 0, "After rotation and hitbox regeneration: x_0 is 0");
+ equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0");
+ equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50");
+ equal(Math.round(e.map.points[2][1]), 40, "y_2 is 40");
// Check that changing the width when rotated resizes correctly for both hitbox and MBR
// Rotated by 90 degrees, changing the width of the entity should change the height of the hitbox/mbr
e.w = 100;
- equal(Math.round(e.map.points[0][0]), 0, "After rotation and increase in width: x_0 is 0")
- equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0")
- equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50")
- equal(Math.round(e.map.points[2][1]), 100, "y_2 is 100")
+ equal(Math.round(e.map.points[0][0]), 0, "After rotation and increase in width: x_0 is 0");
+ equal(Math.round(e.map.points[0][1]), 0, "y_0 is 0");
+ equal(Math.round(e.map.points[2][0]), -50, "x_2 is -50");
+ equal(Math.round(e.map.points[2][1]), 100, "y_2 is 100");
// After rotation the MBR will have changed
equal(Math.round(e._mbr._w), 50, "_mbr._w is 50");
@@ -418,7 +415,7 @@ test("Hitboxes outside of entities (CBR)", function() {
equal(cbr._x, x0 + 10, "cbr x position moves correctly");
equal(cbr._y, y0 + 15, "cbr y position moves correctly");
-})
+});
test("CBRs on resize", function() {
var poly = new Crafty.polygon([
@@ -445,7 +442,7 @@ test("CBRs on resize", function() {
ok(e._cbr === null, "_cbr should not exist after entity grows again");
-})
+});
test("CBRs should be removed on removal of component", function() {
var poly = new Crafty.polygon([
diff --git a/tests/audio.js b/tests/audio.js
index 7c33fecb..29f09f76 100644
--- a/tests/audio.js
+++ b/tests/audio.js
@@ -23,7 +23,7 @@ function MockAudio() {
default:
throw new Exception("Not implemented");
}
- }
+ };
this.removeEventListener = function(event, listener) {
switch (event) {
case "ended":
@@ -33,14 +33,14 @@ function MockAudio() {
default:
throw new Exception("Not implemented");
}
- }
+ };
function fireEnded() {
setTimeout(function() {
self.ended = true;
self.endedListeners.forEach(function(f) {
f.call(self);
- })
+ });
}, 0);
}
this.play = function() {
@@ -85,7 +85,7 @@ asyncTest("setChannels", function() {
delete window.Audio; //reset Audio to platform default
Crafty.audio.channels = [];
start();
- })
+ });
});
test("chromeBug", function() {
diff --git a/tests/core.js b/tests/core.js
index 3e93162d..3f25d2df 100644
--- a/tests/core.js
+++ b/tests/core.js
@@ -64,7 +64,7 @@ test("remove", function() {
removeRan = true;
destroyFlag = destroyed;
}
- })
+ });
var e = Crafty.e("comp, blank");
e.removeComponent("blank");
strictEqual(removeRan, false, "Remove doesn't run on other component removal");
@@ -76,7 +76,7 @@ test("remove", function() {
removeRan = false;
e.addComponent("comp");
- e.destroy()
+ e.destroy();
strictEqual(removeRan, true, "Remove runs on component destrution");
strictEqual(destroyFlag, true, "Destroy flag true on destruction");
});
@@ -103,15 +103,15 @@ test("setter", function() {
}
var first = Crafty.e("test");
first.setter('p1', function(v) {
- this._p1 = v * 2
+ this._p1 = v * 2;
});
first.p1 = 2;
strictEqual(first._p1, 4, "single property setter");
first.setter('p2', function(v) {
- this._p2 = v * 2
+ this._p2 = v * 2;
}).setter('p3', function(v) {
- this._p3 = v * 2
+ this._p3 = v * 2;
});
first.p2 = 2;
first.p3 = 3;
@@ -211,7 +211,7 @@ test("Crafty.get() to find an array", function() {
equal(result[0].has("test"), true, "Result elements should have correct component");
equal(collection[0], result[0].getId(), "First id of result should match first id of Crafty array");
-})
+});
test("Crafty.get(index) to find the indicated entity", function() {
Crafty.e("test");
@@ -228,7 +228,7 @@ test("Crafty.get(index) to find the indicated entity", function() {
equal(result.has("test"), true, "Result should have correct component");
equal(result.getId(), collection[2], "result should be last element of collection");
-})
+});
test("Crafty.get(index) error checking", function() {
Crafty.e("test");
@@ -239,22 +239,22 @@ test("Crafty.get(index) error checking", function() {
collection = Crafty("test");
result = collection.get(3);
- equal(typeof result, "undefined", "result of get(3) should be undefined")
+ equal(typeof result, "undefined", "result of get(3) should be undefined");
result = collection.get(-4);
- equal(typeof result, "undefined", "result of get(-4) should be undefined")
+ equal(typeof result, "undefined", "result of get(-4) should be undefined");
-})
+});
test("Crafty.get with only one object", function() {
var e = Crafty.e("test");
var collection = Crafty("test");
result = collection.get(0);
- equal(result.getId(), e.getId(), "result of get(0) is correct entity")
+ equal(result.getId(), e.getId(), "result of get(0) is correct entity");
result = collection.get();
equal(result.length, 1, "result of get() is array of length 1");
-})
+});
test("requires", function() {
var first = Crafty.e("test");
@@ -298,10 +298,10 @@ test("Scene calling", function() {
var x = 0;
var sceneInit = function() {
x = 13;
- }
+ };
Crafty.scene("test-call", sceneInit);
Crafty.scene("test-call");
- equal(x, 13, "Scene called succesfully.")
+ equal(x, 13, "Scene called succesfully.");
});
@@ -309,10 +309,10 @@ test("Scene parameters", function() {
var x = 0;
var paramTaker = function(y) {
x = y;
- }
+ };
Crafty.scene("test-param", paramTaker);
Crafty.scene("test-param", 11);
- equal(x, 11, "Scene called succesfully with parameter.")
+ equal(x, 11, "Scene called succesfully with parameter.");
});
test("Calling a scene destroys 2D entities", function() {
@@ -341,13 +341,13 @@ test("Scene uninit function called", function() {
var y = 0;
var sceneInit = function() {
x = 13;
- }
+ };
var sceneUninit = function() {
x = 20;
- }
+ };
var sceneGame = function() {
y = 5;
- }
+ };
Crafty.defineScene("test-uninit", sceneInit, sceneUninit);
Crafty.defineScene("game", sceneGame);
Crafty.enterScene("test-uninit");
@@ -378,7 +378,7 @@ test("DebugCanvas", function() {
e.debugFill("purple");
equal(e._debug.fillStyle, "purple", "fill style set correctly on entity");
- e.debugStroke("green")
+ e.debugStroke("green");
equal(e._debug.strokeStyle, "green", "stroke style set correctly on entity");
e.debugDraw(ctx);
@@ -430,23 +430,23 @@ test("Hitbox debugging", function() {
e.destroy();
- var e = Crafty.e("2D, Collision, SolidHitBox").attr({
+ var e2 = Crafty.e("2D, Collision, SolidHitBox").attr({
x: 10,
y: 10,
w: 10,
h: 20
}).collision();
- e.matchHitBox(); // only necessary until collision works properly!
- equal(e.polygon.points[0][0], 10, "SolidHitBox -- correct x coord for upper right corner");
- equal(e.polygon.points[2][1], 30, "correct y coord for lower right corner");
- equal(typeof e._debug.strokeStyle, "undefined", "stroke style is undefined");
- notEqual(typeof e._debug.fillStyle, "undefined", "fill style is assigned");
+ e2.matchHitBox(); // only necessary until collision works properly!
+ equal(e2.polygon.points[0][0], 10, "SolidHitBox -- correct x coord for upper right corner");
+ equal(e2.polygon.points[2][1], 30, "correct y coord for lower right corner");
+ equal(typeof e2._debug.strokeStyle, "undefined", "stroke style is undefined");
+ notEqual(typeof e2._debug.fillStyle, "undefined", "fill style is assigned");
- e.collision(new Crafty.polygon([0, 0], [15, 0], [0, 15]));
- e.matchHitBox();
- equal(e.polygon.points[2][1], 25, "After change -- correct y coord for third point");
+ e2.collision(new Crafty.polygon([0, 0], [15, 0], [0, 15]));
+ e2.matchHitBox();
+ equal(e2.polygon.points[2][1], 25, "After change -- correct y coord for third point");
- e.destroy();
+ e2.destroy();
});
@@ -463,7 +463,8 @@ module("Easing", {
test("Crafty.easing duration", function() {
var e = new Crafty.easing(80); // 4 frames == 80ms by default
equal(e.duration, 80, "Default duration in ms");
-})
+});
+
test("Crafty.easing", function() {
var e = new Crafty.easing(80); // 4 frames == 80ms by default
e.tick(20);
@@ -471,7 +472,7 @@ test("Crafty.easing", function() {
equal(e.value(), 0.5, ".5 after two steps");
e.tick(20);
e.tick(20);
- equal(e.value(), 1, "1 after completed")
+ equal(e.value(), 1, "1 after completed");
e.tick(20);
- equal(e.value(), 1, "Remains 1 after completion")
-})
\ No newline at end of file
+ equal(e.value(), 1, "Remains 1 after completion");
+});
\ No newline at end of file
diff --git a/tests/events.js b/tests/events.js
index 21bc7247..8e8b2b1e 100644
--- a/tests/events.js
+++ b/tests/events.js
@@ -12,23 +12,23 @@ test("Global binding events", function() {
var x = 0;
function add() {
- x++
+ x++;
}
- Crafty.bind("Increment", add)
- Crafty.trigger("Increment")
+ Crafty.bind("Increment", add);
+ Crafty.trigger("Increment");
strictEqual(x, 1, "Crafty.bind fired once");
x = 0;
- Crafty.unbind("Increment", add)
- Crafty.trigger("Increment")
+ Crafty.unbind("Increment", add);
+ Crafty.trigger("Increment");
strictEqual(x, 0, "Crafty.bind does not fire once unbound");
x = 0;
- Crafty.one("Increment", add)
- Crafty.trigger("Increment")
- Crafty.trigger("Increment")
+ Crafty.one("Increment", add);
+ Crafty.trigger("Increment");
+ Crafty.trigger("Increment");
strictEqual(x, 1, "Event bound by Crafty.one fires exactly once");
x = 0;
@@ -39,7 +39,7 @@ test("Global binding events", function() {
x = 0;
Crafty.unbind("Increment", add);
- Crafty.trigger("Increment")
+ Crafty.trigger("Increment");
strictEqual(x, 0, "uniqueBound does not fire once unbound");
});
@@ -49,24 +49,24 @@ test("Entity binding events", function() {
var x = 0;
function add() {
- x++
+ x++;
}
- var e = Crafty.e("Triggerable")
+ var e = Crafty.e("Triggerable");
- e.bind("Increment", add)
- e.trigger("Increment")
+ e.bind("Increment", add);
+ e.trigger("Increment");
strictEqual(x, 1, ".bind fired once");
x = 0;
- e.unbind("Increment", add)
- e.trigger("Increment")
+ e.unbind("Increment", add);
+ e.trigger("Increment");
strictEqual(x, 0, ".bind does not fire once unbound");
x = 0;
- e.one("Increment", add)
- e.trigger("Increment")
- e.trigger("Increment")
+ e.one("Increment", add);
+ e.trigger("Increment");
+ e.trigger("Increment");
strictEqual(x, 1, "Event bound by .one fires exactly once");
x = 0;
@@ -77,7 +77,7 @@ test("Entity binding events", function() {
x = 0;
e.unbind("Increment", add);
- e.trigger("Increment")
+ e.trigger("Increment");
strictEqual(x, 0, "uniqueBound does not fire once unbound");
e.destroy();
@@ -147,7 +147,7 @@ test("Multiple bound events", function() {
strictEqual(temp.abc, 2, "regular event should trigger twice");
strictEqual(temp.def, 1, "second one() should trigger once");
- Crafty.unbind("Event A")
+ Crafty.unbind("Event A");
});
@@ -156,42 +156,42 @@ test("Data passing", function() {
e;
function add(data) {
- x += data.amount
+ x += data.amount;
}
x = 0;
- e = Crafty.e("Triggerable")
- e.bind("Increment", add)
+ e = Crafty.e("Triggerable");
+ e.bind("Increment", add);
e.trigger("Increment", {
amount: 2
- })
+ });
strictEqual(x, 2, "data passed correctly with .bind");
e.destroy();
x = 0;
- e = Crafty.e("Triggerable")
- e.one("Increment", add)
+ e = Crafty.e("Triggerable");
+ e.one("Increment", add);
e.trigger("Increment", {
amount: 2
- })
+ });
strictEqual(x, 2, "data passed correctly with .one");
e.destroy();
x = 0;
- Crafty.bind("Increment", add)
+ Crafty.bind("Increment", add);
Crafty.trigger("Increment", {
amount: 2
- })
+ });
strictEqual(x, 2, "data passed correctly with Crafty.bind");
- Crafty.unbind("Increment")
+ Crafty.unbind("Increment");
x = 0;
- Crafty.one("Increment", add)
+ Crafty.one("Increment", add);
Crafty.trigger("Increment", {
amount: 3
- })
+ });
strictEqual(x, 3, "data passed correctly with Crafty.one");
- Crafty.unbind("Increment")
+ Crafty.unbind("Increment");
diff --git a/tests/stage.js b/tests/stage.js
index d25f62f3..2da503d9 100644
--- a/tests/stage.js
+++ b/tests/stage.js
@@ -1,11 +1,10 @@
var reset = function() {
- Crafty("*").destroy();
Crafty.viewport.reset();
Crafty.viewport.scroll('_x', 0);
Crafty.viewport.scroll('_y', 0);
Crafty.viewport.clampToEntities = true;
-}
+};
test("simulateFrames", function() {
var framesPlayed = 0;
@@ -17,9 +16,7 @@ test("simulateFrames", function() {
Crafty.timer.simulateFrames(100);
equal(framesPlayed, 101, "101 frames should have been simulated");
-})
-
-
+});
module("Viewport", {
setup: function() {
@@ -92,7 +89,7 @@ test("pan", function() {
var done = 0;
var panDone = function() {
- done++
+ done++;
};
Crafty.one("CameraAnimationDone", panDone);
@@ -121,7 +118,7 @@ test("zoom", function() {
var done = 0;
var panDone = function() {
- done++
+ done++;
};
Crafty.one("CameraAnimationDone", panDone);
@@ -160,7 +157,7 @@ test("centerOn", function() {
var done = 0;
var panDone = function() {
- done++
+ done++;
};
Crafty.one("CameraAnimationDone", panDone);
diff --git a/tests/storage.js b/tests/storage.js
index be75b1e1..a67c692f 100644
--- a/tests/storage.js
+++ b/tests/storage.js
@@ -7,7 +7,7 @@ test("saveAndLoadObject", function() {
});
stop();
Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb["name"], "Matthew");
+ equal(lb.name, "Matthew");
start();
});
});
@@ -23,7 +23,7 @@ test("saveAndLoadArray", function() {
}]);
stop();
Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb[1]["name"], "Louis");
+ equal(lb[1].name, "Louis");
equal(lb.length, 2);
start();
});
@@ -39,7 +39,7 @@ test("saveAndLoadEntity", function() {
Crafty.storage.load("Hero", "save", function(hero) {
console.log(hero);
ok(hero.__c["2D"]);
- ok(hero.__c["DOM"])
+ ok(hero.__c.DOM);
equal(hero.x, 0, "Entity state is not saved");
start();
});
@@ -61,13 +61,13 @@ test("individualNamespaces", function() {
stop();
Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb["name"], "Louis");
+ equal(lb.name, "Louis");
start();
});
Crafty.storage.open("MyGame3");
Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb["name"], "Matthew");
+ equal(lb.name, "Matthew");
start();
});
-})
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/tests/text.js b/tests/text.js
index 575cce7f..aefbd9f8 100644
--- a/tests/text.js
+++ b/tests/text.js
@@ -13,7 +13,7 @@ test("fontFamily", function() {
family: 'Times New Roman 400',
size: '30px'
}).text('Test');
- equal(text.attr('_textFont')['family'], "'Times New Roman 400'", 'Expect to have singlequotes arount the family property.');
+ equal(text.attr('_textFont').family, "'Times New Roman 400'", 'Expect to have singlequotes arount the family property.');
});
@@ -23,7 +23,7 @@ test("_getFontHeight", function() {
equal(h, 10, "Font height is 10 pixels");
h = e._getFontHeight("10in");
equal(h, 960, "Font height is 960 pixels");
-})
+});
test("Width of canvas element", function() {
var e = Crafty.e("2D, Canvas, Text");
@@ -31,18 +31,18 @@ test("Width of canvas element", function() {
var w1 = e.w;
e.text("abc");
var w2 = e.w;
- ok(w2 > w1, "Entity increases in width when text is changed.")
-})
+ ok(w2 > w1, "Entity increases in width when text is changed.");
+});
test("Height of canvas element", function() {
var e = Crafty.e("2D, Canvas, Text");
e.text("a");
e.textFont("size", "10");
var h1 = e.h;
- ok(h1 > 10, "Font height set correctly.")
+ ok(h1 > 10, "Font height set correctly.");
e.textFont("size", "20");
var h2 = e.h;
- ok(h2 > 20, "Font height set correctly.")
- ok(h2 > h1, "Entity increases in height when font size is increased.")
+ ok(h2 > 20, "Font height set correctly.");
+ ok(h2 > h1, "Entity increases in height when font size is increased.");
-})
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/tests/tween.js b/tests/tween.js
index 0e986ea0..0c49a97b 100644
--- a/tests/tween.js
+++ b/tests/tween.js
@@ -9,7 +9,7 @@ module("Tween", {
});
test("Tween", function() {
- var e = Crafty.e("2D, Tween")
+ var e = Crafty.e("2D, Tween");
e.x = 0;
e.y = 10;
var ret = e.tween({
From 8021787b6db91ce94fc7204dbeaace3249748e72 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Thu, 2 Jan 2014 13:34:18 +0100
Subject: [PATCH 49/61] Include the animation tests, as they have their own
HTML for test (+2 squashed commits) Squashed commits: [68da0e6] Use
Apostrophe instead [58272c2] Changed name of the index.html Qunit test markup
---
Gruntfile.js | 5 +++--
tests/index.html | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/Gruntfile.js b/Gruntfile.js
index 391ceb01..00b48f0a 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -86,12 +86,13 @@ module.exports = function (grunt) {
qunit: {
all: [
- 'tests/index.html'
+ 'tests/index.html',
+ 'tests/animation/animation.html'
]
},
jsvalidate: {
- files: ["crafty.js", 'tests/*.js']
+ files: ['crafty.js', 'tests/*.js']
},
});
diff --git a/tests/index.html b/tests/index.html
index 06c07d7c..dc435be1 100755
--- a/tests/index.html
+++ b/tests/index.html
@@ -29,7 +29,7 @@
-
Crafty: Core
+
Crafty.js Test Suite
From 409ab21f1fa09705c3c6f9c33589b1e36e67bf80 Mon Sep 17 00:00:00 2001
From: mucaho
Date: Tue, 24 Dec 2013 11:10:26 +0100
Subject: [PATCH 50/61] abstracted sprite coord computation
---
src/animation.js | 20 +++++---------------
src/extensions.js | 16 +++++++---------
src/sprite.js | 21 ++++++++++++---------
tests/animation/sprite-animation.js | 8 ++++----
4 files changed, 28 insertions(+), 37 deletions(-)
diff --git a/src/animation.js b/src/animation.js
index c148a7d5..e115723f 100644
--- a/src/animation.js
+++ b/src/animation.js
@@ -213,11 +213,7 @@ Crafty.c("SpriteAnimation", {
}
- var reel, i, tile, tileh, pos;
-
- // Get the dimensions of a single frame, as defind in Sprite component.
- tile = this.__tile + parseInt(this.__padding[0] || 0, 10);
- tileh = this.__tileh + parseInt(this.__padding[1] || 0, 10);
+ var reel, i;
reel = {
id: reelId,
@@ -235,22 +231,18 @@ Crafty.c("SpriteAnimation", {
y = fromY;
if (frameCount >= 0) {
for (; i < fromX + frameCount ; i++) {
- reel.frames.push([i * tile, y * tileh]);
+ reel.frames.push([i, y]);
}
}
else {
for (; i > fromX + frameCount; i--) {
- reel.frames.push([i * tile, y * tileh]);
+ reel.frames.push([i, y]);
}
}
}
// @sign public this .reel(String reelId, Number duration, Array frames)
else if (arguments.length === 3 && typeof fromX === "object") {
- // In this case, fromX is actually the array of frames
- for (i=0; i < fromX.length; i++) {
- pos = fromX[i];
- reel.frames.push([pos[0] * tile, pos[1] * tileh]);
- }
+ reel.frames = fromX;
}
else {
throw "Urecognized arguments. Please see the documentation for 'reel(...)'.";
@@ -503,9 +495,7 @@ Crafty.c("SpriteAnimation", {
_updateSprite: function() {
var currentReel = this._currentReel;
var pos = currentReel.frames[currentReel.currentFrame];
- this.__coord[0] = pos[0];
- this.__coord[1] = pos[1];
- this.trigger("Change"); // needed to trigger a redraw
+ this.sprite(pos[0], pos[1]); // .sprite will trigger redraw
},
diff --git a/src/extensions.js b/src/extensions.js
index 132160af..7b50d793 100644
--- a/src/extensions.js
+++ b/src/extensions.js
@@ -139,13 +139,14 @@ Crafty.extend({
/**@
* #Crafty.sprite
* @category Graphics
- * @sign public this Crafty.sprite([Number tile, [Number tileh]], String url, Object map[, Number paddingX[, Number paddingY]])
+ * @sign public this Crafty.sprite([Number tile, [Number tileh]], String url, Object map[, Number paddingX[, Number paddingY[, Boolean paddingAroundBorder]]])
* @param tile - Tile size of the sprite map, defaults to 1
* @param tileh - Height of the tile; if provided, tile is interpreted as the width
* @param url - URL of the sprite image
* @param map - Object where the key is what becomes a new component and the value points to a position on the sprite map
* @param paddingX - Horizontal space in between tiles. Defaults to 0.
* @param paddingY - Vertical space in between tiles. Defaults to paddingX.
+ * @param paddingAroundBorder - If padding should be applied around the border of the sprite sheet. If enabled the first tile starts at (paddingX,paddingY) instead of (0,0). Defaults to false.
* Generates components based on positions in a sprite image to be applied to entities.
*
* Accepts a tile size, URL and map for the name of the sprite and its position.
@@ -186,7 +187,7 @@ Crafty.extend({
*
* @see Sprite
*/
- sprite: function (tile, tileh, url, map, paddingX, paddingY) {
+ sprite: function (tile, tileh, url, map, paddingX, paddingY, paddingAroundBorder) {
var spriteName, temp, x, y, w, h, img;
//if no tile value, default to 1.
@@ -235,12 +236,13 @@ Crafty.extend({
this.requires("2D, Sprite");
this.__trim = [0, 0, 0, 0];
this.__image = url;
- this.__coord = [this.__coord[0], this.__coord[1], this.__coord[2], this.__coord[3]];
this.__tile = tile;
this.__tileh = tileh;
this.__padding = [paddingX, paddingY];
+ this.__padBorder = paddingAroundBorder;
+ this.sprite(this.__coord[0], this.__coord[1], this.__coord[2], this.__coord[3]);
+
this.img = img;
-
//draw now
if (this.img.complete && this.img.width > 0) {
this.ready = true;
@@ -256,15 +258,11 @@ Crafty.extend({
if (!map.hasOwnProperty(spriteName)) continue;
temp = map[spriteName];
- x = temp[0] * (tile + paddingX);
- y = temp[1] * (tileh + paddingY);
- w = temp[2] * tile || tile;
- h = temp[3] * tileh || tileh;
//generates sprite components for each tile in the map
Crafty.c(spriteName, {
ready: false,
- __coord: [x, y, w, h],
+ __coord: [temp[0], temp[1], temp[2] || 1, temp[3] || 1],
init: sharedSpriteInit
});
diff --git a/src/sprite.js b/src/sprite.js
index 4c102b96..5a3ff9aa 100644
--- a/src/sprite.js
+++ b/src/sprite.js
@@ -73,13 +73,13 @@ Crafty.c("Sprite", {
/**@
* #.sprite
* @comp Sprite
- * @sign public this .sprite(Number x, Number y, Number w, Number h)
+ * @sign public this .sprite(Number x, Number y[, Number w, Number h])
* @param x - X cell position
* @param y - Y cell position
- * @param w - Width in cells
- * @param h - Height in cells
+ * @param w - Width in cells. Optional.
+ * @param h - Height in cells. Optional.
*
- * Uses a new location on the sprite map as its sprite.
+ * Uses a new location on the sprite map as its sprite. If w or h are ommitted, the width and height are not changed.
*
* Values should be in tiles or cells (not pixels).
*
@@ -97,11 +97,14 @@ Crafty.c("Sprite", {
* The coordinate of the slide within the sprite in the format of [x, y, w, h].
*/
sprite: function (x, y, w, h) {
- this.__coord = [x * (this.__tile + this.__padding[0]) + this.__trim[0],
- y * (this.__tileh + this.__padding[1]) + this.__trim[1],
- this.__trim[2] || w * this.__tile || this.__tile,
- this.__trim[3] || h * this.__tileh || this.__tileh
- ];
+ this.__coord = this.__coord || [0, 0, 0, 0];
+
+ this.__coord[0] = x * (this.__tile + this.__padding[0]) + (this.__padBorder ? this.__padding[0] : 0) + this.__trim[0];
+ this.__coord[1] = y * (this.__tileh + this.__padding[1]) + (this.__padBorder ? this.__padding[1] : 0) + this.__trim[1];
+ if (typeof(w)!=='undefined' && typeof(h)!=='undefined') {
+ this.__coord[2] = this.__trim[2] || w * this.__tile || this.__tile;
+ this.__coord[3] = this.__trim[3] || h * this.__tileh || this.__tileh;
+ }
this.trigger("Change");
return this;
diff --git a/tests/animation/sprite-animation.js b/tests/animation/sprite-animation.js
index edf0f5bc..95731aab 100644
--- a/tests/animation/sprite-animation.js
+++ b/tests/animation/sprite-animation.js
@@ -218,8 +218,8 @@ test("Test using .reel to set an animation using start and end values", function
var frames = reel.frames;
equal(frames.length, 3, "Reel has correct number of frames.");
deepEqual(frames[0], [0, 0], "First frame is correct.");
- deepEqual(frames[1], [64, 0], "Second frame is correct.");
- deepEqual(frames[2], [128, 0], "Third frame is correct.");
+ deepEqual(frames[1], [1, 0], "Second frame is correct.");
+ deepEqual(frames[2], [2, 0], "Third frame is correct.");
})
@@ -239,8 +239,8 @@ test("Test using .reel to set an animation using an array of frames", function()
equal(frames.length, 3, "Reel has correct number of frames.");
// This relies on the sprite being defined with a size of 64
deepEqual(frames[0], [0, 0], "First frame is correct.");
- deepEqual(frames[1], [64, 0], "Second frame is correct.");
- deepEqual(frames[2], [128, 0], "Third frame is correct.");
+ deepEqual(frames[1], [1, 0], "Second frame is correct.");
+ deepEqual(frames[2], [2, 0], "Third frame is correct.");
})
From d7309dec1503127746ef12326fd9db56abe21e86 Mon Sep 17 00:00:00 2001
From: Tim Martin
Date: Sat, 4 Jan 2014 17:26:11 -0500
Subject: [PATCH 51/61] Fix the matrix inversion test to avoid floating point
issues.
---
tests/math.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/math.js b/tests/math.js
index 88b8c2a4..ecd9cb4a 100644
--- a/tests/math.js
+++ b/tests/math.js
@@ -247,8 +247,9 @@ test("determinant()", function() {
});
test("invert()", function() {
- equal((new Matrix2D()).scale(2, 3).rotate(Math.PI / 2).invert().equals(new Matrix2D(3.061616997868383e-17, -0.3333333333333333, 0.5, 2.041077998578922e-17, 0, 0)),
- true, "(new Matrix2D()).scale(2, 3).rotate(Math.PI / 2).invert().equals(new Matrix2D(3.061616997868383e-17, -0.3333333333333333, 0.5, 2.041077998578922e-17, 0, 0))");
+ var m = new Matrix2D(4, 3, 3, 2, 0, 0);
+ var m2 = new Matrix2D(-2, 3, 3, -4, 0, 0);
+ ok( m.invert().equals(m2), "Matrix (4,3,3,2) inverts to (-2,3,3,-4)");
});
test("isIdentity()", function() {
From 088d0e0423823aac96709fc46b8f74734bb6cb1a Mon Sep 17 00:00:00 2001
From: mucaho
Date: Mon, 6 Jan 2014 19:04:38 +0100
Subject: [PATCH 52/61] fix jshint warnings
---
tests/events.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/events.js b/tests/events.js
index 78a90650..b0d6dacd 100644
--- a/tests/events.js
+++ b/tests/events.js
@@ -26,9 +26,9 @@ test("Global binding events", function() {
strictEqual(x, 0, "Crafty.bind does not fire once unbound");
x = 0;
- var ref = Crafty.bind("Increment", add)
- Crafty.unbind("Increment", ref)
- Crafty.trigger("Increment")
+ var ref = Crafty.bind("Increment", add);
+ Crafty.unbind("Increment", ref);
+ Crafty.trigger("Increment");
strictEqual(x, 0, "Crafty.bind does not fire once unbound via reference");
x = 0;
From 435b5259662238c6b71582f46d3f89a4485c5646 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Fri, 10 Jan 2014 10:04:56 +0100
Subject: [PATCH 53/61] Failing test for the Crafty.frame();
---
tests/core.js | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/tests/core.js b/tests/core.js
index 3f25d2df..410e0736 100644
--- a/tests/core.js
+++ b/tests/core.js
@@ -284,6 +284,19 @@ test("destroy", function() {
});
+test(".frame() function", function(){
+ var frameNumber;
+ var frameFunction = function() {
+ frameNumber = Crafty.frame();
+ };
+ Crafty.bind('EnterFrame', frameFunction);
+ Crafty.timer.simulateFrames(1);
+
+ ok(frameNumber, '.frame function should return a value.');
+
+ Crafty.unbind(frameFunction);
+});
+
module("Scenes", {
setup: function() {
// prepare something for all following tests
From dc11c9fa2730d0176c1f5fa5b14ae4105ec2b1a6 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Fri, 10 Jan 2014 10:07:19 +0100
Subject: [PATCH 54/61] Remove frame variable so the crafty scope can access
frame variable. Fixed #688
---
src/core.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/core.js b/src/core.js
index 48ba6f37..bd6fe16d 100644
--- a/src/core.js
+++ b/src/core.js
@@ -46,7 +46,8 @@ var Crafty = function (selector) {
initState = function () {
- GUID = 1; //GUID for entity IDs
+ GUID = 1, //GUID for entity IDs
+ frame = 0;
components = {}; //map of components and their functions
entities = {}; //map of entities and their data
@@ -1019,8 +1020,7 @@ Crafty.extend({
// variables used by the game loop to track state
var endTime = 0,
timeSlip = 0,
- gameTime,
- frame = 0;
+ gameTime;
// Controls the target rate of fixed mode loop. Set these with the Crafty.timer.FPS function
var FPS = 50,
From 15f2970e2a3927a71834d4e123d9c5edc726c889 Mon Sep 17 00:00:00 2001
From: Tim Martin
Date: Fri, 10 Jan 2014 18:03:17 -0500
Subject: [PATCH 55/61] Abstract viewport resizing
Add setters/getters for the viewport, and trigger a "ViewportResize" event. Use that event to alter the dimensions of the stage and canvas appropriately.
---
src/DOM.js | 11 ++++++--
src/canvas.js | 13 +++++++--
src/viewport.js | 70 +++++++++++++++++++++++++++++++++++++++----------
tests/stage.js | 29 ++++++++++++++++++++
4 files changed, 105 insertions(+), 18 deletions(-)
diff --git a/src/DOM.js b/src/DOM.js
index cfa4a35c..bb3f4783 100644
--- a/src/DOM.js
+++ b/src/DOM.js
@@ -298,8 +298,15 @@ Crafty.extend({
this.height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
// Bind scene rendering (see drawing.js)
- Crafty.unbind("RenderScene", Crafty.DrawManager.renderDOM);
- Crafty.bind("RenderScene", Crafty.DrawManager.renderDOM);
+ Crafty.uniqueBind("RenderScene", Crafty.DrawManager.renderDOM);
+ // Resize the viewport
+ Crafty.uniqueBind("ViewportResize", this._resize);
+
+ },
+
+ _resize: function(){
+ Crafty.stage.elem.style.width = Crafty.viewport.width + "px";
+ Crafty.stage.elem.style.height = Crafty.viewport.height + "px";
},
width: 0,
diff --git a/src/canvas.js b/src/canvas.js
index 44260acb..c11e29c6 100644
--- a/src/canvas.js
+++ b/src/canvas.js
@@ -207,8 +207,17 @@ Crafty.extend({
Crafty.canvas.context.scale(zoom, zoom);
//Bind rendering of canvas context (see drawing.js)
- Crafty.unbind("RenderScene", Crafty.DrawManager.renderCanvas);
- Crafty.bind("RenderScene", Crafty.DrawManager.renderCanvas);
+ Crafty.uniqueBind("RenderScene", Crafty.DrawManager.renderCanvas);
+
+ Crafty.uniqueBind("ViewportResize", this._resize);
+ },
+
+ // Resize the canvas element to the current viewport
+ _resize: function() {
+ var c = Crafty.canvas._canvas;
+ c.width = Crafty.viewport.width;
+ c.height = Crafty.viewport.height;
+
}
}
diff --git a/src/viewport.js b/src/viewport.js
index 8319295e..3d77db67 100644
--- a/src/viewport.js
+++ b/src/viewport.js
@@ -7,6 +7,7 @@ Crafty.extend({
* @category Stage
* @trigger ViewportScroll - when the viewport's x or y coordinates change
* @trigger ViewportScale - when the viewport's scale changes
+ * @trigger ViewportResize - when the viewport's dimension's change
* @trigger InvalidateViewport - when the viewport changes
* @trigger StopCamera - when any camera animations should stop, such as at the start of a new animation.
* @trigger CameraAnimationDone - when a camera animation comes reaches completion
@@ -25,8 +26,8 @@ Crafty.extend({
* For development it can be useful to set this to false.
*/
clampToEntities: true,
- width: 0,
- height: 0,
+ _width: 0,
+ _height: 0,
/**@
* #Crafty.viewport.x
* @comp Crafty.viewport
@@ -475,9 +476,12 @@ Crafty.extend({
init: function (w, h, stage_elem) {
Crafty.DOM.window.init();
+ // setters+getters for the viewport
+ this._defineViewportProperties();
+
//fullscreen if mobile or not specified
- this.width = (!w || Crafty.mobile) ? Crafty.DOM.window.width : w;
- this.height = (!h || Crafty.mobile) ? Crafty.DOM.window.height : h;
+ this._width = (!w || Crafty.mobile) ? Crafty.DOM.window.width : w;
+ this._height = (!h || Crafty.mobile) ? Crafty.DOM.window.height : h;
//check if stage exists
if (typeof stage_elem === 'undefined')
@@ -587,6 +591,10 @@ Crafty.extend({
elem.height = this.height + "px";
elem.overflow = "hidden";
+
+ // resize events
+ Crafty.bind("ViewportResize", function(){Crafty.trigger("InvalidateViewport");});
+
if (Crafty.mobile) {
elem.position = "absolute";
elem.left = "0px";
@@ -629,6 +637,11 @@ Crafty.extend({
Crafty.stage.y = offset.y;
}
+
+ },
+
+ // Create setters/getters for x, y, width, height
+ _defineViewportProperties: function(){
if (Crafty.support.setter) {
//define getters and setters to scroll the viewport
this.__defineSetter__('x', function (v) {
@@ -637,12 +650,28 @@ Crafty.extend({
this.__defineSetter__('y', function (v) {
this.scroll('_y', v);
});
+ this.__defineSetter__('width', function (v) {
+ this._width = v;
+ Crafty.trigger("ViewportResize");
+ });
+ this.__defineSetter__('height', function (v) {
+ this._height = v;
+ Crafty.trigger("ViewportResize");
+ });
this.__defineGetter__('x', function () {
return this._x;
});
this.__defineGetter__('y', function () {
return this._y;
});
+ this.__defineGetter__('width', function () {
+ return this._width;
+ });
+ this.__defineGetter__('height', function () {
+ return this._height;
+ });
+
+
//IE9
} else if (Crafty.support.defineProperty) {
@@ -664,6 +693,26 @@ Crafty.extend({
},
configurable : true
});
+ Object.defineProperty(this, 'width', {
+ set: function (v) {
+ this._width = v;
+ Crafty.trigger("ViewportResize");
+ },
+ get: function () {
+ return this._width;
+ },
+ configurable : true
+ });
+ Object.defineProperty(this, 'height', {
+ set: function (v) {
+ this._height = v;
+ Crafty.trigger("ViewportResize");
+ },
+ get: function () {
+ return this._height;
+ },
+ configurable : true
+ });
}
},
@@ -685,16 +734,9 @@ Crafty.extend({
if (Crafty.stage.fullscreen) {
- this.width = w;
- this.height = h;
- Crafty.stage.elem.style.width = w + "px";
- Crafty.stage.elem.style.height = h + "px";
-
- if (Crafty.canvas._canvas) {
- Crafty.canvas._canvas.width = w;
- Crafty.canvas._canvas.height = h;
- Crafty.trigger("InvalidateViewport");
- }
+ this._width = w;
+ this._height = h;
+ Crafty.trigger("ViewportResize");
}
offset = Crafty.DOM.inner(Crafty.stage.elem);
diff --git a/tests/stage.js b/tests/stage.js
index 2da503d9..e1957aed 100644
--- a/tests/stage.js
+++ b/tests/stage.js
@@ -66,6 +66,35 @@ test("scroll using x, y", function() {
equal(before.y - Crafty.DOM.translate(e.x, e.y).y, 0, "Scroll to 0");
});
+test("Viewport resizing", function(){
+ var flag = 0;
+ var e = Crafty("2D, Canvas");
+ Crafty.canvas.init();
+
+ var w = Crafty.viewport.width;
+
+ equal( Crafty.canvas._canvas.width, Crafty.viewport.width, "Initial canvas size matches viewport");
+ equal(Crafty.stage.elem.style.width, Crafty.viewport.width + "px", "Initial stage size matches viewport");
+ Crafty.bind("ViewportResize", function(){flag++;});
+
+ Crafty.viewport.width += 10;
+
+ equal(flag, 1, "ViewportResize triggered");
+ equal(Crafty.viewport.width, w+10, "Viewport increased in width");
+ equal( Crafty.canvas._canvas.width, Crafty.viewport.width , "Canvas size matches viewport after change");
+ equal(Crafty.stage.elem.style.width, Crafty.viewport.width +"px", "Stage size matches viewport after change");
+
+ var h = Crafty.viewport.height;
+
+ Crafty.viewport.height += 10;
+
+ equal(flag, 2, "ViewportResize triggered");
+ equal(Crafty.viewport.height, h+10, "Viewport increased in width");
+ equal( Crafty.canvas._canvas.height, Crafty.viewport.height , "Canvas size matches viewport after change");
+ equal(Crafty.stage.elem.style.height, Crafty.viewport.height +"px", "Stage size matches viewport after change");
+
+});
+
test("follow", function() {
Crafty.viewport.clampToEntities = false;
var e = Crafty.e("2D, DOM").attr({
From fadef8896b13abc21352278f6a9fb27dff653e3d Mon Sep 17 00:00:00 2001
From: Tim Martin
Date: Mon, 13 Jan 2014 03:14:35 -0500
Subject: [PATCH 56/61] Fix shared coord issue
---
src/extensions.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/extensions.js b/src/extensions.js
index 7b50d793..9327b0ba 100644
--- a/src/extensions.js
+++ b/src/extensions.js
@@ -236,6 +236,7 @@ Crafty.extend({
this.requires("2D, Sprite");
this.__trim = [0, 0, 0, 0];
this.__image = url;
+ this.__coord = [this.__coord[0], this.__coord[1], this.__coord[2], this.__coord[3]];
this.__tile = tile;
this.__tileh = tileh;
this.__padding = [paddingX, paddingY];
From bdbf1e3d5e34b655d23a1e293a6ecfaf2e71e941 Mon Sep 17 00:00:00 2001
From: Tim Martin
Date: Mon, 13 Jan 2014 16:44:55 -0500
Subject: [PATCH 57/61] Switch redraw event name to "Invalidate"
Currently we use "Change" to indicate both when an attribute has been changed by `attr`, and to indicate when an entity needs to be redrawn.
This patch switches the name of the latter type of event to "Invalidate".
Since every other instance of "Invalidate" doesn't pass any date, this no longer passes the old coordinates when an entity is invalidated becuase of a move -- the event "Move" already covers that case.
---
src/2D.js | 14 +++++++-------
src/DOM.js | 4 ++--
src/canvas.js | 2 +-
src/drawing.js | 14 +++++++-------
src/extensions.js | 4 ++--
src/sprite.js | 6 +++---
src/text.js | 14 +++++++-------
src/viewport.js | 4 ++--
8 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/src/2D.js b/src/2D.js
index 76ad38d7..46824cd2 100644
--- a/src/2D.js
+++ b/src/2D.js
@@ -71,7 +71,7 @@ Crafty.extend({
* @category 2D
* Component for any entity that has a position on the stage.
* @trigger Move - when the entity has moved - { _x:Number, _y:Number, _w:Number, _h:Number } - Old position
- * @trigger Change - when the entity has moved - { _x:Number, _y:Number, _w:Number, _h:Number } - Old position
+ * @trigger Invalidate - when the entity needs to be redrawn
* @trigger Rotate - when the entity is rotated - { cos:Number, sin:Number, deg:Number, rad:Number, o: {x:Number, y:Number}}
*/
Crafty.c("2D", {
@@ -871,7 +871,7 @@ Crafty.c("2D", {
/**@
* #.flip
* @comp 2D
- * @trigger Change - when the entity has flipped
+ * @trigger Invalidate - when the entity has flipped
* @sign public this .flip(String dir)
* @param dir - Flip direction
*
@@ -886,7 +886,7 @@ Crafty.c("2D", {
dir = dir || "X";
if (!this["_flip" + dir]) {
this["_flip" + dir] = true;
- this.trigger("Change");
+ this.trigger("Invalidate");
}
return this;
},
@@ -894,7 +894,7 @@ Crafty.c("2D", {
/**@
* #.unflip
* @comp 2D
- * @trigger Change - when the entity has unflipped
+ * @trigger Invalidate - when the entity has unflipped
* @sign public this .unflip(String dir)
* @param dir - Unflip direction
*
@@ -909,7 +909,7 @@ Crafty.c("2D", {
dir = dir || "X";
if (this["_flip" + dir]) {
this["_flip" + dir] = false;
- this.trigger("Change");
+ this.trigger("Invalidate");
}
return this;
},
@@ -990,8 +990,8 @@ Crafty.c("2D", {
//everything will assume the value
this[name] = value;
- //trigger a change
- this.trigger("Change", old);
+ // flag for redraw
+ this.trigger("Invalidate");
Crafty._rectPool.recycle(old);
}
diff --git a/src/DOM.js b/src/DOM.js
index cfa4a35c..8cdc999c 100644
--- a/src/DOM.js
+++ b/src/DOM.js
@@ -40,7 +40,7 @@ Crafty.c("DOM", {
this._element.style.position = "absolute";
this._element.id = "ent" + this[0];
- this.bind("Change", function () {
+ this.bind("Invalidate", function () {
if (!this._changed) {
this._changed = true;
Crafty.DrawManager.addDom(this);
@@ -270,7 +270,7 @@ Crafty.c("DOM", {
}
}
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
}
diff --git a/src/canvas.js b/src/canvas.js
index 44260acb..9d77427a 100644
--- a/src/canvas.js
+++ b/src/canvas.js
@@ -32,7 +32,7 @@ Crafty.c("Canvas", {
this._changed = true;
Crafty.DrawManager.addCanvas(this);
- this.bind("Change", function (e) {
+ this.bind("Invalidate", function (e) {
//flag if changed
if (this._changed === false) {
this._changed = true;
diff --git a/src/drawing.js b/src/drawing.js
index 24913e8e..cc7b2276 100644
--- a/src/drawing.js
+++ b/src/drawing.js
@@ -25,7 +25,7 @@ Crafty.c("Color", {
/**@
* #.color
* @comp Color
- * @trigger Change - when the color changes
+ * @trigger Invalidate - when the color changes
* @sign public this .color(String color)
* @sign public String .color()
* @param color - Color of the rectangle
@@ -43,7 +43,7 @@ Crafty.c("Color", {
color: function (color) {
if (!color) return this._color;
this._color = color;
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
}
});
@@ -75,7 +75,7 @@ Crafty.c("Tint", {
/**@
* #.tint
* @comp Tint
- * @trigger Change - when the tint is applied
+ * @trigger Invalidate - when the tint is applied
* @sign public this .tint(String color, Number strength)
* @param color - The color in hexadecimal
* @param strength - Level of opacity
@@ -92,7 +92,7 @@ Crafty.c("Tint", {
this._strength = strength;
this._color = Crafty.toRGB(color, this._strength);
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
}
});
@@ -136,7 +136,7 @@ Crafty.c("Image", {
/**@
* #.image
* @comp Image
- * @trigger Change - when the image is loaded
+ * @trigger Invalidate - when the image is loaded
* @sign public this .image(String url[, String repeat])
* @param url - URL of the image
* @param repeat - If the image should be repeated to fill the entity.
@@ -183,7 +183,7 @@ Crafty.c("Image", {
self.h = self.img.height;
}
- self.trigger("Change");
+ self.trigger("Invalidate");
};
return this;
@@ -197,7 +197,7 @@ Crafty.c("Image", {
}
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
}
diff --git a/src/extensions.js b/src/extensions.js
index 7b50d793..3ef2b786 100644
--- a/src/extensions.js
+++ b/src/extensions.js
@@ -216,7 +216,7 @@ Crafty.extend({
var markSpritesReady = function() {
this.ready = true;
- this.trigger("Change");
+ this.trigger("Invalidate");
};
img = Crafty.asset(url);
@@ -246,7 +246,7 @@ Crafty.extend({
//draw now
if (this.img.complete && this.img.width > 0) {
this.ready = true;
- this.trigger("Change");
+ this.trigger("Invalidate");
}
//set the width and height to the sprite size
diff --git a/src/sprite.js b/src/sprite.js
index 5a3ff9aa..af86bf72 100644
--- a/src/sprite.js
+++ b/src/sprite.js
@@ -4,7 +4,7 @@ var Crafty = require('./core.js'),
/**@
* #Sprite
* @category Graphics
- * @trigger Change - when the sprites change
+ * @trigger Invalidate - when the sprites change
* Component for using tiles in a sprite map.
*/
Crafty.c("Sprite", {
@@ -106,7 +106,7 @@ Crafty.c("Sprite", {
this.__coord[3] = this.__trim[3] || h * this.__tileh || this.__tileh;
}
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
},
@@ -144,7 +144,7 @@ Crafty.c("Sprite", {
this._w = w;
this._h = h;
- this.trigger("Change", old);
+ this.trigger("Invalidate", old);
return this;
}
});
\ No newline at end of file
diff --git a/src/text.js b/src/text.js
index 641c0ab1..a9959658 100644
--- a/src/text.js
+++ b/src/text.js
@@ -4,7 +4,7 @@ var Crafty = require('./core.js'),
/**@
* #Text
* @category Graphics
- * @trigger Change - when the text is changed
+ * @trigger Invalidate - when the text is changed
* @requires Canvas or DOM
* Component to make a text entity.
*
@@ -129,7 +129,7 @@ Crafty.c("Text", {
if (this.has("Canvas") )
this._resizeForCanvas();
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
},
@@ -171,14 +171,14 @@ Crafty.c("Text", {
textColor: function (color, strength) {
this._strength = strength;
this._textColor = Crafty.toRGB(color, this._strength);
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
},
/**@
* #.textFont
* @comp Text
- * @triggers Change
+ * @triggers Invalidate
* @sign public this .textFont(String key, * value)
* @param key - Property of the entity to modify
* @param value - Value to set the property to
@@ -222,13 +222,13 @@ Crafty.c("Text", {
if (this.has("Canvas") )
this._resizeForCanvas();
- this.trigger("Change");
+ this.trigger("Invalidate");
return this;
},
/**@
* #.unselectable
* @comp Text
- * @triggers Change
+ * @triggers Invalidate
* @sign public this .unselectable()
*
* This method sets the text so that it cannot be selected (highlighted) by dragging.
@@ -251,7 +251,7 @@ Crafty.c("Text", {
'-ms-user-select': 'none',
'user-select': 'none'
});
- this.trigger("Change");
+ this.trigger("Invalidate");
}
return this;
}
diff --git a/src/viewport.js b/src/viewport.js
index 8319295e..41bfd073 100644
--- a/src/viewport.js
+++ b/src/viewport.js
@@ -201,7 +201,7 @@ Crafty.extend({
function stopFollow(){
if (oldTarget)
- oldTarget.unbind('Change', change);
+ oldTarget.unbind('Move', change);
}
Crafty.bind("StopCamera", stopFollow);
@@ -215,7 +215,7 @@ Crafty.extend({
offx = (typeof offsetx != 'undefined') ? offsetx : 0;
offy = (typeof offsety != 'undefined') ? offsety : 0;
- target.bind('Change', change);
+ target.bind('Move', change);
change.call(target);
};
})(),
From ffba1c0c8eeede128b48bb83ce61018e291f1ef2 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Sun, 12 Jan 2014 00:25:02 +0100
Subject: [PATCH 58/61] More documentation for storage function
---
src/storage.js | 621 ++++---------------------------------------------
1 file changed, 41 insertions(+), 580 deletions(-)
diff --git a/src/storage.js b/src/storage.js
index 5cdcebed..c6c5791f 100644
--- a/src/storage.js
+++ b/src/storage.js
@@ -8,608 +8,69 @@ var Crafty = require('./core.js'),
/**@
* #Storage
* @category Utilities
- * Utility to allow data to be saved to a permanent storage solution: IndexedDB, WebSql, localstorage or cookies
+ * Very simple way to get and set values, which will persist when the browser is closed also.
*/
/**@
- * #.open
+ * #.storage
* @comp Storage
- * @sign .open(String gameName)
- * @param gameName - a machine readable string to uniquely identify your game
+ * @sign .storage(String key)
+ * @param key - a key you would like to get from the storage. It will return null if the key does not exists.
+ * @sign .storage(String key, String value)
+ * @param key - the key you would like to save the data under.
+ * @param value - the value you would like to save.
+ * @sign .storage(String key, [Object value, Array value, Boolean value])
+ * @param key - the key you would like to save the data under.
+ * @param value - the value you would like to save, can be an Object or an Array.
*
- * Opens a connection to the database. If the best they have is localstorage or lower, it does nothing
+ * Storage function is very simple and can be used to either get or set values.
+ * You can store both booleans, strings, objects and arrays.
*
* @example
- * Open a database
+ * Get an already stored value
* ~~~
- * Crafty.storage.open('MyGame');
+ * var playername = Crafty.storage('playername');
* ~~~
- */
-/**@
- * #.save
- * @comp Storage
- * @sign .save(String key, String type, Mixed data)
- * @param key - A unique key for identifying this piece of data
- * @param type - 'save' or 'cache'
- * @param data - Some kind of data.
- *
- * Saves a piece of data to the database. Can be anything, although entities are preferred.
- * For all storage methods but IndexedDB, the data will be serialized as a string
- * During serialization, an entity's SaveData event will be triggered.
- * Components should implement a SaveData handler and attach the necessary information to the passed object
*
* @example
- * Saves an entity to the database
+ * Save a value
* ~~~
- * var ent = Crafty.e("2D, DOM")
- * .attr({x: 20, y: 20, w: 100, h:100});
- * Crafty.storage.open('MyGame');
- * Crafty.storage.save('MyEntity', 'save', ent);
+ * Crafty.storage('playername', 'Hero');
* ~~~
- */
-/**@
- * #.load
- * @comp Storage
- * @sign .load(String key, String type)
- * @param key - A unique key to search for
- * @param type - 'save' or 'cache'
- * @param callback - Do things with the data you get back
- *
- * Loads a piece of data from the database.
- * Entities will be reconstructed from the serialized string
-
- * @example
- * Loads an entity from the database
- * ~~~
- * Crafty.storage.open('MyGame');
- * Crafty.storage.load('MyEntity', 'save', function (data) { // do things });
- * ~~~
- */
-/**@
- * #.getAllKeys
- * @comp Storage
- * @sign .getAllKeys(String type)
- * @param type - 'save' or 'cache'
- * Gets all the keys for a given type
-
- * @example
- * Gets all the save games saved
- * ~~~
- * Crafty.storage.open('MyGame');
- * var saves = Crafty.storage.getAllKeys('save');
- * ~~~
- */
-/**@
- * #.external
- * @comp Storage
- * @sign .external(String url)
- * @param url - URL to an external to save games too
- *
- * Enables and sets the url for saving games to an external server
- *
- * @example
- * Save an entity to an external server
- * ~~~
- * Crafty.storage.external('http://somewhere.com/server.php');
- * Crafty.storage.open('MyGame');
- * var ent = Crafty.e('2D, DOM')
- * .attr({x: 20, y: 20, w: 100, h:100});
- * Crafty.storage.save('save01', 'save', ent);
- * ~~~
- */
-/**@
- * #SaveData event
- * @comp Storage
- * @param data - An object containing all of the data to be serialized
- * @param prepare - The function to prepare an entity for serialization
- *
- * Any data a component wants to save when it's serialized should be added to this object.
- * Straight attribute should be set in data.attr.
- * Anything that requires a special handler should be set in a unique property.
*
* @example
- * Saves the innerHTML of an entity
+ * Test to see if a value is already there.
* ~~~
- * Crafty.e("2D DOM").bind("SaveData", function (data, prepare) {
- * data.attr.x = this.x;
- * data.attr.y = this.y;
- * data.dom = this.element.innerHTML;
- * });
+ * var heroname = Crafty.storage('name');
+ * if(!heroname){
+ * // Maybe ask the player what their name is here
+ * heroname = 'Guest';
+ * }
+ * // Do something with heroname
* ~~~
*/
-/**@
- * #LoadData event
- * @comp Storage
- * @param data - An object containing all the data that been saved
- * @param process - The function to turn a string into an entity
- *
- * Handlers for processing any data that needs more than straight assignment
- *
- * Note that data stored in the .attr object is automatically added to the entity.
- * It does not need to be handled here
- *
- * @example
- * ~~~
- * Sets the innerHTML from a saved entity
- * Crafty.e("2D DOM").bind("LoadData", function (data, process) {
- * this.element.innerHTML = data.dom;
- * });
- * ~~~
- */
-Crafty.storage = (function () {
- var db = null,
- url, gameName, timestamps = {},
- transactionType = {
- READ: "readonly",
- READ_WRITE: "readwrite"
- };
-
- /*
- * Processes a retrieved object.
- * Creates an entity if it is one
- */
-
- function process(obj) {
- if (obj.c) {
- var d = Crafty.e(obj.c)
- .attr(obj.attr)
- .trigger('LoadData', obj, process);
- return d;
- } else if (typeof obj == 'object') {
- for (var prop in obj) {
- obj[prop] = process(obj[prop]);
- }
- }
- return obj;
- }
-
- function unserialize(str) {
- if (typeof str != 'string') return null;
- var data = (JSON ? JSON.parse(str) : eval('(' + str + ')'));
- return process(data);
- }
- /* recursive function
- * searches for entities in an object and processes them for serialization
- */
+Crafty.storage = function(key, value){
+ var storage = window.localStorage,
+ _value = value;
- function prep(obj) {
- if (obj.__c) {
- // object is entity
- var data = {
- c: [],
- attr: {}
- };
- obj.trigger("SaveData", data, prep);
- for (var i in obj.__c) {
- data.c.push(i);
- }
- data.c = data.c.join(', ');
- obj = data;
- } else if (typeof obj == 'object') {
- // recurse and look for entities
- for (var prop in obj) {
- obj[prop] = prep(obj[prop]);
- }
- }
- return obj;
+ if(arguments.length === 1) {
+ try {
+ return JSON.parse(storage.getItem(key));
}
-
- function serialize(e) {
- if (JSON) {
- var data = prep(e);
- return JSON.stringify(data);
- } else {
- alert("Crafty does not support saving on your browser. Please upgrade to a newer browser.");
- return false;
- }
+ catch (e) {
+ return storage.getItem(key);
}
-
- // for saving a game to a central server
-
- function external(setUrl) {
- url = setUrl;
+ } else {
+ if(typeof value === "object") {
+ _value = JSON.stringify(value);
}
- function openExternal() {
- if (1 && typeof url == "undefined") return;
- // get the timestamps for external saves and compare them to local
- // if the external is newer, load it
+ storage.setItem(key, _value);
+
+ }
- var xml = new XMLHttpRequest();
- xhr.open("POST", url);
- xhr.onreadystatechange = function (evt) {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- var data = eval("(" + xhr.responseText + ")");
- for (var i in data) {
- if (Crafty.storage.check(data[i].key, data[i].timestamp)) {
- loadExternal(data[i].key);
- }
- }
- }
- }
- };
- xhr.send("mode=timestamps&game=" + gameName);
- }
+};
- function saveExternal(key, data, ts) {
- if (1 && typeof url == "undefined") return;
- var xhr = new XMLHttpRequest();
- xhr.open("POST", url);
- xhr.send("mode=save&key=" + key + "&data=" + encodeURIComponent(data) + "&ts=" + ts + "&game=" + gameName);
- }
-
- function loadExternal(key) {
- if (1 && typeof url == "undefined") return;
- var xhr = new XMLHttpRequest();
- xhr.open("POST", url);
- xhr.onreadystatechange = function (evt) {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- var data = eval("(" + xhr.responseText + ")");
- Crafty.storage.save(key, 'save', data);
- }
- }
- };
- xhr.send("mode=load&key=" + key + "&game=" + gameName);
- }
-
- /**
- * get timestamp
- */
-
- function ts() {
- var d = new Date();
- return d.getTime();
- }
-
- // everyone names their object different. Fix that nonsense.
- if (typeof indexedDB != 'object') {
- window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
- window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;
- window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
-
- /* Numeric constants for transaction type are deprecated
- * Ensure that the script will work consistenly for recent and legacy browser versions
- */
- if (typeof IDBTransaction == 'object') {
- transactionType.READ = IDBTransaction.READ || IDBTransaction.readonly || transactionType.READ || 'read';
- transactionType.READ_WRITE = IDBTransaction.READ_WRITE || IDBTransaction.readwrite || transactionType.READ_WRITE || 'readwrite';
- }
- }
-
- if (typeof indexedDB == 'object') {
-
- return {
- open: function (gameName_n) {
- gameName = gameName_n;
- var stores = [];
-
- if (arguments.length == 1) {
- stores.push('save');
- stores.push('cache');
- } else {
- stores = arguments;
- stores.shift();
- stores.push('save');
- stores.push('cache');
- }
- if (db === null) {
- var request = indexedDB.open(gameName);
- request.onsuccess = function (e) {
- db = e.target.result;
- getTimestamps();
- openExternal();
- };
- request.onupgradeneeded = function (e) {
- createStores();
- };
- } else {
- createStores();
- getTimestamps();
- openExternal();
- }
-
- // get all the timestamps for existing keys
-
- function getTimestamps() {
- try {
- var trans = db.transaction(['save'], "read"),
- store = trans.objectStore('save'),
- request = store.getAll();
- request.onsuccess = function (e) {
- var i = 0,
- a = event.target.result,
- l = a.length;
- for (; i < l; i++) {
- timestamps[a[i].key] = a[i].timestamp;
- }
- };
- } catch (e) {}
- }
-
- function createStores() {
- var request = db.setVersion("1.0");
- request.onsuccess = function (e) {
- for (var i = 0; i < stores.length; i++) {
- var st = stores[i];
- if (db.objectStoreNames.contains(st)) continue;
- var store = db.createObjectStore(st, {
- keyPath: "key"
- });
- }
- };
- }
- },
-
- save: function (key, type, data, callback) {
- if (db === null) {
- setTimeout(function () {
- Crafty.storage.save(key, type, data);
- }, 1);
- return;
- }
-
- var str = serialize(data),
- t = ts();
- if (type == 'save') saveExternal(key, str, t);
- try {
- var request = db.transaction([type], transactionType.READ_WRITE).objectStore(type).add({
- "data": str,
- "timestamp": t,
- "key": key
- });
- if (typeof callback == 'function') {
- request.onsuccess = callback;
- }
- } catch (e) {
- console.error(e);
- }
- },
-
- load: function (key, type, callback) {
- if (db === null) {
- setTimeout(function () {
- Crafty.storage.load(key, type, callback);
- }, 1);
- return;
- }
- try {
- var request = db.transaction([type], transactionType.READ).objectStore(type).get(key);
- request.onsuccess = function (e) {
- callback(unserialize(e.target.result.data));
- };
- } catch (e) {
- console.error(e);
- }
- },
-
- getAllKeys: function (type, callback) {
- if (db === null) {
- setTimeout(function () {
- Crafty.storage.getAllkeys(type, callback);
- }, 1);
- }
- try {
- var request = db.transaction([type], transactionType.READ).objectStore(type).openCursor(),
- res = [];
- request.onsuccess = function (e) {
- var cursor = e.target.result;
- if (cursor) {
- res.push(cursor.key);
- // 'continue' is a reserved word, so .continue() causes IE8 to completely bark with "SCRIPT1010: Expected identifier".
- cursor['continue']();
- } else {
- callback(res);
- }
- };
- } catch (e) {
- console.error(e);
- }
- },
-
- check: function (key, timestamp) {
- return (timestamps[key] > timestamp);
- },
-
- external: external
- };
- } else if (typeof openDatabase == 'function') {
- return {
- open: function (gameName_n) {
- gameName = gameName_n;
- if (arguments.length == 1) {
- db = {
- save: openDatabase(gameName_n + '_save', '1.0', 'Saves games for ' + gameName_n, 5 * 1024 * 1024),
- cache: openDatabase(gameName_n + '_cache', '1.0', 'Cache for ' + gameName_n, 5 * 1024 * 1024)
- };
- } else {
- // allows for any other types that can be thought of
- var args = arguments,
- i = 0;
- args.shift();
- for (; i < args.length; i++) {
- if (typeof db[args[i]] == 'undefined')
- db[args[i]] = openDatabase(gameName + '_' + args[i], '1.0', type, 5 * 1024 * 1024);
- }
- }
-
- db.save.transaction(function (tx) {
- tx.executeSql('SELECT key, timestamp FROM data', [], function (tx, res) {
- var i = 0,
- a = res.rows,
- l = a.length;
- for (; i < l; i++) {
- timestamps[a.item(i).key] = a.item(i).timestamp;
- }
- });
- });
- },
-
- save: function (key, type, data) {
- if (typeof db[type] == 'undefined' && gameName !== '') {
- this.open(gameName, type);
- }
-
- var str = serialize(data),
- t = ts();
- if (type == 'save') saveExternal(key, str, t);
- db[type].transaction(function (tx) {
- tx.executeSql('CREATE TABLE IF NOT EXISTS data (key unique, text, timestamp)');
- tx.executeSql('SELECT * FROM data WHERE key = ?', [key], function (tx, results) {
- if (results.rows.length) {
- tx.executeSql('UPDATE data SET text = ?, timestamp = ? WHERE key = ?', [str, t, key]);
- } else {
- tx.executeSql('INSERT INTO data VALUES (?, ?, ?)', [key, str, t]);
- }
- });
- });
- },
-
- load: function (key, type, callback) {
- if (typeof db[type] === 'undefined') {
- setTimeout(function () {
- Crafty.storage.load(key, type, callback);
- }, 1);
- return;
- }
- db[type].transaction(function (tx) {
- tx.executeSql('SELECT text FROM data WHERE key = ?', [key], function (tx, results) {
- if (results.rows.length) {
- res = unserialize(results.rows.item(0).text);
- callback(res);
- }
- });
- });
- },
-
- getAllKeys: function (type, callback) {
- if (typeof db[type] === 'undefined') {
- setTimeout(function () {
- Crafty.storage.getAllKeys(type, callback);
- }, 1);
- return;
- }
- db[type].transaction(function (tx) {
- tx.executeSql('SELECT key FROM data', [], function (tx, results) {
- callback(results.rows);
- });
- });
- },
-
- check: function (key, timestamp) {
- return (timestamps[key] > timestamp);
- },
-
- external: external
- };
- } else if (typeof window.localStorage == 'object') {
- return {
- open: function (gameName_n) {
- gameName = gameName_n;
- },
-
- save: function (key, type, data) {
- var k = gameName + '.' + type + '.' + key,
- str = serialize(data),
- t = ts();
- if (type == 'save') saveExternal(key, str, t);
- window.localStorage[k] = str;
- if (type == 'save')
- window.localStorage[k + '.ts'] = t;
- },
-
- load: function (key, type, callback) {
- var k = gameName + '.' + type + '.' + key,
- str = window.localStorage[k];
-
- callback(unserialize(str));
- },
-
- getAllKeys: function (type, callback) {
- var res = {}, output = [],
- header = gameName + '.' + type;
- for (var i in window.localStorage) {
- if (i.indexOf(header) != -1) {
- var key = i.replace(header, '').replace('.ts', '');
- res[key] = true;
- }
- }
- for (i in res) {
- output.push(i);
- }
- callback(output);
- },
-
- check: function (key, timestamp) {
- var ts = window.localStorage[gameName + '.save.' + key + '.ts'];
-
- return (parseInt(timestamp, 10) > parseInt(ts, 10));
- },
-
- external: external
- };
- } else {
- // default fallback to cookies
- return {
- open: function (gameName_n) {
- gameName = gameName_n;
- },
-
- save: function (key, type, data) {
- // cookies are very limited in space. we can only keep saves there
- if (type != 'save') return;
- var str = serialize(data),
- t = ts();
- if (type == 'save') saveExternal(key, str, t);
- document.cookie = gameName + '_' + key + '=' + str + '; ' + gameName + '_' + key + '_ts=' + t + '; expires=Thur, 31 Dec 2099 23:59:59 UTC; path=/';
- },
-
- load: function (key, type, callback) {
- if (type != 'save') return;
- var reg = new RegExp(gameName + '_' + key + '=[^;]*'),
- result = reg.exec(document.cookie),
- data = unserialize(result[0].replace(gameName + '_' + key + '=', ''));
-
- callback(data);
- },
-
- getAllKeys: function (type, callback) {
- if (type != 'save') return;
- var reg = new RegExp(gameName + '_[^_=]', 'g'),
- matches = reg.exec(document.cookie),
- i = 0,
- l = matches.length,
- res = {}, output = [];
- for (; i < l; i++) {
- var key = matches[i].replace(gameName + '_', '');
- res[key] = true;
- }
- for (i in res) {
- output.push(i);
- }
- callback(output);
- },
-
- check: function (key, timestamp) {
- var header = gameName + '_' + key + '_ts',
- reg = new RegExp(header + '=[^;]'),
- result = reg.exec(document.cookie),
- ts = result[0].replace(header + '=', '');
-
- return (parseInt(timestamp, 10) > parseInt(ts, 10));
- },
-
- external: external
- };
- }
- /* template
- return {
- open: function (gameName) {
- },
- save: function (key, type, data) {
- },
- load: function (key, type, callback) {
- },
- }*/
-})();
\ No newline at end of file
+Crafty.storage.remove = function(key){
+ window.localStorage.removeItem(key);
+};
\ No newline at end of file
From 3558a92fe23df2f801e1c8e357b01972a3dce09d Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Sun, 12 Jan 2014 00:25:39 +0100
Subject: [PATCH 59/61] Added the storage to the test again
New tests for storage.js
---
tests/index.html | 1 +
tests/storage.js | 88 +++++++++++++-----------------------------------
2 files changed, 25 insertions(+), 64 deletions(-)
diff --git a/tests/index.html b/tests/index.html
index dc435be1..4a1dfdf7 100755
--- a/tests/index.html
+++ b/tests/index.html
@@ -54,6 +54,7 @@
+
diff --git a/tests/storage.js b/tests/storage.js
index a67c692f..da43b83e 100644
--- a/tests/storage.js
+++ b/tests/storage.js
@@ -1,73 +1,33 @@
-module("Storage");
-test("saveAndLoadObject", function() {
- Crafty.storage.open("MyGame");
- Crafty.storage.save("LeaderBoard", "save", {
- name: "Matthew",
- score: 150
- });
- stop();
- Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb.name, "Matthew");
- start();
- });
+module("Storage", {
+ setup: function() {
+ reset();
+ },
+ teardown: function() {
+ // clean up after each test
+ Crafty("*").destroy();
+ }
});
-test("saveAndLoadArray", function() {
- Crafty.storage.open("MyGame1");
- Crafty.storage.save("LeaderBoard", "save", [{
- name: "Matthew",
- score: 150
- }, {
- name: "Louis",
- score: 17
- }]);
- stop();
- Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb[1].name, "Louis");
- equal(lb.length, 2);
- start();
- });
-});
+test('get a value', function(){
+ Crafty.storage('name', 'test');
+ var name = Crafty.storage('name');
-test("saveAndLoadEntity", function() {
- Crafty.storage.open("MyGame2");
- Crafty.storage.save("Hero", "save", Crafty.e("2D, DOM").attr({
- x: 20,
- y: 137
- }));
- stop();
- Crafty.storage.load("Hero", "save", function(hero) {
- console.log(hero);
- ok(hero.__c["2D"]);
- ok(hero.__c.DOM);
- equal(hero.x, 0, "Entity state is not saved");
- start();
- });
-});
+ equal(name, 'test', 'the values should be equal');
-test("individualNamespaces", function() {
- Crafty.storage.open("MyGame3");
- Crafty.storage.save("LeaderBoard", "save", {
- name: "Matthew",
- score: 150
- });
+ Crafty.storage.remove('name');
+});
+test('get null when a value does not exist', function(){
+ var name = Crafty.storage('notexisting');
+ equal(name, null, 'should be null');
+});
- Crafty.storage.open("MyGame4");
- Crafty.storage.save("LeaderBoard", "save", {
- name: "Louis",
- score: 150
- });
+test('remove an value', function(){
+ var person = Crafty.storage('person', 'test');
+ equal(Crafty.storage('person'), 'test', 'person should be defined');
- stop();
- Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb.name, "Louis");
- start();
- });
+ Crafty.storage.remove('person');
- Crafty.storage.open("MyGame3");
- Crafty.storage.load("LeaderBoard", "save", function(lb) {
- equal(lb.name, "Matthew");
- start();
- });
+ var savedperson = Crafty.storage('person');
+ equal(savedperson, null, 'should be null because we just removed the value');
});
\ No newline at end of file
From f61e5f55eba050a67de346a9b5d685f2a806e787 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Wed, 15 Jan 2014 00:37:33 +0100
Subject: [PATCH 60/61] Updated the documentation for the storage function
explaining when to use it
If the localStorage object is not supported return false.
Added documentation for remove function
---
src/storage.js | 28 +++++++++++++++++++++++-----
1 file changed, 23 insertions(+), 5 deletions(-)
diff --git a/src/storage.js b/src/storage.js
index c6c5791f..66962158 100644
--- a/src/storage.js
+++ b/src/storage.js
@@ -1,10 +1,6 @@
var Crafty = require('./core.js'),
document = window.document;
-// Directive for jshint to ignore evals
-// eval is used to support IE8, so this can be removed if we decide to drop that
-/* jshint evil:true */
-
/**@
* #Storage
* @category Utilities
@@ -25,6 +21,8 @@ var Crafty = require('./core.js'),
* Storage function is very simple and can be used to either get or set values.
* You can store both booleans, strings, objects and arrays.
*
+ * Please note: You should not store data, while the game is playing, as it can cause the game to slow down. You should load data when you start the game, or when the user for an example click a "Save gameprocess" button.
+ *
* @example
* Get an already stored value
* ~~~
@@ -53,6 +51,10 @@ Crafty.storage = function(key, value){
var storage = window.localStorage,
_value = value;
+ if(!storage){
+ return false;
+ }
+
if(arguments.length === 1) {
try {
return JSON.parse(storage.getItem(key));
@@ -70,7 +72,23 @@ Crafty.storage = function(key, value){
}
};
-
+/**@
+ * #.storage.remove
+ * @comp Storage
+ * @sign .storage.remove(String key)
+ * @param key - a key where you will like to delete the value of.
+ *
+ * Generally you do not need to remove values from localStorage, but if you do
+ * store large amount of text, or want to unset something you can do that with
+ * this function.
+ *
+ * @example
+ * Get an already stored value
+ * ~~~
+ * Crafty.storage.remove('playername');
+ * ~~~
+ *
+ */
Crafty.storage.remove = function(key){
window.localStorage.removeItem(key);
};
\ No newline at end of file
From 56b3f0fb073d19351227031f7c938395961310b1 Mon Sep 17 00:00:00 2001
From: Kevin Simper
Date: Wed, 15 Jan 2014 12:38:16 +0100
Subject: [PATCH 61/61] Move sprite function to sprite.js
---
src/extensions.js | 138 +--------------------------------------------
src/sprite.js | 139 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 140 insertions(+), 137 deletions(-)
diff --git a/src/extensions.js b/src/extensions.js
index 372b8de7..aabeece1 100644
--- a/src/extensions.js
+++ b/src/extensions.js
@@ -134,144 +134,8 @@ var Crafty = require('./core.js'),
support.devicemotion = (typeof window.DeviceMotionEvent !== "undefined");
})();
-Crafty.extend({
-
- /**@
- * #Crafty.sprite
- * @category Graphics
- * @sign public this Crafty.sprite([Number tile, [Number tileh]], String url, Object map[, Number paddingX[, Number paddingY[, Boolean paddingAroundBorder]]])
- * @param tile - Tile size of the sprite map, defaults to 1
- * @param tileh - Height of the tile; if provided, tile is interpreted as the width
- * @param url - URL of the sprite image
- * @param map - Object where the key is what becomes a new component and the value points to a position on the sprite map
- * @param paddingX - Horizontal space in between tiles. Defaults to 0.
- * @param paddingY - Vertical space in between tiles. Defaults to paddingX.
- * @param paddingAroundBorder - If padding should be applied around the border of the sprite sheet. If enabled the first tile starts at (paddingX,paddingY) instead of (0,0). Defaults to false.
- * Generates components based on positions in a sprite image to be applied to entities.
- *
- * Accepts a tile size, URL and map for the name of the sprite and its position.
- *
- * The position must be an array containing the position of the sprite where index `0`
- * is the `x` position, `1` is the `y` position and optionally `2` is the width and `3`
- * is the height. If the sprite map has padding, pass the values for the `x` padding
- * or `y` padding. If they are the same, just add one value.
- *
- * If the sprite image has no consistent tile size, `1` or no argument need be
- * passed for tile size.
- *
- * Entities that add the generated components are also given the `2D` component, and
- * a component called `Sprite`.
- *
- * @example
- * ~~~
- * Crafty.sprite("imgs/spritemap6.png", {flower:[0,0,20,30]});
- * var flower_entity = Crafty.e("2D, DOM, flower");
- * ~~~
- * The first line creates a component called `flower` associated with the sub-image of
- * spritemap6.png with top-left corner (0,0), width 20 pixels, and height 30 pixels.
- * The second line creates an entity with that image. (Note: The `2D` is not really
- * necessary here, because adding the `flower` component automatically also adds the
- * `2D` component.)
- * ~~~
- * Crafty.sprite(50, "imgs/spritemap6.png", {flower:[0,0], grass:[0,1,3,1]});
- * ~~~
- * In this case, the `flower` component is pixels 0 <= x < 50, 0 <= y < 50, and the
- * `grass` component is pixels 0 <= x < 150, 50 <= y < 100. (The `3` means grass has a
- * width of 3 tiles, i.e. 150 pixels.)
- * ~~~
- * Crafty.sprite(50, 100, "imgs/spritemap6.png", {flower:[0,0], grass:[0,1]}, 10);
- * ~~~
- * In this case, each tile is 50x100, and there is a spacing of 10 pixels between
- * consecutive tiles. So `flower` is pixels 0 <= x < 50, 0 <= y < 100, and `grass` is
- * pixels 0 <= x < 50, 110 <= y < 210.
- *
- * @see Sprite
- */
- sprite: function (tile, tileh, url, map, paddingX, paddingY, paddingAroundBorder) {
- var spriteName, temp, x, y, w, h, img;
-
- //if no tile value, default to 1.
- //(if the first passed argument is a string, it must be the url.)
- if (typeof tile === "string") {
- paddingY = paddingX;
- paddingX = map;
- map = tileh;
- url = tile;
- tile = 1;
- tileh = 1;
- }
-
- if (typeof tileh == "string") {
- paddingY = paddingX;
- paddingX = map;
- map = url;
- url = tileh;
- tileh = tile;
- }
-
- //if no paddingY, use paddingX
- if (!paddingY && paddingX) paddingY = paddingX;
- paddingX = parseInt(paddingX || 0, 10); //just incase
- paddingY = parseInt(paddingY || 0, 10);
-
- var markSpritesReady = function() {
- this.ready = true;
- this.trigger("Invalidate");
- };
-
- img = Crafty.asset(url);
- if (!img) {
- img = new Image();
- img.src = url;
- Crafty.asset(url, img);
- img.onload = function () {
- //all components with this img are now ready
- for (var spriteName in map) {
- Crafty(spriteName).each(markSpritesReady);
- }
- };
- }
-
- var sharedSpriteInit = function() {
- this.requires("2D, Sprite");
- this.__trim = [0, 0, 0, 0];
- this.__image = url;
- this.__coord = [this.__coord[0], this.__coord[1], this.__coord[2], this.__coord[3]];
- this.__tile = tile;
- this.__tileh = tileh;
- this.__padding = [paddingX, paddingY];
- this.__padBorder = paddingAroundBorder;
- this.sprite(this.__coord[0], this.__coord[1], this.__coord[2], this.__coord[3]);
-
- this.img = img;
- //draw now
- if (this.img.complete && this.img.width > 0) {
- this.ready = true;
- this.trigger("Invalidate");
- }
-
- //set the width and height to the sprite size
- this.w = this.__coord[2];
- this.h = this.__coord[3];
- };
-
- for (spriteName in map) {
- if (!map.hasOwnProperty(spriteName)) continue;
-
- temp = map[spriteName];
-
- //generates sprite components for each tile in the map
- Crafty.c(spriteName, {
- ready: false,
- __coord: [temp[0], temp[1], temp[2] || 1, temp[3] || 1],
-
- init: sharedSpriteInit
- });
- }
-
- return this;
- },
+Crafty.extend({
_events: {},
/**@
diff --git a/src/sprite.js b/src/sprite.js
index af86bf72..dba19be8 100644
--- a/src/sprite.js
+++ b/src/sprite.js
@@ -1,6 +1,145 @@
var Crafty = require('./core.js'),
document = window.document;
+Crafty.extend({
+
+ /**@
+ * #Crafty.sprite
+ * @category Graphics
+ * @sign public this Crafty.sprite([Number tile, [Number tileh]], String url, Object map[, Number paddingX[, Number paddingY[, Boolean paddingAroundBorder]]])
+ * @param tile - Tile size of the sprite map, defaults to 1
+ * @param tileh - Height of the tile; if provided, tile is interpreted as the width
+ * @param url - URL of the sprite image
+ * @param map - Object where the key is what becomes a new component and the value points to a position on the sprite map
+ * @param paddingX - Horizontal space in between tiles. Defaults to 0.
+ * @param paddingY - Vertical space in between tiles. Defaults to paddingX.
+ * @param paddingAroundBorder - If padding should be applied around the border of the sprite sheet. If enabled the first tile starts at (paddingX,paddingY) instead of (0,0). Defaults to false.
+ * Generates components based on positions in a sprite image to be applied to entities.
+ *
+ * Accepts a tile size, URL and map for the name of the sprite and its position.
+ *
+ * The position must be an array containing the position of the sprite where index `0`
+ * is the `x` position, `1` is the `y` position and optionally `2` is the width and `3`
+ * is the height. If the sprite map has padding, pass the values for the `x` padding
+ * or `y` padding. If they are the same, just add one value.
+ *
+ * If the sprite image has no consistent tile size, `1` or no argument need be
+ * passed for tile size.
+ *
+ * Entities that add the generated components are also given the `2D` component, and
+ * a component called `Sprite`.
+ *
+ * @example
+ * ~~~
+ * Crafty.sprite("imgs/spritemap6.png", {flower:[0,0,20,30]});
+ * var flower_entity = Crafty.e("2D, DOM, flower");
+ * ~~~
+ * The first line creates a component called `flower` associated with the sub-image of
+ * spritemap6.png with top-left corner (0,0), width 20 pixels, and height 30 pixels.
+ * The second line creates an entity with that image. (Note: The `2D` is not really
+ * necessary here, because adding the `flower` component automatically also adds the
+ * `2D` component.)
+ * ~~~
+ * Crafty.sprite(50, "imgs/spritemap6.png", {flower:[0,0], grass:[0,1,3,1]});
+ * ~~~
+ * In this case, the `flower` component is pixels 0 <= x < 50, 0 <= y < 50, and the
+ * `grass` component is pixels 0 <= x < 150, 50 <= y < 100. (The `3` means grass has a
+ * width of 3 tiles, i.e. 150 pixels.)
+ * ~~~
+ * Crafty.sprite(50, 100, "imgs/spritemap6.png", {flower:[0,0], grass:[0,1]}, 10);
+ * ~~~
+ * In this case, each tile is 50x100, and there is a spacing of 10 pixels between
+ * consecutive tiles. So `flower` is pixels 0 <= x < 50, 0 <= y < 100, and `grass` is
+ * pixels 0 <= x < 50, 110 <= y < 210.
+ *
+ * @see Sprite
+ */
+ sprite: function (tile, tileh, url, map, paddingX, paddingY, paddingAroundBorder) {
+ var spriteName, temp, x, y, w, h, img;
+
+ //if no tile value, default to 1.
+ //(if the first passed argument is a string, it must be the url.)
+ if (typeof tile === "string") {
+ paddingY = paddingX;
+ paddingX = map;
+ map = tileh;
+ url = tile;
+ tile = 1;
+ tileh = 1;
+ }
+
+ if (typeof tileh == "string") {
+ paddingY = paddingX;
+ paddingX = map;
+ map = url;
+ url = tileh;
+ tileh = tile;
+ }
+
+ //if no paddingY, use paddingX
+ if (!paddingY && paddingX) paddingY = paddingX;
+ paddingX = parseInt(paddingX || 0, 10); //just incase
+ paddingY = parseInt(paddingY || 0, 10);
+
+ var markSpritesReady = function() {
+ this.ready = true;
+ this.trigger("Invalidate");
+ };
+
+ img = Crafty.asset(url);
+ if (!img) {
+ img = new Image();
+ img.src = url;
+ Crafty.asset(url, img);
+ img.onload = function () {
+ //all components with this img are now ready
+ for (var spriteName in map) {
+ Crafty(spriteName).each(markSpritesReady);
+ }
+ };
+ }
+
+ var sharedSpriteInit = function() {
+ this.requires("2D, Sprite");
+ this.__trim = [0, 0, 0, 0];
+ this.__image = url;
+ this.__coord = [this.__coord[0], this.__coord[1], this.__coord[2], this.__coord[3]];
+ this.__tile = tile;
+ this.__tileh = tileh;
+ this.__padding = [paddingX, paddingY];
+ this.__padBorder = paddingAroundBorder;
+ this.sprite(this.__coord[0], this.__coord[1], this.__coord[2], this.__coord[3]);
+
+ this.img = img;
+ //draw now
+ if (this.img.complete && this.img.width > 0) {
+ this.ready = true;
+ this.trigger("Invalidate");
+ }
+
+ //set the width and height to the sprite size
+ this.w = this.__coord[2];
+ this.h = this.__coord[3];
+ };
+
+ for (spriteName in map) {
+ if (!map.hasOwnProperty(spriteName)) continue;
+
+ temp = map[spriteName];
+
+ //generates sprite components for each tile in the map
+ Crafty.c(spriteName, {
+ ready: false,
+ __coord: [temp[0], temp[1], temp[2] || 1, temp[3] || 1],
+
+ init: sharedSpriteInit
+ });
+ }
+
+ return this;
+ }
+});
+
/**@
* #Sprite
* @category Graphics