From e7297ab811980fd794e20f584acc88ac64a24c90 Mon Sep 17 00:00:00 2001 From: Sven Slootweg Date: Sun, 18 May 2014 13:16:41 +0200 Subject: [PATCH] Separate experiments folder, gulpfile fixes, and general repo clean-up --- TODO.md | 6 +- docs/api/draw.html | 168 ---- docs/api/draw.zpy | 94 -- docs/api/math.html | 162 ---- docs/api/math.zpy | 150 --- docs/api/random.html | 163 ---- docs/api/random.zpy | 123 --- easing.html | 13 - easing/assets/images/cursor.png | Bin 1469 -> 0 bytes easing/core.coffee | 33 - easing/easing.css | 7 - easing/easing.css.map | 7 - easing/easing.js | 29 - easing/easing.scss | 9 - experiments/assets/ball.png | Bin 0 -> 10023 bytes experiments/assets/style.css | 8 + experiments/assets/style.css.map | 7 + experiments/assets/style.scss | 10 + experiments/drag.html | 11 + experiments/drag.js | 27 + experiments/drag/core.coffee | 37 + experiments/easing.html | 11 + experiments/easing.js | 31 + experiments/easing/core.coffee | 41 + gulpfile.js | 59 +- lib/engine.js | 1462 ------------------------------ lib/soundmanager2.js | 78 -- lib/soundmanager2.swf | Bin 2934 -> 0 bytes lib/soundmanager2_debug.swf | Bin 3310 -> 0 bytes watch.sh | 4 - 30 files changed, 241 insertions(+), 2509 deletions(-) delete mode 100644 docs/api/draw.html delete mode 100644 docs/api/draw.zpy delete mode 100644 docs/api/math.html delete mode 100644 docs/api/math.zpy delete mode 100644 docs/api/random.html delete mode 100644 docs/api/random.zpy delete mode 100644 easing.html delete mode 100644 easing/assets/images/cursor.png delete mode 100644 easing/core.coffee delete mode 100644 easing/easing.css delete mode 100644 easing/easing.css.map delete mode 100644 easing/easing.js delete mode 100644 easing/easing.scss create mode 100644 experiments/assets/ball.png create mode 100644 experiments/assets/style.css create mode 100644 experiments/assets/style.css.map create mode 100644 experiments/assets/style.scss create mode 100644 experiments/drag.html create mode 100644 experiments/drag.js create mode 100644 experiments/drag/core.coffee create mode 100644 experiments/easing.html create mode 100644 experiments/easing.js create mode 100644 experiments/easing/core.coffee delete mode 100644 lib/engine.js delete mode 100755 lib/soundmanager2.js delete mode 100755 lib/soundmanager2.swf delete mode 100755 lib/soundmanager2_debug.swf delete mode 100755 watch.sh diff --git a/TODO.md b/TODO.md index 81b4f4a..7c26016 100644 --- a/TODO.md +++ b/TODO.md @@ -8,6 +8,10 @@ * Make the first frame draw correctly, without requiring a `return true` from the onStep event. +## Build process + +* Add build-games.sh functionality (ie. SVG-to-PNG export) to gulpfile. + ## Ideas -None. +jQuery-like $ selector on scene objects (ie. @$) for selecting instances by name, coordinates, etc. diff --git a/docs/api/draw.html b/docs/api/draw.html deleted file mode 100644 index 44015cc..0000000 --- a/docs/api/draw.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - -

Engine.Draw

The Draw library provides functions to draw shapes, text, and sprites on a scene.
Engine.Draw.Rectangle(x1, y1, x2, y2, options)
Draws a rectangle.
x1
The X coordinate of the top left corner.
y1
The Y coordinate of the top left corner.
x2
The X coordinate of the right bottom corner.
y2
The Y coordinate of the right bottom corner.
options
Optional. Options for drawing the rectangle.
width
Width of the outline in pixels.
linecolor
The color of the outline.
cap
The type line cap for the outline.
rx
The horizontal radius of the corners of the rectangle.
ry
The vertical radius of the corners of the rectangle.
radius
A short-hand option that sets both rx and ry.
color
The fill color of the rectangle.
alpha
The alpha value of the rectangle.
Example: Draw a blue rectangle with a yellow outline, rounded borders and at 70% opacity
Code:
Engine.Draw.Rectangle(20, 30, 150, 180, {
-	linecolor: "yellow",
-	color: "blue",
-	radius: 8,
-	alpha: 0.7
-});
- - diff --git a/docs/api/draw.zpy b/docs/api/draw.zpy deleted file mode 100644 index 4a32670..0000000 --- a/docs/api/draw.zpy +++ /dev/null @@ -1,94 +0,0 @@ -# Engine.Draw - -The Draw library provides functions to draw shapes, text, and sprites on a scene. - -{TOC} - -^ Engine.Draw.Line(**x1**, **y1**, **x2**, **y2**, **options**) - - Draws a line. - - x1:: - The X coordinate of the starting position. - - y1:: - The Y coordinate of the starting position. - - x2:: - The X coordinate of the ending position. - - y2:: - The Y coordinate of the ending position. - - options:: - **Optional.** Options for drawing the line. - - width:: - Width of the line in pixels. - - color:: - The line {>../drawing}(color). - - cap:: - The type of {>../drawing}(line cap). - - alpha:: - The alpha value of the line. - - @ Draw a blue line - - $ Engine.Draw.Line(10, 10, 120, 120, { - color: "blue" - }); - -^ Engine.Draw.Rectangle(**x1**, **y1**, **x2**, **y2**, **options**) - - Draws a rectangle. - - x1:: - The X coordinate of the top left corner. - - y1:: - The Y coordinate of the top left corner. - - x2:: - The X coordinate of the right bottom corner. - - y2:: - The Y coordinate of the right bottom corner. - - options:: - **Optional.** Options for drawing the rectangle. - - width:: - Width of the outline in pixels. - - linecolor:: - The {>../drawing}(color) of the outline. - - cap:: - The type {>../drawing}(line cap) for the outline. - - rx:: - The horizontal radius of the corners of the rectangle. - - ry:: - The vertical radius of the corners of the rectangle. - - radius:: - A short-hand option that sets both `rx` and `ry`. - - color:: - The fill color of the rectangle. - - alpha:: - The alpha value of the rectangle. - - @ Draw a blue rectangle with a yellow outline, rounded borders and at 70% opacity - - $ Engine.Draw.Rectangle(20, 30, 150, 180, { - linecolor: "yellow", - color: "blue", - radius: 8, - alpha: 0.7 - }); diff --git a/docs/api/math.html b/docs/api/math.html deleted file mode 100644 index 5092aa8..0000000 --- a/docs/api/math.html +++ /dev/null @@ -1,162 +0,0 @@ - - - - - - -

Engine.Math

The Math library provides several functions to do mathematical operations or calculations. Most of these functions are simply aliases of the functions built into JavaScript.

Table of contents

- - diff --git a/docs/api/math.zpy b/docs/api/math.zpy deleted file mode 100644 index 8ae3568..0000000 --- a/docs/api/math.zpy +++ /dev/null @@ -1,150 +0,0 @@ -# Engine.Math - -The Math library provides several functions to do mathematical operations or calculations. Most of these functions are simply aliases of the functions built into JavaScript. - -{TOC} - -^ Engine.Math.Absolute(**x**) - Engine.Math.Abs(**x**) - - Returns the absolute value of `x`. - - **This is an alias of the standard Math.abs function in JavaScript.** - - x:: - The number. - - @ Get the absolute value of a positive number - - $ Engine.Math.Absolute(16); - - > 16 - - @ Get the absolute value of a negative number - - $ Engine.Math.Absolute(-23); - - > 23 - -^ Engine.Random.Sum(**item** [, **item** [, **item** ...]]) - Engine.Random.Sum(**itemarray**) - - Returns the sum of all supplied numbers. - - item:: - An individual number. - itemarray:: - An array of numbers. - - @ Sum several numbers using individual arguments - - $ Engine.Math.Sum(42, 6, 17, 2, 7); - - > 74 - - @ Sum several numbers using an array - - $ var numbers = [42, 6, 17, 2, 7]; - Engine.Math.Sum(numbers); - - > 74 - -^ Engine.Math.Round(**x**) - - Rounds `x` to the nearest integer. - - **This is an alias of the standard Math.round function in JavaScript.** - - x:: - The value to round. - - @ Rounding a number in the upper half - - $ Engine.Math.Ceiling(82.62); - - > 83 - - @ Rounding a number in the lower half - - $ Engine.Math.Ceiling(82.13); - - > 82 - -^ Engine.Math.Ceiling(**x**) - Engine.Math.Ceil(**x**) - - Rounds up `x`. - - **This is an alias of the standard Math.ceil function in JavaScript.** - - x:: - The value to round up. - - @ Rounding up a number - - $ Engine.Math.Ceiling(614.2162); - - > 615 - -^ Engine.Math.Floor(**x**) - - Rounds down `x`. - - **This is an alias of the standard Math.floor function in JavaScript.** - - x:: - The value to round down. - - @ Rounding down a number - - $ Engine.Math.Floor(7.612); - - > 7 - -^ Engine.Math.Tangent(**x**) - Engine.Math.Tan(**x**) - - Returns the tangent of angle `x`. - - **This is an alias of the standard Math.tan function in JavaScript.** - - x:: - The value. - - @ Calculating the tangent - - $ Engine.Math.Tangent(84.15); - - > -0.7971515163204654 - -^ Engine.Math.Cosine(**x**) - Engine.Math.Cos(**x**) - - Returns the cosine of `x`. - - **This is an alias of the standard Math.cos function in JavaScript.** - - x:: - The value (in radians). - - @ Calculating the cosine - - $ Engine.Math.Cosine(162.54); - - > 0.6801581420388815 - -^ Engine.Math.Sine(**x**) - Engine.Math.Sin(**x**) - - Returns the sine of `x`. - - **This is an alias of the standard Math.sin function in JavaScript.** - - x:: - The value (in radians). - - @ Calculating the sine - - $ Engine.Math.Sine(62.4); - - > -0.41855446451842543 diff --git a/docs/api/random.html b/docs/api/random.html deleted file mode 100644 index 555f7c1..0000000 --- a/docs/api/random.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - - - -

Engine.Random

The Random library provides several functions to pick random numbers or items.

Table of contents

- - diff --git a/docs/api/random.zpy b/docs/api/random.zpy deleted file mode 100644 index d9fa2f3..0000000 --- a/docs/api/random.zpy +++ /dev/null @@ -1,123 +0,0 @@ -# Engine.Random - -The Random library provides several functions to pick random numbers or items. - -{TOC} - -^ Engine.Random.Number(**min**, **max**, **precision**) - - Selects a random number between `min` and `max`, excluding `max` itself. - - - min:: - **Optional:** The minimum number. **Defaults to 0.** - - max:: - **Optional:** The maximum number (itself excluded). **Defaults to 1.** - - precision:: - **Optional:** The precision; this is what the result will be rounded to. **Defaults to 0.00000001.** - - - @ Get a whole number from 0 to 9 - - $ Engine.Random.Number(0, 10, 1); - - > 7 - - - @ Get a one-tenth-precision number from 0 to 9.9 - - $ Engine.Random.Number(0, 10, 0.1); - - > 3.7 - - - @ Get a one-fifth-precision number from 5 to 9.8: - - $ Engine.Random.Number(5, 10, 0.2); - - > 6.4 - - -^ Engine.Random.Choose(**item** [, **item** [, **item** ...]]) - Engine.Random.Choose(**itemarray**) - - Selects a random item from the supplied items. - - - item:: - An item to choose from. - - itemarray:: - An array of items to choose from. - - - @ Select a random color from a list using multiple arguments - - $ Engine.Random.Choose("blue", "green", "red", "yellow"); - - > "green" - - - @ Select a random day from a list using an array - - $ var days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; - Engine.Random.Choose(days); - - > "Thursday" - - -^ Engine.Random.Pick(**amount**, **item** [, **item** [, **item** ...]]) - Engine.Random.Pick(**amount**, **itemarray**) - - Selects `amount` unique random items from the supplied items. Each item can only appear in the result once. - - ! The `amount` argument must always be equal to or higher than the amount of supplied items! - - - amount:: - The amount of items to select. - - item:: - An item to choose from. - - itemarray:: - An array of items to choose from. - - - @ Select three random colors from a list using multiple arguments - - $ Engine.Random.Pick(3, "red", "green", "blue", "yellow", "purple", "brown", "black", "white", "orange"); - - > ["blue", "orange", "red"] - - - @ Select two vegetables from a list using an array - - $ var vegetables = ["celery", "potato", "tomato", "coleslaw", "onion"]; - Engine.Random.Pick(2, vegetables); - - > ["tomato", "onion"] - -^ Engine.Random.String(**length** [, **alphabet**]) - - Generates a random string with the specified `length`, and optionally a custom alphabet. - - length:: - The length of the string that has to be generated. - - alphabet:: - **Optional:** The alphabet (set of characters) to choose from. **Defaults to a-z, A-Z, 0-9.** - - @ Generate a random string with the default alphabet - - $ Engine.Random.String(14); - - > "NCm2Y7lEleCTa5" - - @ Generate a random string with a custom alphabet - - $ Engine.Random.String(10, "abcde"); - - > "baeddebaca" diff --git a/easing.html b/easing.html deleted file mode 100644 index 894d743..0000000 --- a/easing.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - Easing Demo - - - - - - -
- - diff --git a/easing/assets/images/cursor.png b/easing/assets/images/cursor.png deleted file mode 100644 index 74d44bdf558e73a304bac04a0d9602d95a207cf8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1469 zcmcgs`#aMM7@tK(ktvr=ldWO7R&M2T%6ym6c$iBlLfg>L^)M;3sV2CO*AtaWn*Gk5R(^T`L|4|K#5inFHEEN})8g!bHN{=~1 z2GQwsyM!bv?L6Q<3l-Az4bH7(pD|ZmWcrFf0-_n(9(PY; z5J7#a+16cHnf{;Lx{vzajN$=IO0?7gMJ~Eow}fb^@ZX#UE=lI;@2FDulG|5F>lSnD zSNK+khjC*8<~o2Lj}`AA|D`15qWvLW%d%eI_E}pyiOh3CApy|2Eys}}g2JXKGk15z zS8p6%GZDe$<}mw6PuZYg32mU8C@pP}Fkyd92N5Ygn7jvf^Yx(vODJ;GfI+%jz)AEZ zm=o!byQ7RRelIQ~9>}Gp;qd#r;D}gaM{YF~YN=K3rIitKke{d6(=GhAkws06U@De; z*Y`mXSB|}OzFe4)(iXtkE1KF7LWDMfM=>XZkLXQse?G_N$2w6jPBsfSOp3IpLfvo> z+C6C%CM}7^7bFs@#eu!CCdNVtVtTJUlePOfb;^s<8d)>TvzjqK zxM!Vr(K5XhW-c|wHSmf9x12Q_k1J$$snXXoluJsw?=CPj+T=dW`N|;?eoJ;cZ zD&yC>9SiN5>~tJI(`GV?WRC&iwf&9hKL+&Fv7`*p^TEB^mH z3oAw8?T!iqWl5EZ#Mj1~uMEQqNx$hD?duDC^0@|f^Oi+Nh+z7yo@a{;#@*VM(A7@M z$1SjKy;4#w2|Kr2D6=Lzm$^*i%c5SuRec{$ao^^~Wt2N=Ml%@|nIv@%inl*dPRYOV zaPp9(bJLKVJwiFpk=wt1h^LFa5iXJMqGD=mMZ4NA+}>SU`2)u2p}TJm86kz{57@D# zP|NU|M6a$!hld0{s|-hO4$4Rydy~}w!REiX8pnt2_d{dDZfTU+xS6jd zXr`h?LerwI$qF|rpytsDQ%TOyy!9?5`KLHO8{hKy*#?e*wF}VVoN$5$1=}TWoEaV@ zJ@$|7Nl&YFS0Z1{GZ*Y!B8uUD^@J3RwIS(<(j6MNNq2U2<cj2c<>4=d zhV7C*TJTtR15>eW!MXj-V=<*GyU&2@z0*G96W8?=T(zvs??!9O*D{4h8#&AukV3p8 t3-Z0sQenJx1|7}6lmBah - manager = new ResourceManager("easing/assets") - engine = new Engine(manager) - window.debug_engine = engine - - # Configure game assets - manager.addImages([ - "images/cursor.png" - ]) - - manager.prepare() - manager.preload(null, -> - engine.addCanvas($("#gamecanvas")); - - scene = engine.createScene("main") - - engine.createSprite("cursor", "images/cursor.png") - - cursor = engine.createObject("cursor") - cursor.sprite = engine.getSprite("cursor") - - cursor.onClickGlobal = (event) -> - @x = @engine.ease.quadInOut(@x, event.x - 41, 35) - @y = @engine.ease.quadInOut(@y, event.y - 41, 35) - - cursor.onStep = -> - return true - - scene.createInstance(cursor, 0, 0) - - engine.start() - ) -) diff --git a/easing/easing.css b/easing/easing.css deleted file mode 100644 index e1ee634..0000000 --- a/easing/easing.css +++ /dev/null @@ -1,7 +0,0 @@ -body { - background-color: #ebebeb; } - -canvas { - background-color: white; } - -/*# sourceMappingURL=easing.css.map */ diff --git a/easing/easing.css.map b/easing/easing.css.map deleted file mode 100644 index d6c949a..0000000 --- a/easing/easing.css.map +++ /dev/null @@ -1,7 +0,0 @@ -{ - "version": 3, - "file": "", - "sources": ["easing.scss"], - "names": [], - "mappings": "AAAA;EAEC,kBAAkB;;AAGnB;EAEC,kBAAkB" -} \ No newline at end of file diff --git a/easing/easing.js b/easing/easing.js deleted file mode 100644 index 3782f4a..0000000 --- a/easing/easing.js +++ /dev/null @@ -1,29 +0,0 @@ -// Generated by CoffeeScript 1.7.1 -(function() { - $(function() { - var engine, manager; - manager = new ResourceManager("easing/assets"); - engine = new Engine(manager); - window.debug_engine = engine; - manager.addImages(["images/cursor.png"]); - manager.prepare(); - return manager.preload(null, function() { - var cursor, scene; - engine.addCanvas($("#gamecanvas")); - scene = engine.createScene("main"); - engine.createSprite("cursor", "images/cursor.png"); - cursor = engine.createObject("cursor"); - cursor.sprite = engine.getSprite("cursor"); - cursor.onClickGlobal = function(event) { - this.x = this.engine.ease.quadInOut(this.x, event.x - 41, 35); - return this.y = this.engine.ease.quadInOut(this.y, event.y - 41, 35); - }; - cursor.onStep = function() { - return true; - }; - scene.createInstance(cursor, 0, 0); - return engine.start(); - }); - }); - -}).call(this); diff --git a/easing/easing.scss b/easing/easing.scss deleted file mode 100644 index 35a5704..0000000 --- a/easing/easing.scss +++ /dev/null @@ -1,9 +0,0 @@ -body -{ - background-color: #ebebeb; -} - -canvas -{ - background-color: white; -} diff --git a/experiments/assets/ball.png b/experiments/assets/ball.png new file mode 100644 index 0000000000000000000000000000000000000000..782b7f977907bef655bb71fc3529e8014f00151e GIT binary patch literal 10023 zcmV+?C)n7DP)WFU8GbZ8()Nlj2>E@cM*03ZNKL_t(|+ReLZm|a(S zrhTtHp83?NQ}ZO1RGMwsl8v!39snByiSdAeFm`B2Ai;401n3SVF-fj;0ttpdNT)*r zAEBGsHZw9dc#>r-VXS#5m8w*wQjKRmXU}V`{!zk^{=Otl8v4t=uJhyk*!x=RS?_v> z=XqbjFYwvE{jWH7?5=13Uv&@0srhV3z znbWWT@}7e*4!~c$WR&0i&fG6-jpFD1!GVE0SX}%vXWxW*<#%538rvDYsc6@3Sgf5H zXtvLg&+i~f+H~<01BDV-Z`{cbrjIgSXtSlSo9o9EtG+`!R*PP2JlF{3o(E5#{oJ0@ z$oF15#-Ber`|lfoLSfhI-PFii%f*T3yPW0l)VH)!ffycsBX(*tGgE&^q3c>8q1l?o zQ0EvanB4c;3BGp9VDD^|=MT2He$z&3o~K)(6sw&Ukum!Cxs^kI`|$(nv;Qsu$YeI$ zZQK3tH%-Ts(%0?wagonoL?ktiXmizgflK@6x$W9t<;bzG@}UQ3`21@&vMINMVK{vH zaEkXmRN*~WfzUp?M#eD+NQ?oN>ytG6P)EkFn6I9dA)|lt@h1-5{qtD2`EPyk(v8=# zSUXEDchP$c!+kuL+kSnL)D7D%BZLr^-Oa>MnH#p1XvZb?o?PO^mu%z7qx<-SZ_Tjm z4ROas5gYmkk-m@JR9Y(>SF1LD1Pu^l~WggcZ#P?@tHV-m5_-b|yFVo|m zV5xG7zr5Y$-lr=(ex}0PZ@7xjzGWA?daHc)V9eL1)?uo1Ja1r$yPl)iH&^Gf@v9kd zr%7ahFdT%DMQcqEF46WEh^0r`&fGZGmAF!lF<+g*kD(RD)Y^+QgMdzKQ4f6D zNnSUS9(9l37&nVZ*j*GYGe2_w@( zCgXBy_7qRggp|uKBnam4yfc8o^lA&Y^fr9&7)escPL1>CTi=4?SiJMk-@?l-TE}G< zU(d0lU!&wk6h?oWe0B$W7svR|-~J(vXfv}iMc%5ANDsp*6D4gF4vCT&MqXHE28DZ7 z-j05y*mcb(v*L_g@zl=`0R6=e&~@g%{%H5>&t~)9FyW*S-Iqf!32qr{;6~o_-&54; z(_}Ims8qfW=nFrn)%G$t_(~jim=}#cz*hUa>~`+slkHut~%Bxc6ui+j7d4#?iZa)A6VJ ziX)wcX7m3X0R8uOz{U^uF)}`Dw!fLdO$j#sHq;-6>^g8tF#bj!dNNO=<5I0Yf|MPE z0MH0w0g7hxX6cJy!e z0ekP-#Pc?n`{|lEi&%6pJb`LJst+!^7oK?ybS9au<=AlN!Jm9on50r;WV4%*vQ4eF zmyH{Lk9y-UgXyRFo7)_&e$HzV{l5bHU%^cNcX{<^x+u8;!(BEXd(nC3ranY749FE< zfHcaSnfp9`V&Er&b{yly;HxxVY|soM{_77~7>0w;5w_*%oMS{+tlPNmv8mHbtF>Xd<>jw4kUh@f&-@wBA9oRz`_ZkVfM9)mFL%9Ygm=EMmwT>$j7+AVp1v2; zmIWjMR;r9PKv)*akaYLmK(??Ige27Pozn`#bkSO(FbR`HxE9X7nW>YlFmyNc4E*d@ z-~(U!F7MvGd?cHx4wD@e4BP}muYjRjAY6q0=fk?U!PJLYZuIia!?)9@KTH%Y;kvyj zN~P<1Iw6)?jC3V#A(eUM znM(Dqe`WxJkKOR$wEn@(y&u`fQ!BhO5tWRq6w z;04p~5Qd9L*&>c>Z0n1;dMM(*fA2@EtRCm?@7DR7@69k?O0nmR#YoREx2-=yKKK$t zgD;|(&hglM51aantkix$B5cgmdRm=nv|XkhoTufVBT^FENwI$>#Ikc}6`@fi3KDGy zEzF)Ik;O#mJ^xz(%>CgNeE5zHyS3T=l$o-?GJycxG8}s+_-A4KZRn_qurwd}(l8&r zZw1S=SY7=#-QCwBWk9=q4A&h%2m{L==A&=9nP2~h@AHjctI}sF-v0b??!5ICOr&PH zVj$#^vk_0sHu$s0+GNt>JaR70>n_U^>KsbA)LTcP(_PRy{@0yge9!h3tE*VX3=V zL3-y1q#_Y{!lZ+p8YMP*S*jkzmjWxZ6EBGgq>Z0IJ8ZJrI7LjJhF?XRqqKrHejM=V zi8d$C`3Td&wghn$qe%dzg|I7Hg}wi(1)RS7`S0oJb#6g41*tOhzXXyMnEeEd{3?3m zdyyk=;5ENB#ln(Lweldv;w}~zK9B46SD1S(UUQG@wODi z9SG*oNrbct*u|?btTO51RT!xW8r}k-iV2g5PPl{@RPdrI!X2dL&7+JwonW3&CU{|$ zAn^#Lq`S*vs4q*D#MBxAhLr*ohM5&wdYPdwYW4eMv)j;GB4r!HaH-dyB9q<3r+@Q0K6w8W z`#-P=eg6B1)HsMND2)s%blRu!Vvk7KMB1hkwQ%xR(hh3G^4n9kR-nNXD#67D{j5};^F4?${nCI zFvvS7yvoAD7YTxSy1TEY)p~}su}CBx z-1Jsny4_*CWUv};=c}*y209Ul;Wu4K5+$;A1TAd5Xq8wCVyy^Of)pwIs75VQhtn0GKbr(^=aen<*zrxGMg*axuRjH*rdBmEjgTa2qg99yCLj#MU<%Abpw<9Lk`~R@ zGk?8YpC26_ewA1&W)$uA5yIdM+3Y5Kf0jbwQku;lk|b+IhUIRjd&y>csd>vtkwMudLK)#l z4g9!?7go`B4}RPxOainsK&AR5onR3&w+qidkG4w8HFr>JfmR8TG-^z;t@FmVTes$)}!mf*<*aHsANYElDObfs`HMxK68e5Xb2yj+?k{KdICZzCVlB z32|IQiyR-kE#XXSC)W%gmaD0dR~I|&LOOR z>gT_}xz$;2{I9DVx%)-zI~%gTtZ9cGn%+F2R0L9xD&Ne)!qMkycD%+Tqa#J0Q1W+$-SVgCNL4JP^v+;wBb#iQfU_eR9ZLr{4H z7QO_+h3*^H+)U>bq$kk95-M&YqZXaY!-U}+=USTIyD86~erK9@d}*0N)?xEdjzESe zs~4wmCCf|SL_0$`h36s7ZtC^@Bt`*kWvF<0_UxUa)mXx@W7ciR5G4Z7a|pZ`uWcZN zMi?%Tprr>W&`g3pWOh0yxNP&S@19>hezEJ0id!%8xoKw)Z-0Kok)<;AAd4WPr{@N2 zyF{h(ARoT1&F&GCtG5h5C?IzUkb>ehu<%9L@IDxQE6n{p);fm*7&geRmlha%1G#8PvkLiwpFhKeU!$r$B!peh|+A!0eR?&R|peH}H z@WRXAI1tsp%ImHj=Z>9=5G-;3!I0_IfOp>82H>($gZJFn&G`CDdCrC&sO^LFCTJc6 zsX;3c4qW{-C<(QF==?6k>Z63GKR_ZA(px`5bM7-VYCj-Sf>3E93898iYH-I1l9+Z- zB_@Lxcksdn+H`2TZ{|}E2Anzm-vFONPOxR$PD*_n@nSf6s!6M55L6!qy~YCwGXuf` z6`{4fz)t|eSk$sJC_wYc*Son3g5JVxXv)^MRAFz^o z856k^;4QD2d02zgIJAy{mTMsF`U<2sqJ<6fpCexQ3SsLQvB;1rzZ9!<4KqjINuq5+ zrHC|y3PLG}aEO${{XddiylH~IqT;~$P5h5XJZejO*twy@#Q1u$=~bNkIvVX29zOH} zYUjR69M(YC7)}|}=|h+~qWY5-WO56`h!>}?xa|#L*)cuLv9?x4wSBg?w6nq3lUY|N4GPb z`CU%8d$=+64_N6fI2V70~lfjtCd5Cg9RYZPnpk0A0OyAzTK zk{GlJq+$6%IR6F2>La}E6QAOpU+d6Q>ZX02(kqR+hg_q!fm` zj_%?ANT&NnVr>vS~O@Y*cO+8OhF2?-MuM~-u=0_(JV(BnBwaCfC4-mBu zqM{W5WL!tsgG^lgOKiPDlI!V1i!54SAW5}C%K$LYDw;5=zF4O<9DMB)=yQ9(?1#*D z@Rp$WHYi*Jg{vT}f;|lO2uMI_Xr6%l4%(d#E7es#z0c#;?HO*l?l<|vFYIBi?ed9- z9lo^ZQ;hX!YI2mIzK=*LA|>e?|IcV=0B!ezGe9II^+557w-$K!?Kz@g4kx{lV$mj$ z0n3eq`@eVLq;uPmaRtLF5__jF@LMiI*jU+(B(aC-3dS!E7@6>Ja_cDc&uhqLCz+o7D^&X--ucS+@a@O{hz_SE>DCL8e z7*03Q>bEhHe$X*E{p8DYxY-u@-VG$JNs>ro7z)3YttmMEUby)GL7)3HqVolC#y~as=;IYW_X^Fovz5&C^l0*wM z;uQ=dXMpJrmIJx-gv{WKeo%h5qpv!_>%d7Q^a7m=1}~Q(vfKyPDn+lQ`7WmOU&f%6L%+D@n*$F8|?M zW88b_Ggzj}<^3M}7IIwsosVFcDGo$$;blXg=Jl6tZ5tn#g39bfz0AY?PJ3viiU*(+(;e zINs*UOI`e^O-PoRbAa*)n?J%ZvlvbfGF%4b0}eyGUrJBUgP5h45H6oV$4f+d6vG|n z%mJUiu@&Yg(CYHwOU>UFY*YY8XLPc|9FeVW&J*uDHs`kHG9rP{BU)I z_g)us-wzLP-S5AFH(oSDU5(L>T@V&Zc}V49S_S;hBuTQS&)H5d`QjC83en0pY1SU$ z!P#3lwp=D<&QTb+ou+v$MrsskcG2!k(X8*~p(pl(I!kQyk_eYa_to$Mmn4`)Mav|? z9EQ`2nH~cSgoqg2(aYkLiPBxzU6&zcgLJ7#XLSy@P-5|n;NqKhgEL5NDMcpRZkey% zIXdJR@vBTjlXKI2?x^O!JaUfFqQwJKFJ+=LrPVkX1{Sj;bbJawRk5CUOj5T*+%Si5RY4=OxQaRAC2`l-&gnST5+ z`p2s%r7@g7(&fz*N;7ozhd9NHsm{#MT&m!A;=eO@_g0+VLf_jQQ_%J+oNH%zbb5u! zs${KHu49@Ry1K4F#tWn~;|vYGjzAhz+cmt-DJ;8-C|qLOK$cIudVnt8NR#!IDN$x#@6jd)27v)$I6sR6^59vxIFq)gM%kD&l~|% z>w@ZJptZzs`cTm#DqH}21M7GBoO;})wOk=x>Spk=n~>ouDwx7>`;gu=R(?CuJ5AJX zfi@9B|Ec-i>C)1xF3#S4y5jSnz87%a#xeG;UPBa2{lvMTh@w>{Cf?8N*^kpzx*91x z8jbyE6k3JE(F!ZA4!2$`Sl8djzB4iD>^NF0qHqDrE)ho+9CzqK$Vvzkc=EX9!NWZ~ zedHj^%^cr)!sGCXd7jwcpx)ASIspQOFtZngECX~17#L<2t$g}6+bCV8xzNH&Ib?f# z@f#gNc{QuY9;4lyz{#1|u8CF&PRhj;A**xE-!Py`z2hx@`9zK@hSU7TBM0%Ck25^{ zCf2Wi7uoD4w3ftim3m`8+3Z%%&3zKr?Z>vevCIrIX=6KUjB`&OJZ}Np=_cq*fe@rJ z6NJG$rd7bOGH9Lr6d&uOWrM}4;D;wdIzfiziiu$t*mYSig|0MO1*mxSLJAuLCR(;o zvIDqeyF3a*Wj4Q{NNF^Sn_gh$OosV=U!=YOj4J0)pmdC3cY!dFNe5xLsA!g2Wt#O9AgmrtcL1$? z5C(=*Mi{9zKOhX^sEkY!rk|K&`RGZOCJRXKC_1TNxPzRZ+(0THkt7aIIwpx?-PLbB z2w;BrWt&NKCOcL%Z~y9vCbP9Bj#FA&d|V@y8m6b`CYsG3VcTVV{|p0zucFgFP82Vb zO0Or5Rew7wGPwO^HQ3%M^Vz}?YG~^rtT+5M2d5b zG)L#sJaWiD#Z?f3B&uBKC9n~~KuQ0nEJUmkuudN;X~74|2u6AXnalz5Wr^+Dq*Fe{XvKQsaijt8)G9L3#^bJ)((Ai4N+lPX z90XFfX*Pez(&D{TE8jz@h%h)uCbNlh?=PctjP3N2a|MQBW0;u>i%4C#ql!;Gl0z95 zv#Svw`Qj|a^a2B=6@=AC5-x&{5rzdqpfNyz>GrRIU^qW+I#>&T!bHmshTXl!J)rQa z>e8`0O9l^%nSl+?PSe7 zDy|{S99sW4Lj2UD;v>+r`9&wO?? zAIe0TX!M%c5zOQJGYH|3PLEMp-GgoS;I&T>_%nFzGPxWZ$I|ROuxCwa2KFD4OrK9PzTRYfW0q3c2JNp=Svo>S4P?}~Q2O?wWDI5+ zEn8qX2s67zcj;)&N`wi*M3@%kjW&oB(m%HbhN>WhL)WlPZC*==KU-Uj|KHMBD^43% zjdfjL%nov<+QhapBuSlIZWEq2gJpFgrH53VpQuUOGi)d?lb9v?OEE(|Mb6hWoxmqk zd=6&tZ8nT`^Ov7n;MD1(Y#dWue^rJp7wzQ9eMhO+JlbBKuAVfRf?B2GX?;kisrf?afrQ^8farQs6fSp;##XGl9>@rBA}S_UM3gG^61mK&2Po2*S>D{FIlLT)I97hE0%k zkVX-uTbx)JqSZLYl7A_iwp`AZZROlv9e}Vf zoL+LJWe|d~o#pqgoN4X-7XdiiNcJYObLUb=q!*hjLKqHO`Iu%7PzYh-IK7xw5hdGz zCRPbUec3goHmVYlr>hWgYQBgeV&-PP$ENWXgA=#1+AfoI_R;Rlp^XluAxU=h3ZylN zRz51OAe<7y$e@yNEeW#fWcwWIbDB=gMtVz_`E4lw99sDZr%V#%K|@fTN0 zRF+J4O7~A>E5{!?f9t>6AhEfxkCeqjGtJ^#W3?88wNBPJb;Bl!>m*5St^32uqP1k8 zOHt0p__2?+2MLl8+f{5>pQf)=VcX72SY0{A5B66nkL)B}j0qA&5O;`;G9o=n+}I1c zg$B&jAS$V@g*{?G5ql=}**d~1prwZ}G8n9)wSzDWWaJ_&izJljxUrTyq}O8_%jElq zL_WK8P2cAJh2^Q{zYIX7(_x_qr;MHe00w_aL_t&)EM!w%#ZFMU%5nNglC@HFEoev# z!$qrjtt-pSvQX!8;;;`<@EPdMz!j?tI>_S*wI9ZF)9rB(--&y|j|GN2qwNWzdb{`L8e~W2mL>#X<71PY2kyv&w zAdyKMrF;g<7SGv{LR%%mc$q*Jn4DVR{DPo&bT_Hgd4{%b!E5{ockq=U5*Cg;O1qJ# zXJbDZ_Yp8m=ALPh>$NBjr`DDy#M+e*K0zzO&1n!>Gz!D*r+Kcy;?V#Zm(WObcm^RH z6ln}Ir`KQZo}7B@)V80wO|IYy3by>DmzZ}+8Ms0Su~v)6Yt*w5u)bg8Is&D9F4^o5 zDYd5PCJ`asoH$-%!xopJEn}GC1Yxj%mD@_veu`RcCzhL{P&|kxLv^-|O23T0&BG{T z2T`YilMWGXKPp~92p7W)LD*}d&2T_Rq`NZoY#F3Fmqsg)-V$0yVD#$^&)?kaAFNFj zN3wGHbn|BeAe0b`vJ}Gpl-A*0AWW^L5JG^CNu;7&v>55r^p`cERzyk@%9v0p;-rRf z2k9Q^Cv2a>F6_c^xcU$FTAQ^%j1mfnn6pqF)be%|zpuZ` zLKOO>tjuby9E}z~&Ic?rX2+%+$}m7^6agJCq20ESS~9r42VsP0Ld?uMggeUYsSKIa z)2OJz(p(>Ax*zFHucfuvjP9tA?W*E*Uq+|yFn?e#Zs`&d?;K9XBHtfkxhAQiMq`2W z&^l)MxMcNoh~2eY_f6!Y_1h1OHEZjZ4}bmm|M|d#Wfe)1M!#uhPD<$&gs_Fynhhfv z(&-4p$)gDomPN-;upNo*3N#WkGm5ZWFrd1cXXVUE1~w$j9BknBy&M_LBmF6y(shKZ zdl0G1*>!slN&6sLE@5Vdk--AOD&SQ;WCHCaN&mJy2!*iAsBi%lMO3DR?%8%jGvD34 z#anuK>F_tFem?U8YrMYb^!EPJJwY)0O08v&X_*Xn1BP)SESVUl!)irQDreS&Qemu# zlCpzVE1W%A!M0oUjTb-%G|!*J?YW7#z8@V|aJsL-HjW_M&oFK+!lnzOhCesyx;et%iaTC+-C)=GnX~oe*5-&Fnef`M)*1&}EGYrhIynKHsrMFE8 z^B$Qf&aEU`U|^Vez(UE8LSEy0Av$iMRfvpgsJMm+(i46!IyAurLgXk}(U + + Drag Experiment + + + + + + + + \ No newline at end of file diff --git a/experiments/drag.js b/experiments/drag.js new file mode 100644 index 0000000..ad34e06 --- /dev/null +++ b/experiments/drag.js @@ -0,0 +1,27 @@ +(function () {$(function() { + var engine, manager; + manager = new ResourceManager("assets"); + engine = new Engine(manager); + window.debug_engine = engine; + manager.addImages(["ball.png"]); + return manager.prepare(function() { + engine.addCanvas($("#gamecanvas")); + engine.setInitialScene(engine.createScene("main")); + return manager.load(function() { + var ball; + engine.createSprites({ + "ball": "ball.png" + }); + ball = engine.createObject("ball"); + ball.sprite = engine.getSprite("ball"); + ball.onStep = function() { + return true; + }; + engine.getScene("main").onLoad = function() { + return this.createInstance(ball, 0, 0); + }; + return engine.start(); + }); + }); +}); +})(); \ No newline at end of file diff --git a/experiments/drag/core.coffee b/experiments/drag/core.coffee new file mode 100644 index 0000000..cfae978 --- /dev/null +++ b/experiments/drag/core.coffee @@ -0,0 +1,37 @@ +$(-> + manager = new ResourceManager("assets") + engine = new Engine(manager) + window.debug_engine = engine + + # Configure game assets + manager.addImages([ + "ball.png" + ]) + + manager.prepare -> + # Set up the engine + engine.addCanvas($("#gamecanvas")); + engine.setInitialScene(engine.createScene("main")) + + manager.load -> + # Game asset initialization... + engine.createSprites({ + "ball": "ball.png", + }) + + # Object definitions + ball = engine.createObject("ball") + ball.sprite = engine.getSprite("ball") + + ball.onStep = -> + return true + + # Scene configuration + engine.getScene("main").onLoad = -> + # Actual game initialization + @createInstance(ball, 0, 0) + + # Let's go! + engine.start() + +) diff --git a/experiments/easing.html b/experiments/easing.html new file mode 100644 index 0000000..7c1c792 --- /dev/null +++ b/experiments/easing.html @@ -0,0 +1,11 @@ + + + Easing Experiment + + + + + + + + \ No newline at end of file diff --git a/experiments/easing.js b/experiments/easing.js new file mode 100644 index 0000000..92bb4fb --- /dev/null +++ b/experiments/easing.js @@ -0,0 +1,31 @@ +(function () {$(function() { + var engine, manager; + manager = new ResourceManager("assets"); + engine = new Engine(manager); + window.debug_engine = engine; + manager.addImages(["ball.png"]); + return manager.prepare(function() { + engine.addCanvas($("#gamecanvas")); + engine.setInitialScene(engine.createScene("main")); + return manager.load(function() { + var ball; + engine.createSprites({ + "ball": "ball.png" + }); + ball = engine.createObject("ball"); + ball.sprite = engine.getSprite("ball"); + ball.onStep = function() { + return true; + }; + ball.onClickGlobal = function(event) { + this.x = this.engine.ease.quadInOut(this.x, event.x - 41, 35); + return this.y = this.engine.ease.quadInOut(this.y, event.y - 41, 35); + }; + engine.getScene("main").onLoad = function() { + return this.createInstance(ball, 0, 0); + }; + return engine.start(); + }); + }); +}); +})(); \ No newline at end of file diff --git a/experiments/easing/core.coffee b/experiments/easing/core.coffee new file mode 100644 index 0000000..3ebf9bb --- /dev/null +++ b/experiments/easing/core.coffee @@ -0,0 +1,41 @@ +$(-> + manager = new ResourceManager("assets") + engine = new Engine(manager) + window.debug_engine = engine + + # Configure game assets + manager.addImages([ + "ball.png" + ]) + + manager.prepare -> + # Set up the engine + engine.addCanvas($("#gamecanvas")); + engine.setInitialScene(engine.createScene("main")) + + manager.load -> + # Game asset initialization... + engine.createSprites({ + "ball": "ball.png", + }) + + # Object definitions + ball = engine.createObject("ball") + ball.sprite = engine.getSprite("ball") + + ball.onStep = -> + return true + + ball.onClickGlobal = (event) -> + @x = @engine.ease.quadInOut(@x, event.x - 41, 35) + @y = @engine.ease.quadInOut(@y, event.y - 41, 35) + + # Scene configuration + engine.getScene("main").onLoad = -> + # Actual game initialization + @createInstance(ball, 0, 0) + + # Let's go! + engine.start() + +) diff --git a/gulpfile.js b/gulpfile.js index 08aa1b9..c110af0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -11,6 +11,9 @@ var header = require('gulp-header'); var footer = require('gulp-footer'); var plumber = require('gulp-plumber'); +/* Configuration */ +var experiments = ["drag", "easing"] + /* Engine build tasks */ engine = { source: "radium/*.coffee", @@ -44,6 +47,45 @@ gulp.task("prod-engine", ["dev-engine"], function(){ .pipe(gulp.dest(engine.target.path)); }); +/* Experiment build tasks */ +var experiment_settings = {}; + +for(var i in experiments) +{ + var name = experiments[i]; + + experiment_settings[name] = { + source: "experiments/" + name + "/*.coffee", + external: "", + target: { + path: "experiments", + name: name + ".js", + minName: name + ".min.js" + } + } + + gulp.task('dev-' + name, function() { + return gulp.src(experiment_settings[name].source) + .pipe(plumber()) + .pipe(cache(name)) + .pipe(coffee({bare: true}).on('error', gutil.log)).on('data', gutil.log) + .pipe(remember(name)) + .pipe(concat(name + ".coffee.js")) + .pipe(header('(function () {')) + .pipe(footer('})();')) + .pipe(concat(name + ".concat.js")) + .pipe(rename(experiment_settings[name].target.name)) + .pipe(gulp.dest(experiment_settings[name].target.path)); + }); + + gulp.task("prod-" + name, ["dev-" + name], function(){ + return gulp.src(experiment_settings[name].target.path + "/" + experiment_settings[name].target.name) + .pipe(uglify()) + .pipe(rename(experiment_settings[name].target.minName)) + .pipe(gulp.dest(experiment_settings[name].target.path)); + }); +} + /* Sample game build tasks */ gemswap = { source: "gemswap/*.coffee", @@ -79,21 +121,26 @@ gulp.task("prod-gemswap", ["dev-gemswap"], function(){ /* Watcher */ gulp.task('watch', function () { - targets = { + var targets = { "gemswap": gemswap, "engine": engine } - - for(name in targets) + + for (var attrname in experiment_settings) { targets[attrname] = experiment_settings[attrname]; } + + for(var tname in targets) { - var watcher = gulp.watch(targets[name].source, ['dev-' + name]); + var watcher = gulp.watch(targets[tname].source, ['dev-' + tname]); watcher.on('change', function (event) { if (event.type === 'deleted') { - delete cache.caches[name + '-coffee'][event.path]; - remember.forget(name + '-coffee', event.path); + delete cache.caches[tname + '-coffee'][event.path]; + remember.forget(tname + '-coffee', event.path); } }); + + /* Initial build */ + gulp.start("dev-" + tname); } }); diff --git a/lib/engine.js b/lib/engine.js deleted file mode 100644 index 686598b..0000000 --- a/lib/engine.js +++ /dev/null @@ -1,1462 +0,0 @@ -/* Prototype modifications of standard types go here. */ - -HTMLCanvasElement.prototype.relativeCoordinates = function(event) -{ - var totalOffsetX = 0; - var totalOffsetY = 0; - var canvasX = 0; - var canvasY = 0; - var currentElement = this; - - do { - if(!$(currentElement).is('body')) - { - totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft; - totalOffsetY += currentElement.offsetTop - currentElement.scrollTop; - } - } while(currentElement = currentElement.offsetParent) - - canvasX = event.pageX - totalOffsetX; - canvasY = event.pageY - totalOffsetY; - - return {x:canvasX, y:canvasY} -} - -/* Save the engine path for later use. */ -var script_elements = document.getElementsByTagName('script'); -var this_element = script_elements[script_elements.length - 1]; -var script_path = this_element.src; -var engine_path = script_path.substr(0, script_path.lastIndexOf( '/' )+1 ); - -/* Core engine constructor. */ -function Engine(settings) -{ - this.resources = {}; - this.sprites = {}; - this.sounds = {}; - this.objects = {}; - this.scenes = {}; - this.canvas = null; - this.settings = settings; - this.loader_created = false; - this.instance_increment = 10000; - - _engine = this; - - /**--------------------------------------**/ - /** PRELOADER **/ - /**--------------------------------------**/ - - this.Preloader = function() - { - this._engine = _engine; - this.queue = []; - this.resources_left = 0; - this.resources_done = 0; - this.resources_total = 0; - this.resources_failed = 0; - this.images_total = 0; - this.scripts_total = 0; - this.sounds_total = 0; - this.sound_enabled = false; - this.sound_ignore_failure = false; - - if(this._engine.loader_created == false) - { - /* This is the first Preloader that is being created. Load scripts that are needed by the engine. */ - this._engine.loader_created = true; - - if(typeof this._engine.settings !== "undefined") - { - if(this._engine.settings["enable_sound"]) - { - this.AddScript(engine_path + "soundmanager2.js", "SoundManager2"); - - this.AddFunction(function(){ - soundManager.setup({ - url: 'static/', - onready: this._HandleSM2Ready.bind(this), - ontimeout: this._HandleSM2Failed.bind(this), - useHighPerformance: true, - preferFlash: false - }); - - return false; - }, "Initializing SoundManager2"); - } - else - { - this._engine.sound_enabled = false; - } - } - } - } - - /* Add function */ - this.Preloader.prototype.AddFunction = function(func, description) - { - this.queue.push({ - type: "function", - func: func.bind(this), - desc: description - }); - - this.resources_left++; - this.resources_total++; - } - - /* Add image */ - this.Preloader.prototype.AddImage = function(name, path) - { - this.queue.push({ - type: "image", - name: name, - path: path - }); - - this.resources_left++; - this.resources_total++; - } - - /* Add a dictionary of items */ - this.Preloader.prototype.AddItems = function(items) - { - if(typeof items.images != "undefined") - { - for(name in items.images) - { - this.AddImage(name, items.images[name]); - } - } - - if(typeof items.sounds != "undefined") - { - for(name in items.sounds) - { - this.AddSound(name, items.sounds[name]); - } - } - - if(typeof items.scripts != "undefined") - { - for(name in items.scripts) - { - this.AddScript(name, items.scripts[name]); - } - } - - if(typeof items.functions != "undefined") - { - for(name in items.functions) - { - this.AddFunction(name, items.functions[name]); - } - } - - } - - /* Add script file */ - this.Preloader.prototype.AddScript = function(path, description) - { - this.queue.push({ - type: "script", - path: path, - desc: description - }); - - this.resources_left++; - this.resources_total++; - } - - /* Add sound file */ - this.Preloader.prototype.AddSound = function(name, path) - { - this.queue.push({ - type: "sound", - name: name, - path: path - }); - - this.resources_left++; - this.resources_total++; - } - - /* Start the preloading sequence. */ - this.Preloader.prototype.Run = function(callbacks) - { - if(typeof callbacks == "undefined") - { - this.callbacks = {}; - } - else - { - this.callbacks = callbacks; - } - - this.RunCycle(); - } - - /* Process one item in the preloading sequence. */ - this.Preloader.prototype.RunCycle = function() - { - if(this.queue.length > 0) - { - current_object = this.queue.shift(); - - if(current_object.type == "image") - { - this._DoCallback(this.callbacks.onstagechange, { - type: "image", - description: current_object.path - }); - - current_image = new Image(); - current_image.onload = this._ReportResourceFinished.bind(this); - current_image.src = current_object.path; - - this.images_total++; - this._engine.resources[current_object.name] = current_image; - } - else if(current_object.type == "sound") - { - this._DoCallback(this.callbacks.onstagechange, { - type: "sound", - description: current_object.path - }); - - if(this._engine.sound_enabled == true) - { - if(soundManager.canPlayURL(current_object.path)) - { - var sound = soundManager.createSound({ - id: current_object.name, - url: current_object.path, - autoLoad: true, - autoPlay: false, - onload: this._ReportResourceFinished.bind(this) - }); - - this.sounds_total++; - this._engine.resources[current_object.name] = sound; - } - else - { - throw { - "name": "SoundError", - "message": "The sound format is not supported." - } - } - } - else if(this._engine.sound_ignore_failure == true) - { - /* TODO: Log error */ - } - else - { - throw { - "name": "SoundError", - "message": "Cannot add audio file because sound support is not enabled in the engine." - } - } - } - else if(current_object.type == "script") - { - this._DoCallback(this.callbacks.onstagechange, { - type: "script", - description: current_object.desc - }); - - $.getScript(current_object.path, this._ReportResourceFinished.bind(this)); - - this.scripts_total++; - } - else if(current_object.type == "function") - { - this._DoCallback(this.callbacks.onstagechange, { - type: "function", - description: current_object.desc - }); - - var result = current_object.func(this.callbacks); - - if(result == true) - { - this._ReportResourceFinished(); - } - } - } - else - { - this._DoCallback(this.callbacks.onfinish) - } - } - - /* Check if the preloading sequence is finished and take appropriate action. */ - this.Preloader.prototype._CheckIfDone = function() - { - if(this.resources_left <= 0) - { - this._DoCallback(this.callbacks.onfinish); - } - else - { - this.RunCycle(); - } - } - - /* Do a pre-specified callback if it exists. */ - this.Preloader.prototype._DoCallback = function(callback, data) - { - if(typeof callback != "undefined") - { - callback(data); - } - } - - /* Handle successful finishing of the SoundManager2 loading process. */ - this.Preloader.prototype._HandleSM2Ready = function() - { - this._engine.sound_enabled = true; - this._ReportResourceFinished(); - } - - /* Handle failure of the SoundManager2 loading process. */ - this.Preloader.prototype._HandleSM2Failed = function() - { - this._engine.sound_enabled = false; - this._ReportResourceFinished(); - } - - /* Mark the currently preloading resource as finished. */ - this.Preloader.prototype._ReportResourceFinished = function() - { - this.resources_left--; - this.resources_done++; - - this._DoCallback(this.callbacks.onprogress, { - done: this.resources_done, - total: this.resources_total, - left: this.resources_left, - failures: this.resources_failed - }); - - this._CheckIfDone(); - } - - /* Mark the currently preloading resource as failed. */ - this.Preloader.prototype._ReportResourceFailed = function() - { - /* TODO: Implement. */ - this.resources_left--; - this.resources_failed++; - } - - - /**--------------------------------------**/ - /** BASE PROPERTIES AND METHODS **/ - /**--------------------------------------**/ - - this.Base = { - timers: {}, - SetTimer: function(duration, func) - { - setTimeout((function(self, f){ return f.call.bind(f, self); })(this, func), duration); - }, - SetInterval: function(name, interval, func) - { - this.timers[name] = setInterval((function(self, f){ return f.call.bind(f, self); })(this, func), interval); - }, - CancelInterval: function(name) - { - clearInterval(this.timers[name]); - }, - CallEvent: function(func, data) - { - if(typeof func !== "undefined") - { - return func.call(this, data); - } - }, - _BubbleEvent: function(func, eventdata, instances) - { - list = instances.slice().reverse(); - - var hit_event = false; - - for(item in list) - { - var object = list[item]; - var result = object.CallEvent(object[func], eventdata); - - if(typeof result != "undefined") - { - if(result == false) - { - break; - } - else if(result == true) - { - hit_event = true; - } - } - } - - return hit_event; - } - } - - - /**--------------------------------------**/ - /** SCENES **/ - /**--------------------------------------**/ - - this.Scene = function(name, options) - { - if(typeof _engine.scenes[name] !== "undefined") - { - throw { - name: "NameError", - message: "A scene with the given name already exists." - } - } - - this._engine = _engine; - this.canvas = null; - this.instances = []; - this.dirty = true; - this.width = 640; - this.height = 480; - this.fps = 45; - this.name = name; - this.cached_selectors = {}; - this.mouse_coordinates = {x: 0, y: 0}; - this.step_counter = 0; - this.draw_counter = 0; - this.current_fps = 0; - this.date = new Date; - - $.extend(true, this, options, this._engine.Base); - - this._engine.scenes[name] = this; - } - - this.Scene.prototype.Add = function(object) - { - if(typeof object == "string") - { - if(typeof this._engine.objects[object] !== "undefined") - { - var instance = this._engine.CreateInstance(object); - } - else - { - throw { - "name": "ObjectError", - "message": "The specified object does not exist." - } - } - } - else - { - var instance = object; - } - - instance.scene = this; - this.instances.push(instance); - this.dirty = true; - } - - this.Scene.prototype.Attach = function(canvas) - { - if(typeof $(canvas).data("current-scene") !== "undefined") - { - /* A different scene was previously attached to this canvas. - * Let's detach it first. */ - var previous_scene = $(canvas).data("current-scene"); - this._engine.scenes[previous_scene].Detach(); - } - - this.canvas = canvas; - this._engine.canvas = canvas; - canvas.width = this.width; - canvas.height = this.height; - $(canvas).data("current-scene", this.name); - - $(canvas).click(this._ProcessClickEvent.bind(this)); - $(canvas).mousemove(this._ProcessMouseMoveEvent.bind(this)); - - this.CallEvent(this.OnLoad); - this._Initialize(); - } - - this.Scene.prototype.Detach = function() - { - $(this.canvas).unbind('click'); - $(this.canvas).unbind('mousemove'); - $(this.canvas).removeData("current-scene"); - this.canvas = null; - } - - this.Scene.prototype.DrawText = function(text, options) - { - var type = "fill", color = "#000000", x = 0, y = 0; - - if(typeof options.outline != "undefined" && options.outline) - { - type = "outline"; - } - - if(typeof options.color != "undefined") - { - color = options.color; - } - - if(typeof options.x != "undefined") - { - x = options.x; - } - - if(typeof options.y != "undefined") - { - y = options.y; - } - - ctx = this._GetTextContext(options); - - if(type == "fill") - { - ctx.fillStyle = color; - ctx.fillText(text, x, y); - } - else if(type == "outline") - { - ctx.strokeStyle = color; - ctx.outlineText(text, x, y); - } - - ctx.restore(); - } - - this.Scene.prototype.DrawTextCentered = function(text, options) - { - var x = 0, scale = 1, width = this.GetTextWidth(text, options); - - if(typeof options.x != "undefined") - { - x = options.x; - } - - if(typeof options.scale != "undefined") - { - scale = options.scale; - } - - x = x - ((width / 2) * scale * scale); - - options.x = x; - - this.DrawText(text, options); - } - - this.Scene.prototype.GetTextWidth = function(text, options) - { - ctx = this._GetTextContext(options); - var width = ctx.measureText(text).width; - ctx.restore(); - - return width; - } - - this.Scene.prototype.Redraw = function() - { - this.dirty = true; - } - - this.Scene.prototype.$ = function(selector) - { - if(typeof this.cached_selectors[selector] != "undefined") - { - return this.cached_selectors[selector]; - } - else - { - list = this._SelectInstances(this, this.instances, selector); - this.cached_selectors[selector] = list; - return list; - } - } - - this.Scene.prototype._Draw = function() - { - this.draw_count += 1; - - if(this.canvas !== null) - { - var ctx = this.canvas.getContext("2d"); - ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - - for(i in this.instances) - { - this.instances[i]._Draw(); - } - } - } - - this.Scene.prototype._GetTextContext = function(options) - { - var weight = "normal", style = "normal", font = "sans-serif", size = 16, alpha = 1, scale = 1; - - if(typeof options.bold != "undefined" && options.bold) - { - weight = "bold"; - } - - if(typeof options.italic != "undefined" && options.italic) - { - style = "italic"; - } - - if(typeof options.size != "undefined") - { - size = options.size; - } - - if(typeof options.font != "undefined") - { - font = options.font; - } - - if(typeof options.alpha != "undefined") - { - alpha = options.alpha; - } - - if(typeof options.scale != "undefined") - { - scale = options.scale; - } - - var ctx = this.canvas.getContext("2d"); - - ctx.save(); - - ctx.font = weight + " " + style + " " + size + "px '" + font + "'"; - ctx.globalAlpha = alpha; - ctx.scale(scale, scale); - - return ctx; - } - - this.Scene.prototype._Initialize = function(event) - { - this.last_timestamp = this.date.getTime(); - this.SetInterval("_step", (1000/this.fps), this._Step); - } - - this.Scene.prototype._ProcessClickEvent = function(event) - { - var coordinates = this.canvas.relativeCoordinates(event); - - var changed = this._BubbleEvent("_HandleClickEvent", { - x: coordinates.x, - y: coordinates.y, - button: event.which - }, this.$("/" + coordinates.x + "," + coordinates.y)); - - if(changed == true) - { - this.dirty = true; - } - } - - this.Scene.prototype._ProcessMouseMoveEvent = function(event) - { - var coordinates = this.canvas.relativeCoordinates(event); - this.mouse_coordinates = coordinates; - this.mouse_moved = true; - } - - this.Scene.prototype._SelectInstances = function(context, items, selector) - { - var segments = selector.split("/"); - segments.shift(); - - methods = { - "coordinate": { - "regex": /^(!?)([0-9]+),([0-9]+)$/i, - "action": function(context, items, match){ - var inverted = (match[1] == "!"); - var x = match[2]; - var y = match[3]; - - return items.filter(function(object){ - var hit = false; - - if(object.draw_self === true) - { - var sprite = this._engine.GetSprite(object.sprite); - - if(x >= object.x && x < (object.x + sprite.width) && y > object.y && y < (object.y + sprite.height)) - { - /* Initial region test succeeded. - * TODO: Add bounding rectangles. */ - var relative_x = x - object.x; - var relative_y = y - object.y; - - if(object.precise_collision == false) - { - hit = true; - } - else - { - alpha = sprite.GetAlpha(relative_x, relative_y) / 255; - - if(alpha > object.collision_tolerance) - { - /* Alpha hit. */ - hit = true; - } - } - } - } - - if(inverted == true) - { - return !hit; - } - else - { - return hit; - } - }); - } - }, - "object": { - "regex": /^(!?)([a-z_][a-z0-9_+-]*)$/i, - "action": function(context, items, match){ - inverted = (match[1] == "!"); - name = match[2]; - - return items.filter(function(object){ - if(inverted) - { - return !(name == object.name); - } - else - { - return (name == object.name); - } - }); - } - } - } - - for(i in segments) - { - var segment = segments[i]; - - for(m in methods) - { - var method = methods[m]; - var match = method.regex.exec(segment); - - if(match != null) - { - items = method.action(context, items, match); - break; - } - } - } - - return items; - } - - this.Scene.prototype._Step = function(event) - { - this.step_counter++; - - if(this.step_counter == this.fps) - { - this.step_counter = 0; - - var date = new Date; - var current_timestamp = date.getTime() - this.current_fps = (1000 / (current_timestamp - this.last_timestamp)) * this.fps; - this.last_timestamp = current_timestamp; - } - - if(this.mouse_moved == true) - { - this.dirty = this.CallEvent(this.OnMouseMove, this.mouse_coordinates) ? true : this.dirty; - - var select = function(prefix, coordinates) - { - var selector = "/" + prefix + coordinates.x + "," + coordinates.y; - return this.$(selector); - }.bind(this); - - this.dirty = this._BubbleEvent("_HandleMouseOutEvent", this.mouse_coordinates, select("!", this.mouse_coordinates)) ? true : this.dirty; - this.dirty = this._BubbleEvent("_HandleMouseOverEvent", this.mouse_coordinates, select("", this.mouse_coordinates)) ? true : this.dirty; - this.dirty = this._BubbleEvent("_HandleMouseMoveEvent", this.mouse_coordinates, this.$("/")) ? true : this.dirty; - - this.mouse_moved = false; - } - - if(this.CallEvent(this.OnStep, {}) == true) - { - this.dirty = true; - } - - if(this._BubbleEvent("_HandleStepEvent", {}, this.instances) == true) - { - this.dirty = true; - } - - if(this.dirty == true) - { - this.dirty = false; - this.cached_selectors = {}; - this._Draw(); - } - } - - - /**--------------------------------------**/ - /** SOUNDS **/ - /**--------------------------------------**/ - - this.Sound = function(name, source) - { - if(typeof _engine.sounds[name] !== "undefined") - { - throw { - name: "NameError", - message: "A sound with the given name already exists." - } - } - - if(typeof _engine.resources[source] === "undefined") - { - throw { - name: "ResourceError", - message: "The specified resource does not exist." - } - } - - this._engine = _engine; - this.source = this._engine.resources[source]; - this.name = name; - - this._engine.sounds[name] = this; - } - - this.Sound.prototype.Play = function(options) - { - if(this._engine.sound_enabled == true) - { - this.source.play(options); - } - } - - - /**--------------------------------------**/ - /** OBJECTS **/ - /**--------------------------------------**/ - - this.Object = function(name, proto) - { - if(typeof _engine.objects[name] !== "undefined") - { - throw { - name: "NameError", - message: "An object with the given name already exists." - } - } - - /* Base settings */ - this._engine = _engine; - this.name = ""; - - /* Metrics */ - this.x = 0; - this.y = 0; - this.width = 0; - this.height = 0; - this.alpha = 1; - - /* Collision handling */ - this.collision_tolerance = 0.2; - this.precise_collision = false; - - /* Internal variables */ - this.draw_self = (typeof proto.sprite !== "undefined"); - this.scene = null; - this.last_moused_over = false; - - /* Create a constructor for the object. */ - var skeleton = new Function(); - $.extend(true, skeleton.prototype, this, this._engine.Base, proto); - skeleton.prototype.name = name; - - /* Store constructor and return prototype. */ - this._engine.objects[name] = skeleton; - return skeleton.prototype; - } - - this.Object.prototype.CreateInstance = function(vars) - { - return this._engine.CreateInstance(this, vars); - } - - this.Object.prototype.Destroy = function() - { - this.CallEvent(this.OnDestroy); - - if(this.scene != null) - { - var index = this.scene.instances.indexOf(this); - - if(index != -1) - { - this.scene.instances.splice(index, 1); - } - } - } - - this.Object.prototype._Draw = function() - { - if(this.draw_self == true && typeof this.sprite !== "undefined") - { - if(typeof this._engine.sprites[this.sprite] === "undefined") - { - throw { - name: "SpriteError", - message: "The specified sprite does not exist." - } - } - - this._engine.sprites[this.sprite].Draw(this.scene.canvas, this); - } - - this.CallEvent(this.OnDraw, {canvas: this.scene.canvas}); - } - - this.Object.prototype._HandleClickEvent = function(event) - { - var relative_x = event.x - this.x; - var relative_y = event.y - this.y; - - events = { - 1: this.OnClick, - 2: this.OnMiddleClick, - 3: this.OnRightClick - } - - func = events[event.button]; - - this.CallEvent(func, { - x: event.x, - y: event.y, - button: event.button, - relative_x: relative_x, - relative_y: relative_y - }); - - return true; - } - - this.Object.prototype._HandleMouseMoveEvent = function(event) - { - this.CallEvent(this.OnMouseMove, { - x: event.x, - y: event.y - }); - return true; - } - - this.Object.prototype._HandleMouseOutEvent = function(event) - { - if(this.last_moused_over == true) - { - this.last_moused_over = false; - - this.CallEvent(this.OnMouseOut, { - x: event.x, - y: event.y - }); - - return true; - } - } - - this.Object.prototype._HandleMouseOverEvent = function(event) - { - if(this.last_moused_over == false) - { - var relative_x = event.x - this.x; - var relative_y = event.y - this.y; - - this.last_moused_over = true; - - this.CallEvent(this.OnMouseOver, { - x: event.x, - y: event.y, - relative_x: relative_x, - relative_y: relative_y - }); - - return true; - } - } - - this.Object.prototype._HandleStepEvent = function(event) - { - if(typeof this.sprite != "undefined") - { - var sprite = this._engine.sprites[this.sprite]; - this.width = sprite.width; - this.height = sprite.height; - } - - return this.CallEvent(this.OnStep, event); - } - - /**--------------------------------------**/ - /** SPRITES **/ - /**--------------------------------------**/ - - this.Sprite = function(name, source, options) - { - if(typeof _engine.sprites[name] !== "undefined") - { - throw { - name: "NameError", - message: "A sprite with the given name already exists." - } - } - - if(typeof _engine.resources[source] === "undefined") - { - throw { - name: "ResourceError", - message: "The specified resource does not exist." - } - } - - this._engine = _engine; - this.source = this._engine.resources[source]; - this.name = name; - - if(typeof options.tile_x !== "undefined" && typeof options.tile_y !== "undefined" && typeof options.tile_w !== "undefined" && typeof options.tile_h !== "undefined") - { - this.tile_x = options.tile_x; - this.tile_y = options.tile_y; - this.tile_w = options.tile_w; - this.tile_h = options.tile_h; - this.tile = true; - } - else if(typeof options.tile_x !== "undefined" || typeof options.tile_y !== "undefined" || typeof options.tile_w !== "undefined" || typeof options.tile_h !== "undefined") - { - throw { - name: "SpriteError", - message: "Only a part of the tile parameters were specified." - } - } - else - { - this.tile = false; - } - - /* Store image data for click events and collision detection. */ - var collision_canvas = document.createElement("canvas"); - var width, height; - - if(this.tile == false) - { - width = this.source.width; - height = this.source.height; - } - else if(this.tile == true) - { - width = this.tile_w; - height = this.tile_h; - } - - collision_canvas.width = this.width = width; - collision_canvas.height = this.height = height; - - this.Draw(collision_canvas, null, {x: 0, y: 0, alpha: 1}); - - ctx = collision_canvas.getContext("2d"); - this.image_data = ctx.getImageData(0, 0, width, height); - - delete collision_canvas; - - /* Store in engine. */ - this._engine.sprites[name] = this; - } - - this.Sprite.prototype.Draw = function(canvas, object, options) - { - ctx = canvas.getContext("2d"); - - if((typeof object == "undefined" || object == null) && (typeof options == "undefined" || typeof options.x == "undefined" || typeof options.y == "undefined")) - { - throw { - name: "DrawError", - message: "No drawing coordinates were specified." - } - } - else if(typeof object == "undefined" || object == null) - { - var x = options.x; - var y = options.y; - } - else - { - var x = object.x; - var y = object.y; - } - - if(typeof options != "undefined" && typeof options.alpha != "undefined") - { - var alpha = options.alpha; - } - else if(typeof object != "undefined" && object != null) - { - var alpha = object.alpha; - } - else - { - throw { - name: "DrawError", - message: "No alpha value was specified." - } - } - - ctx.globalAlpha = alpha; - - if(this.tile == true) - { - ctx.drawImage(this.source, this.tile_x, this.tile_y, this.tile_w, this.tile_h, x, y, this.tile_w, this.tile_h); - } - else - { - ctx.drawImage(this.source, x, y); - } - } - - this.Sprite.prototype.GetAlpha = function(x, y) - { - var key = (((y * this.width) + x) * 4) + 3; - return this.image_data.data[key]; - } - - /**--------------------------------------**/ - /** ENGINE FUNCTIONS **/ - /**--------------------------------------**/ - - this.AddItems = function(items) - { - if(typeof items.sprites != "undefined") - { - - for(name in items.sprites) - { - if(typeof items.sprites[name] == "string") - { - /* Stand-alone sprite. */ - new _engine.Sprite(name, items.sprites[name], {}); - } - else - { - /* Probably a tileset. */ - new _engine.Sprite(name, items.sprites[name], { - tile_x: items.sprites[name].tile_x, - tile_y: items.sprites[name].tile_y, - tile_w: items.sprites[name].tile_w, - tile_h: items.sprites[name].tile_h, - }); - } - } - } - - if(typeof items.sounds != "undefined") - { - for(name in items.sounds) - { - new _engine.Sound(name, items.sounds[name]); - } - } - - if(typeof items.objects != "undefined") - { - for(name in items.objects) - { - new _engine.Object(name, items.objects[name]); - } - } - - if(typeof items.scenes != "undefined") - { - for(name in items.scenes) - { - new _engine.Scene(name, items.scenes[name]); - } - } - } - - this.CreateInstance = function(object, vars) - { - this.instance_increment++; - - if(typeof data == "undefined") - { - var data = {id: this.instance_increment}; - } - else - { - data.id = this.instance_increment; - } - - if(typeof object == "string") - { - var instance = new this.objects[object](); - } - else - { - var skeleton = new Function(); - skeleton.prototype = object; - var instance = new skeleton(); - } - - $.extend(true, instance, vars); - - /* Call creation event. */ - instance.CallEvent(instance.OnCreate, {}); - - return instance; - } - - this.GetObject = function(name) - { - return this.objects[name].prototype; - } - - this.GetScene = function(name) - { - return this.scenes[name]; - } - - this.GetSound = function(name) - { - return this.sounds[name]; - } - - this.GetSprite = function(name) - { - return this.sprites[name]; - } - - /**--------------------------------------**/ - /** STANDARD LIBRARY **/ - /**--------------------------------------**/ - - this.Math = {}; - - this.Math.Abs = Math.abs; - this.Math.Absolute = Math.abs; - this.Math.Acos = Math.acos; - this.Math.Arccosine = Math.acos; - this.Math.Asin = Math.asin; - this.Math.Arcsine = Math.asin; - this.Math.Atan = Math.atan; - this.Math.Arctangent = Math.atan; - this.Math.Atan2 = Math.atan2; - this.Math.Arctangent2 = Math.atan2; - this.Math.Ceil = Math.ceil; - this.Math.Ceiling = Math.ceil; - this.Math.Cos = Math.cos; - this.Math.Cosine = Math.cos; - this.Math.Exp = Math.exp; - this.Math.Floor = Math.floor; - this.Math.Log = Math.log; - this.Math.Logarithm = Math.log; - this.Math.Min = Math.min; - this.Math.Minimum = Math.min; - this.Math.Max = Math.max; - this.Math.Maximum = Math.max; - this.Math.Pow = Math.pow; - this.Math.Power = Math.pow; - this.Math.Round = Math.round; - this.Math.Sin = Math.sin; - this.Math.Sine = Math.sin; - this.Math.Sqrt = Math.sqrt; - this.Math.SquareRoot = Math.sqrt; - this.Math.Tan = Math.tan; - this.Math.Tangent = Math.tan; - - this.Random = {}; - - this.Random.Choose = function() - { - if(arguments.length == 0) - { - /* The user passed in nothing. Bail out. */ - throw { - name: "ArgumentError", - message: "No arguments were specified." - } - } - else if(arguments.length == 1 && typeof arguments[0].length != "undefined") - { - /* The user passed in an array. */ - arguments = arguments[0]; - } - - return arguments[Math.floor(Math.random() * arguments.length)]; - } - - this.Random.Number = function(floor, ceiling, precision) - { - var floor = (typeof floor == "undefined") ? 0 : floor; - var ceiling = (typeof ceiling == "undefined") ? 1 : ceiling; - var precision = (typeof ceiling == "undefined") ? 0.00000001 : precision; - - var base_number = Math.random(); - var width = Math.abs(ceiling - floor); - var rounding_factor = 1 / precision; - - var multiplied = floor + (base_number * width); - return Math.floor(multiplied * rounding_factor) / rounding_factor; - } - - this.Random.Pick = function() - { - var chosen = []; - var results = []; - var _arguments = Array.prototype.slice.call(arguments); - var count = _arguments.shift(); - - if(arguments.length == 0) - { - /* The user passed in nothing. Bail out. */ - throw { - name: "ArgumentError", - message: "No arguments were specified." - } - } - else if(_arguments.length == 1 && typeof _arguments[0].length != "undefined") - { - /* The user passed in an array. */ - _arguments = _arguments[0]; - } - - if(count > _arguments.length) - { - /* The user requested more items than exist in the arguments. */ - throw { - name: "ArgumentError", - message: "Not enough arguments were specified. The amount of specified items must be equal to or larger than the requested amount." - } - } - - for(var i = 0; i < count; i++) - { - var id = 0; - - do - { - id = Math.floor(Math.random() * _arguments.length); - } while (chosen.indexOf(id) != -1) - - chosen.push(id); - results.push(_arguments[id]); - } - - return results; - } - - this.Random.String = function(length, alphabet) - { - if(typeof alphabet == "undefined") - { - alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - } - - rand = ""; - - for(i = 0; i < length; i++) - { - rand += alphabet[Math.floor(Math.random() * alphabet.length)]; - } - - return rand; - } - - this.Draw = {}; - - this.Draw.Text = function(x, y, text, options) - { - - } - - this.Draw.Rectangle = function(x1, y1, x2, y2, options) - { - - } - - this.Draw.Line = function(x1, y1, x2, y2, options) - { - - } - - this.Draw.BoxEllipse = function(x1, y1, x2, y2, options) - { - var x = (x1 + x2) / 2; - var y = (y1 + y2) / 2; - var rx = (x2 - x1) / 2; - var ry = (y2 - y1) / 2; - - this.RadiusEllipse(x, y, rx, ry, options); - } - - this.Draw.RadiusEllipse = function(x, y, rx, ry, options) - { - var canvas = $("#gamecanvas")[0]; - var ctx = canvas.getContext("2d"); - ctx.beginPath(); - - if(rx == ry) - { - /* Circle. */ - ctx.arc(x, y, rx, 0, 2 * Math.PI, false); - } - else - { - /* Ellipse. */ - var step = 0.1 - - ctx.moveTo(x + rx, y); - - for (var i = 0; i < Math.PI * 2 + step; i += step) - { - ctx.lineTo(x + Math.cos(i) * rx, y + Math.sin(i) * ry); - } - } - - ctx.lineWidth = 1; - ctx.strokeStyle = 'black'; - ctx.stroke(); - } - - this.Draw.BoxPolygon = function(x1, y1, x2, y2, sides, options) - { - - } - - this.Draw.RadiusPolygon = function(x, y, radius, sides, options) - { - - } -} diff --git a/lib/soundmanager2.js b/lib/soundmanager2.js deleted file mode 100755 index 1c28af1..0000000 --- a/lib/soundmanager2.js +++ /dev/null @@ -1,78 +0,0 @@ -/** @license - * - * SoundManager 2: JavaScript Sound for the Web - * ---------------------------------------------- - * http://schillmania.com/projects/soundmanager2/ - * - * Copyright (c) 2007, Scott Schiller. All rights reserved. - * Code provided under the BSD License: - * http://schillmania.com/projects/soundmanager2/license.txt - * - * V2.97a.20130101 - */ -(function(i,g){function R(R,fa){function S(b){return c.preferFlash&&A&&!c.ignoreFlash&&c.flash[b]!==g&&c.flash[b]}function m(b){return function(c){var d=this._s;return!d||!d._a?null:b.call(this,c)}}this.setupOptions={url:R||null,flashVersion:8,debugMode:!0,debugFlash:!1,useConsole:!0,consoleOnly:!0,waitForWindowLoad:!1,bgColor:"#ffffff",useHighPerformance:!1,flashPollingInterval:null,html5PollingInterval:null,flashLoadTimeout:1E3,wmode:null,allowScriptAccess:"always",useFlashBlock:!1,useHTML5Audio:!0, -html5Test:/^(probably|maybe)$/i,preferFlash:!0,noSWFCache:!1};this.defaultOptions={autoLoad:!1,autoPlay:!1,from:null,loops:1,onid3:null,onload:null,whileloading:null,onplay:null,onpause:null,onresume:null,whileplaying:null,onposition:null,onstop:null,onfailure:null,onfinish:null,multiShot:!0,multiShotEvents:!1,position:null,pan:0,stream:!0,to:null,type:null,usePolicyFile:!1,volume:100};this.flash9Options={isMovieStar:null,usePeakData:!1,useWaveformData:!1,useEQData:!1,onbufferchange:null,ondataerror:null}; -this.movieStarOptions={bufferTime:3,serverURL:null,onconnect:null,duration:null};this.audioFormats={mp3:{type:['audio/mpeg; codecs="mp3"',"audio/mpeg","audio/mp3","audio/MPA","audio/mpa-robust"],required:!0},mp4:{related:["aac","m4a","m4b"],type:['audio/mp4; codecs="mp4a.40.2"',"audio/aac","audio/x-m4a","audio/MP4A-LATM","audio/mpeg4-generic"],required:!1},ogg:{type:["audio/ogg; codecs=vorbis"],required:!1},wav:{type:['audio/wav; codecs="1"',"audio/wav","audio/wave","audio/x-wav"],required:!1}};this.movieID= -"sm2-container";this.id=fa||"sm2movie";this.debugID="soundmanager-debug";this.debugURLParam=/([#?&])debug=1/i;this.versionNumber="V2.97a.20130101";this.altURL=this.movieURL=this.version=null;this.enabled=this.swfLoaded=!1;this.oMC=null;this.sounds={};this.soundIDs=[];this.didFlashBlock=this.muted=!1;this.filePattern=null;this.filePatterns={flash8:/\.mp3(\?.*)?$/i,flash9:/\.mp3(\?.*)?$/i};this.features={buffering:!1,peakData:!1,waveformData:!1,eqData:!1,movieStar:!1};this.sandbox={};this.html5={usingFlash:null}; -this.flash={};this.ignoreFlash=this.html5Only=!1;var Ga,c=this,Ha=null,h=null,T,q=navigator.userAgent,ga=i.location.href.toString(),l=document,ha,Ia,ia,k,r=[],J=!1,K=!1,j=!1,s=!1,ja=!1,L,t,ka,U,la,B,C,D,Ja,ma,V,na,W,oa,E,pa,M,qa,X,F,Ka,ra,La,sa,Ma,N=null,ta=null,v,ua,G,Y,Z,H,p,O=!1,va=!1,Na,Oa,Pa,$=0,P=null,aa,Qa=[],u=null,Ra,ba,Q,y,wa,xa,Sa,n,db=Array.prototype.slice,w=!1,ya,A,za,Ta,x,ca=q.match(/(ipad|iphone|ipod)/i),Ua=q.match(/android/i),z=q.match(/msie/i),eb=q.match(/webkit/i),Aa=q.match(/safari/i)&& -!q.match(/chrome/i),Ba=q.match(/opera/i),Ca=q.match(/(mobile|pre\/|xoom)/i)||ca||Ua,Va=!ga.match(/usehtml5audio/i)&&!ga.match(/sm2\-ignorebadua/i)&&Aa&&!q.match(/silk/i)&&q.match(/OS X 10_6_([3-7])/i),Da=l.hasFocus!==g?l.hasFocus():null,da=Aa&&(l.hasFocus===g||!l.hasFocus()),Wa=!da,Xa=/(mp3|mp4|mpa|m4a|m4b)/i,Ea=l.location?l.location.protocol.match(/http/i):null,Ya=!Ea?"http://":"",Za=/^\s*audio\/(?:x-)?(?:mpeg4|aac|flv|mov|mp4||m4v|m4a|m4b|mp4v|3gp|3g2)\s*(?:$|;)/i,$a="mpeg4 aac flv mov mp4 m4v f4v m4a m4b mp4v 3gp 3g2".split(" "), -fb=RegExp("\\.("+$a.join("|")+")(\\?.*)?$","i");this.mimePattern=/^\s*audio\/(?:x-)?(?:mp(?:eg|3))\s*(?:$|;)/i;this.useAltURL=!Ea;var Fa;try{Fa=Audio!==g&&(Ba&&opera!==g&&10>opera.version()?new Audio(null):new Audio).canPlayType!==g}catch(hb){Fa=!1}this.hasHTML5=Fa;this.setup=function(b){var e=!c.url;b!==g&&(j&&u&&c.ok()&&(b.flashVersion!==g||b.url!==g||b.html5Test!==g))&&H(v("setupLate"));ka(b);e&&(M&&b.url!==g)&&c.beginDelayedInit();!M&&(b.url!==g&&"complete"===l.readyState)&&setTimeout(E,1);return c}; -this.supported=this.ok=function(){return u?j&&!s:c.useHTML5Audio&&c.hasHTML5};this.getMovie=function(b){return T(b)||l[b]||i[b]};this.createSound=function(b,e){function d(){a=Y(a);c.sounds[a.id]=new Ga(a);c.soundIDs.push(a.id);return c.sounds[a.id]}var a,f=null;if(!j||!c.ok())return H(void 0),!1;e!==g&&(b={id:b,url:e});a=t(b);a.url=aa(a.url);if(p(a.id,!0))return c.sounds[a.id];ba(a)?(f=d(),f._setup_html5(a)):(8=b)return!1;for(b-=1;0<=b;b--)c=j[b],!c.fired&&a.position>=c.position&&(c.fired=!0,n++,c.method.apply(c.scope,[c.position]));return!0};this._resetOnPosition=function(a){var b,c;b=j.length;if(!b)return!1;for(b-=1;0<=b;b--)c=j[b],c.fired&&a<=c.position&&(c.fired=!1,n--);return!0};u=function(){var b=a._iO,c=b.from,e=b.to,d,f;f=function(){a.clearOnPosition(e,f);a.stop()};d=function(){if(null!==e&&!isNaN(e))a.onPosition(e, -f)};null!==c&&!isNaN(c)&&(b.position=c,b.multiShot=!1,d());return b};m=function(){var b,c=a._iO.onposition;if(c)for(b in c)if(c.hasOwnProperty(b))a.onPosition(parseInt(b,10),c[b])};s=function(){var b,c=a._iO.onposition;if(c)for(b in c)c.hasOwnProperty(b)&&a.clearOnPosition(parseInt(b,10))};l=function(){a.isHTML5&&Na(a)};I=function(){a.isHTML5&&Oa(a)};f=function(b){b||(j=[],n=0);q=!1;a._hasTimer=null;a._a=null;a._html5_canplay=!1;a.bytesLoaded=null;a.bytesTotal=null;a.duration=a._iO&&a._iO.duration? -a._iO.duration:null;a.durationEstimate=null;a.buffered=[];a.eqData=[];a.eqData.left=[];a.eqData.right=[];a.failures=0;a.isBuffering=!1;a.instanceOptions={};a.instanceCount=0;a.loaded=!1;a.metadata={};a.readyState=0;a.muted=!1;a.paused=!1;a.peakData={left:0,right:0};a.waveformData={left:[],right:[]};a.playState=0;a.position=null;a.id3={}};f();this._onTimer=function(b){var c,f=!1,g={};if(a._hasTimer||b){if(a._a&&(b||(0opera.version()?new Audio(null):new Audio,e=a._a,e._called_load=!1,w&&(Ha=e);a.isHTML5=!0;a._a=e;e._s=a;ab();a._apply_loop(e,b.loops);b.autoLoad||b.autoPlay?a.load():(e.autobuffer=!1,e.preload="auto");return e};ab=function(){if(a._a._added_events)return!1;var b;a._a._added_events=!0;for(b in x)x.hasOwnProperty(b)&& -a._a&&a._a.addEventListener(b,x[b],!1);return!0};i=function(){var b;a._a._added_events=!1;for(b in x)x.hasOwnProperty(b)&&a._a&&a._a.removeEventListener(b,x[b],!1)};this._onload=function(b){b=!!b||!a.isHTML5&&8===k&&a.duration;a.loaded=b;a.readyState=b?3:2;a._onbufferchange(0);a._iO.onload&&a._iO.onload.apply(a,[b]);return!0};this._onbufferchange=function(b){if(0===a.playState||b&&a.isBuffering||!b&&!a.isBuffering)return!1;a.isBuffering=1===b;a._iO.onbufferchange&&a._iO.onbufferchange.apply(a);return!0}; -this._onsuspend=function(){a._iO.onsuspend&&a._iO.onsuspend.apply(a);return!0};this._onfailure=function(b,c,e){a.failures++;if(a._iO.onfailure&&1===a.failures)a._iO.onfailure(a,b,c,e)};this._onfinish=function(){var b=a._iO.onfinish;a._onbufferchange(0);a._resetOnPosition(0);a.instanceCount&&(a.instanceCount--,a.instanceCount||(s(),a.playState=0,a.paused=!1,a.instanceCount=0,a.instanceOptions={},a._iO={},I(),a.isHTML5&&(a.position=0)),(!a.instanceCount||a._iO.multiShotEvents)&&b&&b.apply(a))};this._whileloading= -function(b,c,e,d){var f=a._iO;a.bytesLoaded=b;a.bytesTotal=c;a.duration=Math.floor(e);a.bufferLength=d;a.durationEstimate=!a.isHTML5&&!f.isMovieStar?f.duration?a.duration>f.duration?a.duration:f.duration:parseInt(a.bytesTotal/a.bytesLoaded*a.duration,10):a.duration;a.isHTML5||(a.buffered=[{start:0,end:a.duration}]);(3!==a.readyState||a.isHTML5)&&f.whileloading&&f.whileloading.apply(a)};this._whileplaying=function(b,c,e,d,f){var h=a._iO;if(isNaN(b)||null===b)return!1;a.position=Math.max(0,b);a._processOnPosition(); -!a.isHTML5&&8opera.version()?new Audio(null):new Audio:null,d,a,f={},h;h=c.audioFormats;for(d in h)if(h.hasOwnProperty(d)&&(a="audio/"+d,f[d]=b(h[d].type),f[a]=f[d],d.match(Xa)?(c.flash[d]=!0,c.flash[a]= -!0):(c.flash[d]=!1,c.flash[a]=!1),h[d]&&h[d].related))for(a=h[d].related.length-1;0<=a;a--)f["audio/"+h[d].related[a]]=f[d],c.html5[h[d].related[a]]=f[d],c.flash[h[d].related[a]]=f[d];f.canPlayType=e?b:null;c.html5=t(c.html5,f);return!0};na={};v=function(){};Y=function(b){8===k&&(1k)&&(c.flashVersion=k=9);c.version=c.versionNumber+(c.html5Only?" (HTML5-only mode)":9===k?" (AS3/Flash 9)":" (AS2/Flash 8)");8'}if(J&&K)return!1;if(c.html5Only)return ma(),c.oMC=T(c.movieID),ia(),K=J=!0,!1;var a=e||c.url,f=c.altURL||a,h=qa(),i=G(),k=null,k=l.getElementsByTagName("html")[0],j,n,m,k=k&&k.dir&&k.dir.match(/rtl/i),b=b===g?c.id:b;ma();c.url=Ma(Ea?a:f);e=c.url;c.wmode=!c.wmode&&c.useHighPerformance?"transparent":c.wmode;if(null!==c.wmode&&(q.match(/msie 8/i)||!z&&!c.useHighPerformance)&&navigator.platform.match(/win32|win64/i))Qa.push(na.spcWmode), -c.wmode=null;h={name:b,id:b,src:e,quality:"high",allowScriptAccess:c.allowScriptAccess,bgcolor:c.bgColor,pluginspage:Ya+"www.macromedia.com/go/getflashplayer",title:"JS/Flash audio component (SoundManager 2)",type:"application/x-shockwave-flash",wmode:c.wmode,hasPriority:"true"};c.debugFlash&&(h.FlashVars="debug=1");c.wmode||delete h.wmode;if(z)a=l.createElement("div"),n=['',d("movie",e),d("AllowScriptAccess",c.allowScriptAccess),d("quality",h.quality),c.wmode?d("wmode",c.wmode):"",d("bgcolor",c.bgColor),d("hasPriority","true"),c.debugFlash?d("FlashVars",h.FlashVars):"",""].join("");else for(j in a=l.createElement("embed"),h)h.hasOwnProperty(j)&&a.setAttribute(j,h[j]);ra();i=G();if(h=qa())if(c.oMC=T(c.movieID)||l.createElement("div"),c.oMC.id)m=c.oMC.className,c.oMC.className= -(m?m+" ":"movieContainer")+(i?" "+i:""),c.oMC.appendChild(a),z&&(j=c.oMC.appendChild(l.createElement("div")),j.className="sm2-object-box",j.innerHTML=n),K=!0;else{c.oMC.id=c.movieID;c.oMC.className="movieContainer "+i;j=i=null;c.useFlashBlock||(c.useHighPerformance?i={position:"fixed",width:"8px",height:"8px",bottom:"0px",left:"0px",overflow:"hidden"}:(i={position:"absolute",width:"6px",height:"6px",top:"-9999px",left:"-9999px"},k&&(i.left=Math.abs(parseInt(i.left,10))+"px")));eb&&(c.oMC.style.zIndex= -1E4);if(!c.debugFlash)for(m in i)i.hasOwnProperty(m)&&(c.oMC.style[m]=i[m]);try{z||c.oMC.appendChild(a),h.appendChild(c.oMC),z&&(j=c.oMC.appendChild(l.createElement("div")),j.className="sm2-object-box",j.innerHTML=n),K=!0}catch(p){throw Error(v("domError")+" \n"+p.toString());}}return J=!0};W=function(){if(c.html5Only)return X(),!1;if(h||!c.url)return!1;h=c.getMovie(c.id);h||(N?(z?c.oMC.innerHTML=ta:c.oMC.appendChild(N),N=null,J=!0):X(c.id,c.url),h=c.getMovie(c.id));"function"===typeof c.oninitmovie&& -setTimeout(c.oninitmovie,1);return!0};D=function(){setTimeout(Ja,1E3)};Ja=function(){var b,e=!1;if(!c.url||O)return!1;O=!0;n.remove(i,"load",D);if(da&&!Da)return!1;j||(b=c.getMoviePercent(),0b&&(e=!0));setTimeout(function(){b=c.getMoviePercent();if(e)return O=!1,i.setTimeout(D,1),!1;!j&&Wa&&(null===b?c.useFlashBlock||0===c.flashLoadTimeout?c.useFlashBlock&&ua():B({type:"ontimeout",ignoreInit:!0}):0!==c.flashLoadTimeout&&sa(!0))},c.flashLoadTimeout)};V=function(){if(Da||!da)return n.remove(i, -"focus",V),!0;Da=Wa=!0;O=!1;D();n.remove(i,"focus",V);return!0};L=function(b){if(j)return!1;if(c.html5Only)return j=!0,C(),!0;var e=!0,d;if(!c.useFlashBlock||!c.flashLoadTimeout||c.getMoviePercent())j=!0,s&&(d={type:!A&&u?"NO_FLASH":"INIT_TIMEOUT"});if(s||b)c.useFlashBlock&&c.oMC&&(c.oMC.className=G()+" "+(null===c.getMoviePercent()?"swf_timedout":"swf_error")),B({type:"ontimeout",error:d,ignoreInit:!0}),F(d),e=!1;s||(c.waitForWindowLoad&&!ja?n.add(i,"load",C):C());return e};Ia=function(){var b,e= -c.setupOptions;for(b in e)e.hasOwnProperty(b)&&(c[b]===g?c[b]=e[b]:c[b]!==e[b]&&(c.setupOptions[b]=c[b]))};ia=function(){if(j)return!1;if(c.html5Only)return j||(n.remove(i,"load",c.beginDelayedInit),c.enabled=!0,L()),!0;W();try{h._externalInterfaceTest(!1),Ka(!0,c.flashPollingInterval||(c.useHighPerformance?10:50)),c.debugMode||h._disableDebug(),c.enabled=!0,c.html5Only||n.add(i,"unload",ha)}catch(b){return F({type:"JS_TO_FLASH_EXCEPTION",fatal:!0}),sa(!0),L(),!1}L();n.remove(i,"load",c.beginDelayedInit); -return!0};E=function(){if(M)return!1;M=!0;Ia();ra();!A&&c.hasHTML5&&c.setup({useHTML5Audio:!0,preferFlash:!1});Sa();c.html5.usingFlash=Ra();u=c.html5.usingFlash;!A&&u&&(Qa.push(na.needFlash),c.setup({flashLoadTimeout:1}));l.removeEventListener&&l.removeEventListener("DOMContentLoaded",E,!1);W();return!0};xa=function(){"complete"===l.readyState&&(E(),l.detachEvent("onreadystatechange",xa));return!0};pa=function(){ja=!0;n.remove(i,"load",pa)};oa=function(){if(Ca&&(c.setupOptions.useHTML5Audio=!0,c.setupOptions.preferFlash= -!1,ca||Ua&&!q.match(/android\s2\.3/i)))ca&&(c.ignoreFlash=!0),w=!0};oa();za();n.add(i,"focus",V);n.add(i,"load",D);n.add(i,"load",pa);l.addEventListener?l.addEventListener("DOMContentLoaded",E,!1):l.attachEvent?l.attachEvent("onreadystatechange",xa):F({type:"NO_DOM2_EVENTS",fatal:!0})}var fa=null;if(void 0===i.SM2_DEFER||!SM2_DEFER)fa=new R;i.SoundManager=R;i.soundManager=fa})(window); \ No newline at end of file diff --git a/lib/soundmanager2.swf b/lib/soundmanager2.swf deleted file mode 100755 index b62fa6e4d7bb99d8fe678e9d1f7eb09dd27874cb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2934 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