From 8a5c868400ab500d3c5ecb66c24b5fc4ff7800f0 Mon Sep 17 00:00:00 2001 From: Kamran Ayub Date: Wed, 25 May 2016 22:13:35 -0500 Subject: [PATCH] Closes #262 Add an optional iOS "Tap to Play" interstitial button to Loader BREAKING: start(ILoader) vs start(ILoadable) change * Refactor loader to handle draw/update, add ILoader interface, extend Class * Add ILoader * Organize resources into folder * Organize resources into folder * Prevent loader from calling onprogress twice at 100% * Add PausedAfterLoader support, docs, and visual tests including iOS * Compile dists * Switch to HTML element instead for iOS to work * Compile dists * Fix tslint and update docs * Compile dists * Recompile dists * Try non-programmatic DOM element * Compile dists * Add webaudio unlocker for iOS and call it after triggering play * Compile dists * Fix indentation * Update docs * Compile dists --- GruntFile.js | 2 +- dist/Excalibur.0.6.0.nupkg | Bin 352479 -> 296935 bytes dist/Excalibur.d.ts | 1556 ++++---- dist/Excalibur.js | 3359 +++++++++-------- dist/Excalibur.min.js | 5 +- dist/excalibur-0.6.0.d.ts | 1556 ++++---- dist/excalibur-0.6.0.js | 3359 +++++++++-------- dist/excalibur-0.6.0.min.js | 5 +- sandbox/web/Excalibur.js | 3359 +++++++++-------- sandbox/web/index.html | 2 + .../web/tests/loader/pauseafter/index.html | 37 + sandbox/web/tests/loader/pauseafter/ios.html | 37 + sandbox/web/tests/loader/pauseafter/ios.js | 22 + sandbox/web/tests/loader/pauseafter/ios.ts | 30 + .../web/tests/loader/pauseafter/pauseafter.js | 16 + .../web/tests/loader/pauseafter/pauseafter.ts | 22 + sandbox/web/tests/spritefont/spritefont.js | 3 +- sandbox/web/tests/spritefont/spritefont.ts | 3 +- sandbox/web/tests/zoom/zoom.js | 3 +- sandbox/web/tests/zoom/zoom.ts | 4 +- src/engine/Engine.ts | 95 +- src/engine/Interfaces/ILoader.ts | 9 + src/engine/Loader.ts | 510 +-- src/engine/{ => Resources}/Resource.ts | 2 +- src/engine/Resources/Sound.ts | 211 ++ src/engine/Resources/Texture.ts | 117 + src/engine/Sound.ts | 39 + 27 files changed, 7689 insertions(+), 6674 deletions(-) create mode 100644 sandbox/web/tests/loader/pauseafter/index.html create mode 100644 sandbox/web/tests/loader/pauseafter/ios.html create mode 100644 sandbox/web/tests/loader/pauseafter/ios.js create mode 100644 sandbox/web/tests/loader/pauseafter/ios.ts create mode 100644 sandbox/web/tests/loader/pauseafter/pauseafter.js create mode 100644 sandbox/web/tests/loader/pauseafter/pauseafter.ts create mode 100644 src/engine/Interfaces/ILoader.ts rename src/engine/{ => Resources}/Resource.ts (98%) create mode 100644 src/engine/Resources/Sound.ts create mode 100644 src/engine/Resources/Texture.ts diff --git a/GruntFile.js b/GruntFile.js index e058e7549..f7d9c7d4d 100644 --- a/GruntFile.js +++ b/GruntFile.js @@ -150,7 +150,7 @@ module.exports = function (grunt) { // visual: { command: function() { - var files = grunt.file.expand("./sandbox/web/tests/*/*.ts"); + var files = grunt.file.expand("./sandbox/web/tests/**/*.ts"); return '<%= tscCmd %> ' + files.join(' '); }, options: { diff --git a/dist/Excalibur.0.6.0.nupkg b/dist/Excalibur.0.6.0.nupkg index 38605d38cfb5868fd9e2e27d545a8f677c35b342..7024cdfddf64e85a4577cde2f07772aafd33cb52 100644 GIT binary patch delta 205445 zcmV(+K;6IJ!4>C^5)x2L0|W{H00000g08tpM2v%Ku@W5t5Hn?DVrFAxVq`HgWi&N3 zG?PC8qCPV>W;r%vGch$}HZe3fF*G@3F*h_fF<~-cGBY+ZI5aMBb8Tc}a3UZ{WIZBM zWMnusWo0rqWMpAAG&y51lOF;e0)noyKLXeR5rVF{NC1=fe)ZV_012}Q03w%9YXl{; zO$6oWe>Y)s9Jduk|B5sB-s$SNy5xPCoH;r2zLodAPk$ZRl5N?tBun!8lK=j=X|pI< zuI@=r?t4zA%a%wG1VIo4K>&U@Z)+*sT7-#!xfE`59+J~3wf(mBp1i1a`NT;g?_hNt zof>l0$9Ae{Zaol)8(reCbCdpXW|}1um)OQ4w|FpztOOLfB8d)?HwPOi)brgkCjX=b%P}x6hMBM9F}Yv zF7;^aFevO4hn&GZwE_lef0RUs)zvjl2m)2n2kU$vZeei|uro#)CP0R4l+n-6;5Yn3 zQRhMZs-yneU4I>>e!)?H;jX_3Q=f(PadpnD=%=XI+A!=mI(w<2e+%eeHnfbze}N_* z4?I>R{uv`rk~oDMcJw9=3S+v7@=4IVE?-v3#G{ggycn#_gcyUwXIix&^43vtiZl#K z3*1~JFn_6sBOu>>iI{@M@oVk+1%wXJoy}jNtp+T>2<5c$N_b>KoppgfRtYclrPxje-~!?ML>DiRF9e?Kq>!|r+XiPgVP0cU`M4U>LQ5#i_=p#DJ}SP1eCqO0aVe}6EYDX$(& z9TF3Z^#6G_L?<$)iO?lY!s3e|JSQQ;D`7#sKqp?27ji-uY~96We|K9jUp|q#uKa8s zr-zLQwAGjYRY9NNW^h?=Gq`SGGgXbdf>v@d_`l#*P*HCqxN2Y{$W{U~cfh7fN%+6u zrcec+_Hg~c_TX;cY>v&tfBywH2h01khN}m*HWN^8Ej(0@ID!rW6 zA2mb@(;9-60~_iC83|i?%;2yjt%-;1Jr*<+u?NmvP(EEq#)DgORG>8o0R;C+(FM|} z?1Slqiqd5O+A>nV-a320WD=iv_uMfe;dj^Zm0kc#;~}1 z)Jy>fPo+t_2aT{dc=;T*l6@%ca9LV2*+(OMbk{uSUPYhbCLGZm%7&10jtVrcd)VL*W_1F4 z2B;XAi{PU+opt;cf5W?G?Er6zUsh%82;nT@^xCSMaVX%K1}^N@#mtgcjg4WbzcGv; zzn#UMsKWRYZ;G~N;4cP1`OeAw_u625UxB+Q@=7{h-j>RqfgY9DFF=d@VkloWy7UG7 zwtt?!AYJOqUf~7l%hH783@1q}Q~@p?c5q0_ISSP;0UdnOf4mH!4>C2}vIJh-AER1+ z2|mHoJjS)qXXg>-cgp$Wn*Mk}e~iz7;lc7dXKdcUSF_2_uP|bU^+J@b7ZebLl#u)o zS`=2LZ3OXw>jl{%Q4z{E1(IDyUeD;B?s5a@0$6Y9E*bKW6e0(gblB(@*d*n&7B(iq zJhN}<$X`Kee1&wJGH`ccCR(6DAUd_QzgHMMxulm?nwn@y!Y&=lo} zeFIrM6Kca6;yl&4XR_v~(^}w}t8`ldo-}@2c^yrKe;9qg4&9%ir;~Z*LHZdp!oqiR z6cTXXuD(VNVAJT!vyNjX2-D)>WAGCIe)9Pqy`Xx~Op5yVT-zqZaMKWS{lQ{c$T&!@ zlAi#Tf4FHY)S+Z0&&@}sC08=f4(=CPvk7=Gl`soQpc;*!D1f<}&+*D0MFW+j$hV)y40#8uWCKAIEs>Sm%LnwNC2(K zn!wjg_;y&c3JDN{;3+GV6u=Oyk|b}lCIHoQ57WD&z)?8xnFAZ>c??uv*qA7wK0Y3_9&s z4q0H*2vtJFu|Z;Dy;zOWuPtzf z0hUJS>S#*xgqb-mi9hR0k0o8@G>$<2jD+WIm}gaR2+c5M*33g`DDA+pNKE2Lg>aGN_^S&PU`?=` z!PLaE-|3bK+35qIw=mq$=W%H8%mYmywTIFWyi-{=W12gZ6ncnse62Yke+GJRW8cvv zEx5Pfj)Bz;2(v0pw7U^T!+rqW`m zbf3%}1e7tM&prh(+!idne;N>YIA*DNzzY!H!ypit_hBLFgfsqR z^zK1o?|~y#+9d6#SNcGiAG2d`gv>S~w9nP6_le`+mSZwYCq@2#3) zsD1p9;%tSUzbUF9zkI5ehh_)uWs2;6ZE5jhQ^4E;<0Tu)XTJvSR!Psw>4%pL`Heo` zFq4tl2%dNsAsdQg-Md=}eXE#Dmvbcx#PWeafFH=3W+i~OanuoiCSv~fsqao674T)5 z3J3N^ytSFM<;W{3e~!oF6ON{-nGuFbexV5N8N84B={4d;$InLl-ARR)`$6@q<(Um( zD^kPU!4Jh`^WCW}k?z}jqEJnK4>J+JQ-np4RPf4l*HDC#6yJSCg&$kP_|*RHlOA~y z#vKTy>A|`Vj$UTw?$I3jmTNDH>IW|wKri)dPakSeArT)4f5f-b64hwsvCuWIbce@Q zr(o;eOp}k3?>uaGKaN3t7($HqU<;)nt#vPO*vB5M)(V)ung|oqp~&peHh`lC^StQ2 zr)lo%p~WXMI6{Mh9^nNr(;;iZK+mRreB?y{A8gW}(1OER8q7X2ks1wMYog!~|8V3k z8x19hGg;OZf5pn?j8VV!hRqEf6jBfT4x}=vW_HB3D#DXw7`EJTvh3K$JIX&{dK?*| z#DHy>Worb5h)Sa~Y&0?eTWs_2nCN5r7fzLq`r8_ag5$PeK_k z;NXb&YM&j>pA51CCP8!nYr6*0`QoeV$1i=NM*adrf62w*KlY=)goLm~+2Rp|IDtSO zg@e!)P(o(}Ab|jwPh5lTtVBlB{mdF#SO*gQ?(JRqzj(>-9BMdtcZn~c8P^nR#z{Vh^= znV}s}e{k$KGA-@o3}6<>ybgoMh&YS(s|o8tKpEET5p+}$y*?LKe~E1wp^ADx9{%JqIc~FvA86Ol{y$=s*?%4aSS~&`P}a)#R{m-|VC! zV4A~QPdKI;7{&#+09z3=t0*=YI-;(eHzE+ce`HnH?UbV^0y~s*D^W(7Od`I$FQ3cJc#U)gk7??AJ_z;pqPc&y4s_3Kv0!g(EsrKl?8Dfp#XKO2j>(Vzir1q2h8hlP< zsYEyjl2byPQJTzU+HvG5T4hnFHazaG;|v1AfO*TnDiXIEB4z!QY?F9fMU;bge@70w zQCSj2>PCh)9R3^r{SUChua8g(vBGL56#G>rsn} zQ9>~*XzYjZg0NmNpeK;~$7|5EGd~ulVM+Txq;sE%#qg0`5`GApC@`w8VGj24#oeK3 zgwpNL|Kxt&Pkx`p!_{2KB?RqaEL992t)P(pOFN07Wy>%HKQTd_B)6T+e~J#|)-oa} zAtF4HLDTDaw`Zh5xYItI5Vj<#IvoII`EfXgZtkvq-y!;X*Dm!m{;p0yVETJy3p3w+ zeF`4{jkdnJC%AbmWD*_?kTb2M7mn@93Khc_%(X6E(KKrKhrrgZK@5J^8Qax>oU?qV z>N@7fN185CWV3*|Y?B!4f8jXD)-%mK$T5P>F#L=3s+1YC+t`v>01+50$@Mu99@);blie;FK`6%oKN00QYw zw8W4b!T@IhJG&Fv$=^?4vX>7SC)~r|aZhQ7@cuJAz=mM13qEtsXMOXk{mVt*G+!>T zO!$BsJ7{ta=iaP~I6yX%0xBMIeA@A+PY*VJ zADL?;ePH;hcCQgWe>>BH>OYuhsN&;!_CI(c;T1S=B7Jz7{Ws!!G?4#7wy(>o$@XRx z5IkTgfXTBv33IGNp7>+l@WIpz-8niB+-_{f|IotjuHjH*E018$JkqaK*+XK?LVH09bQp zfNa0n&%LtS9JEdhmOJ6;lhFlaU7_cXn+pcStIb}BhuO%r<)}p#KTcs z?obM7SagG>N29~~y?oYcSWAX}i@BAm-iFu6>Z&G*@?~}7x+R5gF%Q9hZzqp42 zQC)W;Ha1kVNKk(dpHaQCCR+n@xT)uD+kW2Ae^LAZ|;28kz@$CyyGZAa#W(< zgx)dhfBzxRfoT_H9K`s!_hU>s|0CC9EHZ}FP0?Kk-F4Z)oJBwFu7kH<|KzIl`Pp~R64%ikIiX!{<4HTcf|dtK>ojR|&+0 z46@r{903XKfd8Nl)pq1WR@as^<|H284qKIHtMrgh9Jr!Wz)yI0cc=Zmc{jcv^MLnG zcT;hFX4i@;__RPul7{Skn#14Nv1PNh8N0&&$F^((VM8yU->xA~cMFu2=?JW{ ze<%SA@^UpabczcT5x}1jVYNbDJC0T<8#)Wwky;K;k^y`T)kk@qX>p@MQmtj*HPfg}s_&&fJMn*6YvkH)nbX zLPg7Y?1Ohey3FH!MM=Oar>RLn^z7Xfe<((_Q(t%i1p`x)FpPumdw{}|n=UsdKXL2j z28>Al^3)Cq(IUW$GGNoA1C?6>D?PIQq1z(XfGs6ag=Bh-pl^Vnk1C8g{y9L93z6R>8#gxNsD(q`-Cs!)ZoF>0~LXyIi z4xYrg&{dyAD#zjl1qrfK+WhwEm5>d3dcDBV@SXqwJ`J-5Ox$7+L+DW#Oi*8A-+V#1 z=okBjLfq+sWS*noOC=U|k7b2U1U6Y<%z&nE6|w@du+#SaYm`1BtgrZ8e~cE}10SvH zaB;zM8A890qr65!T-yvt- z{`}u>FJIX&bMDJ6_9g!<`uTs~homs8kt(n@$pvWw`usIc<9n3r&g>h!p#Jg+aU6qU zHNbiS&Z2mSK;Pj~P9%fjf6&Ap1<>8kz*A12g^0`qaw5rtMMT>}osF#jcn-cot?`H? zqij7StG<8-FEZrTpD4#=4?5*@+(q=w55`Cd;a}oY6Mh~=SfP~z%i_zY4O+Cq8Aog! zz@!F(2hk8rS99h2^;dHXZZ3*1{>%qI-vbuW0K1D_6`}Eri#OG7f8Zg?Nz_HKb^6Iv zq4YBZb==CdZ?W*2$TQRlnZeY$+kR4{n8jd!*KbRphy1a>Vw$pr}y3tt8IxNQOeH7KGs>6a@3*WP)HZsE?6|vhHIBf|pq_ zXGb(-mXwuq$lh9lDA-gMqOVSC8t$?~$bGECU98EFZobkE2k6H~7Fp0PmCz<6MUeXR z^NB%~QemZs0r=5D2Y67zD-rB$bQWd503M#MaX4|nkM+&je<|wf@}XXl)1N1LqZ@a# z^hakXfcMe9(2ngaCJYR+;+>HHf)hCB2>gWexBEW*lTY8=!)~5vfJPq&5c~eeM-aoj z=&w(Q3lB!a_C6>bYAFaw2a%qLtL3Wocxd70iKt8=P8Pq@I`56&WOn~U!JDX~L^Xq% zl%QNt2&9GJfA5d#!O5#s`C|gR|G`jF_w)AYXis+&E@U&$g=wrRQI9Aq zc*vMgq$X3OyK?q6$6fe?*k(RRUW>6s87xjmdDmfa^3o zdw{nZaab6LgH8( zuFpWgjtqAY@WV${iRXd4DtYKvmv#a}2={V%ja*-G+ph$UXEJyl$!N7`GRe?5(eMww zfnVdxf1;)rC4Tg-oKVyyZ`jud6^on-&)mC;2u-d&)j4^&0TT&Gk)iT(@1A9qvbdRq zy2OdA>_~w3qUDf2x>x-m_(h@DXUHTAGe&*g8WLh6>K& zU9={%ZZa4eJVXf(Q$2$tZv5?HeY-wbNyre{Yl-Q%>sV84!D*NN@VY`RLSkfn#D8BC zp{7Q02O%$zS376MO@vXvL=>@!(-tC_=-L%UIK^8JGSlEev;ePjS@F{>sGJ`8v^W|D ze^`XzsS!?yCBW|rawaiwtEO)VzLJ9u_9KNWbZ+2a?qK5%Y1EP^6T|1L71|7_z*o3I z(xFKX86d21VxnGxx+(TK(FGI;@^5es{Eg}uQnbUOk;Xlx9>u4sf?qzd#H{oV_mQKl z;R7-aH|rlM>~D~R|7JykLe8m#nx^l+f1`rm*@P&sl$T%3ituhQ>94^5=@-0R2~6&Q zPUZ}oOfX!}OFRa|cpOIGHLqKxVwY4*y|~C_*06o{Ntey)ub>+K&msqS9!ydhFSy`e zO#%BSb-CZ8b{$Qd2@+u*SbEcjK!O}$c!06?3cORSoH;1ie;lo& zxTBFIpcs%vyn~(5jEA+r3WyL$z<-i3H?6lx%ekLGb&QYoigSu2pU`N3ak4T+{~KE4 z6Z#^6IY=MU|1J?#(M2=HhIi0h6`g9|^_hxJZO^6T1=Mk>d2a14pb`%2h;QGU_x6D- z6^LcjoT@r1cmmAJzuwR31=^gDf6Ea*liSs%Ca7Q<=m=5yxL-h)1Bi;yn-5JzWY#g; zCboQt)N5p6i(8xuDgFx8fiH0+Fpn^O3D|>xR|q-O5fNvb7w@7((C=7~xlPek%?OyU zCi*{7<^4`Z;VEYtlZxJ`L|EPBv^B~!>~{^pu5W$=>%Q|%Fs9^-S%bDisQ2Tg?}a&j9?Fj52ZL+uq0F}YnSqXa;SxbQ5<^PQRVM1y<#Qt6>zLX50X5> zbqFb)kxhLNC#}3-h=1_|s7l-tZH4s6g43}HRsyKN)kIng3yq^RbAbV_&^P`9<|=9; z!oU^oKFk>^bhV3LLlg&ef5HJm&01QRMszTl1P5k%_)0c@`UCvny1Ws9=tF)CMC#aP z3Gd#+F~5AhvTV-h!FIq|xqVR)?-iZ`g@u5%&gz6qGf7C{>mqqBYf}f{j z@Sr>6SUoeB(^Ui-Md0D&D_rfch=yYdda3!as3qZj6SbmZJFrxSJ;n0My*nZVTYjBO z#e>9K1oaGmnz3Ch!ZXavMWT3T2MY)fE)=!n?KrBI9>2u9c8B7%MOpe+R}@vehK8;~I;KBp9HR z14E;^Mxfy}G-W4zs48p|-a2~uL^%5s+}6VXC=|5#^@YNusHcJs7*Oy%$uaLm;idu& zRQAr!F8zdo>dyK^H)3IJD7a9_t5qL9XklfrbRPGnX9`S#ic~kWa|1#`hr1&Ia2qrO z%gXI0*(WOAe|!#QToA5-f!95X3fiIB-kVENTOK8dHfajB?XzKWH1gH?{g)yDA_mSCYkKqt>%p?=$GZ*VQ>X}I*oR2&?BHSEi zAx)o1Urrj^EmOA+hzvRUW14*6k6?Z_znL}2fA2@^YJN4VnGb@f@0ul!A0`a@Q4o~- z(SM?VbOpcR*bFJi-ejW?;XPD1^GJ_5Gw^wU|EWFu-Qd35p&mpTn|IxU$qgaEFkpW*H4n$u7Mc}8SObXAdBX+|OM~&) zUjGu<7{&TZ-}pPFnf?6>HWP%EqdqU9R4A4?2DS7bKVpe-fiu@xe{i-ShR6MI1GAL4 zz53#u5r4L+092>9SS%KIo?iOnK;u`Ne~+Eq?T_Fc-%+r%_}sMMM!hv(Bk$;LzbN0~ z^y-?JpUraICAi#!&U+V%H_eB{cZH%ZsY`l$&n#x`H+#KuNc2US8M`DaOm*mfHGPIyUKdG0`_~^g^e;n!U z=40m(g71|#$8zraP0qU^xM243j~)96x@XC!;T?v#9jc7$x7~`>Zip7F;qu>t`AZ1z zChUd!{7x)Tc6sh2pwE&26M0F1he#xJ>mkkGl$D2Ob@snj;#TiNNJbnxO0)Y<>;A)a zoy4s|2V>ZSks?Jsj{mbo7mANO`v3hY38DbhP( zJV@$WPFub_q5_4~NNy5d1YDW$Lz>zq*p=vl2P0b4VA7&(`*N6D9fqd6a#T|mu~~Ut z^hP@NNHe=<+3=tfNn{N@pdx2@OHVP~p^$^CfP!F}E_N0)QHIfnG!mLte-d{>MBghr z@EtpZoH=CY5-utrf`}573dZs+^0zzNn&mna!EQhfzjhQ&3i)FzM-u)4d!A$GnU%od zK)T32yM*CJVDL_QCQ*UYMbMMG4su>}AT>x^pb-m(WfF`G0T@C1_CoRo3ubVuEj*~) zGbVMv7^occ8A7un)FS6ce`rr7wAZQbgXIecFL(R~GkBmelg;v;(q1=0s$1II+nd8- z>*O%t+E=jLgm71}2Z`(ogaAY98@4T@xEq5FrwU#>xd)!c@gg$UrT^l22egAR(iq~l zVaxHByWqD8>RVA}p;_5!WO3Cs-#X^Fw;cRSc6HFW20I4+S~E#!f3QoQr=G3o$KEI% zb6DiCKQ(|0pV@$s%O7;W^3*kpwD6V*xlh3Q&^9Q-!!Yb52wy>mL0Z>|b|1GYs^SG` zIW!uYMZJA6@$lH?`igC0^f-K)+yK5q>Edlu)Dc7B+sv3as4n(7gVWyxu^?aVYr(G8 zU^H!KaTLQ0c|YKpfAVTMr6GmEzT<*2O>ijUzVi|W28vQGpGdS|yQEbHyJSMOjI>Ml z{e;bP67qC{N0t(_@AJq_j(F`^G5?{{hD{`Vf<^`JMf6tmMANO5Ls(8!L!aG-C zqzeU2Qhey?n3Q)>819K<^qrVaX!5;IH-<(Q>^w+p}-3q-~AXG z&Z<9x3J}NQ{`@@1^|o34>WBq)E{cvWk)}uLq()WL50v7;4o-B zeN6e(prA8sf4G)Hg@(I7LGv9GkB;(@QTb5Ywg&W}wt3qcZ{dL0v+c#DAAJsk zjziIkL#@OG;REO)(=OCLx#h+dA9p&^GctszTM3G{Y8ZS>h0uc%x@i)F%f34jkS{|1 zhtr`DL24!x;v`V+5{CcK9fJpVEr5@XC_@4&4ZYaVe+?9*n1H>XZeETRHALu8f&Cwy zLWiRwwjo9E8UGn2CUgk`Q&F@gyLF)^6psF`1JBE<6%tecpmPP&q2-Aq_-}wtx`21i zd}0y?AZhw9czNInDq2^Mp;6!R_IXOEI#1-NRC@v)Go#jrk+Bc_esqaNIFS49PoZFM zneLqlf1Z-)A8+5<-F>KiWJ;6aC@j&o?jtA!xW{~Gp}}17aeRFJZa#ty$rOStPY#P3 zkvd0R@PPO)7{(Fypety|HyAo7LIazugPq?qOHhypO4v2q^4;^yFv_mSpQJ7$kkbNW zx%2%9e%L1Titptb+zv=hY=yL=gMIz#zyaURfBouoHYBDf%YiSjJC+UVLrc3wK+QVi zfC63MpHh;aa)+bgR}=sj!v+O9=mti7(e8)pst#lMXAhHBA4effNmUcf=?xc@(od?CWfVw8a21mIF zf4-K4%X~$DzF9Xlp{{6!#ORnf6){S|mzGFq4PBMQrSO7&Q4U_<$N%07#hIjR+Ws6F zPn}L8u46ZoTy&2Q*C62-AXWvRGZT-WGFDw(l1)KhsSAW7puTCjJjzBS(zY(Vx|Co9 z=TRs|f5O1(PA2ry1vT#>4n6d^qlW+We=ql>!89djY3S6$a^(p+bEX}xdV2>RavHsR zK7Pm+TBxe;xfpatMaV*HEu6U4q+5g4QYKpv8FDoA$oDhY`D1=Zi(u5@Eq#SoA|gDM zf!8-JMze9aBPAR4HH!4zP(zN(0Vcu#=^E?7vj>7tXIo{MB6;?5pU7EwSoS zQ-1eRROs<)@CXL<(L6-Hn4S*s!V)y%dS@2_I12`79ztIo0C5(o!1)S4$U`Mmud!C- z>!D*QLUcT1uTFi*r<;&&1deA^f6cC4{3+zFYLBs5_1^WC5*bJ(Yre~M@$QJfh1~1h z4hna>7uyMq{B&CkVOL)f)}QZR@$i=8_4BLO?)Z8)k?tJb?)s*>4ho${6i>lB$35Na zCi;xWi|XBTP^t!xgc_{UK2Uo7kaw$~KFE80lzjO)z{A7W&C}P(O|=Y2e-0Nncv$CV z510J##-VaRVm%&n=t(f5#I;0y;H&Fh8lMiB@F3!==WZ=-z?H+>1>bMb?X#qSsIT|O zVP>!a%d-6E$U}!ghJjtWJ2AsDOc14)dw7q)*~!lDk^4`SDkM;acPWrB2#J-XnCx>8 zk;+B>#QELl`IpGUhMw9(e^?mU`X5km%N)%3VJpOTWEH^p?tmKJX#JGkLomqicL?Au zOBpM4pk%l0g03Jc(z>z3!buX4!S~j(#29 z>ssTjO}`%h)LnEDe}|Ls`gPi`u*an7E(zm*zyt_fL>Dv>-&RNYV!=0csVCxq-^kTcnD78R4m*fx5R7l% zNT$LE;Sy!=f6^OI!J_H2`SmMF#%d-Vx5AvFlT8g}9|agAfB#eq9?7Wb$Wm=VMpk2- zH}dZ|!vD8#c5+Ra71H+LMAADSDR*@URzB-k&BN2T_xZYuz*z*jg_Qt-yY@d z^ahK>Ar+i4`H%tf0zuTM0Lf3j+!Dg(Te+dFVMuxn^g?ZzD=?V-YJB>f7bc)}6crVzM8^HHN2KpwN;l*LrT1;x7Q2YWJf94lQVf+eidP=zb3oi0X!!D>f z(gyTKaB@b(j#Y_EIHQcxogtk9hiqr>eA=xNGcxlb0_Jorqq2Y3T{THIUx(BJ(n3>? z>kWy3YjX4noY4*BKa5!M~I z1RSf1d0KkEO1YroQ@@BajOM*pwqtolen5CSe~a>C;5aE(#3#v?&4H@t^QyXF+`(Dvhl=}SY2 zf22YS>2+n}Wbr>4J1TA~u)(~cz~0C!Ga@VU7m~8g1KOdJ74GB4BCkD8C)^Uwr3^J~ z^2V1i{%{qTjLtFh&@BrjuikKiKT}M-tw6~!dFz%){`femJVEe#oB)rCH>lbAU{$l; zKY^EBDd^lD`_B8!GvXxg=VuNtWpUCZe+U98Qws!S%HiLM+@Y5dPv3-~0EieIZ-qw8}>QYJWFh|K=f*1;89EdVTyhp!(f_ z(V@5sJqA__?vuMz066!|#sEn8)5sT((<9w!;a)RgQ7me=J1%i6g1Q`8|6k3ke@R%{ zN$Q5Pyw1=qDO?zzMk8g*XFatQJ4X@_%Xin2z!SotADRO-6l zgp&Ykp!DFCi$(%uBDKBl96>GLp6IRJ#$*2g->z0oATJ;4Cswwpoy4!qk;d9H>aYGx zCrJZ8(8D@{@UiYe(-^gL$Y^8se+`c!d?Z5#ChQCsY83K|Tz0eB8>Qs7m>ku9f+DN? zFf$0ilSHY&tJS#TN9clT!lTd+(gxB(mq^}3BnZG50U=~MoB-ee0!J7I8F}nW!x$Yv zkdp{=;GrVVu#|=Tj}oy+0Q~?V$)?nwj?Qv2Og%^_L?92aEkw%8_>eMT9G%)_;U< zI?@sh`s6iV>TX(nm{?Y0{~~e?Nc%s;XhI;#?AJewXpRQ|Ra|Ca@HF9g9$BO6PV?Tk zZ_uQM?mRs~1`9j4&jflDf8^L{x(1V-PC!sOT;Qwt%|QtQKishv4Q+A&?!_D#ntnFo z&eli^;ZXOu`${-nh7{3hR@^WHh7R!w3k9oeKiFw!Lt!KN(-8iyLu);;S~&&^8ks2W z18}DO$zkex6AplitIf+qjVyesbpro?R5$5(RPqjx9wP02lw+{Wdpu=Eg&!GCDuvWY(_*Zw-JzOFhiNh#*ltGOAMgbV5e_sf?KT?4m_<;osyYr3l zsbq*$G}eOm;#kM%0Z<&PLU1AvtN6fI1=*p_q7|lKSJ`rptMCv zX60($KKTiYfa|P?0w)|24xn~C$`Hw&ZR8z?08o4T5`SvpdTv-Lkt-eTqiB#c!TJRV zQ5pk$wDXR@W!8Gfhoi5#w0_r2)NH{kL z&33xLF3k6=LUC2Ks*qRi;Gs_69cRfW@-@9H@=myR;bFi}$;X6>wUl+(luYoonGTe6 z%u&#Mf8!!MtWqI~bJ-&=DgmBL@MFDlReFK=zD7>a5il?$Fq&ELkFOpjDI`WXEsM5a zEk#C-mSL06I_d!yU2D*m{DHcHrrntt9#w=g=q$>-a(+W}D}vQQxX@E@x=4cE_Fq2X z$h6S3HxU*QJYcLUqJ1fJu!p1#zSyF}oOgAwe{munH~2&DTA`T?igSlR$y=&0TENdO`(;+JHhL3J$i zK>}9B6+VanZHhf^*_xV;iRwG~oz)yO^KPz&s%}nB=Ufd@5u)d{KZc|b__hT2f&DG# zeVKFXI;DMIT2NT_hY29+P@BRbH9tlI z3&O{l;$HQ6iW5NPkGBlNeLO#7QMHecxp60>!VNa4^{`1oBUj5#jqkGyf|VEjUcK?F zj~uwkViHyhqAxyv(EYTP3e9B*SUMDD`4K)^*F~Zc@AMpi8c@dr*NB< z5Q{Q8AO4eP3H7BpH5U+tu4eO^e{eX$bSqfYPTyNK!%+M9Aywv*3U7)k$S9AS zTXT3t6FI0FSjkjH)&&x0@Y6z47N3Hed2S*4U=8PkwQe|Bb|t>K=+ zgf*XDBW|?(7EK!)LYbHQ@p)V`jGAUs*@r9Phr*fkRw#>vyRf-u3)`9R4%O_1ZnOzt z8C{Sc@73w@>I2(i$K?OeLiy}Y_%YpSdOc>>C+!Cmgr7ELKv@Q5$w-5SxlzCMhVO)S z7F%IyfZtS1>~6SM1#kEie|oF%!@cR+60}KLr!mokW-+0Cq%C3rI_xlX47K|YyE(jD z%N?7rZ*{J?~H#%M)F`AZ~jWp<@u{B(cl9Q%+p z9MkF#k$QAH9U}9`Eh}NxvL`Hje@y@2hhexo!9^1xKampVAu=II2*abpm`JG=_AC%Z zx^)yF(vVWs9c;~Qf7mpS`NA4D>BoXUbh5j&@OO5{x45-Ychx3ZMU@l1@yPAEi{omA zL)!$IIg$DKr`bXSf(AIDg*9w~l92x&w;S353imy0LHmF?md9FP5S{*A%&TEdkc9o- z)_~F8(5>OfeX`y=YvfNdMp7FF@KNT;J$E5f@mV9KIiG+0e`K46AJvw2PksstKg~)5 zXj8t3MnvE==?Vw=46mXCQNdqv1Ru!4bZ&64IJ6=71~-78f30!n8M6)w(u2j||4{4B zA7|Wwg6;pe@7SL}`_3~a8>%GMuKu$nz)s_X*b?2O4>0`!JpgQc1apAPXl&r%q9{pl zMgLQzzCwJ7f75j@H3eQ3M)%M0P~w1v`y-f`8wLD>q90;q0F5{Ly)pI@x~9J6PMp5f zMAdlv6y|W~vDEvR{Rv8_=Oye13{PaW|Bxk#g29I@Nui7(rb@^QaBiY@EkvFBZ!89V zIqLhJ&WOJRS}dP3iW2iC`axx&*HAWZs(c&C+(JSQf4P_l$cN6BX_2VE$oPck$U;-j zKBvW^-345bsR9(yr^-vll(uf{=e}@Ed<;!n^E{NO}jp?Z4<4% z5B~e#Bjgd}Ghzu2)Cj}dj^W2gOA6YsIU4a`fA(A}q4)f*!jCN7@Z%t*uefmo#=HT# zC1YtCWG}k^e88G*A^F`+gokaxPiRxP`SGDYdiD8jAp%X+Z%qiO?iqd1?*R7pH<0_Z z5yXT9n9bpDXN^;RiSfL;8qy-~6xw9;{iU}5rU8D4Z4Rnq$UV<%;m#IpRzv9jtJy5qJ27I&h|(VhRwmdAHs_s$T-y{ zNe%&Hc565o1BY1`rE7h2g!e`RvbaXReno@B!iqTVzc=Y_Y%0L$tjR4f>A4Qrevuxpn|3#Pn+I z+hS++cJ=#U$PUYZ%l&2GBS@8cyFRFuOBhrLaca%2XVrjzyhc1D;=A06`p9nQ8QXw~ zUf715{h_Tx1h`q=@z(E1-EoY4R}0iIOW~6`>lePd{pNT}?r=YGv%3xje>F6<{giv% zL{Zm+OZCYyh0d7Yg3F^0t~gjBB)a!Cz)BwSrnxiWQdbkcm_of<%`51?-fr z7v+ee@hJ3>1;qeM_nL&Be=;$*&cPO(=1nUETQd_MeftJhAzhGGc9vrpZ{DIg%HU+> zL_(dyi0agoPUQ;+!Tjc;quqI&Bfy!`#j5Pib>v8aL)x=m1!NqeXBe^oSx05Oh?oFI zpLkioBTW_QIWQXvipaBr30PqMEEqq+z$V+zE(Gi@{cZ`GKZE~Be}<*12351)ym^;! zEOUlrqSBc)Du{C~y*l6w;Nud&dt(7Xj{pdy^)Wnr2UOM5FRu~zv%Q-9#YXlYRFWX; zo|&@7K@DWG=B*<}2i2{cToPdn$cq*gKD&s3&pgSiH=rwb&N7e^s-PLy7qk9ncby1n z5c(jR62b=Z)vWc+f05+JUOWD5e{=ToC#04#59q+w;N_Pp%Dn_D15MwNBg-%KkRz8) z%VbzbOE@o{YoYr79WaI<^ZE;}U?$IVE+6+HR;&aum_m9a(oxZPLREtZC@dUA!0F1$ z!Mi9&4++|akCahTH61M1C^Rb+PR_Py`C`b_vzqrTyd?dff1T>@Zr#MIu>dVV(!Yrm zbUg)R`g$K#$L%6XPXuGaD8fvPzNO^j-a1>MmoTL#f`exGy;6Y7fo(n~Jt*XJJnHM# z<2=TuoiGMhd~iG&T-nEaiN168@wzhOV|=xQ@;AgGa2bH7c`xx;4Dc*=mH|V+fUk&* zU>+(J@gndq^sA86ZGV?fH_T9q&k_Au2P~XK#ERK9n+V>QUd=U_(fPub`Q4zEZ;>4a|b~nMx>P%72CE;{ox?@TW&c$I-B; zknZb-94MVSQr=17xh-lHrTeRgz8`u&(`+2Rir<3f+Ft@X2o|orCEe}rDT^(&W1uvJ zH&A9qO*m0rxx??$z`_p%8~q)=hIiQi?twy2{|;(}$!TD^HC7~q_) zD&E+-fT75}E=;U{MDzdYs7Hi zjsJ&K{w?zIVrhO@?*o$xDTU145PgQ3)M1I=BJefMThm0$tO%q(Oepxf8-q7Z;Ezk! zwfyDsxPN~IoD^W@M-;`p>OdaVG>{K%RG%L~;W@af$Ch(ubBO=Eo{)`cFJ_5O*(y?(15lfkW4Z zmy@9O^osLh`p)}5!9rj0{kflVoaBHDFMsZG2r%pW2{1M?eJGLTQ8&O^c*AxO zlFHgI(7tDRrbo2q1&QMF3tpiNXanOak%$!Ba(91e!7SB>CuT7_y094%7KP}&dxoR% z(tnmVd+S4rE;;$cS+RVXNP<$y3=B-Gh~F`hB&8m-zR)5Fll1V&0T$XgDT+UQOcwAu z{O*~e4A8H1NtBJ>cu|Mi`)_;h@&!B)z7PfE{^S?5nn^_#q7l&z4Yn-+pa$#3Whqsr^QEI3`rq<>z;aiP;c$C}l(!h%nGFxr$yYw+y~f0p$k zJA+@cEqDawl}1rav7_B!cBuDuy?=qS z-YEQTJX)6f{n4mg&53J~?R2(E@x3xG>!rHVOt7n6ooja1nND5QwQOp7+;Vv?mya&m zj5eKikAj{{CvLa%iY>C&$)MEkw`c78VN@5&La}to4XY`kckI>6%|;FMniX&JV&%pR z-V1DZ6YZAHT3u&rr!`v;+V8C*TYqAQ^Ar1CxYn36bLgqklARUH?6MHs4L7Y~ogJ~| zLT0;b?!n(Gc*pOH^C8;=psS_UEYaGs71m&@th|aYhHSmaM;lU>?G+YMu{>tEVjmzn zoX<9({5s1vZ{4w?R@ln=%oh6lL9Ul(+iQa@6&mBjyw0|YN%p&ay01*v$2GqaT63-5?X^a% z(vi6_(>_OQsa&@_+3Z^KJRwYX>Gr01DK{3gr8-@$((+ki*fA5=qtjH5>8|3bR#t4( z%h&0wQY&<~>$84~4V$CoEnRPHs;y;O$=8_Hvc)iGK6Y)D2a{%cQh!uNsd#y?oTbZq z<#q#1A&R5spt&4Lu~UARGIDzK{2oo-Myy^{qU`k8Z*d!bcJ3wy*JW=~8?vd>l4ZNi z>>^hiHQ9A(T@_2IWj@J7a||;Q){S0~o$vO8Wsha2yWXxP4V(Inslf@Acysrs@~ zFMv{wVyPh(`u+Ou*l&;4myx25>XmW5wyNis>w0<Kzj6ZbHdLd%5NL+*!{G zw{Ce+VviTSUDStby*O`gui3Jwu~+S~Ih@CbbLp6pGC^=Qf#hqE#ttFLGM zbYW20yidy6*?*w9Ue}7fSeaKE?eng*snm*%Yjb!gA7c$o=|`8n*=$?CY~q`GtJs~C zmE5p(DP+ZRx7@z=2IA=b+Q{yE>~4QiE5kwAXjEhS^q?Ny>4&)<8x)l7E+=#I>hW5* z?MFZWXxI95Ckw+;y42lOqrFW|(wp+6!7jOBY80(2BY#~z3^uYan8x&z+K-CU4BL(I=W~0rnUpT6jod8k7gcsSn_r}4wHciao3nW=rOz+%-no6N zY5R^aFMp+_(|Ei-7^0f1%xle}I&Mk>Zd|=8r*U(CP!F1LSR3P9eA*hhJM0Bz5$`c-Ej?#uyXs`wem}?ZCACsr>tkkn zdY`R}iTAmlTX9~=D=k}3uR%H z`G0Kws75n0SxbXSoPJ+qR)Vld%F)dw-(un;W|GXP%(zyntgHI@yek;``)#w%U54Y! z;&$d+xz!>!u9T+BHrvaLH`1g!P0a@VBVW!b`EhkSnsv8TxjOBQfC*-XtFVv&)L$& z(D#YMVma44(^v6@um*@l;m+~jzUW`?JEJAafDZDts&m1e7X>7etIO@BPP z%=WL9k~--a8SbXuj@@Lkl5Z^3R)U}1E~Rdw)ZH4JZmS8JmB*b$EXK=~gpgjQx;L?Y zYz$JZR!dz*TdKae7|Hrc=r{T9_%anLnb>K<@3Wo7`It}=8RpnNrq!&nTFSX|Oup`g z$*_Hky?5)qXrZ6x%S(~6Ym99)RUN{?>aq@8DH`&WF zn%}0ca`Zi#x}B5BZA+MpnfG?Cn7p=DtzoWxlBH-R8EZ3jCck5n8WZak<#lmXn4de1 z^{85yoLkvwP0iI8(N6cKE#@oknh@fJZL^r}^~Z&6s%fl`(}FgrDA&%lr+*D<$#i<# z*)7v*2?&GLaXX2z{3gAxw$91adm}ZeZN@^in@XR>%9@J}tJC&$)lZh&w`6RX={M%( zq-x0Tqg-0M#+&Vd54VET-4YMS_CBqj3?`Rd zb!sU!DHfycY$Xk(c_n@pxPMybd>T~L3#Ya=b-km`*gV=#Pm5-BQcWyNH8DRmGpY)=natA5OO-uV!JHa1fB|bkf zI>~r`H(j*St9G+}%&xO@u-0~%ZcEI~xmDw)$Fkk{U^njeM}JYNm&h6|-k8*;(Q3Az z-5A+ZcNWXGr;ADUmSl$6#>p_o?0DRcPZs0(%4kHh-DEeDX&jDnN&+vZT)eZG){M)! zJ7Aeut$xlV;#qkV?(lIm4oue^+aY)KquAkRe zrSv)0tw`y?sXe+*WG*vn4R?vv^_IHw(mbADiP?0rT3RUDJey8*JIRF7T|}dqa&5SY z?WT+fB+;pK>P)-M6yI%L6VcIdoZU?Khg@cwNFMl(l7C~=?r@kBvU2OlX_~a;vhq>T z5^*81NM`y+p`FX}`Bprg>o1tNF%de$B!619GYe)_$urYc#Q^e7T;*^2F`Jk!DVl6=Psv*TaIOjKT)wvKGt25`*6o7DGQK_MONCh!EOEzb zX|~Yh?SDGj8OmZe*~({DSGkwV?`~Hh)|rgR=*MH_GCQqK+i@np>cr;TzA|53rF4f` zOs^6nXl&-PKP7UD;$@SGUZ?BZ`#2jLpH9Ykx?1v=tweEL%!5K=ogDc3>Yj0^dpp zxI65qV8dA8PdkaJ^ugCoq0;D=DB&+4R*tWVS*E&Trzdt@D5v(rbuM)|_Jx5u zG;R&3X7t|8-vXkMq(~K1aU2h4a)I{BHlb!4CxEQBO#Zhe9p08D@V#w=*xET+l z8GmEhiL%RWtaRIoRbyK#>a#?un2sf~qd7C&o%oTqiZSDUf6}V!#_F)lZZk|)Zg)!A zc$68VJue$$sIGIIrV96*HG&WYywdPetLT~KiHX)3rr9b?K!@um zv6?JiW`#nz@V?&hLhQKQugcEvXBQ3qE#5aJJ zY_G=_*Rg!Dznc!?Jz;x}s!gzaF0f37ZB>-Qag)ln8uDP*T4i=Xn(te&^EWaFNKLgiU6ww>o+wYm4|$+Qv-O7TG?3V zxB@%^%dH!WVS1A(Z`F5sm{0*4!++XVn+ibnJ7p6_lFzTQ<9az>>OpFOeO8_8Y%A*f zK6%m;rD}VtWDog{JRBctrR%MGo;KC^>3X=u*JZX2dR%SYda>yc2vj~MmoDj%2=Gb7 znfR$I-?FjpakZ?mxSOT&RvQ$z1w-2&OXC5b;FCi9lx0pUPGtu@jBl(P-G9{c#n^FD zyOf5h)4bK5Z{qa=3#of3GQAz&tc@~@>SeKt)}yCpAqJ<>n(ZpG(CLk1+8{mSxAVlR zk~k$B<@{C0?+f)+=P(=R;Crr?t@O}fu}r_5c~{hP!ngu~7;8fFOR-+qZBm)zu%R!; zCs7$6PRHI=Sls$ErQd@ESbui6DMxc^bCNm5j@hboJ2S0odUQJVz|6<}Ei_7-e1ACC z7n}VdemEwLg^(X6Yv&$rqqy75a@&3?t7O~z+jK4$4x3I??=#Y(G+!uNz@)ID@@5vT zZBM5apXq9gQo%@^K>gXU%+CtF(niT24{=Uoiu&3ZY#?YbD({V2qkneUc4KPnbgr|2 z6^iRF+pqFWyO5PLY!A9JBJZ59i;{(B>t=Q^X?WYLm}DFC)pnk;5YDCA&&0areB!4(j2|k093@VgIDtiWl!&ca6eXXx*VrF{Vi_yyn7pxDuht?$* zHSOuE_(U78gw0OR?~09H3J*=Eye(_lxt5-(OER9t zLbQLV074$qQ{%dcV?wg^TDo@L%<|W^svDzK9WzY03_%#jA8Xml00&+NC^8f>jUD?3mBUMWa`Q4S{zE#&i`^ zVkg9(ps%H3KQTxcSs`DFO3?!80~}8m%}dCxSS*%HDX~5{MdPE*J{QZxAx97z?N){M ziP6VxAXnIySbv>r`RH_IY`D4@XZvilx8AKX(UX?lz03PtLMRFCd~zBaL)qLuWLP*B zqgEV^g2MSa(_ot0)5}GImoiwCBCiz zoOj9SVt=o0ZngUKZ1Z6oh;D@gyt`~*a@Lgfdiq=&WbDy*#QKi!pba!m?(e;x{e4%g z@t{3GuX?pCoRXRL;JC?W(u>nERZU(5mP>3Du2p1CNgXV+y)nD2*HW`?wSCmf+5VuE zT~#O9^AU)rMyYZ=Q*j(}BPlr_#s;mCR*q(vet)_-xpi^{z8q~X_+ zx8t?E9K@=LXxq3pqKo!9!H*l=X{XWJH;T#Rd9|#h#FU&_EGq5oZhKg=Gr0N!IhrpI z)5^BcVBbq%!6~lPsZyG*u2mH-Z*}$kl1L1jxzlL6NpaP|8Vu)p4LY;y)NcK1alpfK^gNb&PZX6-sTb$#3Z~tlHcTm{N|SxB!G_+|Dzk{TjMh$3 z%H?7q#!cIUdUM@MANwqm8nwjOtx&J^dfk%(i8HIVb_oXT{>PhGZ_+ENX@dcJ80-TW z_;abToXy8Lnr0TkGs? zfEWRgl`ZzcHmEAci?NQdf3Jy+;x^S?aTA_nr{~J1BAy{$yH$zZ#*W3!t<&z8T8moZ z!ZPofDW{cm^_pAs`?FCpan9UkY%Ol&r0hYD59Z1DL26QG3YWtEJZkD^eRWCY0DmuE zs+H22EnRxC@ukn5nie73tf&-(Gfk!=fkEaQqc*kyXz)@@sp_`|6-8`ig(Y5O*Mzr=GT zuyix~YyTV@B%(bg-fU;8tABZ-d|V{6i(a%6i{)DfF+1b>(@Zuy&Z~p#w90SfbFYzN zx`W*zvxur}bJWdDXB$pT#e1job|V~7mu z>K5NM7BNj26|Rj+OzG+EZA_RH(vyK&*ZZwyC#E)azHRgtwch45sDEh3nb=kJ(=M9n zZG}@pj1F%?Y0Tw{*V?#|yKtxdZKXBJ*;PByJuKtftfG~Yy<~;Y=aNf3e`Yq7U3VFs z-#W}bCpCAiTq1tVCdBtJ-MOIPP~`?6j*V z<&$vg^7?>Hikn_>wSO8WMSi$kD9v)NoU6&{+%I_*po9QHPyKX%Z1@m$#T+1=0ngx5$Q(G$?vPR)DIe%BA-mx8LM&dk{tRK(1 zkUmw*i~h2^6tr4{*Sf;3&W|gAokeA?x9dzkp~rgtOGlZ-JC|K=u*zmL`T1$KN~HLF zqTE?<$%T+yEzdwAm(H;Tvq>eDX*FBe)TF^~R#^@gyG3luWt%6_nC%;@p_-p$-?RH$ zeLh*Wlj2T@4}Y2W)Sx#3lYH1%F8cdyKAPsP+e|z+Xd8QRJWg|kQ!C#o-sbsJeu35u zCSM(9CP(?kYWdYUljzHnMk7DYT$g9Cjo6(tXXZE?O*Q5=;isKcm%FBf!DM>V3(e}X z)7N6}wbLY8OlphR`z@w-&W-x2qP6P$Wy2}E`L1%?#(yVy?Z~SJUp00>fjjSb2JB)+ z=VN}A6w=pLZIT)#&gs~Dax3WT?5uq}j$@NbJ5|UI_zHiU>}95{&ga?qVbPi&a_#fz zxR0ruT8y2~^Eo*`R$Fypb7>yN@vc4`OPNAqw^|m?gYuS1HEPjx;gpV5XYae1szs0b zrQO)i+JE)dv5=kTZXKPE&j*{^__%M)YpudSJ(T;GUFkdoI#K)57LU`>pt_00W$it$ z+*Y>?Z*Ze(BC)#`qNQp%UujQMx9TjL%)Q4Cc_p^nO%wS_qMyl>a`RCtr}GVXtvU>QIiHcNW%{G2 zy6#4Ai4OMAeJDsZf@jYD@%I)f$QE$uGAr`GS2W72r++?Qlsn*PMEm^2BC9Sh+&86sK zp_Nyq(|j^+||#%LYW z@r04v%-eFQc`)L)Ua^v!ZvS82-h@k4B!6og{VVy_UH3bunySMjQ*~E=7evJgK@`+l zy}FnMnPd{V@B80x1Zt+4X`Z3_Ti4ZHC&d_d?BUs)h}iXPqx6AI82W^cr)=mhvOY^A zVvi8ck|gnJ9VeWy3&|G828o|fhE8uLg;RSmJd=6b*H^pVcy!)r+mTsr=9T5ugMam| zr4BT^-MHi&mC%hRt_iyWV5XR0@p4BZjHK`_DGO(HOG=A;$F*Q(I&+5t>`#t~7{jN? zz?ZD~Y9X9XYN*cUOS=-)!O#pXBIh4YA#8X{3HSBXyS)+f+0PbU8+(M?lwc# z2zU6l7@b$yatAD8BJsu4*-z_(sw<;SBA3I$b>_n(MqxQ#m@k} zcC5@}-u#r%{lj477QM6{NUJbDj0yh4wn4p3l?lCIP-SMhiIbNW)h9@LJAVbh3QbG7 zwfB*ooJ_^#&cSXlQ31qH*QdH(9L4Q0XAoiF?uxC)jOdwb?NZ%+o|X71HZ&Nj`KiC0?$;!vK^spTryILnw0 z_F6Vj@?gSp1F{$Ml)9mnEq`Ve%wkdktBM?JYcOn=M}jk#>jg45sM+*{v@Wqggax%+ z7WJ61FrH?5`iWqua^sF=>`a?31JPygDX!-x3+o*{xS( zV)O!Utky$9WbFQ|2RQtwV{_WA*pSC}zH1SbDA&b?MmYdf1!N`wkbkHj$M)Fq?D)*? zQYAG8RyG;zcEgHb)(DeI{YvFm*`YF1FLAT^Ksl&IST783dd^L2b951LCLqdD;jn1k z_K)^V>noKp9{5C?2Wt%gLIk6>XiVqliM>y0a>rzTX+%9_8UkO8Ci6f~yd!iG6uFNK zw~Plq3>Vw1+4+vFXn&=k1!1c(!On}c(i&`9H>=LRCaS3`heon%P4k=qogGJ(R_qIM z9c=+tJt^*S9JV8BL%QRXoYf)$9IVr7cA(N_71?n#^Ec{3-Q@ew5m|4w=BrWIBNpS( znA$bFZjhrm{dhC+8VX z5>;C`N;^*~G7zd_xKG(tZpBS7DwnjlQSj|RA`Ji^qtRN_w)5LuVS)^k5`R{PD;WfL(C#I_#Nq870-8$Al9qUP~49pO@$Pj?l58v7mx6(l;8T z?)PP9NNnt#xqn|*c4o>^WvHW|&G<#luQzTz4wlZ`6$u~lt+>RoDJ$d(?eyH#I$K+SNnx`s7Zibd&G8L7~z(}G_f2KO^mPO3~6jBHdA%gI}BP) zL0e%nG8BI=oeU}tl-?{IZDu&K+iq4wGn@9<{l+L(n|~80(JIfT663dZJdP<#wB{Ok`GT3;g6Fl`RKM(YP#%i=i-z*uT+jsXy%Pm0H^;~?3Te(yx*NA0xk zo71LQS}w!e8sWABVKSO!{#j9CchPL-V#5L}bLvrv84Ou&ME1_Zu+m2izLldQ%S2>6 zUyb%LA%CVERcu!lDW3hT7UBTQrzn!oi#(yRlvR(T(O%fq7F~I_p~vo{+IL zZ}SN0&mzC+`Q>N?{dsdP5GXU-FMCCd5#hof9n`)`ZOx*zAouX zbM#QN*!E`YogO(G+gpdElvNdt&W@zDIteO(=YND8E=f{M1%e?*=fy zvP`w6f98|YvItTldzIEQ35^u_bUAPA6#CY*H(f@~Il-%@SEaO4Z4lZyc&l+QG1@4s z%jtr#EurM=y=7M!wPNgSxvY0#f(fBR<$t;_GD$4(nlo;swm#)C!`8=v7mC)QKM3cm z0c|V#PGtZb@NE9z@y#3|2j(u^OqJ0|bo9u|<8z-jVtfVsc+?BFD|S}Q&8olEU92Ei z^A!XjcANBtb5rhf)#DeFN(GR7y`oC)h$^juP*%VKIS_(fvc!z(A_UfX&6VdQ%YRCJ zKA%bI*igp2bjXsF4De~Zq&P-JP4P@sleFj!O!u@Fh@frP0c|NjO{ybj%Id6gG6v@r z?oz9=7cwoSw^rHe_3@M*PW-{2uhwT9FBZ~@Bc!CYr(+=Zz6#|YTbHR!+Y_uIFpZ%C z#bnLx!0H8vG@NV&Ug&EJd*8?y*?&?cx?IYG=qQ`?Ksx%F4$$nr*@mIfZ&S)OgK}OH zhY`2cdd9*(`HnfIa}FWR_0S<@6z!>7C1Knp#~O@L>E2=>o&XHpYJ}X1HTTdMZ+>%LXyz=p+~xlc<u2dKUUN&o0201Kl_wjxs zax>hnPKQkp^<|XV`3_oPtL0wU_G<+5F+m4Pi6T{NQwfq1tcsM!27d>&(gZK34vS3R zZ8scEqXe++ndU;p^7pt3TAp{kNPoUSBJ%zS|s5)+p->A z5dK8stavCROxvc*+C_>*ScHdGvM`l6t}riWCv<;9_3C4>T* z>!W~%>}28yhq1EtW}?2rp6dolGOo~ll$ z=1ft&mM4n5^Xqe>NG`AvX?&8h{TLxe`7Go0G+8*2qh<7JW4W_L%u~EM_E!S3@i(3voPS(zEo)Y>@k${Z@)Lv|QEEOusmw%Xc!o<&DMWHnWH~A!a-(%uzT#U9 zg4QM}pP-_w`1xUeR{j8Dzx57MhvG#7%(&{)8T30-vkD5}#s4%#sV2bPM=?Dsa!!rRR?+yT7AR1wYIrd!aEswXAH)E0rmCVjR@TE1e)b znK++vTz{N#;-rigQ^Fhb_GT%b46~;d^?4eo!UXu80RL!3b)M=bZj{!jQN1voVE{Xk zq)Q>SK>69wFo2yHj@F(IPl}nOKqMyv`0)eIO1ESdE*C`0%T;hf(th4=XK0~0+-fB7 zld*aN;DB?6(w?@A#KPNb(+elNT8@CHhhWF(kbi~Ec&sW@oU`hfGEt|HO>TFdwB9BY zhXr;LCR6KN8ADcb7i1(%jNwZ6kAYV*<6)W+I?~K$Q`#T!1|OeDsR2s301h+7tO$AE zF!)>^Vb;!)c0yA17GVW6b9fr}Y}uTz#n81iI0w;-O_# zRDUu#NG6-CBRMJuv$;>Oq_K&DNG#00Lh{F!+{-+Sf7TRwQi|58oC#Kyg2=bb2IpM7 zV#*n^@D;(XHyalf8G^B9W~N6J7ZE#j**A+kiU}%Pjx{wtiP|KRhx-v@)(3h?5z5j@ z=LH~oRf~>IOxeCWTQRu+9Q7Eevf&bCv407$Xw*7qmxnnXOU`;HHq%6P6Wxq9IgM0< z5D6E{>57?+SBIVC=o!K9W|c|T0*&@-(WH?nz|(yhu*pdpY{TPz<(Ip7T$AMpi-{vY z%lYw^A2^HiGa!wB~>vq?uhd0?8Uu5$LW6?(fRbx34$voYwg zw`3XzM*=cfOoV{u6ESKPW$5jauy+)vJC>spJ0&a8nDn*zz*9@$`4ID^k~GfA_q~%7 zE~eR1^QhClU@)pToAwR^{s^uDvp}=$(EmCsw*BBYY{IGr>r+6a<9(%{J7UM7f4Kv-Pl9hT}~z|9cS^8 zolK>v%W%2eGOK2M8Xa1a#4xKy3~N})OeUl%018}BEpmbbNKsX5f4td=BPV2lZCMi4 zR<>KOFIDC&G7+0m6rL$6fPXU#yjTiRe_rkU^0@SOoMH1a3#{4joUsIbw&r;-A=qrh z>ZG2SsZzBmfI?nwuX{6n9~Se_lUJm*t@y)gDs$!{X9-#0r`c}A zFQNqM7RQqU*W-Ezsg}{>ZrNWXqgW7upQ=v#p_$HOj@V4&adfUinSXN8MXTqo#g_un zZjqCb?I|3|n_`L|uwp=r!Y#M8>*0JV7rhvp4@W%}IVP<&Tdn6s9gYprmVqD4k@2Zq z9r#0J16SLpPSkqccNCD;uMYnCSq-`CY^Lo zqKQ_|9hu}Sp8`%*lUH@Xl2o!eB5ODqLc?} z<>33uTywjfp0g!hjM^hK{Em*+j^H#SV&+cq6Gm9Jf|mTwYH~#}O?#h24ug8(tY4$Y zJziJmlZ5ULiGNUqam-D(xj`4Bo^s~#V@Z_95>sVkkpV>OO5OiPC&cM!wqk$dQdOC=hQH>}w;eW`h7G*75fjm!=sH`wzZV(2w zJ5b1U7l7}>zIn>VuAQw&ca$E^;vx%MX0+&s2kz{dBbC8X-!?0`CPyMZBDmN|848V& zg{QELDta!Slp)E@s>Dnd9wnY~D$$BzT$~y@ocbG2V29#tJL{Ky9FYSbcQntVsnnaD zgTdJy$$zVqCWoFk+s&z*KoCS9T1Hz)J3!~nWE2ngm6zF3T(rscwv@~yeQ9jGENfQ zJI!ec5uz#6Yirxi%U#Bt*_?=zo?DDgMXnjZ`l&vyp%lB#QuC{wE6U!k0iq8jSeIg#PG zBe~?U9(XeF99)IwjopAi^;%7NLO=7;@m3ZSaK#sntn$87Djz=N9?6^#Md8q2b5n~S9;C#88AILST&8Q;_L{uY%Qx)&~Ij4lXjYJ{_URtO5Qh%Lp4SkoH z`e=Au10x$y$DL7X(Q&<&SvtjH#)YZ`~BfU&I-;M z^lSZC(p+`k0jgvZgshonjvS8iHX|j&^5!uvr`3sWfqu`(-l@qCGlhl@XHipj$WFs8 zL)8=Be3ycwCj}WHt$%cAXqoeojq0C*G9FSvSQrK`CmjXk zVk<93NzDSPD1R{XIX_gbUQc%9k&aO1a;^n*j>l&h`bpYd7AFL~_cmt$>~_MES?Akw zp_Adf1i*uu#iWic*1T$CjiU{Yjx86m>bcFt*;I3DHupk9HC6zkVa#qnpQkj73LPSTQC9%cm|dh>`3XSOnI%$@J^nlcU!?Oejl9DnPFn?jxL)~-ozbk;>xippdR zDJEkrZhf88d#$4H$J{}f2(+(hp$s62+mtIZwT>Z~Gl>uWGUjCFnqq9BZ8VJRQM_^8 zY)d$H(#%FkCN_Cw6+!K=i*~h<{TV(QiU^J>ajESo*`08+c+r|P@6d6^jwE~LG7OWh zjm3PeE`M^pCN*cvoIMv9@}tnx)ah6m6Fv332|TIkAxED@m8m@&vdoapdx6-n2<~}a zj>g{XxF=+D8Koo;I!!O-TxEOO93e;8E)oxXx+wa>P7o~8Ua9l(WE>_sz3X9%@K`+K zIma(qb~jpjKx3h)gk_H0pADyVP~_7l(XI5j8h?|mI^y+6^x@{|@t8MPjH+q%B5_Vh z=J)b-8+(g$wXfQ;c4i!cqAIlcD2*7pTN#w&j|Q8$GI02xyv44r0z?xEESX+rF9myr@OBhjI%STdIDxI+MpkoRV^~vMJ6p zlB%pdvQCo|O;XrS+M}B+YtXdUV-s{p4(9;V#9lQT4B$q3(bS2tj`2pGczly{Syb*T zZJ053?V1>}FIvatO2oCwmRK!Ja(o_Ib$?yWJW?w;6s2Ueim1)n8OuaZI?@77_i!=h z$9=cb2nInp`w%S;BJT^6LD-AMt==y5aaBtPCSMO@P{PKH_E=!1V+a5%>T@bN6*Yny zc*-CM!=cB}8Ivj&Y_ML*m6)?M;<+Efa|%m*MQ+KUZ$RSq_ge&1KWB@at+ZW6*?+ZT zp0(*b@8WuJ^gH-VqpCox?&(S+oV zL~TUm027K6+<%rTi^)0(DVE7wIba0fX#oRiv>5A|q(^2Rr&#ToatZk6dw(@Qhx2OE zKkS#&RMsQTa%ox;DTIhiBe(e31g9p`b+4ZDgJC$Fs1&bgvPuxtBs~J{!HEGj$!xJC4~X$pppPVVvvS2q_kU7VTUtnyYH>n60^bm10}Vz%x2um+^{P z@3!k0LzwCKuqTB6w$auLm482AeVJU2T%qA zcJg~(7@m>{Gz)k^iTHyzH4g+WwE>RA@f`0BjUtl5DrcJ!ha;s%rTyWd$*QeJZ=~F% zNq9ENS9aX6o_{gzIaW~GNiM^M>-VX)Ik3`WP56A^1ks!5zH z7irNQG9<#SW7mFK4ARMX#5O+LQ>JCztGtDFsNW{a%B4AGqe5)HtuRWUOL z+h@uO*nbIqblgOv(mCwbNy+56dQ==UNl03yXR|HYvRG2-l6**bsdj2U703P|oCth5 zz|BGPt1PHD97oji!0(o+4>XI|FiUz4Xnz|47&0JpGFd0}x;?BS;kaAVq?c+( zAPzX)jJv~rK)A(V81~L|HS$?}w@BJNNtz_Dq9iV{Q+W*94EUvu*rHg|d#*!IHs=Gr zkOiu}tVM|FnY^bCn~d6}O^-FEHUa10gGmgS!Pb%K^L%hRv4?Pm5k?WFGULM7cl`&7mNY#b%h59sR!hBG3}XRs~2=k z)<8g|es;DC#Y%!zGcEj>s!&&84MJ0e?#RyIAWKa$biuHv42vlJ(x7S#MK>`)R#iNV z^!4e8^t;nRfSjDtUmjvqMNHI-x2*%#A%BK85t$ol&wv zn6O%*#g5H~MxLX~1LL9qHj^2OZybI!8v&H$G$`8JV~Q;Jm${G7v)C3$JV};kZqNi# z!jT-kL0B&kHWgL46u=Qy-lG;YZfA2;S*eC_Jx#C_SR|{~J4d3<+_+t2B{gf6F@H*u z^symI6h|2(uf1%yjyFcCDw>v$ZPLS_eZdz!Vcx1(HXZH9`u1`dN>Vd#v^tDPFqdj1 zkh2lNdRl`goU2^KcMi1e8-~F~Uz0Cqs9nfn*lcK9i~f*@j2{tSzDlY+S5Uo`hP-(Z;mvu zuB@$aQp+4YCtEU`Mk>m^H#X4`XN{JrZi?NyPR4s=5N2CdUX-ZgnF-4EP?WI%UqGP0 z5NbP!%CL6Q)D@AFq;-cug300#`ojr66eCx})0XzBcNi1$kXv@Q zoizh1$W#7cIeluuG2-rQ_1WntYgT{GM(qPR*Wup2Vc5L-D5_I)7NTZKPt{bqddO-F9R zy6{Ax8-WTA(5dQ(J5o7CQDxAjXUr5D(i$GY9M6g+hi#4of)&=PL5-N0kokW)bMrlL zYi1E7T7MjHd-Al&(G`ifx_y!o7p(yYLsrg1;N9U<1(;__C#8YcFl%dgJp-bWb!f-PQ zrFDAF5x${H6OGxLgA=yGWhb_XKM_k1Xa)_jR$ zQlT`GPqurd7U|6vwL%yk{5M(EywIIcyG+Hyl#Sjuj4tsc+qm^*)%nUpzjOo}*y zp^Tg;P?0Bx<4t>*$apJJfPqbg^fF@6Y_sEBX2K?0FgRjnz(c}F>2fZ$EcZ6QO>%&> z;$Dl#NqOeS_#oeGj84sp`vMJcZU|VGX9lNT9Xp%j z6eY2onYc{cFjx9^3k1~IPF+y;dQIa@G~aE`3v@C)u%)>_pM<`q69kbD)nsfeq0KVT z2>c%~1c$`hXu%5INC(21F9K(Z9dkLYbqbwev61)JF6n=cB2J!}nLk>O&&LwWP^~{e z$Eb%6(A;+urKGrH4~fDiDY_%${6t*yz$L;oN16H!j8C_p*FzjDpvuO<%9L4atlSVSPHDut~Z$Pn9Cvo#L5f7sqlmae+Gtg z9UjmF3E$ZWHN)2yzHxz1dfYI*o=H|F@TMhxhhy?YvAP^LS;6_ z4zz*}EosFe$8y*UsYBw>Y`JFD+pv9K3B?BO-b0;t0B8f<(bNYrTall5zWQ-&l9ILihYxQEU8~eC&4}`@dyD{kjXMtAT{r<#F z&haH4L~XF6hd5JoD^-n8l6%T#2$VUkcM}XAcI~WkKj4p|W$E^gW9NtD(4^L)VRmY) zo~d@-08fm;2UttGoYjuRGqpORMgp)EmkocJihXV)9$RRx)IEpc7?~R95~}xu5gX^` zI-W6TMehK zThoepfU3=5Hzdhs#f21JmLseNz*AskpI1dyLK~;x>1v_uGb5B z21JM0LhEO-1wa!JVxn{m8M z0(#9*y>M}B7wBKM=rL)FJI5jAdeDDn@uHfj9dGhiWySLnW~+)tZ1Q2;eIKZ%I?gMR zs;nAaV(Ds2OiNnY-P)Z2Q=I##H6lw+()QC#ci=I9*mipw9?WPE$-PyXpEDl|f_9j#3MHZ(M;p(^yUjGI7;l5F z7m8#bTAlB(q^htxc-G$mt)}LP^pYeAa$1i79$R5_%qfz@5K#{q`KiRvcxlRYT_;P0 ztBp`N%mJTD&-fyqmtMk6un;5nQ{WGlxlPJa?X}3B^`vDOGCfEyl=6R-lW%wHM^Tx} z??#6O?ye8X(pnb`gD#c_ZOu3v6-c9ZYA)cN_cXz6l+_4UH(r@uXsPv{f-;8K6;6hPOc49qAni??@L z`)>LCTaftgE}ec=xOh|eQQmoYc{jWg{BnnNH_+||Z}2}B1OFl6f0|#O&QHI-n#QkB z1o+{4wfEf*?{2|OFP{a*n&c#6QjR`k^k?eM1jOG&t@FMq!t!#|&}r~m!tS(oJD@y+dD<-2=^{`otv%vapp zOY`{2OwLcX8QE3TC0;I`((dx}z=m0d;GO7yR+(d#?w@~8v0Ls_=aPN&cA@^Cm+SBU zd~#B^cuLapRUb|Yn+HRO*Sud6^;}zlSwe#nX1^&+ue)?Vyw^*+-Y{ z14+4d(q$aG)PGE@YZih_pD#&v-R4U_GK*&#KWD82qj**JK1D2lpFFio2$aDT=*2Yw z^i6nS+OvNsN>5!f_2%FR5L-?9p&dy1bNk>D9Z;jDY{1>)p~cg2panzvgIy zNu+{>_R?FI3bc6DUzarg)!07s8O%z1O&FiM$0`6!`+B7J>EGY9{!5n+zUvzfym(GG z`ds;Mf0NVF{q1is{gMr-bIa%ubW8;(mUr35%qM@%cHs)c3B%O4&n-YYys#=vO!_C( zx`1oVr0Qq{#`TlE4mlU>f@BO<6Be6{?X^miq)W>T_3+8XbLr#Qj;C*{@~#D_rG2-}mw7pMUPl_=S)D;RN+l;Qap6DL1ps z&42pm^H1ROk4pxKt^geKPyhS}dU^D^nAw%M>-ndreeQa{e+o@d*3N^h{H;y{n9T9- zpZ>WrGdKwal=}y2zO?iY6b$B{_d|U*e8YeJRJ%`ERd&iHDPTem^XWSFj=9q!=vXv> zS$tuRS;!gnH6JpZ!_zgZ#k;m;z|R+|!<4sO-uAwxT^0`7CeY$%(50Khp25>U|FL&X z=bwN6{M)yw+_mtEW>5duZPc&R-onpq62AdJs0g?xSBjEc^8$-E1A#PIL1z&c}b`ja&~jf%lk)ZKT<60Ac>$AFb{`&^Ju?NS+|i zpE{9vNsIkJ>zx7sUSRsqTZ(mP&+in_Mb|x)gO`Nq4>NVY?d$WWJBIx9%hMlUzI^%D z<8;dRN_`D1%G;)Hw(y~9&vF2{^K)lEZ4>+l7KV1a!`UwQc1`WvneLnF=+b|IKeq!@ zvOjf}6X=YqVdxA3Fl5kl-kZz|sxn;biLaa>g=v)`6Wm$XoAm{KT+`h+PuBSvhymyv zMDLq@G`YMR{x8p2+Mh8(kpw{FbOtL;qRZspQ4JIyi5^z9n3G68t(C5N+pZ@3? zD}jbLoqv7amu2=F3Yg8b4^V&6dH@%EvC|kmR&LQDPL#t)mL@3l(#)@c2Y9~@Z1>lo z_%%ph;6k?uF(f@Gw@(7t!p{$F*c+~b!~FdT4HVP)??BlDVFLf84*I18L-?GSb>N$2 znty@h<9!z<8~b1X>*>Ef{{x`cf1ZNGNl!n2nQK}JrWF7E0mJ_G3JQP1?*8}paq!Pi zzkNF?{ex8JfbGATMEu>-eSbRfw^bh{7JqK)-3+f{Ke*tZvGdDI;?^HcRrxj>_niR$iBE}qPwyk^0KN#9Es)cCL8f4@tPsllgT6hI>&_uoj;_T-sS z@it>6{5(k223(UWiBf<2aFcSN2_7keyAK%D7z%n~Mqh5Fzg!x5n9L4z0ow|a%6&%p zce(EGY5txXw=8+rpDrm0bu)S&?zncfhsaA@%x@t0!(QMxu50zBGe}>qm;(Cx(Coc+ z^}j*j$EnxvdI9Y^sa?TA!C=poNrm&+dB?XOBze9YF%ZcCaBY7|n9L6NB|y0CD6kKo zetFD|uYB{DKi>+_|H)jh@7D6$317kT!Sb(7iUT~&@{;xW=8#^^pcf=T(Yg3<(m_An z5*=rkiGiN4;{1AkFVg)kL1Epo*dsZ6#ffn0dG$!v-ZLyH+qL?bZ;L%ZJpU2TT2KPt zGVTBT^7I3fdM$r>&{e(G`Bvh|R|%2tTKOO(bS?gt{a)f7m+yDcjt3^?LG3P5^7P;T z{RIE{{ptVxpPyk9C?M}YULay-miym-nx+1iviRu<1vnHkiwlwL9Ru9u%Y;9R9YRRo zn6g*2e13c@`(9)^`gmplAk+!~04O*~6nT|A61-a*w|*WhI_L@hdi6U|!nx`EF5`5XKj6blQSI{cZ{L%OwWBRy>wE2Y zLG)K`2Q*jL=% z$ZhVBx?O*;3{o1vu;e+`9V8H+!#s@dTkKjAx`uv~NX`D{eQf4431HWy+X2-N6U2fF zU(yU{txu!D3Ml?h=!YaM^Yhn|*us_ocVz$)yDOj^p*HDeav{khL)ek@@nfK_?fuuX zIm6F4kjht@zt(&|=HI_P>aQ^YT+pW~kBV0-UjTo9tbCO|{`!H%*Ln1#t9*@H{inik z4HcEC2#2wpeg5>E67A7txd32U6~IS`(onlqF6y~2TeS1W&Iq6wtu~ZiQuR{;}rG_K~cZJf4@*a ze8e=6nBYjv&(xQ6WU<- z$^Zt79oNqxKza-vyCymwd}zN;SLfp|@ELzFCKnF-(zS3iDF6N6A8V{@dC=)0D1Wq8 zoVGt)rTEbr>3xOowSizh{ts)h|33|SH^2{U`p0Z|_tOoI-GTq|!c$+FEnwmP4TW{3 zJC41gF8E^T5%PkhxuCn}y1zd(aj>1wuyogSkUYX{AE#@7Q1}nn(7!(a{Nbv-MV^0O zvZ~mBhP6Igr7kekc^Y6f#z|2^!TtR67dOuVwEfio0HZzu*bifszucufzrCCK4Z5da z>GB=zKJcyHuKVk+kVdatdPtS8x$^IL!MNz6ZuA9wy9`<24ujvd)#Y(dW8h^3RuBc{ z`Gcjus<)TbzteZ$TKl`Ae_a3m+TwqIw3M*w=TEn}eaAv}La;Y$7tGkHY~Y97DRsEI z*TH;`us(JmUoZFrpYbNmFTUcPmw4x;-Ie+0k zFYccS{;2?7Nf2FBgd1n@of}vw8*T;o<+_c*d=5-r-tl*9bQci$TlW?gzV&~5@^aJf z-UE1Gnok|t{c^XucRhf1YZo{TmRSUL7n6T!4ZdH$Izmoo;;$*}p=N#h6GF~kq2~Vm zr;b+v8vFuZS;BXoKmGa3b2FEM9Sr&Xrwf>QF5i6x;8rX1ZYR`Fe|~uqZoOUJ@57hM zH5m8HEGN%zbOD(&xU~g__@94+^mpOu)n%UUSA6-mdshCR%*@TWTUxjw#O~gX-6r1A z_Da0_sOJ49lIMPIoqvXHJq{3bz5L#F_AsUv6ti3K>5=y83PtHP&l4km9z8caY))4BVjG1@vHJ(BpN!ZmNQd)cx_D`=^#2c`kc8yb3Dhd;SB+ z9tsVRS)ht8(Z`QAHa(aH;E~(Yi|~CNCEb~%8&iJG)_!^yo%~7^5zgu|h7aiSVEF%r zj2J}k`0$%-(0!3s^Vxs%uFQwsztrv&*R}S`R?b xI?hHGpTK8RDbp^QS*vbl$%{ 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 z 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%0D)7C>Gg@$vPb21NU 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 + getData(): any; + setData(data: any): void; + /** + * Processes the downloaded data. Meant to be overridden. + */ + processData(data: any): any; + /** + * Wires engine into loadable to receive game level events + */ + wireEngine(engine: Engine): void; + /** + * onprogress handler + */ + onprogress: (e: any) => void; + /** + * oncomplete handler + */ + oncomplete: () => void; + /** + * onerror handler + */ + onerror: (e: any) => void; + /** + * Returns true if the loadable is loaded + */ + isLoaded(): boolean; } } declare module ex { /** - * Triggers + * Generic Resources * - * Triggers are a method of firing arbitrary code on collision. These are useful - * as 'buttons', 'switches', or to trigger effects in a game. By default triggers - * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * The [[Resource]] type allows games built in Excalibur to load generic resources. + * For any type of remote resource it is recommended to use [[Resource]] for preloading. * - * ## Creating a trigger + * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before + * a level or game. * - * ```js - * var game = new ex.Game(); + * Example usages: JSON, compressed files, blobs. * - * // create a handler - * function onTrigger() { + * ## Pre-loading generic resources * - * // `this` will be the Trigger instance - * ex.Logger.getInstance().info("Trigger was triggered!", this); - * } + * ```js + * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); + * var loader = new ex.Loader(resLevel1); * - * // set a trigger at (100, 100) that is 40x40px - * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * // attach a handler to process once loaded + * resLevel1.processData = function (data) { * - * // create an actor across from the trigger - * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * // process JSON + * var json = JSON.parse(data); * - * // tell the actor to move towards the trigger over 3 seconds - * actor.moveTo(100, 200, 3000); + * // create a new level (inherits Scene) with the JSON configuration + * var level = new Level(json); * - * game.add(trigger); - * game.add(actor); + * // add a new scene + * game.add(level.name, level); + * } * - * game.start(); + * game.start(loader); * ``` */ - class Trigger extends Actor { - private _action; - repeats: number; - target: Actor; + class Resource extends Class implements ILoadable { + path: string; + responseType: string; + bustCache: boolean; + data: T; + logger: Logger; + private _engine; /** - * @param x The x position of the trigger - * @param y The y position of the trigger - * @param width The width of the trigger - * @param height The height of the trigger - * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance - * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely + * @param path Path to the remote resource + * @param responseType The Content-Type to expect (e.g. `application/json`) + * @param bustCache Whether or not to cache-bust requests */ - constructor(x?: number, y?: number, width?: number, height?: number, action?: () => void, repeats?: number); - update(engine: Engine, delta: number): void; - private _dispatchAction(); - draw(ctx: CanvasRenderingContext2D, delta: number): void; - debugDraw(ctx: CanvasRenderingContext2D): void; - } -} -declare module ex { - /** - * An enum that represents the types of emitter nozzles - */ - enum EmitterType { + constructor(path: string, responseType: string, bustCache?: boolean); /** - * Constant for the circular emitter type + * Returns true if the Resource is completely loaded and is ready + * to be drawn. */ - Circle = 0, + isLoaded(): boolean; + wireEngine(engine: Engine): void; + private _cacheBust(uri); + private _start(e); /** - * Constant for the rectangular emitter type + * Begin loading the resource and returns a promise to be resolved on completion */ - Rectangle = 1, + load(): Promise; + /** + * Returns the loaded data once the resource is loaded + */ + getData(): any; + /** + * Sets the data for this resource directly + */ + setData(data: any): void; + /** + * This method is meant to be overriden to handle any additional + * processing. Such as decoding downloaded audio bits. + */ + processData(data: T): any; + onprogress: (e: any) => void; + oncomplete: () => void; + onerror: (e: any) => void; } +} +declare module ex { /** - * Particle is used in a [[ParticleEmitter]] + * Valid states for a promise to be in */ - class Particle { - position: Vector; - velocity: Vector; - acceleration: Vector; - particleRotationalVelocity: number; - currentRotation: number; - focus: Vector; - focusAccel: number; - opacity: number; - beginColor: Color; - endColor: Color; - life: number; - fadeFlag: boolean; - private _rRate; - private _gRate; - private _bRate; - private _aRate; - private _currentColor; - emitter: ParticleEmitter; - particleSize: number; - particleSprite: Sprite; - startSize: number; - endSize: number; - sizeRate: number; - elapsedMultiplier: number; - constructor(emitter: ParticleEmitter, life?: number, opacity?: number, beginColor?: Color, endColor?: Color, position?: Vector, velocity?: Vector, acceleration?: Vector, startSize?: number, endSize?: number); - kill(): void; - update(delta: number): void; - draw(ctx: CanvasRenderingContext2D): void; + enum PromiseState { + Resolved = 0, + Rejected = 1, + Pending = 2, + } + interface IPromise { + then(successCallback?: (value?: T) => any, rejectCallback?: (value?: T) => any): IPromise; + error(rejectCallback?: (value?: any) => any): IPromise; + resolve(value?: T): IPromise; + reject(value?: any): IPromise; + state(): PromiseState; } /** - * Particle Emitters + * Promises/A+ spec implementation of promises * - * Using a particle emitter is a great way to create interesting effects - * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` - * extend [[Actor]] allowing you to use all of the features that come with. + * Promises are used to do asynchronous work and they are useful for + * creating a chain of actions. In Excalibur they are used for loading, + * sounds, animation, actions, and more. * - * The easiest way to create a `ParticleEmitter` is to use the - * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. + * ## A Promise Chain * - * ## Example: Adding an emitter + * Promises can be chained together and can be useful for creating a queue + * of functions to be called when something is done. * - * ```js - * var actor = new ex.Actor(...); - * var emitter = new ex.ParticleEmitter(...); + * The first [[Promise]] you will encounter is probably [[Engine.start]] + * which resolves when the game has finished loading. * - * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle - * emitter.radius = 5; - * emitter.minVel = 100; - * emitter.maxVel = 200; - * emitter.minAngle = 0; - * emitter.maxAngle = Math.PI * 2; - * emitter.emitRate = 300; // 300 particles/second - * emitter.opacity = 0.5; - * emitter.fadeFlag = true; // fade particles overtime - * emitter.particleLife = 1000; // in milliseconds = 1 sec - * emitter.maxSize = 10; // in pixels - * emitter.minSize = 1; - * emitter.particleColor = ex.Color.Rose; + * ```js + * var game = new ex.Engine(); * - * // set emitter settings - * emitter.isEmitting = true; // should the emitter be emitting + * // perform start-up logic once game is ready + * game.start().then(function () { * - * // add the emitter as a child actor, it will draw on top of the parent actor - * // and move with the parent - * actor.add(emitter); + * // start-up & initialization logic * - * // or, alternatively, add it to the current scene - * engine.add(emitter); + * }); * ``` - */ - class ParticleEmitter extends Actor { - private _particlesToEmit; - numParticles: number; - /** - * Gets or sets the isEmitting flag - */ - isEmitting: boolean; - /** - * Gets or sets the backing particle collection - */ - particles: Util.Collection; - /** - * Gets or sets the backing deadParticle collection - */ - deadParticles: Util.Collection; - /** - * Gets or sets the minimum partical velocity - */ - minVel: number; - /** - * Gets or sets the maximum partical velocity - */ - maxVel: number; - /** - * Gets or sets the acceleration vector for all particles - */ - acceleration: Vector; - /** - * Gets or sets the minimum angle in radians - */ - minAngle: number; - /** - * Gets or sets the maximum angle in radians - */ - maxAngle: number; - /** - * Gets or sets the emission rate for particles (particles/sec) - */ - emitRate: number; - /** - * Gets or sets the life of each particle in milliseconds - */ - particleLife: number; - /** - * Gets or sets the opacity of each particle from 0 to 1.0 - */ - opacity: number; + * + * ## Handling errors + * + * You can optionally pass an error handler to [[Promise.then]] which will handle + * any errors that occur during Promise execution. + * + * ```js + * var game = new ex.Engine(); + * + * game.start().then( + * // success handler + * function () { + * }, + * + * // error handler + * function (err) { + * } + * ); + * ``` + * + * Any errors that go unhandled will be bubbled up to the browser. + */ + class Promise implements IPromise { + private _state; + private _value; + private _successCallbacks; + private _rejectCallback; + private _errorCallback; + private _logger; /** - * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. + * Wrap a value in a resolved promise + * @param value An optional value to wrap in a resolved promise */ - fadeFlag: boolean; + static wrap(value?: T): Promise; /** - * Gets or sets the optional focus where all particles should accelerate towards + * Returns a new promise that resolves when all the promises passed to it resolve, or rejects + * when at least 1 promise rejects. */ - focus: Vector; + static join(...promises: Promise[]): Promise; /** - * Gets or sets the acceleration for focusing particles if a focus has been specified + * Chain success and reject callbacks after the promise is resovled + * @param successCallback Call on resolution of promise + * @param rejectCallback Call on rejection of promise */ - focusAccel: number; - startSize: number; - endSize: number; + then(successCallback?: (value?: T) => any, rejectCallback?: (value?: any) => any): Promise; /** - * Gets or sets the minimum size of all particles + * Add an error callback to the promise + * @param errorCallback Call if there was an error in a callback */ - minSize: number; + error(errorCallback?: (value?: any) => any): Promise; /** - * Gets or sets the maximum size of all particles + * Resolve the promise and pass an option value to the success callbacks + * @param value Value to pass to the success callbacks */ - maxSize: number; + resolve(value?: T): Promise; /** - * Gets or sets the beginning color of all particles + * Reject the promise and pass an option value to the reject callbacks + * @param value Value to pass to the reject callbacks */ - beginColor: Color; + reject(value?: any): Promise; /** - * Gets or sets the ending color of all particles + * Inpect the current state of a promise */ - endColor: Color; + state(): PromiseState; + private _handleError(e); + } +} +declare module ex { + /** + * Textures + * + * The [[Texture]] object allows games built in Excalibur to load image resources. + * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] + * to pre-load before starting a level or game. + * + * Textures are the raw image so to add a drawing to a game, you must create + * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite + * instance. + * + * ## Pre-loading textures + * + * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] + * is loaded, you can generate a [[Sprite]] with it. + * + * ```js + * var txPlayer = new ex.Texture("/assets/tx/player.png"); + * + * var loader = new ex.Loader(txPlayer); + * + * game.start(loader).then(function () { + * + * var player = new ex.Actor(); + * + * player.addDrawing(txPlayer); + * + * game.add(player); + * }); + * ``` + */ + class Texture extends Resource { + path: string; + bustCache: boolean; /** - * Gets or sets the sprite that a particle should use - * @warning Performance intensive + * The width of the texture in pixels */ - particleSprite: ex.Sprite; + width: number; /** - * Gets or sets the emitter type for the particle emitter + * The height of the texture in pixels */ - emitterType: ex.EmitterType; + height: number; /** - * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] + * A [[Promise]] that resolves when the Texture is loaded. */ - radius: number; + loaded: Promise; + private _isLoaded; + private _sprite; /** - * Gets or sets the particle rotational speed velocity + * Populated once loading is complete */ - particleRotationalVelocity: number; + image: HTMLImageElement; + private _progressCallback; + private _doneCallback; + private _errorCallback; /** - * Indicates whether particles should start with a random rotation + * @param path Path to the image resource + * @param bustCache Optionally load texture with cache busting */ - randomRotation: boolean; + constructor(path: string, bustCache?: boolean); /** - * @param x The x position of the emitter - * @param y The y position of the emitter - * @param width The width of the emitter - * @param height The height of the emitter + * Returns true if the Texture is completely loaded and is ready + * to be drawn. */ - constructor(x?: number, y?: number, width?: number, height?: number); - removeParticle(particle: Particle): void; + isLoaded(): boolean; /** - * Causes the emitter to emit particles - * @param particleCount Number of particles to emit right now + * Begins loading the texture and returns a promise to be resolved on completion */ - emitParticles(particleCount: number): void; - clearParticles(): void; - private _createParticle(); - update(engine: Engine, delta: number): void; - draw(ctx: CanvasRenderingContext2D, delta: number): void; - debugDraw(ctx: CanvasRenderingContext2D): void; + load(): Promise; + asSprite(): Sprite; } } declare module ex { /** - * Animations + * Sounds * - * Animations allow you to display a series of images one after another, - * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. + * The [[Sound]] object allows games built in Excalibur to load audio + * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] + * which means it can be passed to a [[Loader]] to pre-load before a game or level. * - * ## Creating an animation + * ## Pre-loading sounds * - * Create a [[Texture]] that contains the frames of your animation. Once the texture - * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] - * and using [[SpriteSheet.getAnimationForAll]]. + * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] + * is loaded, you can [[Sound.play|play]] it. * * ```js - * var game = new ex.Engine(); - * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); + * // define multiple sources (such as mp3/wav/ogg) as a browser fallback + * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); * - * // load assets - * var loader = new ex.Loader(txAnimPlayerIdle); + * var loader = new ex.Loader(sndPlayerDeath); * - * // start game * game.start(loader).then(function () { - * var player = new ex.Actor(); - * - * // create sprite sheet with 5 columns, 1 row, 80x80 frames - * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); - * - * // create animation (125ms frame speed) - * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); * - * // add drawing to player as "idle" - * player.addDrawing("idle", playerIdleAnimation); - * - * // add player to game - * game.add(player); + * sndPlayerDeath.play(); * }); * ``` - * - * ## Sprite effects - * - * You can add [[SpriteEffect|sprite effects]] to an animation through methods - * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this - * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - class Animation implements IDrawable { + class Sound implements ILoadable, ex.Internal.ISound { + private _logger; + path: string; + onprogress: (e: any) => void; + oncomplete: () => void; + onerror: (e: any) => void; + onload: (e: any) => void; + private _isLoaded; + private _engine; + private _wasPlayingOnHidden; /** - * The sprite frames to play, in order. See [[SpriteSheet.getAnimationForAll]] to quickly - * generate an [[Animation]]. + * Populated once loading is complete */ - sprites: Sprite[]; + sound: ex.Internal.FallbackAudio; /** - * Duration to show each frame (in milliseconds) + * Whether or not the browser can play this file as HTML5 Audio */ - speed: number; + static canPlayFile(file: string): boolean; /** - * Current frame index being shown + * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. */ - currentFrame: number; - private _oldTime; - anchor: Point; - rotation: number; - scale: Point; - /** - * Indicates whether the animation should loop after it is completed + constructor(...paths: string[]); + wireEngine(engine: Engine): void; + /** + * Sets the volume of the sound clip + * @param volume A volume value between 0-1.0 */ - loop: boolean; + setVolume(volume: number): void; /** - * Indicates the frame index the animation should freeze on for a non-looping - * animation. By default it is the last frame. + * Indicates whether the clip should loop when complete + * @param loop Set the looping flag */ - freezeFrame: number; - private _engine; + setLoop(loop: boolean): void; /** - * Flip each frame vertically. Sets [[Sprite.flipVertical]]. + * Whether or not the sound is playing right now */ - flipVertical: boolean; + isPlaying(): boolean; /** - * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + * Play the sound, returns a promise that resolves when the sound is done playing */ - flipHorizontal: boolean; - width: number; - height: number; - naturalWidth: number; - naturalHeight: number; + play(): ex.Promise; /** - * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. - * - * @param engine Reference to the current game engine - * @param images An array of sprites to create the frames for the animation - * @param speed The number in milliseconds to display each frame in the animation - * @param loop Indicates whether the animation should loop after it is completed + * Stop the sound, and do not rewind */ - constructor(engine: Engine, images: Sprite[], speed: number, loop?: boolean); + pause(): void; /** - * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + * Stop the sound and rewind */ - opacity(value: number): void; + stop(): void; /** - * Applies the grayscale effect to a sprite, removing color information. + * Returns true if the sound is loaded */ - grayscale(): void; + isLoaded(): boolean; /** - * Applies the invert effect to a sprite, inverting the pixel colors. + * Begins loading the sound and returns a promise to be resolved on completion */ - invert(): void; + load(): Promise; + getData(): any; + setData(data: any): void; + processData(data: any): any; + } +} +declare module ex { + /** + * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does + * not participate in collisions. Drawn on top of all other actors. + */ + class UIActor extends Actor { + protected _engine: Engine; /** - * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color + * @param x The starting x coordinate of the actor + * @param y The starting y coordinate of the actor + * @param width The starting width of the actor + * @param height The starting height of the actor */ - fill(color: Color): void; + constructor(x?: number, y?: number, width?: number, height?: number); + onInitialize(engine: Engine): void; + contains(x: number, y: number, useWorld?: boolean): boolean; + } +} +declare module ex { + /** + * Triggers + * + * Triggers are a method of firing arbitrary code on collision. These are useful + * as 'buttons', 'switches', or to trigger effects in a game. By default triggers + * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * + * ## Creating a trigger + * + * ```js + * var game = new ex.Game(); + * + * // create a handler + * function onTrigger() { + * + * // `this` will be the Trigger instance + * ex.Logger.getInstance().info("Trigger was triggered!", this); + * } + * + * // set a trigger at (100, 100) that is 40x40px + * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * + * // create an actor across from the trigger + * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * + * // tell the actor to move towards the trigger over 3 seconds + * actor.moveTo(100, 200, 3000); + * + * game.add(trigger); + * game.add(actor); + * + * game.start(); + * ``` + */ + class Trigger extends Actor { + private _action; + repeats: number; + target: Actor; /** - * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the - * provided color. + * @param x The x position of the trigger + * @param y The y position of the trigger + * @param width The width of the trigger + * @param height The height of the trigger + * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance + * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely */ - colorize(color: Color): void; + constructor(x?: number, y?: number, width?: number, height?: number, action?: () => void, repeats?: number); + update(engine: Engine, delta: number): void; + private _dispatchAction(); + draw(ctx: CanvasRenderingContext2D, delta: number): void; + debugDraw(ctx: CanvasRenderingContext2D): void; + } +} +declare module ex { + /** + * An enum that represents the types of emitter nozzles + */ + enum EmitterType { /** - * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl + * Constant for the circular emitter type */ - lighten(factor?: number): void; + Circle = 0, /** - * Applies the darken effect to a sprite, changes the darkness of the color according to hsl + * Constant for the rectangular emitter type */ - darken(factor?: number): void; + Rectangle = 1, + } + /** + * Particle is used in a [[ParticleEmitter]] + */ + class Particle { + position: Vector; + velocity: Vector; + acceleration: Vector; + particleRotationalVelocity: number; + currentRotation: number; + focus: Vector; + focusAccel: number; + opacity: number; + beginColor: Color; + endColor: Color; + life: number; + fadeFlag: boolean; + private _rRate; + private _gRate; + private _bRate; + private _aRate; + private _currentColor; + emitter: ParticleEmitter; + particleSize: number; + particleSprite: Sprite; + startSize: number; + endSize: number; + sizeRate: number; + elapsedMultiplier: number; + constructor(emitter: ParticleEmitter, life?: number, opacity?: number, beginColor?: Color, endColor?: Color, position?: Vector, velocity?: Vector, acceleration?: Vector, startSize?: number, endSize?: number); + kill(): void; + update(delta: number): void; + draw(ctx: CanvasRenderingContext2D): void; + } + /** + * Particle Emitters + * + * Using a particle emitter is a great way to create interesting effects + * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` + * extend [[Actor]] allowing you to use all of the features that come with. + * + * The easiest way to create a `ParticleEmitter` is to use the + * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. + * + * ## Example: Adding an emitter + * + * ```js + * var actor = new ex.Actor(...); + * var emitter = new ex.ParticleEmitter(...); + * + * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle + * emitter.radius = 5; + * emitter.minVel = 100; + * emitter.maxVel = 200; + * emitter.minAngle = 0; + * emitter.maxAngle = Math.PI * 2; + * emitter.emitRate = 300; // 300 particles/second + * emitter.opacity = 0.5; + * emitter.fadeFlag = true; // fade particles overtime + * emitter.particleLife = 1000; // in milliseconds = 1 sec + * emitter.maxSize = 10; // in pixels + * emitter.minSize = 1; + * emitter.particleColor = ex.Color.Rose; + * + * // set emitter settings + * emitter.isEmitting = true; // should the emitter be emitting + * + * // add the emitter as a child actor, it will draw on top of the parent actor + * // and move with the parent + * actor.add(emitter); + * + * // or, alternatively, add it to the current scene + * engine.add(emitter); + * ``` + */ + class ParticleEmitter extends Actor { + private _particlesToEmit; + numParticles: number; /** - * Applies the saturate effect to a sprite, saturates the color acccording to hsl + * Gets or sets the isEmitting flag */ - saturate(factor?: number): void; + isEmitting: boolean; /** - * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl + * Gets or sets the backing particle collection */ - desaturate(factor?: number): void; + particles: Util.Collection; /** - * Add a [[ISpriteEffect]] manually + * Gets or sets the backing deadParticle collection */ - addEffect(effect: Effects.ISpriteEffect): void; + deadParticles: Util.Collection; /** - * Removes an [[ISpriteEffect]] from this animation. - * @param effect Effect to remove from this animation + * Gets or sets the minimum partical velocity */ - removeEffect(effect: Effects.ISpriteEffect): void; + minVel: number; /** - * Removes an effect given the index from this animation. - * @param index Index of the effect to remove from this animation + * Gets or sets the maximum partical velocity */ - removeEffect(index: number): void; + maxVel: number; /** - * Clear all sprite effects + * Gets or sets the acceleration vector for all particles */ - clearEffects(): void; - private _setAnchor(point); - private _setRotation(radians); - private _setScale(scale); + acceleration: Vector; /** - * Resets the animation to first frame. + * Gets or sets the minimum angle in radians */ - reset(): void; + minAngle: number; /** - * Indicates whether the animation is complete, animations that loop are never complete. + * Gets or sets the maximum angle in radians */ - isDone(): boolean; + maxAngle: number; /** - * Not meant to be called by game developers. Ticks the animation forward internally and - * calculates whether to change to the frame. - * @internal + * Gets or sets the emission rate for particles (particles/sec) */ - tick(): void; - private _updateValues(); + emitRate: number; /** - * Skips ahead a specified number of frames in the animation - * @param frames Frames to skip ahead + * Gets or sets the life of each particle in milliseconds */ - skip(frames: number): void; - draw(ctx: CanvasRenderingContext2D, x: number, y: number): void; + particleLife: number; /** - * Plays an animation at an arbitrary location in the game. - * @param x The x position in the game to play - * @param y The y position in the game to play + * Gets or sets the opacity of each particle from 0 to 1.0 */ - play(x: number, y: number): void; - } -} -declare module ex.Internal { - interface ISound { - setVolume(volume: number): any; - setLoop(loop: boolean): any; - isPlaying(): boolean; - play(): ex.Promise; - pause(): any; - stop(): any; - load(): any; - setData(data: any): any; - getData(): any; - processData(data: any): any; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - path: string; - } - class FallbackAudio implements ISound { - path: string; - private _soundImpl; - private _log; - constructor(path: string, volume?: number); - setVolume(volume: number): void; - setLoop(loop: boolean): void; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - load(): void; - processData(data: any): any; - getData(): any; - setData(data: any): void; - isPlaying(): boolean; - play(): ex.Promise; - pause(): void; - stop(): void; - } - class AudioTag implements ISound { - path: string; - private _audioElements; - private _loadedAudio; - private _isLoaded; - private _index; - private _log; - private _isPlaying; - private _playingTimer; - private _currentOffset; - constructor(path: string, volume?: number); - isPlaying(): boolean; - private _audioLoaded(); - setVolume(volume: number): void; - setLoop(loop: boolean): void; - getLoop(): void; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - load(): void; - getData(): any; - setData(data: any): void; - processData(data: any): any; - play(): Promise; - pause(): void; - stop(): void; - } - class WebAudio implements ISound { - path: string; - private _context; - private _volume; - private _buffer; - private _sound; - private _isLoaded; - private _loop; - private _isPlaying; - private _isPaused; - private _playingTimer; - private _currentOffset; - private _playPromise; - private _logger; - private _data; - constructor(path: string, volume?: number); - setVolume(volume: number): void; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - load(): void; - getData(): any; - setData(data: any): void; - processData(data: any): any; - setLoop(loop: boolean): void; - isPlaying(): boolean; - play(): Promise; - pause(): void; - stop(): void; - } -} -declare module ex { - /** - * Valid states for a promise to be in - */ - enum PromiseState { - Resolved = 0, - Rejected = 1, - Pending = 2, - } - interface IPromise { - then(successCallback?: (value?: T) => any, rejectCallback?: (value?: T) => any): IPromise; - error(rejectCallback?: (value?: any) => any): IPromise; - resolve(value?: T): IPromise; - reject(value?: any): IPromise; - state(): PromiseState; - } - /** - * Promises/A+ spec implementation of promises - * - * Promises are used to do asynchronous work and they are useful for - * creating a chain of actions. In Excalibur they are used for loading, - * sounds, animation, actions, and more. - * - * ## A Promise Chain - * - * Promises can be chained together and can be useful for creating a queue - * of functions to be called when something is done. - * - * The first [[Promise]] you will encounter is probably [[Engine.start]] - * which resolves when the game has finished loading. - * - * ```js - * var game = new ex.Engine(); - * - * // perform start-up logic once game is ready - * game.start().then(function () { - * - * // start-up & initialization logic - * - * }); - * ``` - * - * ## Handling errors - * - * You can optionally pass an error handler to [[Promise.then]] which will handle - * any errors that occur during Promise execution. - * - * ```js - * var game = new ex.Engine(); - * - * game.start().then( - * // success handler - * function () { - * }, - * - * // error handler - * function (err) { - * } - * ); - * ``` - * - * Any errors that go unhandled will be bubbled up to the browser. - */ - class Promise implements IPromise { - private _state; - private _value; - private _successCallbacks; - private _rejectCallback; - private _errorCallback; - private _logger; + opacity: number; /** - * Wrap a value in a resolved promise - * @param value An optional value to wrap in a resolved promise + * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. */ - static wrap(value?: T): Promise; + fadeFlag: boolean; /** - * Returns a new promise that resolves when all the promises passed to it resolve, or rejects - * when at least 1 promise rejects. + * Gets or sets the optional focus where all particles should accelerate towards */ - static join(...promises: Promise[]): Promise; + focus: Vector; /** - * Chain success and reject callbacks after the promise is resovled - * @param successCallback Call on resolution of promise - * @param rejectCallback Call on rejection of promise + * Gets or sets the acceleration for focusing particles if a focus has been specified */ - then(successCallback?: (value?: T) => any, rejectCallback?: (value?: any) => any): Promise; + focusAccel: number; + startSize: number; + endSize: number; /** - * Add an error callback to the promise - * @param errorCallback Call if there was an error in a callback + * Gets or sets the minimum size of all particles */ - error(errorCallback?: (value?: any) => any): Promise; + minSize: number; /** - * Resolve the promise and pass an option value to the success callbacks - * @param value Value to pass to the success callbacks + * Gets or sets the maximum size of all particles */ - resolve(value?: T): Promise; + maxSize: number; /** - * Reject the promise and pass an option value to the reject callbacks - * @param value Value to pass to the reject callbacks + * Gets or sets the beginning color of all particles */ - reject(value?: any): Promise; + beginColor: Color; /** - * Inpect the current state of a promise + * Gets or sets the ending color of all particles */ - state(): PromiseState; - private _handleError(e); - } -} -declare module ex { - /** - * Loadables - * - * An interface describing loadable resources in Excalibur. Built-in loadable - * resources include [[Texture]], [[Sound]], and a generic [[Resource]]. - * - * ## Advanced: Custom loadables - * - * You can implement the [[ILoadable]] interface to create your own custom loadables. - * This is an advanced feature, as the [[Resource]] class already wraps logic around - * blob/plain data for usages like JSON, configuration, levels, etc through XHR (Ajax). - * - * However, as long as you implement the facets of a loadable, you can create your - * own. - */ - interface ILoadable { + endColor: Color; /** - * Begins loading the resource and returns a promise to be resolved on completion + * Gets or sets the sprite that a particle should use + * @warning Performance intensive */ - load(): Promise; - getData(): any; - setData(data: any): void; + particleSprite: ex.Sprite; /** - * Processes the downloaded data. Meant to be overridden. + * Gets or sets the emitter type for the particle emitter */ - processData(data: any): any; + emitterType: ex.EmitterType; /** - * Wires engine into loadable to receive game level events + * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] */ - wireEngine(engine: Engine): void; + radius: number; /** - * onprogress handler + * Gets or sets the particle rotational speed velocity */ - onprogress: (e: any) => void; + particleRotationalVelocity: number; /** - * oncomplete handler + * Indicates whether particles should start with a random rotation */ - oncomplete: () => void; + randomRotation: boolean; /** - * onerror handler + * @param x The x position of the emitter + * @param y The y position of the emitter + * @param width The width of the emitter + * @param height The height of the emitter */ - onerror: (e: any) => void; + constructor(x?: number, y?: number, width?: number, height?: number); + removeParticle(particle: Particle): void; /** - * Returns true if the loadable is loaded + * Causes the emitter to emit particles + * @param particleCount Number of particles to emit right now */ - isLoaded(): boolean; + emitParticles(particleCount: number): void; + clearParticles(): void; + private _createParticle(); + update(engine: Engine, delta: number): void; + draw(ctx: CanvasRenderingContext2D, delta: number): void; + debugDraw(ctx: CanvasRenderingContext2D): void; } } declare module ex { /** - * Generic Resources - * - * The [[Resource]] type allows games built in Excalibur to load generic resources. - * For any type of remote resource it is recommended to use [[Resource]] for preloading. + * Animations * - * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before - * a level or game. + * Animations allow you to display a series of images one after another, + * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. * - * Example usages: JSON, compressed files, blobs. + * ## Creating an animation * - * ## Pre-loading generic resources + * Create a [[Texture]] that contains the frames of your animation. Once the texture + * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] + * and using [[SpriteSheet.getAnimationForAll]]. * * ```js - * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); - * var loader = new ex.Loader(resLevel1); + * var game = new ex.Engine(); + * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); * - * // attach a handler to process once loaded - * resLevel1.processData = function (data) { + * // load assets + * var loader = new ex.Loader(txAnimPlayerIdle); * - * // process JSON - * var json = JSON.parse(data); + * // start game + * game.start(loader).then(function () { + * var player = new ex.Actor(); * - * // create a new level (inherits Scene) with the JSON configuration - * var level = new Level(json); + * // create sprite sheet with 5 columns, 1 row, 80x80 frames + * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); * - * // add a new scene - * game.add(level.name, level); - * } + * // create animation (125ms frame speed) + * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); * - * game.start(loader); + * // add drawing to player as "idle" + * player.addDrawing("idle", playerIdleAnimation); + * + * // add player to game + * game.add(player); + * }); * ``` + * + * ## Sprite effects + * + * You can add [[SpriteEffect|sprite effects]] to an animation through methods + * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this + * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - class Resource extends Class implements ILoadable { - path: string; - responseType: string; - bustCache: boolean; - data: T; - logger: Logger; - private _engine; + class Animation implements IDrawable { /** - * @param path Path to the remote resource - * @param responseType The Content-Type to expect (e.g. `application/json`) - * @param bustCache Whether or not to cache-bust requests + * The sprite frames to play, in order. See [[SpriteSheet.getAnimationForAll]] to quickly + * generate an [[Animation]]. */ - constructor(path: string, responseType: string, bustCache?: boolean); + sprites: Sprite[]; /** - * Returns true if the Resource is completely loaded and is ready - * to be drawn. + * Duration to show each frame (in milliseconds) */ - isLoaded(): boolean; - wireEngine(engine: Engine): void; - private _cacheBust(uri); - private _start(e); + speed: number; /** - * Begin loading the resource and returns a promise to be resolved on completion + * Current frame index being shown */ - load(): Promise; + currentFrame: number; + private _oldTime; + anchor: Point; + rotation: number; + scale: Point; /** - * Returns the loaded data once the resource is loaded + * Indicates whether the animation should loop after it is completed */ - getData(): any; + loop: boolean; /** - * Sets the data for this resource directly + * Indicates the frame index the animation should freeze on for a non-looping + * animation. By default it is the last frame. */ - setData(data: any): void; + freezeFrame: number; + private _engine; /** - * This method is meant to be overriden to handle any additional - * processing. Such as decoding downloaded audio bits. + * Flip each frame vertically. Sets [[Sprite.flipVertical]]. */ - processData(data: T): any; - onprogress: (e: any) => void; - oncomplete: () => void; - onerror: (e: any) => void; - } -} -declare module ex { - /** - * Textures - * - * The [[Texture]] object allows games built in Excalibur to load image resources. - * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] - * to pre-load before starting a level or game. - * - * Textures are the raw image so to add a drawing to a game, you must create - * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite - * instance. - * - * ## Pre-loading textures - * - * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] - * is loaded, you can generate a [[Sprite]] with it. - * - * ```js - * var txPlayer = new ex.Texture("/assets/tx/player.png"); - * - * var loader = new ex.Loader(txPlayer); - * - * game.start(loader).then(function () { - * - * var player = new ex.Actor(); - * - * player.addDrawing(txPlayer); - * - * game.add(player); - * }); - * ``` - */ - class Texture extends Resource { - path: string; - bustCache: boolean; + flipVertical: boolean; /** - * The width of the texture in pixels + * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. */ + flipHorizontal: boolean; width: number; + height: number; + naturalWidth: number; + naturalHeight: number; /** - * The height of the texture in pixels + * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. + * + * @param engine Reference to the current game engine + * @param images An array of sprites to create the frames for the animation + * @param speed The number in milliseconds to display each frame in the animation + * @param loop Indicates whether the animation should loop after it is completed */ - height: number; + constructor(engine: Engine, images: Sprite[], speed: number, loop?: boolean); /** - * A [[Promise]] that resolves when the Texture is loaded. + * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value */ - loaded: Promise; - private _isLoaded; - private _sprite; + opacity(value: number): void; + /** + * Applies the grayscale effect to a sprite, removing color information. + */ + grayscale(): void; + /** + * Applies the invert effect to a sprite, inverting the pixel colors. + */ + invert(): void; /** - * Populated once loading is complete + * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color */ - image: HTMLImageElement; - private _progressCallback; - private _doneCallback; - private _errorCallback; + fill(color: Color): void; /** - * @param path Path to the image resource - * @param bustCache Optionally load texture with cache busting + * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the + * provided color. */ - constructor(path: string, bustCache?: boolean); + colorize(color: Color): void; /** - * Returns true if the Texture is completely loaded and is ready - * to be drawn. + * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl */ - isLoaded(): boolean; + lighten(factor?: number): void; /** - * Begins loading the texture and returns a promise to be resolved on completion + * Applies the darken effect to a sprite, changes the darkness of the color according to hsl */ - load(): Promise; - asSprite(): Sprite; - } - /** - * Sounds - * - * The [[Sound]] object allows games built in Excalibur to load audio - * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] - * which means it can be passed to a [[Loader]] to pre-load before a game or level. - * - * ## Pre-loading sounds - * - * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] - * is loaded, you can [[Sound.play|play]] it. - * - * ```js - * // define multiple sources (such as mp3/wav/ogg) as a browser fallback - * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); - * - * var loader = new ex.Loader(sndPlayerDeath); - * - * game.start(loader).then(function () { - * - * sndPlayerDeath.play(); - * }); - * ``` - */ - class Sound implements ILoadable, ex.Internal.ISound { - private _logger; - path: string; - onprogress: (e: any) => void; - oncomplete: () => void; - onerror: (e: any) => void; - onload: (e: any) => void; - private _isLoaded; - private _engine; - private _wasPlayingOnHidden; + darken(factor?: number): void; /** - * Populated once loading is complete + * Applies the saturate effect to a sprite, saturates the color acccording to hsl */ - sound: ex.Internal.FallbackAudio; + saturate(factor?: number): void; /** - * Whether or not the browser can play this file as HTML5 Audio + * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl */ - static canPlayFile(file: string): boolean; + desaturate(factor?: number): void; /** - * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. + * Add a [[ISpriteEffect]] manually */ - constructor(...paths: string[]); - wireEngine(engine: Engine): void; + addEffect(effect: Effects.ISpriteEffect): void; /** - * Sets the volume of the sound clip - * @param volume A volume value between 0-1.0 + * Removes an [[ISpriteEffect]] from this animation. + * @param effect Effect to remove from this animation */ - setVolume(volume: number): void; + removeEffect(effect: Effects.ISpriteEffect): void; /** - * Indicates whether the clip should loop when complete - * @param loop Set the looping flag + * Removes an effect given the index from this animation. + * @param index Index of the effect to remove from this animation */ - setLoop(loop: boolean): void; + removeEffect(index: number): void; /** - * Whether or not the sound is playing right now + * Clear all sprite effects */ - isPlaying(): boolean; + clearEffects(): void; + private _setAnchor(point); + private _setRotation(radians); + private _setScale(scale); /** - * Play the sound, returns a promise that resolves when the sound is done playing + * Resets the animation to first frame. */ - play(): ex.Promise; + reset(): void; /** - * Stop the sound, and do not rewind + * Indicates whether the animation is complete, animations that loop are never complete. */ - pause(): void; + isDone(): boolean; /** - * Stop the sound and rewind + * Not meant to be called by game developers. Ticks the animation forward internally and + * calculates whether to change to the frame. + * @internal */ - stop(): void; + tick(): void; + private _updateValues(); /** - * Returns true if the sound is loaded + * Skips ahead a specified number of frames in the animation + * @param frames Frames to skip ahead */ - isLoaded(): boolean; + skip(frames: number): void; + draw(ctx: CanvasRenderingContext2D, x: number, y: number): void; /** - * Begins loading the sound and returns a promise to be resolved on completion + * Plays an animation at an arbitrary location in the game. + * @param x The x position in the game to play + * @param y The y position in the game to play */ - load(): Promise; + play(x: number, y: number): void; + } +} +declare module ex.Internal { + interface ISound { + setVolume(volume: number): any; + setLoop(loop: boolean): any; + isPlaying(): boolean; + play(): ex.Promise; + pause(): any; + stop(): any; + load(): any; + setData(data: any): any; + getData(): any; + processData(data: any): any; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + path: string; + } + class FallbackAudio implements ISound { + path: string; + private _soundImpl; + private _log; + constructor(path: string, volume?: number); + setVolume(volume: number): void; + setLoop(loop: boolean): void; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + load(): void; + processData(data: any): any; + getData(): any; + setData(data: any): void; + isPlaying(): boolean; + play(): ex.Promise; + pause(): void; + stop(): void; + } + class AudioTag implements ISound { + path: string; + private _audioElements; + private _loadedAudio; + private _isLoaded; + private _index; + private _log; + private _isPlaying; + private _playingTimer; + private _currentOffset; + constructor(path: string, volume?: number); + isPlaying(): boolean; + private _audioLoaded(); + setVolume(volume: number): void; + setLoop(loop: boolean): void; + getLoop(): void; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + load(): void; + getData(): any; + setData(data: any): void; + processData(data: any): any; + play(): Promise; + pause(): void; + stop(): void; + } + class WebAudio implements ISound { + path: string; + private _context; + private _volume; + private _buffer; + private _sound; + private _isLoaded; + private _loop; + private _isPlaying; + private _isPaused; + private _playingTimer; + private _currentOffset; + private _playPromise; + private _logger; + private _data; + constructor(path: string, volume?: number); + setVolume(volume: number): void; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + load(): void; getData(): any; setData(data: any): void; processData(data: any): any; + setLoop(loop: boolean): void; + isPlaying(): boolean; + play(): Promise; + pause(): void; + stop(): void; + private static _unlocked; + /** + * Play an empty sound to unlock Safari WebAudio context. Call this function + * right after a user interaction event. Typically used by [[PauseAfterLoader]] + * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/ + */ + static unlock(): void; + static isUnlocked(): boolean; + } +} +declare module ex { + interface ILoader extends ILoadable { + draw(ctx: CanvasRenderingContext2D, delta: number): any; + update(engine: Engine, delta: number): any; } +} +declare module ex { /** * Pre-loading assets * @@ -5275,7 +5293,7 @@ declare module ex { * }); * ``` */ - class Loader implements ILoadable { + class Loader extends Class implements ILoader { private _resourceList; private _index; private _resourceCount; @@ -5308,6 +5326,15 @@ declare module ex { * that resolves when loading of all is complete */ load(): Promise; + /** + * Loader draw function. Draws the default Excalibur loading screen. Override to customize the drawing. + */ + draw(ctx: CanvasRenderingContext2D, delta: number): void; + /** + * Perform any calculations or logic in the `update` method. The default `Loader` does not + * do anything in this method so it is safe to override. + */ + update(engine: ex.Engine, delta: number): void; getData: () => any; setData: (data: any) => any; processData: (data: any) => any; @@ -5315,6 +5342,91 @@ declare module ex { oncomplete: () => void; onerror: () => void; } + /** + * A [[Loader]] that pauses after loading to allow user + * to proceed to play the game. Typically you will + * want to use this loader for iOS to allow sounds + * to play after loading (Apple Safari requires user + * interaction to allow sounds, even for games) + * + * **Note:** Because Loader is not part of a Scene, you must + * call `update` and `draw` manually on "child" objects. + * + * ## Implementing a Trigger + * + * The `PauseAfterLoader` requires an element to act as the trigger button + * to start the game. + * + * For example, let's create an `` tag to be our trigger and call it `tap-to-play`. + * + * ```html + * + * ``` + * + * We've put it inside a wrapper to position it properly over the game canvas. + * + * Now let's add some CSS to style it (insert into ``): + * + * ```html + * + * ``` + * + * Now we can create a `PauseAfterLoader` with a reference to our trigger button: + * + * ```ts + * var loader = new ex.PauseAfterLoader('tap-to-play', [...]); + * ``` + * + * ## Use PauseAfterLoader for iOS + * + * The primary use case for pausing before starting the game is to + * pass Apple's requirement of user interaction. The Web Audio context + * in Safari is disabled by default until user interaction. + * + * Therefore, you can use this snippet to only use PauseAfterLoader when + * iOS is detected (see [this thread](http://stackoverflow.com/questions/9038625/detect-if-device-is-ios) + * for more techniques). + * + * ```ts + * var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window).MSStream; + * var loader: ex.Loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); + * + * loader.addResource(...); + * ``` + */ + class PauseAfterLoader extends Loader { + private _loaded; + private _loadedValue; + private _waitPromise; + private _playTrigger; + constructor(triggerElementId: string, loadables?: ILoadable[]); + load(): Promise; + private _handleOnTrigger; + } } declare module ex { class Detector { @@ -6828,9 +6940,6 @@ declare module ex { private _compatible; private _loader; private _isLoading; - private _progress; - private _total; - private _loadingDraw; /** * Creates a new game using the given [[IEngineOptions]] */ @@ -7036,10 +7145,10 @@ declare module ex { /** * Starts the internal game loop for Excalibur after loading * any provided assets. - * @param loader Optional resources to load before starting the main loop. Some [[ILoadable]] such as a [[Loader]] collection, - * [[Sound]], or [[Texture]]. + * @param loader Optional [[ILoader]] to use to load resources. The default loader is [[Loader]], override to provide your own + * custom loader. */ - start(loader?: ILoadable): Promise; + start(loader?: ILoader): Promise; /** * Stops Excalibur's main loop, useful for pausing the game. */ @@ -7049,19 +7158,6 @@ declare module ex { * HTML Image Element. */ screenshot(): HTMLImageElement; - /** - * Draws the Excalibur loading bar - * @param ctx The canvas rendering context - * @param loaded Number of bytes loaded - * @param total Total number of bytes to load - */ - private _drawLoadingBar(ctx, loaded, total); - /** - * Sets the loading screen draw function if you want to customize the draw - * @param fcn Callback to draw the loading screen which is passed a rendering context, the number of bytes loaded, and the total - * number of bytes to load. - */ - setLoadingDrawFunction(fcn: (ctx: CanvasRenderingContext2D, loaded: number, total: number) => void): void; /** * Another option available to you to load resources into the game. * Immediately after calling this the game will pause and the loading screen diff --git a/dist/Excalibur.js b/dist/Excalibur.js index b62b46962..d36c58af0 100644 --- a/dist/Excalibur.js +++ b/dist/Excalibur.js @@ -8213,1769 +8213,1816 @@ var ex; return HSLColor; })(); })(ex || (ex = {})); -/// -var ex; -(function (ex) { - /** - * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does - * not participate in collisions. Drawn on top of all other actors. - */ - var UIActor = (function (_super) { - __extends(UIActor, _super); - /** - * @param x The starting x coordinate of the actor - * @param y The starting y coordinate of the actor - * @param width The starting width of the actor - * @param height The starting height of the actor - */ - function UIActor(x, y, width, height) { - _super.call(this, x, y, width, height); - this.traits = []; - this.traits.push(new ex.Traits.Movement()); - this.traits.push(new ex.Traits.CapturePointer()); - this.anchor.setTo(0, 0); - this.collisionType = ex.CollisionType.PreventCollision; - this.enableCapturePointer = true; - } - UIActor.prototype.onInitialize = function (engine) { - this._engine = engine; - }; - UIActor.prototype.contains = function (x, y, useWorld) { - if (useWorld === void 0) { useWorld = true; } - if (useWorld) { - return _super.prototype.contains.call(this, x, y); - } - var coords = this._engine.worldToScreenCoordinates(new ex.Point(x, y)); - return _super.prototype.contains.call(this, coords.x, coords.y); - }; - return UIActor; - })(ex.Actor); - ex.UIActor = UIActor; -})(ex || (ex = {})); -/// -/// +/// var ex; (function (ex) { /** - * Triggers + * Generic Resources * - * Triggers are a method of firing arbitrary code on collision. These are useful - * as 'buttons', 'switches', or to trigger effects in a game. By default triggers - * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * The [[Resource]] type allows games built in Excalibur to load generic resources. + * For any type of remote resource it is recommended to use [[Resource]] for preloading. * - * ## Creating a trigger + * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before + * a level or game. * - * ```js - * var game = new ex.Game(); + * Example usages: JSON, compressed files, blobs. * - * // create a handler - * function onTrigger() { + * ## Pre-loading generic resources * - * // `this` will be the Trigger instance - * ex.Logger.getInstance().info("Trigger was triggered!", this); - * } + * ```js + * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); + * var loader = new ex.Loader(resLevel1); * - * // set a trigger at (100, 100) that is 40x40px - * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * // attach a handler to process once loaded + * resLevel1.processData = function (data) { * - * // create an actor across from the trigger - * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * // process JSON + * var json = JSON.parse(data); * - * // tell the actor to move towards the trigger over 3 seconds - * actor.moveTo(100, 200, 3000); + * // create a new level (inherits Scene) with the JSON configuration + * var level = new Level(json); * - * game.add(trigger); - * game.add(actor); + * // add a new scene + * game.add(level.name, level); + * } * - * game.start(); + * game.start(loader); * ``` */ - var Trigger = (function (_super) { - __extends(Trigger, _super); + var Resource = (function (_super) { + __extends(Resource, _super); /** - * @param x The x position of the trigger - * @param y The y position of the trigger - * @param width The width of the trigger - * @param height The height of the trigger - * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance - * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely + * @param path Path to the remote resource + * @param responseType The Content-Type to expect (e.g. `application/json`) + * @param bustCache Whether or not to cache-bust requests */ - function Trigger(x, y, width, height, action, repeats) { - _super.call(this, x, y, width, height); - this._action = function () { return; }; - this.repeats = 1; - this.target = null; - this.repeats = repeats || this.repeats; - this._action = action || this._action; - this.collisionType = ex.CollisionType.PreventCollision; - this.eventDispatcher = new ex.EventDispatcher(this); - this.actionQueue = new ex.Internal.Actions.ActionQueue(this); + function Resource(path, responseType, bustCache) { + if (bustCache === void 0) { bustCache = true; } + _super.call(this); + this.path = path; + this.responseType = responseType; + this.bustCache = bustCache; + this.data = null; + this.logger = ex.Logger.getInstance(); + this.onprogress = function () { return; }; + this.oncomplete = function () { return; }; + this.onerror = function () { return; }; } - Trigger.prototype.update = function (engine, delta) { - // Update action queue - this.actionQueue.update(delta); - // Update placements based on linear algebra - this.x += this.dx * delta / 1000; - this.y += this.dy * delta / 1000; - this.rotation += this.rx * delta / 1000; - this.scale.x += this.sx * delta / 1000; - this.scale.y += this.sy * delta / 1000; - // check for trigger collisions - if (this.target) { - if (this.collides(this.target)) { - this._dispatchAction(); - } + /** + * Returns true if the Resource is completely loaded and is ready + * to be drawn. + */ + Resource.prototype.isLoaded = function () { + return this.data !== null; + }; + Resource.prototype.wireEngine = function (engine) { + this._engine = engine; + }; + Resource.prototype._cacheBust = function (uri) { + var query = /\?\w*=\w*/; + if (query.test(uri)) { + uri += ('&__=' + Date.now()); } else { - for (var i = 0; i < engine.currentScene.children.length; i++) { - var other = engine.currentScene.children[i]; - if (other !== this && - other.collisionType !== ex.CollisionType.PreventCollision && - this.collides(other)) { - this._dispatchAction(); - } - } + uri += ('?__=' + Date.now()); } - // remove trigger if its done, -1 repeat forever - if (this.repeats === 0) { - this.kill(); + return uri; + }; + Resource.prototype._start = function (e) { + this.logger.debug('Started loading resource ' + this.path); + }; + /** + * Begin loading the resource and returns a promise to be resolved on completion + */ + Resource.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + // Exit early if we already have data + if (this.data !== null) { + this.logger.debug('Already have data for resource', this.path); + complete.resolve(this.data); + this.oncomplete(); + return complete; } + var request = new XMLHttpRequest(); + request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true); + request.responseType = this.responseType; + request.onloadstart = function (e) { _this._start(e); }; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function (e) { + if (request.status !== 200) { + _this.logger.error('Failed to load resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + complete.resolve(request.response); + return; + } + _this.data = _this.processData(request.response); + _this.oncomplete(); + _this.logger.debug('Completed loading resource', _this.path); + complete.resolve(_this.data); + }; + request.send(); + return complete; }; - Trigger.prototype._dispatchAction = function () { - this._action.call(this); - this.repeats--; + /** + * Returns the loaded data once the resource is loaded + */ + Resource.prototype.getData = function () { + return this.data; }; - Trigger.prototype.draw = function (ctx, delta) { - // does not draw - return; + /** + * Sets the data for this resource directly + */ + Resource.prototype.setData = function (data) { + this.data = this.processData(data); }; - Trigger.prototype.debugDraw = function (ctx) { - _super.prototype.debugDraw.call(this, ctx); - // Meant to draw debug information about actors - ctx.save(); - ctx.translate(this.x, this.y); - var bb = this.getBounds(); - bb.left = bb.left - this.getWorldX(); - bb.right = bb.right - this.getWorldX(); - bb.top = bb.top - this.getWorldY(); - bb.bottom = bb.bottom - this.getWorldY(); - // Currently collision primitives cannot rotate - // ctx.rotate(this.rotation); - ctx.fillStyle = ex.Color.Violet.toString(); - ctx.strokeStyle = ex.Color.Violet.toString(); - ctx.fillText('Trigger', 10, 10); - bb.debugDraw(ctx); - ctx.restore(); + /** + * This method is meant to be overriden to handle any additional + * processing. Such as decoding downloaded audio bits. + */ + Resource.prototype.processData = function (data) { + // Handle any additional loading after the xhr has completed. + return URL.createObjectURL(data); }; - return Trigger; - })(ex.Actor); - ex.Trigger = Trigger; + return Resource; + })(ex.Class); + ex.Resource = Resource; })(ex || (ex = {})); -/// -/// -/// -/// +/// +// Promises/A+ Spec http://promises-aplus.github.io/promises-spec/ var ex; (function (ex) { /** - * An enum that represents the types of emitter nozzles + * Valid states for a promise to be in */ - (function (EmitterType) { - /** - * Constant for the circular emitter type - */ - EmitterType[EmitterType["Circle"] = 0] = "Circle"; - /** - * Constant for the rectangular emitter type - */ - EmitterType[EmitterType["Rectangle"] = 1] = "Rectangle"; - })(ex.EmitterType || (ex.EmitterType = {})); - var EmitterType = ex.EmitterType; - /** - * Particle is used in a [[ParticleEmitter]] - */ - var Particle = (function () { - function Particle(emitter, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) { - this.position = new ex.Vector(0, 0); - this.velocity = new ex.Vector(0, 0); - this.acceleration = new ex.Vector(0, 0); - this.particleRotationalVelocity = 0; - this.currentRotation = 0; - this.focus = null; - this.focusAccel = 0; - this.opacity = 1; - this.beginColor = ex.Color.White.clone(); - this.endColor = ex.Color.White.clone(); - // Life is counted in ms - this.life = 300; - this.fadeFlag = false; - // Color transitions - this._rRate = 1; - this._gRate = 1; - this._bRate = 1; - this._aRate = 0; - this._currentColor = ex.Color.White.clone(); - this.emitter = null; - this.particleSize = 5; - this.particleSprite = null; - this.sizeRate = 0; - this.elapsedMultiplier = 0; - this.emitter = emitter; - this.life = life || this.life; - this.opacity = opacity || this.opacity; - this.endColor = endColor || this.endColor.clone(); - this.beginColor = beginColor || this.beginColor.clone(); - this._currentColor = this.beginColor.clone(); - this.position = position || this.position; - this.velocity = velocity || this.velocity; - this.acceleration = acceleration || this.acceleration; - this._rRate = (this.endColor.r - this.beginColor.r) / this.life; - this._gRate = (this.endColor.g - this.beginColor.g) / this.life; - this._bRate = (this.endColor.b - this.beginColor.b) / this.life; - this._aRate = this.opacity / this.life; - this.startSize = startSize || 0; - this.endSize = endSize || 0; - if ((this.endSize > 0) && (this.startSize > 0)) { - this.sizeRate = (this.endSize - this.startSize) / this.life; - this.particleSize = this.startSize; - } - } - Particle.prototype.kill = function () { - this.emitter.removeParticle(this); - }; - Particle.prototype.update = function (delta) { - this.life = this.life - delta; - this.elapsedMultiplier = this.elapsedMultiplier + delta; - if (this.life < 0) { - this.kill(); - } - if (this.fadeFlag) { - this.opacity = ex.Util.clamp(this._aRate * this.life, 0.0001, 1); - } - if ((this.startSize > 0) && (this.endSize > 0)) { - this.particleSize = ex.Util.clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize)); - } - this._currentColor.r = ex.Util.clamp(this._currentColor.r + this._rRate * delta, 0, 255); - this._currentColor.g = ex.Util.clamp(this._currentColor.g + this._gRate * delta, 0, 255); - this._currentColor.b = ex.Util.clamp(this._currentColor.b + this._bRate * delta, 0, 255); - this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); - if (this.focus) { - var accel = this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(delta / 1000); - this.velocity = this.velocity.add(accel); - } - else { - this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000)); - } - this.position = this.position.add(this.velocity.scale(delta / 1000)); - if (this.particleRotationalVelocity) { - this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI); - } - }; - Particle.prototype.draw = function (ctx) { - if (this.particleSprite) { - this.particleSprite.rotation = this.currentRotation; - this.particleSprite.scale.setTo(this.particleSize, this.particleSize); - this.particleSprite.draw(ctx, this.position.x, this.position.y); - return; - } - this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); - ctx.fillStyle = this._currentColor.toString(); - ctx.beginPath(); - ctx.arc(this.position.x, this.position.y, this.particleSize, 0, Math.PI * 2); - ctx.fill(); - ctx.closePath(); - }; - return Particle; - })(); - ex.Particle = Particle; + (function (PromiseState) { + PromiseState[PromiseState["Resolved"] = 0] = "Resolved"; + PromiseState[PromiseState["Rejected"] = 1] = "Rejected"; + PromiseState[PromiseState["Pending"] = 2] = "Pending"; + })(ex.PromiseState || (ex.PromiseState = {})); + var PromiseState = ex.PromiseState; /** - * Particle Emitters + * Promises/A+ spec implementation of promises * - * Using a particle emitter is a great way to create interesting effects - * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` - * extend [[Actor]] allowing you to use all of the features that come with. + * Promises are used to do asynchronous work and they are useful for + * creating a chain of actions. In Excalibur they are used for loading, + * sounds, animation, actions, and more. * - * The easiest way to create a `ParticleEmitter` is to use the - * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. + * ## A Promise Chain * - * ## Example: Adding an emitter + * Promises can be chained together and can be useful for creating a queue + * of functions to be called when something is done. + * + * The first [[Promise]] you will encounter is probably [[Engine.start]] + * which resolves when the game has finished loading. * * ```js - * var actor = new ex.Actor(...); - * var emitter = new ex.ParticleEmitter(...); + * var game = new ex.Engine(); * - * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle - * emitter.radius = 5; - * emitter.minVel = 100; - * emitter.maxVel = 200; - * emitter.minAngle = 0; - * emitter.maxAngle = Math.PI * 2; - * emitter.emitRate = 300; // 300 particles/second - * emitter.opacity = 0.5; - * emitter.fadeFlag = true; // fade particles overtime - * emitter.particleLife = 1000; // in milliseconds = 1 sec - * emitter.maxSize = 10; // in pixels - * emitter.minSize = 1; - * emitter.particleColor = ex.Color.Rose; + * // perform start-up logic once game is ready + * game.start().then(function () { * - * // set emitter settings - * emitter.isEmitting = true; // should the emitter be emitting + * // start-up & initialization logic * - * // add the emitter as a child actor, it will draw on top of the parent actor - * // and move with the parent - * actor.add(emitter); + * }); + * ``` * - * // or, alternatively, add it to the current scene - * engine.add(emitter); + * ## Handling errors + * + * You can optionally pass an error handler to [[Promise.then]] which will handle + * any errors that occur during Promise execution. + * + * ```js + * var game = new ex.Engine(); + * + * game.start().then( + * // success handler + * function () { + * }, + * + * // error handler + * function (err) { + * } + * ); * ``` + * + * Any errors that go unhandled will be bubbled up to the browser. */ - var ParticleEmitter = (function (_super) { - __extends(ParticleEmitter, _super); + var Promise = (function () { + function Promise() { + this._state = PromiseState.Pending; + this._successCallbacks = []; + this._rejectCallback = function () { return; }; + this._logger = ex.Logger.getInstance(); + } /** - * @param x The x position of the emitter - * @param y The y position of the emitter - * @param width The width of the emitter - * @param height The height of the emitter + * Wrap a value in a resolved promise + * @param value An optional value to wrap in a resolved promise */ - function ParticleEmitter(x, y, width, height) { - _super.call(this, x, y, width, height, ex.Color.White); - this._particlesToEmit = 0; - this.numParticles = 0; - /** - * Gets or sets the isEmitting flag - */ - this.isEmitting = true; - /** - * Gets or sets the backing particle collection - */ - this.particles = null; - /** - * Gets or sets the backing deadParticle collection - */ - this.deadParticles = null; - /** - * Gets or sets the minimum partical velocity - */ - this.minVel = 0; - /** - * Gets or sets the maximum partical velocity - */ - this.maxVel = 0; - /** - * Gets or sets the acceleration vector for all particles - */ - this.acceleration = new ex.Vector(0, 0); - /** - * Gets or sets the minimum angle in radians - */ - this.minAngle = 0; - /** - * Gets or sets the maximum angle in radians - */ - this.maxAngle = 0; - /** - * Gets or sets the emission rate for particles (particles/sec) - */ - this.emitRate = 1; //particles/sec - /** - * Gets or sets the life of each particle in milliseconds - */ - this.particleLife = 2000; - /** - * Gets or sets the opacity of each particle from 0 to 1.0 - */ - this.opacity = 1; - /** - * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. - */ - this.fadeFlag = false; - /** - * Gets or sets the optional focus where all particles should accelerate towards - */ - this.focus = null; - /** - * Gets or sets the acceleration for focusing particles if a focus has been specified - */ - this.focusAccel = 1; - /* - * Gets or sets the optional starting size for the particles - */ - this.startSize = null; - /* - * Gets or sets the optional ending size for the particles - */ - this.endSize = null; - /** - * Gets or sets the minimum size of all particles - */ - this.minSize = 5; - /** - * Gets or sets the maximum size of all particles - */ - this.maxSize = 5; - /** - * Gets or sets the beginning color of all particles - */ - this.beginColor = ex.Color.White; - /** - * Gets or sets the ending color of all particles - */ - this.endColor = ex.Color.White; - /** - * Gets or sets the sprite that a particle should use - * @warning Performance intensive - */ - this.particleSprite = null; - /** - * Gets or sets the emitter type for the particle emitter - */ - this.emitterType = EmitterType.Rectangle; - /** - * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] - */ - this.radius = 0; - /** - * Gets or sets the particle rotational speed velocity - */ - this.particleRotationalVelocity = 0; - /** - * Indicates whether particles should start with a random rotation - */ - this.randomRotation = false; - this.collisionType = ex.CollisionType.PreventCollision; - this.particles = new ex.Util.Collection(); - this.deadParticles = new ex.Util.Collection(); - // Remove offscreen culling from particle emitters - for (var trait in this.traits) { - if (this.traits[trait] instanceof ex.Traits.OffscreenCulling) { - this.traits.splice(trait, 1); - } - } - } - ParticleEmitter.prototype.removeParticle = function (particle) { - this.deadParticles.push(particle); + Promise.wrap = function (value) { + var promise = (new Promise()).resolve(value); + return promise; }; /** - * Causes the emitter to emit particles - * @param particleCount Number of particles to emit right now + * Returns a new promise that resolves when all the promises passed to it resolve, or rejects + * when at least 1 promise rejects. */ - ParticleEmitter.prototype.emitParticles = function (particleCount) { - for (var i = 0; i < particleCount; i++) { - this.particles.push(this._createParticle()); + Promise.join = function () { + var promises = []; + for (var _i = 0; _i < arguments.length; _i++) { + promises[_i - 0] = arguments[_i]; } + var joinedPromise = new Promise(); + if (!promises || !promises.length) { + return joinedPromise.resolve(); + } + var total = promises.length; + var successes = 0; + var rejects = 0; + var errors = []; + promises.forEach(function (p) { + p.then(function () { + successes += 1; + if (successes === total) { + joinedPromise.resolve(); + } + else if (successes + rejects + errors.length === total) { + joinedPromise.reject(errors); + } + }, function () { + rejects += 1; + if (successes + rejects + errors.length === total) { + joinedPromise.reject(errors); + } + }).error(function (e) { + errors.push(e); + if ((errors.length + successes + rejects) === total) { + joinedPromise.reject(errors); + } + }); + }); + return joinedPromise; }; - ParticleEmitter.prototype.clearParticles = function () { - this.particles.clear(); - }; - // Creates a new particle given the contraints of the emitter - ParticleEmitter.prototype._createParticle = function () { - // todo implement emitter contraints; - var ranX = 0; - var ranY = 0; - var angle = ex.Util.randomInRange(this.minAngle, this.maxAngle); - var vel = ex.Util.randomInRange(this.minVel, this.maxVel); - var size = this.startSize || ex.Util.randomInRange(this.minSize, this.maxSize); - var dx = vel * Math.cos(angle); - var dy = vel * Math.sin(angle); - if (this.emitterType === EmitterType.Rectangle) { - ranX = ex.Util.randomInRange(this.x, this.x + this.getWidth()); - ranY = ex.Util.randomInRange(this.y, this.y + this.getHeight()); + /** + * Chain success and reject callbacks after the promise is resovled + * @param successCallback Call on resolution of promise + * @param rejectCallback Call on rejection of promise + */ + Promise.prototype.then = function (successCallback, rejectCallback) { + if (successCallback) { + this._successCallbacks.push(successCallback); + // If the promise is already resovled call immediately + if (this.state() === PromiseState.Resolved) { + try { + successCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); + } + } } - else if (this.emitterType === EmitterType.Circle) { - var radius = ex.Util.randomInRange(0, this.radius); - ranX = radius * Math.cos(angle) + this.x; - ranY = radius * Math.sin(angle) + this.y; + if (rejectCallback) { + this._rejectCallback = rejectCallback; + // If the promise is already rejected call immediately + if (this.state() === PromiseState.Rejected) { + try { + rejectCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); + } + } } - var p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new ex.Vector(ranX, ranY), new ex.Vector(dx, dy), this.acceleration, this.startSize, this.endSize); - p.fadeFlag = this.fadeFlag; - p.particleSize = size; - if (this.particleSprite) { - p.particleSprite = this.particleSprite; + return this; + }; + /** + * Add an error callback to the promise + * @param errorCallback Call if there was an error in a callback + */ + Promise.prototype.error = function (errorCallback) { + if (errorCallback) { + this._errorCallback = errorCallback; } - p.particleRotationalVelocity = this.particleRotationalVelocity; - if (this.randomRotation) { - p.currentRotation = ex.Util.randomInRange(0, Math.PI * 2); + return this; + }; + /** + * Resolve the promise and pass an option value to the success callbacks + * @param value Value to pass to the success callbacks + */ + Promise.prototype.resolve = function (value) { + var _this = this; + if (this._state === PromiseState.Pending) { + this._value = value; + try { + this._state = PromiseState.Resolved; + this._successCallbacks.forEach(function (cb) { + cb.call(_this, _this._value); + }); + } + catch (e) { + this._handleError(e); + } } - if (this.focus) { - p.focus = this.focus.add(new ex.Vector(this.x, this.y)); - p.focusAccel = this.focusAccel; + else { + throw new Error('Cannot resolve a promise that is not in a pending state!'); } - return p; + return this; }; - ParticleEmitter.prototype.update = function (engine, delta) { - var _this = this; - _super.prototype.update.call(this, engine, delta); - if (this.isEmitting) { - this._particlesToEmit += this.emitRate * (delta / 1000); - //var numParticles = Math.ceil(this.emitRate * delta / 1000); - if (this._particlesToEmit > 1.0) { - this.emitParticles(Math.floor(this._particlesToEmit)); - this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit); + /** + * Reject the promise and pass an option value to the reject callbacks + * @param value Value to pass to the reject callbacks + */ + Promise.prototype.reject = function (value) { + if (this._state === PromiseState.Pending) { + this._value = value; + try { + this._state = PromiseState.Rejected; + this._rejectCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); } } - this.particles.forEach(function (p) { return p.update(delta); }); - this.deadParticles.forEach(function (p) { return _this.particles.removeElement(p); }); - this.deadParticles.clear(); + else { + throw new Error('Cannot reject a promise that is not in a pending state!'); + } + return this; }; - ParticleEmitter.prototype.draw = function (ctx, delta) { - // todo is there a more efficient to draw - // possibly use a webgl offscreen canvas and shaders to do particles? - this.particles.forEach(function (p) { return p.draw(ctx); }); + /** + * Inpect the current state of a promise + */ + Promise.prototype.state = function () { + return this._state; }; - ParticleEmitter.prototype.debugDraw = function (ctx) { - _super.prototype.debugDraw.call(this, ctx); - ctx.fillStyle = ex.Color.Black.toString(); - ctx.fillText('Particles: ' + this.particles.count(), this.x, this.y + 20); - if (this.focus) { - ctx.fillRect(this.focus.x + this.x, this.focus.y + this.y, 3, 3); - ex.Util.drawLine(ctx, 'yellow', this.focus.x + this.x, this.focus.y + this.y, _super.prototype.getCenter.call(this).x, _super.prototype.getCenter.call(this).y); - ctx.fillText('Focus', this.focus.x + this.x, this.focus.y + this.y); + Promise.prototype._handleError = function (e) { + if (this._errorCallback) { + this._errorCallback.call(this, e); + } + else { + // rethrow error + throw e; } }; - return ParticleEmitter; - })(ex.Actor); - ex.ParticleEmitter = ParticleEmitter; + return Promise; + })(); + ex.Promise = Promise; })(ex || (ex = {})); +/// +/// +/// +/// var ex; (function (ex) { /** - * Animations + * Textures * - * Animations allow you to display a series of images one after another, - * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. + * The [[Texture]] object allows games built in Excalibur to load image resources. + * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] + * to pre-load before starting a level or game. * - * ## Creating an animation + * Textures are the raw image so to add a drawing to a game, you must create + * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite + * instance. * - * Create a [[Texture]] that contains the frames of your animation. Once the texture - * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] - * and using [[SpriteSheet.getAnimationForAll]]. + * ## Pre-loading textures * - * ```js - * var game = new ex.Engine(); - * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); + * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] + * is loaded, you can generate a [[Sprite]] with it. * - * // load assets - * var loader = new ex.Loader(txAnimPlayerIdle); + * ```js + * var txPlayer = new ex.Texture("/assets/tx/player.png"); * - * // start game - * game.start(loader).then(function () { - * var player = new ex.Actor(); + * var loader = new ex.Loader(txPlayer); * - * // create sprite sheet with 5 columns, 1 row, 80x80 frames - * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); + * game.start(loader).then(function () { * - * // create animation (125ms frame speed) - * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); + * var player = new ex.Actor(); * - * // add drawing to player as "idle" - * player.addDrawing("idle", playerIdleAnimation); + * player.addDrawing(txPlayer); * - * // add player to game * game.add(player); * }); * ``` - * - * ## Sprite effects - * - * You can add [[SpriteEffect|sprite effects]] to an animation through methods - * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this - * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - var Animation = (function () { + var Texture = (function (_super) { + __extends(Texture, _super); /** - * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. - * - * @param engine Reference to the current game engine - * @param images An array of sprites to create the frames for the animation - * @param speed The number in milliseconds to display each frame in the animation - * @param loop Indicates whether the animation should loop after it is completed + * @param path Path to the image resource + * @param bustCache Optionally load texture with cache busting */ - function Animation(engine, images, speed, loop) { - /** - * Current frame index being shown - */ - this.currentFrame = 0; - this._oldTime = Date.now(); - this.anchor = new ex.Point(0.0, 0.0); - this.rotation = 0.0; - this.scale = new ex.Point(1, 1); - /** - * Indicates whether the animation should loop after it is completed - */ - this.loop = false; - /** - * Indicates the frame index the animation should freeze on for a non-looping - * animation. By default it is the last frame. - */ - this.freezeFrame = -1; - /** - * Flip each frame vertically. Sets [[Sprite.flipVertical]]. - */ - this.flipVertical = false; + function Texture(path, bustCache) { + if (bustCache === void 0) { bustCache = true; } + _super.call(this, path, 'blob', bustCache); + this.path = path; + this.bustCache = bustCache; /** - * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + * A [[Promise]] that resolves when the Texture is loaded. */ - this.flipHorizontal = false; - this.width = 0; - this.height = 0; - this.naturalWidth = 0; - this.naturalHeight = 0; - this.sprites = images; - this.speed = speed; - this._engine = engine; - if (loop != null) { - this.loop = loop; - } - if (images && images[0]) { - this.height = images[0] ? images[0].height : 0; - this.width = images[0] ? images[0].width : 0; - this.naturalWidth = images[0] ? images[0].naturalWidth : 0; - this.naturalHeight = images[0] ? images[0].naturalHeight : 0; - this.freezeFrame = images.length - 1; - } + this.loaded = new ex.Promise(); + this._isLoaded = false; + this._sprite = null; + this._sprite = new ex.Sprite(this, 0, 0, 0, 0); } /** - * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + * Returns true if the Texture is completely loaded and is ready + * to be drawn. */ - Animation.prototype.opacity = function (value) { - this.addEffect(new ex.Effects.Opacity(value)); + Texture.prototype.isLoaded = function () { + return this._isLoaded; }; /** - * Applies the grayscale effect to a sprite, removing color information. + * Begins loading the texture and returns a promise to be resolved on completion */ - Animation.prototype.grayscale = function () { - this.addEffect(new ex.Effects.Grayscale()); + Texture.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + var loaded = _super.prototype.load.call(this); + loaded.then(function () { + _this.image = new Image(); + _this.image.addEventListener('load', function () { + _this._isLoaded = true; + _this.width = _this._sprite.swidth = _this._sprite.naturalWidth = _this._sprite.width = _this.image.naturalWidth; + _this.height = _this._sprite.sheight = _this._sprite.naturalHeight = _this._sprite.height = _this.image.naturalHeight; + _this.loaded.resolve(_this.image); + complete.resolve(_this.image); + }); + _this.image.src = _super.prototype.getData.call(_this); + }, function () { + complete.reject('Error loading texture.'); + }); + return complete; }; - /** - * Applies the invert effect to a sprite, inverting the pixel colors. - */ - Animation.prototype.invert = function () { - this.addEffect(new ex.Effects.Invert()); + Texture.prototype.asSprite = function () { + return this._sprite; }; + return Texture; + })(ex.Resource); + ex.Texture = Texture; +})(ex || (ex = {})); +/// +/// +/// +/// +var ex; +(function (ex) { + /** + * Sounds + * + * The [[Sound]] object allows games built in Excalibur to load audio + * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] + * which means it can be passed to a [[Loader]] to pre-load before a game or level. + * + * ## Pre-loading sounds + * + * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] + * is loaded, you can [[Sound.play|play]] it. + * + * ```js + * // define multiple sources (such as mp3/wav/ogg) as a browser fallback + * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); + * + * var loader = new ex.Loader(sndPlayerDeath); + * + * game.start(loader).then(function () { + * + * sndPlayerDeath.play(); + * }); + * ``` + */ + var Sound = (function () { /** - * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color + * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. */ - Animation.prototype.fill = function (color) { - this.addEffect(new ex.Effects.Fill(color)); - }; + function Sound() { + var paths = []; + for (var _i = 0; _i < arguments.length; _i++) { + paths[_i - 0] = arguments[_i]; + } + this._logger = ex.Logger.getInstance(); + this.onprogress = function () { return; }; + this.oncomplete = function () { return; }; + this.onerror = function () { return; }; + this.onload = function () { return; }; + this._isLoaded = false; + this._wasPlayingOnHidden = false; + /* Chrome : MP3, WAV, Ogg + * Firefox : WAV, Ogg, + * IE : MP3, WAV coming soon + * Safari MP3, WAV, Ogg + */ + this.path = ''; + for (var i = 0; i < paths.length; i++) { + if (Sound.canPlayFile(paths[i])) { + this.path = paths[i]; + break; + } + } + if (!this.path) { + this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); + this._logger.warn('Attempting to use', paths[0]); + this.path = paths[0]; // select the first specified + } + this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); + } /** - * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the - * provided color. + * Whether or not the browser can play this file as HTML5 Audio */ - Animation.prototype.colorize = function (color) { - this.addEffect(new ex.Effects.Colorize(color)); + Sound.canPlayFile = function (file) { + try { + var a = new Audio(); + var filetype = /.*\.([A-Za-z0-9]+)$/; + var type = file.match(filetype)[1]; + if (a.canPlayType('audio/' + type)) { + return true; + } + { + return false; + } + } + catch (e) { + ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); + return false; + } + }; + Sound.prototype.wireEngine = function (engine) { + var _this = this; + if (engine) { + this._engine = engine; + this._engine.on('hidden', function () { + if (engine.pauseAudioWhenHidden && _this.isPlaying()) { + _this._wasPlayingOnHidden = true; + _this.pause(); + } + }); + this._engine.on('visible', function () { + if (engine.pauseAudioWhenHidden && _this._wasPlayingOnHidden) { + _this.play(); + _this._wasPlayingOnHidden = false; + } + }); + } }; /** - * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl + * Sets the volume of the sound clip + * @param volume A volume value between 0-1.0 */ - Animation.prototype.lighten = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Lighten(factor)); + Sound.prototype.setVolume = function (volume) { + if (this.sound) { + this.sound.setVolume(volume); + } }; /** - * Applies the darken effect to a sprite, changes the darkness of the color according to hsl + * Indicates whether the clip should loop when complete + * @param loop Set the looping flag */ - Animation.prototype.darken = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Darken(factor)); + Sound.prototype.setLoop = function (loop) { + if (this.sound) { + this.sound.setLoop(loop); + } }; /** - * Applies the saturate effect to a sprite, saturates the color acccording to hsl + * Whether or not the sound is playing right now */ - Animation.prototype.saturate = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Saturate(factor)); + Sound.prototype.isPlaying = function () { + if (this.sound) { + return this.sound.isPlaying(); + } }; /** - * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl + * Play the sound, returns a promise that resolves when the sound is done playing */ - Animation.prototype.desaturate = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Desaturate(factor)); + Sound.prototype.play = function () { + if (this.sound) { + return this.sound.play(); + } }; /** - * Add a [[ISpriteEffect]] manually + * Stop the sound, and do not rewind */ - Animation.prototype.addEffect = function (effect) { - for (var i in this.sprites) { - this.sprites[i].addEffect(effect); + Sound.prototype.pause = function () { + if (this.sound) { + this.sound.pause(); } }; - Animation.prototype.removeEffect = function (param) { - for (var i in this.sprites) { - this.sprites[i].removeEffect(param); + /** + * Stop the sound and rewind + */ + Sound.prototype.stop = function () { + if (this.sound) { + this.sound.stop(); } }; /** - * Clear all sprite effects + * Returns true if the sound is loaded */ - Animation.prototype.clearEffects = function () { - for (var i in this.sprites) { - this.sprites[i].clearEffects(); - } + Sound.prototype.isLoaded = function () { + return this._isLoaded; }; - Animation.prototype._setAnchor = function (point) { - //if (!this.anchor.equals(point)) { - for (var i in this.sprites) { - this.sprites[i].anchor.setTo(point.x, point.y); + /** + * Begins loading the sound and returns a promise to be resolved on completion + */ + Sound.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + if (this.sound.getData() !== null) { + this._logger.debug('Already have data for resource', this.path); + complete.resolve(this.sound); + return complete; } - //} + this._logger.debug('Started loading sound', this.path); + this.sound.onprogress = this.onprogress; + this.sound.onload = function () { + _this.oncomplete(); + _this._isLoaded = true; + _this._logger.debug('Completed loading sound', _this.path); + complete.resolve(_this.sound); + }; + this.sound.onerror = function (e) { + _this.onerror(e); + complete.resolve(e); + }; + this.sound.load(); + return complete; }; - Animation.prototype._setRotation = function (radians) { - //if (this.rotation !== radians) { - for (var i in this.sprites) { - this.sprites[i].rotation = radians; - } - //} + Sound.prototype.getData = function () { + return this.sound.getData(); }; - Animation.prototype._setScale = function (scale) { - //if (!this.scale.equals(scale)) { - for (var i in this.sprites) { - this.sprites[i].scale = scale; - } - //} + Sound.prototype.setData = function (data) { + this.sound.setData(data); }; - /** - * Resets the animation to first frame. - */ - Animation.prototype.reset = function () { - this.currentFrame = 0; + Sound.prototype.processData = function (data) { + return this.sound.processData(data); }; + return Sound; + })(); + ex.Sound = Sound; +})(ex || (ex = {})); +/// +var ex; +(function (ex) { + /** + * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does + * not participate in collisions. Drawn on top of all other actors. + */ + var UIActor = (function (_super) { + __extends(UIActor, _super); /** - * Indicates whether the animation is complete, animations that loop are never complete. + * @param x The starting x coordinate of the actor + * @param y The starting y coordinate of the actor + * @param width The starting width of the actor + * @param height The starting height of the actor */ - Animation.prototype.isDone = function () { - return (!this.loop && this.currentFrame >= this.sprites.length); + function UIActor(x, y, width, height) { + _super.call(this, x, y, width, height); + this.traits = []; + this.traits.push(new ex.Traits.Movement()); + this.traits.push(new ex.Traits.CapturePointer()); + this.anchor.setTo(0, 0); + this.collisionType = ex.CollisionType.PreventCollision; + this.enableCapturePointer = true; + } + UIActor.prototype.onInitialize = function (engine) { + this._engine = engine; }; - /** - * Not meant to be called by game developers. Ticks the animation forward internally and - * calculates whether to change to the frame. - * @internal - */ - Animation.prototype.tick = function () { - var time = Date.now(); - if ((time - this._oldTime) > this.speed) { - this.currentFrame = (this.loop ? (this.currentFrame + 1) % this.sprites.length : this.currentFrame + 1); - this._oldTime = time; + UIActor.prototype.contains = function (x, y, useWorld) { + if (useWorld === void 0) { useWorld = true; } + if (useWorld) { + return _super.prototype.contains.call(this, x, y); } + var coords = this._engine.worldToScreenCoordinates(new ex.Point(x, y)); + return _super.prototype.contains.call(this, coords.x, coords.y); }; - Animation.prototype._updateValues = function () { - this._setAnchor(this.anchor); - this._setRotation(this.rotation); - this._setScale(this.scale); - }; + return UIActor; + })(ex.Actor); + ex.UIActor = UIActor; +})(ex || (ex = {})); +/// +/// +var ex; +(function (ex) { + /** + * Triggers + * + * Triggers are a method of firing arbitrary code on collision. These are useful + * as 'buttons', 'switches', or to trigger effects in a game. By default triggers + * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * + * ## Creating a trigger + * + * ```js + * var game = new ex.Game(); + * + * // create a handler + * function onTrigger() { + * + * // `this` will be the Trigger instance + * ex.Logger.getInstance().info("Trigger was triggered!", this); + * } + * + * // set a trigger at (100, 100) that is 40x40px + * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * + * // create an actor across from the trigger + * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * + * // tell the actor to move towards the trigger over 3 seconds + * actor.moveTo(100, 200, 3000); + * + * game.add(trigger); + * game.add(actor); + * + * game.start(); + * ``` + */ + var Trigger = (function (_super) { + __extends(Trigger, _super); /** - * Skips ahead a specified number of frames in the animation - * @param frames Frames to skip ahead + * @param x The x position of the trigger + * @param y The y position of the trigger + * @param width The width of the trigger + * @param height The height of the trigger + * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance + * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely */ - Animation.prototype.skip = function (frames) { - this.currentFrame = (this.currentFrame + frames) % this.sprites.length; - }; - Animation.prototype.draw = function (ctx, x, y) { - this.tick(); - this._updateValues(); - var currSprite; - if (this.currentFrame < this.sprites.length) { - currSprite = this.sprites[this.currentFrame]; - if (this.flipVertical) { - currSprite.flipVertical = this.flipVertical; - } - if (this.flipHorizontal) { - currSprite.flipHorizontal = this.flipHorizontal; + function Trigger(x, y, width, height, action, repeats) { + _super.call(this, x, y, width, height); + this._action = function () { return; }; + this.repeats = 1; + this.target = null; + this.repeats = repeats || this.repeats; + this._action = action || this._action; + this.collisionType = ex.CollisionType.PreventCollision; + this.eventDispatcher = new ex.EventDispatcher(this); + this.actionQueue = new ex.Internal.Actions.ActionQueue(this); + } + Trigger.prototype.update = function (engine, delta) { + // Update action queue + this.actionQueue.update(delta); + // Update placements based on linear algebra + this.x += this.dx * delta / 1000; + this.y += this.dy * delta / 1000; + this.rotation += this.rx * delta / 1000; + this.scale.x += this.sx * delta / 1000; + this.scale.y += this.sy * delta / 1000; + // check for trigger collisions + if (this.target) { + if (this.collides(this.target)) { + this._dispatchAction(); } - currSprite.draw(ctx, x, y); } - if (this.freezeFrame !== -1 && this.currentFrame >= this.sprites.length) { - currSprite = this.sprites[ex.Util.clamp(this.freezeFrame, 0, this.sprites.length - 1)]; - currSprite.draw(ctx, x, y); + else { + for (var i = 0; i < engine.currentScene.children.length; i++) { + var other = engine.currentScene.children[i]; + if (other !== this && + other.collisionType !== ex.CollisionType.PreventCollision && + this.collides(other)) { + this._dispatchAction(); + } + } } - // add the calculated width - if (currSprite) { - this.width = currSprite.width; - this.height = currSprite.height; + // remove trigger if its done, -1 repeat forever + if (this.repeats === 0) { + this.kill(); } }; - /** - * Plays an animation at an arbitrary location in the game. - * @param x The x position in the game to play - * @param y The y position in the game to play - */ - Animation.prototype.play = function (x, y) { - this.reset(); - this._engine.playAnimation(this, x, y); + Trigger.prototype._dispatchAction = function () { + this._action.call(this); + this.repeats--; }; - return Animation; - })(); - ex.Animation = Animation; + Trigger.prototype.draw = function (ctx, delta) { + // does not draw + return; + }; + Trigger.prototype.debugDraw = function (ctx) { + _super.prototype.debugDraw.call(this, ctx); + // Meant to draw debug information about actors + ctx.save(); + ctx.translate(this.x, this.y); + var bb = this.getBounds(); + bb.left = bb.left - this.getWorldX(); + bb.right = bb.right - this.getWorldX(); + bb.top = bb.top - this.getWorldY(); + bb.bottom = bb.bottom - this.getWorldY(); + // Currently collision primitives cannot rotate + // ctx.rotate(this.rotation); + ctx.fillStyle = ex.Color.Violet.toString(); + ctx.strokeStyle = ex.Color.Violet.toString(); + ctx.fillText('Trigger', 10, 10); + bb.debugDraw(ctx); + ctx.restore(); + }; + return Trigger; + })(ex.Actor); + ex.Trigger = Trigger; })(ex || (ex = {})); -/// +/// +/// /// -/// +/// var ex; (function (ex) { - var Internal; - (function (Internal) { - var FallbackAudio = (function () { - function FallbackAudio(path, volume) { - this.path = path; - this._log = ex.Logger.getInstance(); - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - if (window.AudioContext) { - this._log.debug('Using new Web Audio Api for ' + path); - this._soundImpl = new WebAudio(path, volume); - } - else { - this._log.debug('Falling back to Audio Element for ' + path); - this._soundImpl = new AudioTag(path, volume); - } + /** + * An enum that represents the types of emitter nozzles + */ + (function (EmitterType) { + /** + * Constant for the circular emitter type + */ + EmitterType[EmitterType["Circle"] = 0] = "Circle"; + /** + * Constant for the rectangular emitter type + */ + EmitterType[EmitterType["Rectangle"] = 1] = "Rectangle"; + })(ex.EmitterType || (ex.EmitterType = {})); + var EmitterType = ex.EmitterType; + /** + * Particle is used in a [[ParticleEmitter]] + */ + var Particle = (function () { + function Particle(emitter, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) { + this.position = new ex.Vector(0, 0); + this.velocity = new ex.Vector(0, 0); + this.acceleration = new ex.Vector(0, 0); + this.particleRotationalVelocity = 0; + this.currentRotation = 0; + this.focus = null; + this.focusAccel = 0; + this.opacity = 1; + this.beginColor = ex.Color.White.clone(); + this.endColor = ex.Color.White.clone(); + // Life is counted in ms + this.life = 300; + this.fadeFlag = false; + // Color transitions + this._rRate = 1; + this._gRate = 1; + this._bRate = 1; + this._aRate = 0; + this._currentColor = ex.Color.White.clone(); + this.emitter = null; + this.particleSize = 5; + this.particleSprite = null; + this.sizeRate = 0; + this.elapsedMultiplier = 0; + this.emitter = emitter; + this.life = life || this.life; + this.opacity = opacity || this.opacity; + this.endColor = endColor || this.endColor.clone(); + this.beginColor = beginColor || this.beginColor.clone(); + this._currentColor = this.beginColor.clone(); + this.position = position || this.position; + this.velocity = velocity || this.velocity; + this.acceleration = acceleration || this.acceleration; + this._rRate = (this.endColor.r - this.beginColor.r) / this.life; + this._gRate = (this.endColor.g - this.beginColor.g) / this.life; + this._bRate = (this.endColor.b - this.beginColor.b) / this.life; + this._aRate = this.opacity / this.life; + this.startSize = startSize || 0; + this.endSize = endSize || 0; + if ((this.endSize > 0) && (this.startSize > 0)) { + this.sizeRate = (this.endSize - this.startSize) / this.life; + this.particleSize = this.startSize; } - FallbackAudio.prototype.setVolume = function (volume) { - this._soundImpl.setVolume(volume); - }; - FallbackAudio.prototype.setLoop = function (loop) { - this._soundImpl.setLoop(loop); - }; - FallbackAudio.prototype.load = function () { - this._soundImpl.onload = this.onload; - this._soundImpl.onprogress = this.onprogress; - this._soundImpl.onerror = this.onerror; - this._soundImpl.load(); - }; - FallbackAudio.prototype.processData = function (data) { - return this._soundImpl.processData(data); - }; - FallbackAudio.prototype.getData = function () { - return this._soundImpl.getData(); - }; - FallbackAudio.prototype.setData = function (data) { - this._soundImpl.setData(data); - }; - FallbackAudio.prototype.isPlaying = function () { - return this._soundImpl.isPlaying(); - }; - FallbackAudio.prototype.play = function () { - return this._soundImpl.play(); - }; - FallbackAudio.prototype.pause = function () { - this._soundImpl.pause(); - }; - FallbackAudio.prototype.stop = function () { - this._soundImpl.stop(); - }; - return FallbackAudio; - })(); - Internal.FallbackAudio = FallbackAudio; - var AudioTag = (function () { - function AudioTag(path, volume) { - var _this = this; - this.path = path; - this._audioElements = new Array(5); - this._loadedAudio = null; - this._isLoaded = false; - this._index = 0; - this._log = ex.Logger.getInstance(); - this._isPlaying = false; - this._currentOffset = 0; - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - for (var i = 0; i < this._audioElements.length; i++) { - (function (i) { - _this._audioElements[i] = new Audio(); - })(i); - } - if (volume) { - this.setVolume(ex.Util.clamp(volume, 0, 1.0)); - } - else { - this.setVolume(1.0); - } + } + Particle.prototype.kill = function () { + this.emitter.removeParticle(this); + }; + Particle.prototype.update = function (delta) { + this.life = this.life - delta; + this.elapsedMultiplier = this.elapsedMultiplier + delta; + if (this.life < 0) { + this.kill(); } - AudioTag.prototype.isPlaying = function () { - return this._isPlaying; - }; - AudioTag.prototype._audioLoaded = function () { - this._isLoaded = true; - }; - AudioTag.prototype.setVolume = function (volume) { - var i = 0, len = this._audioElements.length; - for (i; i < len; i++) { - this._audioElements[i].volume = volume; - } - }; - AudioTag.prototype.setLoop = function (loop) { - var i = 0, len = this._audioElements.length; - for (i; i < len; i++) { - this._audioElements[i].loop = loop; - } - }; - AudioTag.prototype.getLoop = function () { - this._audioElements.some(function (a) { return a.loop; }); - }; - AudioTag.prototype.load = function () { - var _this = this; - if (!!this._loadedAudio) { - return; - } - var request = new XMLHttpRequest(); - request.open('GET', this.path, true); - request.responseType = 'blob'; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function (e) { - if (request.status !== 200) { - _this._log.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - _this._isLoaded = false; - return; - } - _this._isLoaded = true; - _this.setData(request.response); - _this.onload(e); - }; - request.send(); - }; - AudioTag.prototype.getData = function () { - return this._loadedAudio; - }; - AudioTag.prototype.setData = function (data) { - this._isLoaded = true; - this._loadedAudio = this.processData(data); - }; - AudioTag.prototype.processData = function (data) { - var blobUrl = URL.createObjectURL(data); - this._audioElements.forEach(function (a) { - a.src = blobUrl; - }); - this._audioLoaded(); - return blobUrl; - }; - AudioTag.prototype.play = function () { - var _this = this; - this._audioElements[this._index].load(); - //this.audioElements[this.index].currentTime = this._currentOffset; - this._audioElements[this._index].play(); - this._currentOffset = 0; - var done = new ex.Promise(); - this._isPlaying = true; - if (!this.getLoop()) { - this._audioElements[this._index].addEventListener('ended', function () { - _this._isPlaying = false; - done.resolve(true); - }); - } - this._index = (this._index + 1) % this._audioElements.length; - return done; - }; - AudioTag.prototype.pause = function () { - this._index = (this._index - 1 + this._audioElements.length) % this._audioElements.length; - this._currentOffset = this._audioElements[this._index].currentTime; - this._audioElements.forEach(function (a) { - a.pause(); - }); - this._isPlaying = false; - }; - AudioTag.prototype.stop = function () { - this._audioElements.forEach(function (a) { - a.pause(); - //a.currentTime = 0; - }); - this._isPlaying = false; - }; - return AudioTag; - })(); - Internal.AudioTag = AudioTag; - if (window.AudioContext) { - var audioContext = new window.AudioContext(); - } - var WebAudio = (function () { - function WebAudio(path, volume) { - this.path = path; - this._context = audioContext; - this._volume = this._context.createGain(); - this._buffer = null; - this._sound = null; - this._isLoaded = false; - this._loop = false; - this._isPlaying = false; - this._isPaused = false; - this._currentOffset = 0; - this._logger = ex.Logger.getInstance(); - this._data = null; - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - if (volume) { - this._volume.gain.value = ex.Util.clamp(volume, 0, 1.0); - } - else { - this._volume.gain.value = 1.0; // max volume - } + if (this.fadeFlag) { + this.opacity = ex.Util.clamp(this._aRate * this.life, 0.0001, 1); } - WebAudio.prototype.setVolume = function (volume) { - this._volume.gain.value = volume; - }; - WebAudio.prototype.load = function () { - var _this = this; - // Exit early if we already have data - if (this._data !== null) { - return; - } - var request = new XMLHttpRequest(); - request.open('GET', this.path); - request.responseType = 'arraybuffer'; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function () { - if (request.status !== 200) { - _this._logger.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - _this._isLoaded = false; - return; - } - _this.setData(request.response); - }; - try { - request.send(); - } - catch (e) { - console.error('Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.'); - } - }; - WebAudio.prototype.getData = function () { - return this._data; - }; - WebAudio.prototype.setData = function (data) { - this._data = this.processData(data); - }; - WebAudio.prototype.processData = function (data) { - var _this = this; - this._context.decodeAudioData(data, function (buffer) { - _this._buffer = buffer; - _this._isLoaded = true; - _this.onload(_this); - }, function (e) { - _this._logger.error('Unable to decode ' + _this.path + - ' this browser may not fully support this format, or the file may be corrupt, ' + - 'if this is an mp3 try removing id3 tags and album art from the file.'); - _this._isLoaded = false; - _this.onload(_this); - }); - return data; - }; - WebAudio.prototype.setLoop = function (loop) { - this._loop = loop; - }; - WebAudio.prototype.isPlaying = function () { - return this._isPlaying; - }; - WebAudio.prototype.play = function () { - var _this = this; - if (this._isLoaded) { - this._sound = this._context.createBufferSource(); - this._sound.buffer = this._buffer; - this._sound.loop = this._loop; - this._sound.connect(this._volume); - this._volume.connect(this._context.destination); - this._sound.start(0, this._currentOffset % this._buffer.duration); - this._currentOffset = 0; - var done; - if (!this._isPaused || !this._playPromise) { - done = new ex.Promise(); - } - else { - done = this._playPromise; - } - this._isPaused = false; - this._isPlaying = true; - if (!this._loop) { - this._sound.onended = (function () { - _this._isPlaying = false; - if (!_this._isPaused) { - done.resolve(true); - } - }).bind(this); - } - this._playPromise = done; - return done; - } - else { - return ex.Promise.wrap(true); - } - }; - WebAudio.prototype.pause = function () { - if (this._isPlaying) { - try { - window.clearTimeout(this._playingTimer); - this._sound.stop(0); - this._currentOffset = this._context.currentTime; - this._isPlaying = false; - this._isPaused = true; - } - catch (e) { - this._logger.warn('The sound clip', this.path, 'has already been paused!'); - } - } - }; - WebAudio.prototype.stop = function () { - if (this._sound) { - try { - window.clearTimeout(this._playingTimer); - this._currentOffset = 0; - this._sound.stop(0); - this._isPlaying = false; - this._isPaused = false; - } - catch (e) { - this._logger.warn('The sound clip', this.path, 'has already been stopped!'); - } - } - }; - return WebAudio; - })(); - Internal.WebAudio = WebAudio; - })(Internal = ex.Internal || (ex.Internal = {})); -})(ex || (ex = {})); -/// -// Promises/A+ Spec http://promises-aplus.github.io/promises-spec/ -var ex; -(function (ex) { - /** - * Valid states for a promise to be in - */ - (function (PromiseState) { - PromiseState[PromiseState["Resolved"] = 0] = "Resolved"; - PromiseState[PromiseState["Rejected"] = 1] = "Rejected"; - PromiseState[PromiseState["Pending"] = 2] = "Pending"; - })(ex.PromiseState || (ex.PromiseState = {})); - var PromiseState = ex.PromiseState; + if ((this.startSize > 0) && (this.endSize > 0)) { + this.particleSize = ex.Util.clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize)); + } + this._currentColor.r = ex.Util.clamp(this._currentColor.r + this._rRate * delta, 0, 255); + this._currentColor.g = ex.Util.clamp(this._currentColor.g + this._gRate * delta, 0, 255); + this._currentColor.b = ex.Util.clamp(this._currentColor.b + this._bRate * delta, 0, 255); + this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); + if (this.focus) { + var accel = this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(delta / 1000); + this.velocity = this.velocity.add(accel); + } + else { + this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000)); + } + this.position = this.position.add(this.velocity.scale(delta / 1000)); + if (this.particleRotationalVelocity) { + this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI); + } + }; + Particle.prototype.draw = function (ctx) { + if (this.particleSprite) { + this.particleSprite.rotation = this.currentRotation; + this.particleSprite.scale.setTo(this.particleSize, this.particleSize); + this.particleSprite.draw(ctx, this.position.x, this.position.y); + return; + } + this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); + ctx.fillStyle = this._currentColor.toString(); + ctx.beginPath(); + ctx.arc(this.position.x, this.position.y, this.particleSize, 0, Math.PI * 2); + ctx.fill(); + ctx.closePath(); + }; + return Particle; + })(); + ex.Particle = Particle; /** - * Promises/A+ spec implementation of promises - * - * Promises are used to do asynchronous work and they are useful for - * creating a chain of actions. In Excalibur they are used for loading, - * sounds, animation, actions, and more. + * Particle Emitters * - * ## A Promise Chain + * Using a particle emitter is a great way to create interesting effects + * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` + * extend [[Actor]] allowing you to use all of the features that come with. * - * Promises can be chained together and can be useful for creating a queue - * of functions to be called when something is done. + * The easiest way to create a `ParticleEmitter` is to use the + * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. * - * The first [[Promise]] you will encounter is probably [[Engine.start]] - * which resolves when the game has finished loading. + * ## Example: Adding an emitter * * ```js - * var game = new ex.Engine(); - * - * // perform start-up logic once game is ready - * game.start().then(function () { - * - * // start-up & initialization logic + * var actor = new ex.Actor(...); + * var emitter = new ex.ParticleEmitter(...); * - * }); - * ``` - * - * ## Handling errors - * - * You can optionally pass an error handler to [[Promise.then]] which will handle - * any errors that occur during Promise execution. + * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle + * emitter.radius = 5; + * emitter.minVel = 100; + * emitter.maxVel = 200; + * emitter.minAngle = 0; + * emitter.maxAngle = Math.PI * 2; + * emitter.emitRate = 300; // 300 particles/second + * emitter.opacity = 0.5; + * emitter.fadeFlag = true; // fade particles overtime + * emitter.particleLife = 1000; // in milliseconds = 1 sec + * emitter.maxSize = 10; // in pixels + * emitter.minSize = 1; + * emitter.particleColor = ex.Color.Rose; * - * ```js - * var game = new ex.Engine(); + * // set emitter settings + * emitter.isEmitting = true; // should the emitter be emitting * - * game.start().then( - * // success handler - * function () { - * }, + * // add the emitter as a child actor, it will draw on top of the parent actor + * // and move with the parent + * actor.add(emitter); * - * // error handler - * function (err) { - * } - * ); + * // or, alternatively, add it to the current scene + * engine.add(emitter); * ``` - * - * Any errors that go unhandled will be bubbled up to the browser. */ - var Promise = (function () { - function Promise() { - this._state = PromiseState.Pending; - this._successCallbacks = []; - this._rejectCallback = function () { return; }; - this._logger = ex.Logger.getInstance(); - } - /** - * Wrap a value in a resolved promise - * @param value An optional value to wrap in a resolved promise - */ - Promise.wrap = function (value) { - var promise = (new Promise()).resolve(value); - return promise; - }; - /** - * Returns a new promise that resolves when all the promises passed to it resolve, or rejects - * when at least 1 promise rejects. - */ - Promise.join = function () { - var promises = []; - for (var _i = 0; _i < arguments.length; _i++) { - promises[_i - 0] = arguments[_i]; - } - var joinedPromise = new Promise(); - if (!promises || !promises.length) { - return joinedPromise.resolve(); - } - var total = promises.length; - var successes = 0; - var rejects = 0; - var errors = []; - promises.forEach(function (p) { - p.then(function () { - successes += 1; - if (successes === total) { - joinedPromise.resolve(); - } - else if (successes + rejects + errors.length === total) { - joinedPromise.reject(errors); - } - }, function () { - rejects += 1; - if (successes + rejects + errors.length === total) { - joinedPromise.reject(errors); - } - }).error(function (e) { - errors.push(e); - if ((errors.length + successes + rejects) === total) { - joinedPromise.reject(errors); - } - }); - }); - return joinedPromise; - }; + var ParticleEmitter = (function (_super) { + __extends(ParticleEmitter, _super); /** - * Chain success and reject callbacks after the promise is resovled - * @param successCallback Call on resolution of promise - * @param rejectCallback Call on rejection of promise + * @param x The x position of the emitter + * @param y The y position of the emitter + * @param width The width of the emitter + * @param height The height of the emitter */ - Promise.prototype.then = function (successCallback, rejectCallback) { - if (successCallback) { - this._successCallbacks.push(successCallback); - // If the promise is already resovled call immediately - if (this.state() === PromiseState.Resolved) { - try { - successCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); - } - } - } - if (rejectCallback) { - this._rejectCallback = rejectCallback; - // If the promise is already rejected call immediately - if (this.state() === PromiseState.Rejected) { - try { - rejectCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); - } + function ParticleEmitter(x, y, width, height) { + _super.call(this, x, y, width, height, ex.Color.White); + this._particlesToEmit = 0; + this.numParticles = 0; + /** + * Gets or sets the isEmitting flag + */ + this.isEmitting = true; + /** + * Gets or sets the backing particle collection + */ + this.particles = null; + /** + * Gets or sets the backing deadParticle collection + */ + this.deadParticles = null; + /** + * Gets or sets the minimum partical velocity + */ + this.minVel = 0; + /** + * Gets or sets the maximum partical velocity + */ + this.maxVel = 0; + /** + * Gets or sets the acceleration vector for all particles + */ + this.acceleration = new ex.Vector(0, 0); + /** + * Gets or sets the minimum angle in radians + */ + this.minAngle = 0; + /** + * Gets or sets the maximum angle in radians + */ + this.maxAngle = 0; + /** + * Gets or sets the emission rate for particles (particles/sec) + */ + this.emitRate = 1; //particles/sec + /** + * Gets or sets the life of each particle in milliseconds + */ + this.particleLife = 2000; + /** + * Gets or sets the opacity of each particle from 0 to 1.0 + */ + this.opacity = 1; + /** + * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. + */ + this.fadeFlag = false; + /** + * Gets or sets the optional focus where all particles should accelerate towards + */ + this.focus = null; + /** + * Gets or sets the acceleration for focusing particles if a focus has been specified + */ + this.focusAccel = 1; + /* + * Gets or sets the optional starting size for the particles + */ + this.startSize = null; + /* + * Gets or sets the optional ending size for the particles + */ + this.endSize = null; + /** + * Gets or sets the minimum size of all particles + */ + this.minSize = 5; + /** + * Gets or sets the maximum size of all particles + */ + this.maxSize = 5; + /** + * Gets or sets the beginning color of all particles + */ + this.beginColor = ex.Color.White; + /** + * Gets or sets the ending color of all particles + */ + this.endColor = ex.Color.White; + /** + * Gets or sets the sprite that a particle should use + * @warning Performance intensive + */ + this.particleSprite = null; + /** + * Gets or sets the emitter type for the particle emitter + */ + this.emitterType = EmitterType.Rectangle; + /** + * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] + */ + this.radius = 0; + /** + * Gets or sets the particle rotational speed velocity + */ + this.particleRotationalVelocity = 0; + /** + * Indicates whether particles should start with a random rotation + */ + this.randomRotation = false; + this.collisionType = ex.CollisionType.PreventCollision; + this.particles = new ex.Util.Collection(); + this.deadParticles = new ex.Util.Collection(); + // Remove offscreen culling from particle emitters + for (var trait in this.traits) { + if (this.traits[trait] instanceof ex.Traits.OffscreenCulling) { + this.traits.splice(trait, 1); } } - return this; + } + ParticleEmitter.prototype.removeParticle = function (particle) { + this.deadParticles.push(particle); }; /** - * Add an error callback to the promise - * @param errorCallback Call if there was an error in a callback + * Causes the emitter to emit particles + * @param particleCount Number of particles to emit right now */ - Promise.prototype.error = function (errorCallback) { - if (errorCallback) { - this._errorCallback = errorCallback; + ParticleEmitter.prototype.emitParticles = function (particleCount) { + for (var i = 0; i < particleCount; i++) { + this.particles.push(this._createParticle()); } - return this; }; - /** - * Resolve the promise and pass an option value to the success callbacks - * @param value Value to pass to the success callbacks - */ - Promise.prototype.resolve = function (value) { - var _this = this; - if (this._state === PromiseState.Pending) { - this._value = value; - try { - this._state = PromiseState.Resolved; - this._successCallbacks.forEach(function (cb) { - cb.call(_this, _this._value); - }); - } - catch (e) { - this._handleError(e); - } + ParticleEmitter.prototype.clearParticles = function () { + this.particles.clear(); + }; + // Creates a new particle given the contraints of the emitter + ParticleEmitter.prototype._createParticle = function () { + // todo implement emitter contraints; + var ranX = 0; + var ranY = 0; + var angle = ex.Util.randomInRange(this.minAngle, this.maxAngle); + var vel = ex.Util.randomInRange(this.minVel, this.maxVel); + var size = this.startSize || ex.Util.randomInRange(this.minSize, this.maxSize); + var dx = vel * Math.cos(angle); + var dy = vel * Math.sin(angle); + if (this.emitterType === EmitterType.Rectangle) { + ranX = ex.Util.randomInRange(this.x, this.x + this.getWidth()); + ranY = ex.Util.randomInRange(this.y, this.y + this.getHeight()); } - else { - throw new Error('Cannot resolve a promise that is not in a pending state!'); + else if (this.emitterType === EmitterType.Circle) { + var radius = ex.Util.randomInRange(0, this.radius); + ranX = radius * Math.cos(angle) + this.x; + ranY = radius * Math.sin(angle) + this.y; } - return this; + var p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new ex.Vector(ranX, ranY), new ex.Vector(dx, dy), this.acceleration, this.startSize, this.endSize); + p.fadeFlag = this.fadeFlag; + p.particleSize = size; + if (this.particleSprite) { + p.particleSprite = this.particleSprite; + } + p.particleRotationalVelocity = this.particleRotationalVelocity; + if (this.randomRotation) { + p.currentRotation = ex.Util.randomInRange(0, Math.PI * 2); + } + if (this.focus) { + p.focus = this.focus.add(new ex.Vector(this.x, this.y)); + p.focusAccel = this.focusAccel; + } + return p; }; - /** - * Reject the promise and pass an option value to the reject callbacks - * @param value Value to pass to the reject callbacks - */ - Promise.prototype.reject = function (value) { - if (this._state === PromiseState.Pending) { - this._value = value; - try { - this._state = PromiseState.Rejected; - this._rejectCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); + ParticleEmitter.prototype.update = function (engine, delta) { + var _this = this; + _super.prototype.update.call(this, engine, delta); + if (this.isEmitting) { + this._particlesToEmit += this.emitRate * (delta / 1000); + //var numParticles = Math.ceil(this.emitRate * delta / 1000); + if (this._particlesToEmit > 1.0) { + this.emitParticles(Math.floor(this._particlesToEmit)); + this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit); } } - else { - throw new Error('Cannot reject a promise that is not in a pending state!'); - } - return this; + this.particles.forEach(function (p) { return p.update(delta); }); + this.deadParticles.forEach(function (p) { return _this.particles.removeElement(p); }); + this.deadParticles.clear(); }; - /** - * Inpect the current state of a promise - */ - Promise.prototype.state = function () { - return this._state; + ParticleEmitter.prototype.draw = function (ctx, delta) { + // todo is there a more efficient to draw + // possibly use a webgl offscreen canvas and shaders to do particles? + this.particles.forEach(function (p) { return p.draw(ctx); }); }; - Promise.prototype._handleError = function (e) { - if (this._errorCallback) { - this._errorCallback.call(this, e); - } - else { - // rethrow error - throw e; + ParticleEmitter.prototype.debugDraw = function (ctx) { + _super.prototype.debugDraw.call(this, ctx); + ctx.fillStyle = ex.Color.Black.toString(); + ctx.fillText('Particles: ' + this.particles.count(), this.x, this.y + 20); + if (this.focus) { + ctx.fillRect(this.focus.x + this.x, this.focus.y + this.y, 3, 3); + ex.Util.drawLine(ctx, 'yellow', this.focus.x + this.x, this.focus.y + this.y, _super.prototype.getCenter.call(this).x, _super.prototype.getCenter.call(this).y); + ctx.fillText('Focus', this.focus.x + this.x, this.focus.y + this.y); } }; - return Promise; - })(); - ex.Promise = Promise; + return ParticleEmitter; + })(ex.Actor); + ex.ParticleEmitter = ParticleEmitter; })(ex || (ex = {})); -/// var ex; (function (ex) { /** - * Generic Resources - * - * The [[Resource]] type allows games built in Excalibur to load generic resources. - * For any type of remote resource it is recommended to use [[Resource]] for preloading. + * Animations * - * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before - * a level or game. + * Animations allow you to display a series of images one after another, + * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. * - * Example usages: JSON, compressed files, blobs. + * ## Creating an animation * - * ## Pre-loading generic resources + * Create a [[Texture]] that contains the frames of your animation. Once the texture + * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] + * and using [[SpriteSheet.getAnimationForAll]]. * * ```js - * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); - * var loader = new ex.Loader(resLevel1); + * var game = new ex.Engine(); + * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); * - * // attach a handler to process once loaded - * resLevel1.processData = function (data) { + * // load assets + * var loader = new ex.Loader(txAnimPlayerIdle); * - * // process JSON - * var json = JSON.parse(data); + * // start game + * game.start(loader).then(function () { + * var player = new ex.Actor(); * - * // create a new level (inherits Scene) with the JSON configuration - * var level = new Level(json); + * // create sprite sheet with 5 columns, 1 row, 80x80 frames + * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); * - * // add a new scene - * game.add(level.name, level); - * } + * // create animation (125ms frame speed) + * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); * - * game.start(loader); + * // add drawing to player as "idle" + * player.addDrawing("idle", playerIdleAnimation); + * + * // add player to game + * game.add(player); + * }); * ``` + * + * ## Sprite effects + * + * You can add [[SpriteEffect|sprite effects]] to an animation through methods + * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this + * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - var Resource = (function (_super) { - __extends(Resource, _super); - /** - * @param path Path to the remote resource - * @param responseType The Content-Type to expect (e.g. `application/json`) - * @param bustCache Whether or not to cache-bust requests - */ - function Resource(path, responseType, bustCache) { - if (bustCache === void 0) { bustCache = true; } - _super.call(this); - this.path = path; - this.responseType = responseType; - this.bustCache = bustCache; - this.data = null; - this.logger = ex.Logger.getInstance(); - this.onprogress = function () { return; }; - this.oncomplete = function () { return; }; - this.onerror = function () { return; }; - } + var Animation = (function () { /** - * Returns true if the Resource is completely loaded and is ready - * to be drawn. + * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. + * + * @param engine Reference to the current game engine + * @param images An array of sprites to create the frames for the animation + * @param speed The number in milliseconds to display each frame in the animation + * @param loop Indicates whether the animation should loop after it is completed */ - Resource.prototype.isLoaded = function () { - return this.data !== null; - }; - Resource.prototype.wireEngine = function (engine) { + function Animation(engine, images, speed, loop) { + /** + * Current frame index being shown + */ + this.currentFrame = 0; + this._oldTime = Date.now(); + this.anchor = new ex.Point(0.0, 0.0); + this.rotation = 0.0; + this.scale = new ex.Point(1, 1); + /** + * Indicates whether the animation should loop after it is completed + */ + this.loop = false; + /** + * Indicates the frame index the animation should freeze on for a non-looping + * animation. By default it is the last frame. + */ + this.freezeFrame = -1; + /** + * Flip each frame vertically. Sets [[Sprite.flipVertical]]. + */ + this.flipVertical = false; + /** + * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + */ + this.flipHorizontal = false; + this.width = 0; + this.height = 0; + this.naturalWidth = 0; + this.naturalHeight = 0; + this.sprites = images; + this.speed = speed; this._engine = engine; - }; - Resource.prototype._cacheBust = function (uri) { - var query = /\?\w*=\w*/; - if (query.test(uri)) { - uri += ('&__=' + Date.now()); + if (loop != null) { + this.loop = loop; } - else { - uri += ('?__=' + Date.now()); + if (images && images[0]) { + this.height = images[0] ? images[0].height : 0; + this.width = images[0] ? images[0].width : 0; + this.naturalWidth = images[0] ? images[0].naturalWidth : 0; + this.naturalHeight = images[0] ? images[0].naturalHeight : 0; + this.freezeFrame = images.length - 1; } - return uri; + } + /** + * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + */ + Animation.prototype.opacity = function (value) { + this.addEffect(new ex.Effects.Opacity(value)); }; - Resource.prototype._start = function (e) { - this.logger.debug('Started loading resource ' + this.path); + /** + * Applies the grayscale effect to a sprite, removing color information. + */ + Animation.prototype.grayscale = function () { + this.addEffect(new ex.Effects.Grayscale()); }; /** - * Begin loading the resource and returns a promise to be resolved on completion + * Applies the invert effect to a sprite, inverting the pixel colors. */ - Resource.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - // Exit early if we already have data - if (this.data !== null) { - this.logger.debug('Already have data for resource', this.path); - complete.resolve(this.data); - this.oncomplete(); - return complete; - } - var request = new XMLHttpRequest(); - request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true); - request.responseType = this.responseType; - request.onloadstart = function (e) { _this._start(e); }; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function (e) { - if (request.status !== 200) { - _this.logger.error('Failed to load resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - complete.resolve(request.response); - return; - } - _this.data = _this.processData(request.response); - _this.oncomplete(); - _this.logger.debug('Completed loading resource', _this.path); - complete.resolve(_this.data); - }; - request.send(); - return complete; + Animation.prototype.invert = function () { + this.addEffect(new ex.Effects.Invert()); }; /** - * Returns the loaded data once the resource is loaded + * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color */ - Resource.prototype.getData = function () { - return this.data; + Animation.prototype.fill = function (color) { + this.addEffect(new ex.Effects.Fill(color)); }; /** - * Sets the data for this resource directly + * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the + * provided color. */ - Resource.prototype.setData = function (data) { - this.data = this.processData(data); + Animation.prototype.colorize = function (color) { + this.addEffect(new ex.Effects.Colorize(color)); }; /** - * This method is meant to be overriden to handle any additional - * processing. Such as decoding downloaded audio bits. + * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl */ - Resource.prototype.processData = function (data) { - // Handle any additional loading after the xhr has completed. - return URL.createObjectURL(data); + Animation.prototype.lighten = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Lighten(factor)); }; - return Resource; - })(ex.Class); - ex.Resource = Resource; -})(ex || (ex = {})); -/// -/// -/// -/// -/// -var ex; -(function (ex) { - /** - * Textures - * - * The [[Texture]] object allows games built in Excalibur to load image resources. - * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] - * to pre-load before starting a level or game. - * - * Textures are the raw image so to add a drawing to a game, you must create - * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite - * instance. - * - * ## Pre-loading textures - * - * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] - * is loaded, you can generate a [[Sprite]] with it. - * - * ```js - * var txPlayer = new ex.Texture("/assets/tx/player.png"); - * - * var loader = new ex.Loader(txPlayer); - * - * game.start(loader).then(function () { - * - * var player = new ex.Actor(); - * - * player.addDrawing(txPlayer); - * - * game.add(player); - * }); - * ``` - */ - var Texture = (function (_super) { - __extends(Texture, _super); /** - * @param path Path to the image resource - * @param bustCache Optionally load texture with cache busting + * Applies the darken effect to a sprite, changes the darkness of the color according to hsl */ - function Texture(path, bustCache) { - if (bustCache === void 0) { bustCache = true; } - _super.call(this, path, 'blob', bustCache); - this.path = path; - this.bustCache = bustCache; - /** - * A [[Promise]] that resolves when the Texture is loaded. - */ - this.loaded = new ex.Promise(); - this._isLoaded = false; - this._sprite = null; - this._sprite = new ex.Sprite(this, 0, 0, 0, 0); - } + Animation.prototype.darken = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Darken(factor)); + }; /** - * Returns true if the Texture is completely loaded and is ready - * to be drawn. + * Applies the saturate effect to a sprite, saturates the color acccording to hsl */ - Texture.prototype.isLoaded = function () { - return this._isLoaded; + Animation.prototype.saturate = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Saturate(factor)); }; /** - * Begins loading the texture and returns a promise to be resolved on completion + * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl */ - Texture.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - var loaded = _super.prototype.load.call(this); - loaded.then(function () { - _this.image = new Image(); - _this.image.addEventListener('load', function () { - _this._isLoaded = true; - _this.width = _this._sprite.swidth = _this._sprite.naturalWidth = _this._sprite.width = _this.image.naturalWidth; - _this.height = _this._sprite.sheight = _this._sprite.naturalHeight = _this._sprite.height = _this.image.naturalHeight; - _this.loaded.resolve(_this.image); - complete.resolve(_this.image); - }); - _this.image.src = _super.prototype.getData.call(_this); - }, function () { - complete.reject('Error loading texture.'); - }); - return complete; + Animation.prototype.desaturate = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Desaturate(factor)); }; - Texture.prototype.asSprite = function () { - return this._sprite; + /** + * Add a [[ISpriteEffect]] manually + */ + Animation.prototype.addEffect = function (effect) { + for (var i in this.sprites) { + this.sprites[i].addEffect(effect); + } + }; + Animation.prototype.removeEffect = function (param) { + for (var i in this.sprites) { + this.sprites[i].removeEffect(param); + } }; - return Texture; - })(ex.Resource); - ex.Texture = Texture; - /** - * Sounds - * - * The [[Sound]] object allows games built in Excalibur to load audio - * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] - * which means it can be passed to a [[Loader]] to pre-load before a game or level. - * - * ## Pre-loading sounds - * - * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] - * is loaded, you can [[Sound.play|play]] it. - * - * ```js - * // define multiple sources (such as mp3/wav/ogg) as a browser fallback - * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); - * - * var loader = new ex.Loader(sndPlayerDeath); - * - * game.start(loader).then(function () { - * - * sndPlayerDeath.play(); - * }); - * ``` - */ - var Sound = (function () { /** - * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. + * Clear all sprite effects */ - function Sound() { - var paths = []; - for (var _i = 0; _i < arguments.length; _i++) { - paths[_i - 0] = arguments[_i]; + Animation.prototype.clearEffects = function () { + for (var i in this.sprites) { + this.sprites[i].clearEffects(); } - this._logger = ex.Logger.getInstance(); - this.onprogress = function () { return; }; - this.oncomplete = function () { return; }; - this.onerror = function () { return; }; - this.onload = function () { return; }; - this._isLoaded = false; - this._wasPlayingOnHidden = false; - /* Chrome : MP3, WAV, Ogg - * Firefox : WAV, Ogg, - * IE : MP3, WAV coming soon - * Safari MP3, WAV, Ogg + }; + Animation.prototype._setAnchor = function (point) { + //if (!this.anchor.equals(point)) { + for (var i in this.sprites) { + this.sprites[i].anchor.setTo(point.x, point.y); + } + //} + }; + Animation.prototype._setRotation = function (radians) { + //if (this.rotation !== radians) { + for (var i in this.sprites) { + this.sprites[i].rotation = radians; + } + //} + }; + Animation.prototype._setScale = function (scale) { + //if (!this.scale.equals(scale)) { + for (var i in this.sprites) { + this.sprites[i].scale = scale; + } + //} + }; + /** + * Resets the animation to first frame. + */ + Animation.prototype.reset = function () { + this.currentFrame = 0; + }; + /** + * Indicates whether the animation is complete, animations that loop are never complete. + */ + Animation.prototype.isDone = function () { + return (!this.loop && this.currentFrame >= this.sprites.length); + }; + /** + * Not meant to be called by game developers. Ticks the animation forward internally and + * calculates whether to change to the frame. + * @internal + */ + Animation.prototype.tick = function () { + var time = Date.now(); + if ((time - this._oldTime) > this.speed) { + this.currentFrame = (this.loop ? (this.currentFrame + 1) % this.sprites.length : this.currentFrame + 1); + this._oldTime = time; + } + }; + Animation.prototype._updateValues = function () { + this._setAnchor(this.anchor); + this._setRotation(this.rotation); + this._setScale(this.scale); + }; + /** + * Skips ahead a specified number of frames in the animation + * @param frames Frames to skip ahead + */ + Animation.prototype.skip = function (frames) { + this.currentFrame = (this.currentFrame + frames) % this.sprites.length; + }; + Animation.prototype.draw = function (ctx, x, y) { + this.tick(); + this._updateValues(); + var currSprite; + if (this.currentFrame < this.sprites.length) { + currSprite = this.sprites[this.currentFrame]; + if (this.flipVertical) { + currSprite.flipVertical = this.flipVertical; + } + if (this.flipHorizontal) { + currSprite.flipHorizontal = this.flipHorizontal; + } + currSprite.draw(ctx, x, y); + } + if (this.freezeFrame !== -1 && this.currentFrame >= this.sprites.length) { + currSprite = this.sprites[ex.Util.clamp(this.freezeFrame, 0, this.sprites.length - 1)]; + currSprite.draw(ctx, x, y); + } + // add the calculated width + if (currSprite) { + this.width = currSprite.width; + this.height = currSprite.height; + } + }; + /** + * Plays an animation at an arbitrary location in the game. + * @param x The x position in the game to play + * @param y The y position in the game to play + */ + Animation.prototype.play = function (x, y) { + this.reset(); + this._engine.playAnimation(this, x, y); + }; + return Animation; + })(); + ex.Animation = Animation; +})(ex || (ex = {})); +/// +/// +/// +var ex; +(function (ex) { + var Internal; + (function (Internal) { + var FallbackAudio = (function () { + function FallbackAudio(path, volume) { + this.path = path; + this._log = ex.Logger.getInstance(); + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + if (window.AudioContext) { + this._log.debug('Using new Web Audio Api for ' + path); + this._soundImpl = new WebAudio(path, volume); + } + else { + this._log.debug('Falling back to Audio Element for ' + path); + this._soundImpl = new AudioTag(path, volume); + } + } + FallbackAudio.prototype.setVolume = function (volume) { + this._soundImpl.setVolume(volume); + }; + FallbackAudio.prototype.setLoop = function (loop) { + this._soundImpl.setLoop(loop); + }; + FallbackAudio.prototype.load = function () { + this._soundImpl.onload = this.onload; + this._soundImpl.onprogress = this.onprogress; + this._soundImpl.onerror = this.onerror; + this._soundImpl.load(); + }; + FallbackAudio.prototype.processData = function (data) { + return this._soundImpl.processData(data); + }; + FallbackAudio.prototype.getData = function () { + return this._soundImpl.getData(); + }; + FallbackAudio.prototype.setData = function (data) { + this._soundImpl.setData(data); + }; + FallbackAudio.prototype.isPlaying = function () { + return this._soundImpl.isPlaying(); + }; + FallbackAudio.prototype.play = function () { + return this._soundImpl.play(); + }; + FallbackAudio.prototype.pause = function () { + this._soundImpl.pause(); + }; + FallbackAudio.prototype.stop = function () { + this._soundImpl.stop(); + }; + return FallbackAudio; + })(); + Internal.FallbackAudio = FallbackAudio; + var AudioTag = (function () { + function AudioTag(path, volume) { + var _this = this; + this.path = path; + this._audioElements = new Array(5); + this._loadedAudio = null; + this._isLoaded = false; + this._index = 0; + this._log = ex.Logger.getInstance(); + this._isPlaying = false; + this._currentOffset = 0; + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + for (var i = 0; i < this._audioElements.length; i++) { + (function (i) { + _this._audioElements[i] = new Audio(); + })(i); + } + if (volume) { + this.setVolume(ex.Util.clamp(volume, 0, 1.0)); + } + else { + this.setVolume(1.0); + } + } + AudioTag.prototype.isPlaying = function () { + return this._isPlaying; + }; + AudioTag.prototype._audioLoaded = function () { + this._isLoaded = true; + }; + AudioTag.prototype.setVolume = function (volume) { + var i = 0, len = this._audioElements.length; + for (i; i < len; i++) { + this._audioElements[i].volume = volume; + } + }; + AudioTag.prototype.setLoop = function (loop) { + var i = 0, len = this._audioElements.length; + for (i; i < len; i++) { + this._audioElements[i].loop = loop; + } + }; + AudioTag.prototype.getLoop = function () { + this._audioElements.some(function (a) { return a.loop; }); + }; + AudioTag.prototype.load = function () { + var _this = this; + if (!!this._loadedAudio) { + return; + } + var request = new XMLHttpRequest(); + request.open('GET', this.path, true); + request.responseType = 'blob'; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function (e) { + if (request.status !== 200) { + _this._log.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + _this._isLoaded = false; + return; + } + _this._isLoaded = true; + _this.setData(request.response); + _this.onload(e); + }; + request.send(); + }; + AudioTag.prototype.getData = function () { + return this._loadedAudio; + }; + AudioTag.prototype.setData = function (data) { + this._isLoaded = true; + this._loadedAudio = this.processData(data); + }; + AudioTag.prototype.processData = function (data) { + var blobUrl = URL.createObjectURL(data); + this._audioElements.forEach(function (a) { + a.src = blobUrl; + }); + this._audioLoaded(); + return blobUrl; + }; + AudioTag.prototype.play = function () { + var _this = this; + this._audioElements[this._index].load(); + //this.audioElements[this.index].currentTime = this._currentOffset; + this._audioElements[this._index].play(); + this._currentOffset = 0; + var done = new ex.Promise(); + this._isPlaying = true; + if (!this.getLoop()) { + this._audioElements[this._index].addEventListener('ended', function () { + _this._isPlaying = false; + done.resolve(true); + }); + } + this._index = (this._index + 1) % this._audioElements.length; + return done; + }; + AudioTag.prototype.pause = function () { + this._index = (this._index - 1 + this._audioElements.length) % this._audioElements.length; + this._currentOffset = this._audioElements[this._index].currentTime; + this._audioElements.forEach(function (a) { + a.pause(); + }); + this._isPlaying = false; + }; + AudioTag.prototype.stop = function () { + this._audioElements.forEach(function (a) { + a.pause(); + //a.currentTime = 0; + }); + this._isPlaying = false; + }; + return AudioTag; + })(); + Internal.AudioTag = AudioTag; + if (window.AudioContext) { + var audioContext = new window.AudioContext(); + } + var WebAudio = (function () { + function WebAudio(path, volume) { + this.path = path; + this._context = audioContext; + this._volume = this._context.createGain(); + this._buffer = null; + this._sound = null; + this._isLoaded = false; + this._loop = false; + this._isPlaying = false; + this._isPaused = false; + this._currentOffset = 0; + this._logger = ex.Logger.getInstance(); + this._data = null; + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + if (volume) { + this._volume.gain.value = ex.Util.clamp(volume, 0, 1.0); + } + else { + this._volume.gain.value = 1.0; // max volume + } + } + WebAudio.prototype.setVolume = function (volume) { + this._volume.gain.value = volume; + }; + WebAudio.prototype.load = function () { + var _this = this; + // Exit early if we already have data + if (this._data !== null) { + return; + } + var request = new XMLHttpRequest(); + request.open('GET', this.path); + request.responseType = 'arraybuffer'; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function () { + if (request.status !== 200) { + _this._logger.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + _this._isLoaded = false; + return; + } + _this.setData(request.response); + }; + try { + request.send(); + } + catch (e) { + console.error('Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.'); + } + }; + WebAudio.prototype.getData = function () { + return this._data; + }; + WebAudio.prototype.setData = function (data) { + this._data = this.processData(data); + }; + WebAudio.prototype.processData = function (data) { + var _this = this; + this._context.decodeAudioData(data, function (buffer) { + _this._buffer = buffer; + _this._isLoaded = true; + _this.onload(_this); + }, function (e) { + _this._logger.error('Unable to decode ' + _this.path + + ' this browser may not fully support this format, or the file may be corrupt, ' + + 'if this is an mp3 try removing id3 tags and album art from the file.'); + _this._isLoaded = false; + _this.onload(_this); + }); + return data; + }; + WebAudio.prototype.setLoop = function (loop) { + this._loop = loop; + }; + WebAudio.prototype.isPlaying = function () { + return this._isPlaying; + }; + WebAudio.prototype.play = function () { + var _this = this; + if (this._isLoaded) { + this._sound = this._context.createBufferSource(); + this._sound.buffer = this._buffer; + this._sound.loop = this._loop; + this._sound.connect(this._volume); + this._volume.connect(this._context.destination); + this._sound.start(0, this._currentOffset % this._buffer.duration); + this._currentOffset = 0; + var done; + if (!this._isPaused || !this._playPromise) { + done = new ex.Promise(); + } + else { + done = this._playPromise; + } + this._isPaused = false; + this._isPlaying = true; + if (!this._loop) { + this._sound.onended = (function () { + _this._isPlaying = false; + if (!_this._isPaused) { + done.resolve(true); + } + }).bind(this); + } + this._playPromise = done; + return done; + } + else { + return ex.Promise.wrap(true); + } + }; + WebAudio.prototype.pause = function () { + if (this._isPlaying) { + try { + window.clearTimeout(this._playingTimer); + this._sound.stop(0); + this._currentOffset = this._context.currentTime; + this._isPlaying = false; + this._isPaused = true; + } + catch (e) { + this._logger.warn('The sound clip', this.path, 'has already been paused!'); + } + } + }; + WebAudio.prototype.stop = function () { + if (this._sound) { + try { + window.clearTimeout(this._playingTimer); + this._currentOffset = 0; + this._sound.stop(0); + this._isPlaying = false; + this._isPaused = false; + } + catch (e) { + this._logger.warn('The sound clip', this.path, 'has already been stopped!'); + } + } + }; + /** + * Play an empty sound to unlock Safari WebAudio context. Call this function + * right after a user interaction event. Typically used by [[PauseAfterLoader]] + * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/ */ - this.path = ''; - for (var i = 0; i < paths.length; i++) { - if (Sound.canPlayFile(paths[i])) { - this.path = paths[i]; - break; + WebAudio.unlock = function () { + if (this._unlocked || !audioContext) { + return; } - } - if (!this.path) { - this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); - this._logger.warn('Attempting to use', paths[0]); - this.path = paths[0]; // select the first specified - } - this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); - } - /** - * Whether or not the browser can play this file as HTML5 Audio - */ - Sound.canPlayFile = function (file) { - try { - var a = new Audio(); - var filetype = /.*\.([A-Za-z0-9]+)$/; - var type = file.match(filetype)[1]; - if (a.canPlayType('audio/' + type)) { - return true; + // create empty buffer and play it + var buffer = audioContext.createBuffer(1, 1, 22050); + var source = audioContext.createBufferSource(); + source.buffer = buffer; + source.connect(audioContext.destination); + if (source.noteOn) { + source.noteOn(0); } - { - return false; + else { + source.start(0); } - } - catch (e) { - ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); - return false; - } - }; - Sound.prototype.wireEngine = function (engine) { - var _this = this; - if (engine) { - this._engine = engine; - this._engine.on('hidden', function () { - if (engine.pauseAudioWhenHidden && _this.isPlaying()) { - _this._wasPlayingOnHidden = true; - _this.pause(); - } - }); - this._engine.on('visible', function () { - if (engine.pauseAudioWhenHidden && _this._wasPlayingOnHidden) { - _this.play(); - _this._wasPlayingOnHidden = false; + // by checking the play state after some time, we know if we're really unlocked + setTimeout(function () { + if (source.playbackState === source.PLAYING_STATE || + source.playbackState === source.FINISHED_STATE) { + this._unlocked = true; } - }); - } - }; - /** - * Sets the volume of the sound clip - * @param volume A volume value between 0-1.0 - */ - Sound.prototype.setVolume = function (volume) { - if (this.sound) { - this.sound.setVolume(volume); - } - }; - /** - * Indicates whether the clip should loop when complete - * @param loop Set the looping flag - */ - Sound.prototype.setLoop = function (loop) { - if (this.sound) { - this.sound.setLoop(loop); - } - }; - /** - * Whether or not the sound is playing right now - */ - Sound.prototype.isPlaying = function () { - if (this.sound) { - return this.sound.isPlaying(); - } - }; - /** - * Play the sound, returns a promise that resolves when the sound is done playing - */ - Sound.prototype.play = function () { - if (this.sound) { - return this.sound.play(); - } - }; - /** - * Stop the sound, and do not rewind - */ - Sound.prototype.pause = function () { - if (this.sound) { - this.sound.pause(); - } - }; - /** - * Stop the sound and rewind - */ - Sound.prototype.stop = function () { - if (this.sound) { - this.sound.stop(); - } - }; - /** - * Returns true if the sound is loaded - */ - Sound.prototype.isLoaded = function () { - return this._isLoaded; - }; - /** - * Begins loading the sound and returns a promise to be resolved on completion - */ - Sound.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - if (this.sound.getData() !== null) { - this._logger.debug('Already have data for resource', this.path); - complete.resolve(this.sound); - return complete; - } - this._logger.debug('Started loading sound', this.path); - this.sound.onprogress = this.onprogress; - this.sound.onload = function () { - _this.oncomplete(); - _this._isLoaded = true; - _this._logger.debug('Completed loading sound', _this.path); - complete.resolve(_this.sound); + }, 0); }; - this.sound.onerror = function (e) { - _this.onerror(e); - complete.resolve(e); + WebAudio.isUnlocked = function () { + return this._unlocked; }; - this.sound.load(); - return complete; - }; - Sound.prototype.getData = function () { - return this.sound.getData(); - }; - Sound.prototype.setData = function (data) { - this.sound.setData(data); - }; - Sound.prototype.processData = function (data) { - return this.sound.processData(data); - }; - return Sound; - })(); - ex.Sound = Sound; + WebAudio._unlocked = false; + return WebAudio; + })(); + Internal.WebAudio = WebAudio; + })(Internal = ex.Internal || (ex.Internal = {})); +})(ex || (ex = {})); +/// +/// +/// +/// +/// +/// +var ex; +(function (ex) { /** * Pre-loading assets * @@ -10010,11 +10057,13 @@ var ex; * }); * ``` */ - var Loader = (function () { + var Loader = (function (_super) { + __extends(Loader, _super); /** * @param loadables Optionally provide the list of resources you want to load at constructor time */ function Loader(loadables) { + _super.call(this); this._resourceList = []; this._index = 0; this._resourceCount = 0; @@ -10024,7 +10073,10 @@ var ex; this.getData = function () { return; }; this.setData = function (data) { return; }; this.processData = function (data) { return; }; - this.onprogress = function () { return; }; + this.onprogress = function (e) { + ex.Logger.getInstance().debug('[ex.Loader] Loading ' + (100 * e.loaded / e.total).toFixed(0)); + return; + }; this.oncomplete = function () { return; }; this.onerror = function () { return; }; if (loadables) { @@ -10099,7 +10151,6 @@ var ex; r.oncomplete = r.onerror = function () { me._numLoaded++; if (me._numLoaded === me._resourceCount) { - me.onprogress.call(me, { loaded: 100, total: 100 }); me.oncomplete.call(me); complete.resolve(); } @@ -10116,9 +10167,160 @@ var ex; loadNext(this._resourceList, 0); return complete; }; + /** + * Loader draw function. Draws the default Excalibur loading screen. Override to customize the drawing. + */ + Loader.prototype.draw = function (ctx, delta) { + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, this._engine.width, this._engine.height); + var y = this._engine.canvas.height / 2; + var width = this._engine.canvas.width / 3; + var x = width; + // loading image + var image = new Image(); + /* tslint:disable:max-line-length */ + // 64 bit string encoding of the excalibur logo + image.src = 'data:image/png;base64,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'; + /* tslint:enable:max-line-length */ + var imageHeight = width * 3 / 8; + var oldAntialias = this._engine.getAntialiasing(); + this._engine.setAntialiasing(true); + ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); + // loading box + ctx.strokeStyle = 'white'; + ctx.lineWidth = 2; + ctx.strokeRect(x, y, width, 20); + var progress = width * (this._numLoaded / this._resourceCount); + ctx.fillStyle = 'white'; + var margin = 5; + var progressWidth = progress - margin * 2; + var height = 20 - margin * 2; + ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); + this._engine.setAntialiasing(oldAntialias); + }; + /** + * Perform any calculations or logic in the `update` method. The default `Loader` does not + * do anything in this method so it is safe to override. + */ + Loader.prototype.update = function (engine, delta) { + // overridable update + }; return Loader; - })(); + })(ex.Class); ex.Loader = Loader; + /** + * A [[Loader]] that pauses after loading to allow user + * to proceed to play the game. Typically you will + * want to use this loader for iOS to allow sounds + * to play after loading (Apple Safari requires user + * interaction to allow sounds, even for games) + * + * **Note:** Because Loader is not part of a Scene, you must + * call `update` and `draw` manually on "child" objects. + * + * ## Implementing a Trigger + * + * The `PauseAfterLoader` requires an element to act as the trigger button + * to start the game. + * + * For example, let's create an `` tag to be our trigger and call it `tap-to-play`. + * + * ```html + * + * ``` + * + * We've put it inside a wrapper to position it properly over the game canvas. + * + * Now let's add some CSS to style it (insert into ``): + * + * ```html + * + * ``` + * + * Now we can create a `PauseAfterLoader` with a reference to our trigger button: + * + * ```ts + * var loader = new ex.PauseAfterLoader('tap-to-play', [...]); + * ``` + * + * ## Use PauseAfterLoader for iOS + * + * The primary use case for pausing before starting the game is to + * pass Apple's requirement of user interaction. The Web Audio context + * in Safari is disabled by default until user interaction. + * + * Therefore, you can use this snippet to only use PauseAfterLoader when + * iOS is detected (see [this thread](http://stackoverflow.com/questions/9038625/detect-if-device-is-ios) + * for more techniques). + * + * ```ts + * var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window).MSStream; + * var loader: ex.Loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); + * + * loader.addResource(...); + * ``` + */ + var PauseAfterLoader = (function (_super) { + __extends(PauseAfterLoader, _super); + function PauseAfterLoader(triggerElementId, loadables) { + var _this = this; + _super.call(this, loadables); + this._handleOnTrigger = function () { + if (_this._waitPromise.state() !== ex.PromiseState.Pending) { + return false; + } + // unlock Safari WebAudio context + ex.Internal.WebAudio.unlock(); + // continue to play game + _this._waitPromise.resolve(_this._loadedValue); + // hide DOM element + _this._playTrigger.style.display = 'none'; + return false; + }; + this._playTrigger = document.getElementById(triggerElementId); + this._playTrigger.addEventListener('click', this._handleOnTrigger); + } + PauseAfterLoader.prototype.load = function () { + var _this = this; + this._waitPromise = new ex.Promise(); + // wait until user indicates to proceed before finishing load + var superLoad = _super.prototype.load.call(this).then(function (value) { + _this._loaded = true; + _this._loadedValue = value; + // show element + _this._playTrigger.style.display = 'block'; + }, function (value) { + _this._waitPromise.reject(value); + }); + return this._waitPromise; + }; + return PauseAfterLoader; + })(Loader); + ex.PauseAfterLoader = PauseAfterLoader; })(ex || (ex = {})); /// var ex; @@ -11936,6 +12138,9 @@ var ex; /// /// /// +/// +/// +/// /// /// /// @@ -12259,8 +12464,6 @@ var ex; this.onFatalException = function (e) { ex.Logger.getInstance().fatal(e); }; this._isSmoothingEnabled = true; this._isLoading = false; - this._progress = 0; - this._total = 1; var width; var height; var canvasElementId; @@ -12651,6 +12854,11 @@ var ex; Engine.prototype._update = function (delta) { if (this._isLoading) { // suspend updates untill loading is finished + this._loader.update(this, delta); + // Update input listeners + this.input.keyboard.update(delta); + this.input.pointers.update(delta); + this.input.gamepads.update(delta); return; } this.emit('preupdate', new ex.PreUpdateEvent(this, delta, this)); @@ -12676,9 +12884,7 @@ var ex; var ctx = this.ctx; this.emit('predraw', new ex.PreDrawEvent(ctx, delta, this)); if (this._isLoading) { - ctx.fillStyle = 'black'; - ctx.fillRect(0, 0, this.width, this.height); - this._drawLoadingBar(ctx, this._progress, this._total); + this._loader.draw(ctx, delta); // Drawing nothing else while loading return; } @@ -12711,8 +12917,8 @@ var ex; /** * Starts the internal game loop for Excalibur after loading * any provided assets. - * @param loader Optional resources to load before starting the main loop. Some [[ILoadable]] such as a [[Loader]] collection, - * [[Sound]], or [[Texture]]. + * @param loader Optional [[ILoader]] to use to load resources. The default loader is [[Loader]], override to provide your own + * custom loader. */ Engine.prototype.start = function (loader) { if (!this._compatible) { @@ -12721,8 +12927,9 @@ var ex; } var loadingComplete; if (loader) { - loader.wireEngine(this); - loadingComplete = this.load(loader); + this._loader = loader; + this._loader.wireEngine(this); + loadingComplete = this.load(this._loader); } else { loadingComplete = ex.Promise.wrap(); @@ -12784,50 +12991,6 @@ var ex; result.src = raw; return result; }; - /** - * Draws the Excalibur loading bar - * @param ctx The canvas rendering context - * @param loaded Number of bytes loaded - * @param total Total number of bytes to load - */ - Engine.prototype._drawLoadingBar = function (ctx, loaded, total) { - if (this._loadingDraw) { - this._loadingDraw(ctx, loaded, total); - return; - } - var y = this.canvas.height / 2; - var width = this.canvas.width / 3; - var x = width; - // loading image - var image = new Image(); - /* tslint:disable:max-line-length */ - // 64 bit string encoding of the excalibur logo - image.src = 'data:image/png;base64,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'; - /* tslint:enable:max-line-length */ - var imageHeight = width * 3 / 8; - var oldAntialias = this.getAntialiasing(); - this.setAntialiasing(true); - ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); - // loading box - ctx.strokeStyle = 'white'; - ctx.lineWidth = 2; - ctx.strokeRect(x, y, width, 20); - var progress = width * (loaded / total); - ctx.fillStyle = 'white'; - var margin = 5; - var progressWidth = progress - margin * 2; - var height = 20 - margin * 2; - ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); - this.setAntialiasing(oldAntialias); - }; - /** - * Sets the loading screen draw function if you want to customize the draw - * @param fcn Callback to draw the loading screen which is passed a rendering context, the number of bytes loaded, and the total - * number of bytes to load. - */ - Engine.prototype.setLoadingDrawFunction = function (fcn) { - this._loadingDraw = fcn; - }; /** * Another option available to you to load resources into the game. * Immediately after calling this the game will pause and the loading screen @@ -12838,18 +13001,12 @@ var ex; var _this = this; var complete = new ex.Promise(); this._isLoading = true; - loader.onprogress = function (e) { - _this._progress = e.loaded; - _this._total = e.total; - _this._logger.debug('Loading ' + (100 * _this._progress / _this._total).toFixed(0)); - }; - loader.oncomplete = function () { + loader.load().then(function () { setTimeout(function () { _this._isLoading = false; complete.resolve(); }, 500); - }; - loader.load(); + }); return complete; }; return Engine; diff --git a/dist/Excalibur.min.js b/dist/Excalibur.min.js index 7c48eb354..4ef3804d0 100644 --- a/dist/Excalibur.min.js +++ b/dist/Excalibur.min.js @@ -4,9 +4,8 @@ "undefined"==typeof window&&(window={audioContext:function(){}}),"undefined"==typeof window||window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setInterval(t,1e3/60)}),"undefined"==typeof window||window.cancelAnimationFrame||(window.cancelAnimationFrame=window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(){}),"undefined"==typeof window||window.AudioContext||(window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){var i,n;if(null==this)throw new TypeError(" this is null or not defined");var s=Object(this),o=s.length>>>0;if("function"!=typeof t)throw new TypeError(t+" is not a function");for(arguments.length>1&&(i=e),n=0;o>n;){var r;n in s&&(r=s[n],t.call(i,r,n,s)),n++}}),Array.prototype.some||(Array.prototype.some=function(t){"use strict";if(void 0===this||null===this)throw new TypeError;var e=Object(this),i=e.length>>>0;if("function"!=typeof t)throw new TypeError;for(var n=arguments.length>=2?arguments[1]:void 0,s=0;i>s;s++)if(s in e&&t.call(n,e[s],s,e))return!0;return!1}),Function.prototype.bind||(Function.prototype.bind=function(t){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var e=Array.prototype.slice.call(arguments,1),i=this,n=function(){},s=function(){return i.apply(this instanceof n&&t?this:t,e.concat(Array.prototype.slice.call(arguments)))};return n.prototype=this.prototype,s.prototype=new n,s});var ex;(function(t){var e;(function(e){var i=function(){function t(){}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data,o=(s[n+0]+s[n+1]+s[n+2])/3;s[n+0]=o,s[n+1]=o,s[n+2]=o},t}();e.Grayscale=i;var n=function(){function t(){}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;s[n+0]=255-s[n+0],s[n+1]=255-s[n+1],s[n+2]=255-s[n+2]},t}();e.Invert=n;var s=function(){function t(t){this.opacity=t}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;0!==s[n+3]&&(s[n+3]=Math.round(255*this.opacity))},t}();e.Opacity=s;var o=function(){function t(t){this.color=t}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;0!==s[n+3]&&(s[n+0]=(s[n+0]+this.color.r)/2,s[n+1]=(s[n+1]+this.color.g)/2,s[n+2]=(s[n+2]+this.color.b)/2)},t}();e.Colorize=o;var r=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).lighten(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Lighten=r;var h=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).darken(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Darken=h;var a=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).saturate(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Saturate=a;var c=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).desaturate(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Desaturate=c;var u=function(){function t(t){this.color=t}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;0!==s[n+3]&&(s[n+0]=this.color.r,s[n+1]=this.color.g,s[n+2]=this.color.b)},t}();e.Fill=u})(e=t.Effects||(t.Effects={}))})(ex||(ex={}));var ex;(function(t){var e;(function(t){var e=function(){function t(){}return t.prototype.update=function(t,e,i){t.x+=t.dx*i/1e3,t.y+=t.dy*i/1e3,t.dx+=t.ax*i/1e3,t.dy+=t.ay*i/1e3,t.rotation+=t.rx*i/1e3,t.scale.x+=t.sx*i/1e3,t.scale.y+=t.sy*i/1e3},t}();t.Movement=e})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this._topLeft=new t.Point(0,0),this._topRight=new t.Point(0,0),this._bottomLeft=new t.Point(0,0),this._bottomRight=new t.Point(0,0)}return e.prototype.isSpriteOffScreen=function(e,i){var n=e.currentDrawing.width*e.currentDrawing.scale.x,s=e.currentDrawing.height*e.currentDrawing.scale.y,o=e.rotation,r=e.getCenter().toPoint();this._topLeft.x=e.getWorldX()-n/2,this._topLeft.y=e.getWorldY()-s/2,this._topLeft=this._topLeft.rotate(o,r),this._topRight.x=e.getWorldX()+n/2,this._topRight.y=e.getWorldY()-s/2,this._topRight=this._topRight.rotate(o,r),this._bottomLeft.x=e.getWorldX()-n/2,this._bottomLeft.y=e.getWorldY()+s/2,this._bottomLeft=this._bottomLeft.rotate(o,r),this._bottomRight.x=e.getWorldX()+n/2,this._bottomRight.y=e.getWorldY()+s/2,this._bottomRight=this._bottomRight.rotate(o,r);var h=i.worldToScreenCoordinates(this._topLeft),a=i.worldToScreenCoordinates(this._topRight),c=i.worldToScreenCoordinates(this._bottomLeft),u=i.worldToScreenCoordinates(this._bottomRight);this._xCoords=[],this._yCoords=[],this._xCoords.push(h.x,a.x,c.x,u.x),this._yCoords.push(h.y,a.y,c.y,u.y),this._xMin=Math.min.apply(null,this._xCoords),this._yMin=Math.min.apply(null,this._yCoords),this._xMax=Math.max.apply(null,this._xCoords),this._yMax=Math.max.apply(null,this._yCoords);var l=i.screenToWorldCoordinates(new t.Point(this._xMin,this._yMin)),p=i.screenToWorldCoordinates(new t.Point(this._xMax,this._yMax));this._xMinWorld=l.x,this._yMinWorld=l.y,this._xMaxWorld=p.x,this._yMaxWorld=p.y;var d=[];d.push(new t.Point(this._xMin,this._yMin),new t.Point(this._xMax,this._yMin),new t.Point(this._xMin,this._yMax),new t.Point(this._xMax,this._yMax));for(var f=0;d.length>f;f++)if(d[f].x>0&&d[f].y>0&&d[f].x0&&a.y+h*c>0&&a.xa.x+r*c||0>a.y+h*c||a.x>i.width||a.y>i.height)&&u&&(n.emit("exitviewport",new t.ExitViewPortEvent),e.isOffScreen=!0)},e}();e.OffscreenCulling=i})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){var e;(function(t){var e=function(){function t(){}return t.prototype.update=function(t,e){t.enableCapturePointer&&(t.isKilled()||e.input.pointers.propogate(t))},t}();t.CapturePointer=e})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(){function e(){}return e.prototype.update=function(e,i){var n=e.eventDispatcher;if(e.collisionType!==t.CollisionType.PreventCollision&&i.currentScene&&i.currentScene.tileMaps)for(var s=0;i.currentScene.tileMaps.length>s;s++)for(var o,r=i.currentScene.tileMaps[s],h=t.Side.None,a=2,c=!1;(o=r.collides(e))&&!(0>a--);)h=e.getSideFromIntersect(o),n.emit("collision",new t.CollisionEvent(e,null,h,o)),(e.collisionType===t.CollisionType.Active||e.collisionType===t.CollisionType.Elastic)&&(e.y+=o.y,e.x+=o.x,e.collisionType!==t.CollisionType.Elastic||c||(c=!0,h===t.Side.Left?e.dx=Math.abs(e.dx):h===t.Side.Right?e.dx=-Math.abs(e.dx):h===t.Side.Top?e.dy=Math.abs(e.dy):h===t.Side.Bottom&&(e.dy=-Math.abs(e.dy))))},e}();e.CollisionDetection=i})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){(function(t){t[t.None=0]="None",t[t.Top=1]="Top",t[t.Bottom=2]="Bottom",t[t.Left=3]="Left",t[t.Right=4]="Right"})(t.Side||(t.Side={})),t.Side})(ex||(ex={}));var __extends=this&&this.__extends||function(t,e){function i(){this.constructor=t}for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)},ex;(function(t){var e=function(){function e(t,e){this.x=t,this.y=e}return e.prototype.toVector=function(){return new i(this.x,this.y)},e.prototype.rotate=function(i,n){n||(n=new t.Point(0,0));var s=Math.sin(i),o=Math.cos(i),r=o*(this.x-n.x)-s*(this.y-n.y)+n.x,h=s*(this.x-n.x)+o*(this.y-n.y)+n.y;return new e(r,h)},e.prototype.add=function(t){return new e(this.x+t.x,this.y+t.y)},e.prototype.setTo=function(t,e){this.x=t,this.y=e},e.prototype.clone=function(){return new e(this.x,this.y)},e.prototype.equals=function(t){return this.x===t.x&&this.y===t.y},e}();t.Point=e;var i=function(t){function i(e,i){t.call(this,e,i),this.x=e,this.y=i}return __extends(i,t),i.fromAngle=function(t){return new i(Math.cos(t),Math.sin(t))},i.prototype.distance=function(t){return t||(t=new i(0,0)),Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},i.prototype.normalize=function(){var t=this.distance();return t>0?new i(this.x/t,this.y/t):new i(0,1)},i.prototype.scale=function(t){return new i(this.x*t,this.y*t)},i.prototype.plus=function(t){return this.add(t)},i.prototype.add=function(t){return new i(this.x+t.x,this.y+t.y)},i.prototype.subtract=function(t){return this.minus(t)},i.prototype.minus=function(t){return new i(this.x-t.x,this.y-t.y)},i.prototype.dot=function(t){return this.x*t.x+this.y*t.y},i.prototype.cross=function(t){return this.x*t.y-this.y*t.x},i.prototype.perpendicular=function(){return new i(this.y,-this.x)},i.prototype.normal=function(){return this.perpendicular().normalize()},i.prototype.toAngle=function(){return Math.atan2(this.y,this.x)},i.prototype.toPoint=function(){return new e(this.x,this.y)},i.prototype.rotate=function(e,i){return t.prototype.rotate.call(this,e,i).toVector()},i.prototype.clone=function(){return new i(this.x,this.y)},i.Zero=new i(0,0),i}(e);t.Vector=i;var n=function(){function t(t,e){this.pos=t,this.dir=e.normalize()}return t.prototype.intersect=function(t){var e=t.begin.toVector().minus(this.pos.toVector());if(0===this.dir.cross(t.getSlope())&&0!==e.cross(this.dir))return-1;var i=this.dir.cross(t.getSlope());if(0===i)return-1;var n=e.cross(t.getSlope())/i;if(n>=0){var s=e.cross(this.dir)/i/t.getLength();if(s>=0&&1>=s)return n}return-1},t.prototype.getPoint=function(t){return this.pos.toVector().add(this.dir.scale(t)).toPoint()},t}();t.Ray=n;var s=function(){function t(t,e){this.begin=t,this.end=e}return t.prototype.getSlope=function(){var t=this.begin.toVector(),e=this.end.toVector(),i=t.distance(e);return e.minus(t).scale(1/i)},t.prototype.getLength=function(){var t=this.begin.toVector(),e=this.end.toVector(),i=t.distance(e);return i},t}();t.Line=s;var o=function(){function t(t,e){this.min=t,this.max=e}return t.prototype.overlaps=function(t){return this.max>t.min&&t.max>this.min},t.prototype.getOverlap=function(t){return this.overlaps(t)?this.max>t.max?t.max-this.min:this.max-t.min:0},t}();t.Projection=o})(ex||(ex={}));var ex;(function(t){var e;(function(e){function i(t){for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",i="",n=0;t.length>n;){var s,o,r=255&t.charCodeAt(n++),h=255&t.charCodeAt(n++),a=255&t.charCodeAt(n++),c=r>>2,u=(3&r)<<4|h>>4;isNaN(h)?s=o=64:(s=(15&h)<<2|a>>6,o=isNaN(a)?64:63&a),i+=e.charAt(c)+e.charAt(u)+e.charAt(s)+e.charAt(o)}return i}function n(t,e,i){return e>=t?e:t>=i?i:t}function s(t,e,i,n,s,o){t.beginPath(),t.strokeStyle=e,t.moveTo(i,n),t.lineTo(s,o),t.closePath(),t.stroke()}function o(t,e){return t+Math.random()*(e-t)}function r(t,e){return Math.round(o(t,e))}function h(t){var e=t;if(t>this.TwoPI)for(;e>this.TwoPI;)e-=this.TwoPI;if(0>t)for(;0>e;)e+=this.TwoPI;return e}function a(t){return 180/Math.PI*t}function c(t){return t/180*Math.PI}function u(e){var i=0,n=0,s=function(t){i+=t.offsetLeft,t.offsetParent&&s(t.offsetParent)},o=function(t){n+=t.offsetTop,t.offsetParent&&o(t.offsetParent)};return s(e),o(e),new t.Point(i,n)}function l(t,e){return-1===e.indexOf(t)?(e.push(t),!0):!1}function p(t,e){var i=-1;return(i=e.indexOf(t))>-1?(e.splice(i,1),!0):!1}function d(t,e){for(var i=0;t.length>i;i++)if(t[i]===e)return!0;return!1}function f(e){return e===t.Side.Top?t.Side.Bottom:e===t.Side.Bottom?t.Side.Top:e===t.Side.Left?t.Side.Right:e===t.Side.Right?t.Side.Left:t.Side.None}e.TwoPI=2*Math.PI,e.base64Encode=i,e.clamp=n,e.drawLine=s,e.randomInRange=o,e.randomIntInRange=r,e.canonicalizeAngle=h,e.toDegrees=a,e.toRadians=c,e.getPosition=u,e.addItemToArray=l,e.removeItemToArray=p,e.contains=d,e.getOppositeSide=f;var g=function(){function t(e){void 0===e&&(e=t.DefaultSize),this._internalArray=null,this._endPointer=0,this._internalArray=Array(e)}return t.prototype._resize=function(){for(var t=2*this._internalArray.length,e=Array(t),i=this.count(),n=0;i>n;n++)e[n]=this._internalArray[n];delete this._internalArray,this._internalArray=e},t.prototype.push=function(t){return this._endPointer===this._internalArray.length&&this._resize(),this._internalArray[this._endPointer++]=t},t.prototype.pop=function(){return this._endPointer=0>this._endPointer-1?0:this._endPointer-1,this._internalArray[this._endPointer]},t.prototype.count=function(){return this._endPointer},t.prototype.clear=function(){this._endPointer=0},t.prototype.internalSize=function(){return this._internalArray.length},t.prototype.elementAt=function(t){return t>=this.count()?void 0:this._internalArray[t]},t.prototype.insert=function(t,e){return t>=this.count()&&this._resize(),this._internalArray[t]=e},t.prototype.remove=function(t){var e=this.count();if(0!==e){for(var i=this._internalArray[t],n=t;e>n;n++)this._internalArray[n]=this._internalArray[n+1];return this._endPointer--,i}},t.prototype.removeElement=function(t){var e=this._internalArray.indexOf(t);this.remove(e)},t.prototype.toArray=function(){return this._internalArray.slice(0,this._endPointer)},t.prototype.forEach=function(t){var e=0,i=this.count();for(e;i>e;e++)t.call(this,this._internalArray[e],e)},t.prototype.map=function(t){for(var e=this.count(),i=0;e>i;i++)this._internalArray[i]=t.call(this,this._internalArray[i],i)},t.DefaultSize=200,t}();e.Collection=g})(e=t.Util||(t.Util={}))})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s,o){var r=this;this.sx=i,this.sy=n,this.swidth=s,this.sheight=o,this.rotation=0,this.anchor=new t.Point(0,0),this.scale=new t.Point(1,1),this.logger=t.Logger.getInstance(),this.flipVertical=!1,this.flipHorizontal=!1,this.width=0,this.height=0,this.effects=[],this.internalImage=new Image,this.naturalWidth=0,this.naturalHeight=0,this._spriteCanvas=null,this._spriteCtx=null,this._pixelData=null,this._pixelsLoaded=!1,this._dirtyEffect=!1,(0>i||0>n||0>s||0>o)&&this.logger.error("Sprite cannot have any negative dimensions x:",i,"y:",n,"width:",s,"height:",o),this._texture=e,this._spriteCanvas=document.createElement("canvas"),this._spriteCanvas.width=s,this._spriteCanvas.height=o,this._spriteCtx=this._spriteCanvas.getContext("2d"),this._texture.loaded.then(function(){r._spriteCanvas.width=r._spriteCanvas.width||r._texture.image.naturalWidth,r._spriteCanvas.height=r._spriteCanvas.height||r._texture.image.naturalHeight,r._loadPixels(),r._dirtyEffect=!0}).error(function(t){r.logger.error("Error loading texture ",r._texture.path,t)}),this.width=s,this.height=o,this.naturalWidth=s,this.naturalHeight=o}return e.prototype._loadPixels=function(){if(this._texture.isLoaded()&&!this._pixelsLoaded){var e=t.Util.clamp,i=this._texture.image.naturalWidth||0,n=this._texture.image.naturalHeight||0;this.swidth>i&&this.logger.warn("The sprite width",this.swidth,"exceeds the width",i,"of the backing texture",this._texture.path),this.sheight>n&&this.logger.warn("The sprite height",this.sheight,"exceeds the height",n,"of the backing texture",this._texture.path),this._spriteCtx.drawImage(this._texture.image,e(this.sx,0,i),e(this.sy,0,n),e(this.swidth,0,i),e(this.sheight,0,n),0,0,this.swidth,this.sheight),this.internalImage.src=this._spriteCanvas.toDataURL("image/png"),this._pixelsLoaded=!0}},e.prototype.opacity=function(e){this.addEffect(new t.Effects.Opacity(e))},e.prototype.grayscale=function(){this.addEffect(new t.Effects.Grayscale)},e.prototype.invert=function(){this.addEffect(new t.Effects.Invert)},e.prototype.fill=function(e){this.addEffect(new t.Effects.Fill(e))},e.prototype.colorize=function(e){this.addEffect(new t.Effects.Colorize(e))},e.prototype.lighten=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Lighten(e))},e.prototype.darken=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Darken(e))},e.prototype.saturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Saturate(e))},e.prototype.desaturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Desaturate(e))},e.prototype.addEffect=function(t){this.effects.push(t),this._texture.isLoaded()&&this._pixelsLoaded?this._applyEffects():this._dirtyEffect=!0},e.prototype.removeEffect=function(t){var e=null;e="number"==typeof t?t:this.effects.indexOf(t),this.effects.splice(e,1),this._texture.isLoaded()&&this._pixelsLoaded?this._applyEffects():this._dirtyEffect=!0},e.prototype._applyEffects=function(){var e=t.Util.clamp,i=this._texture.image.naturalWidth||0,n=this._texture.image.naturalHeight||0;this._spriteCtx.clearRect(0,0,this.swidth,this.sheight),this._spriteCtx.drawImage(this._texture.image,e(this.sx,0,i),e(this.sy,0,n),e(this.swidth,0,i),e(this.sheight,0,n),0,0,this.swidth,this.sheight),this._pixelData=this._spriteCtx.getImageData(0,0,this.swidth,this.sheight);var s=0,o=0,r=0,h=this.effects.length;for(s;h>s;s++)for(r=0;this.sheight>r;r++)for(o=0;this.swidth>o;o++)this.effects[s].updatePixel(o,r,this._pixelData);this._spriteCtx.clearRect(0,0,this.swidth,this.sheight),this._spriteCtx.putImageData(this._pixelData,0,0),this.internalImage.src=this._spriteCanvas.toDataURL("image/png")},e.prototype.clearEffects=function(){this.effects.length=0,this._applyEffects()},e.prototype.reset=function(){},e.prototype.debugDraw=function(e,i,n){e.save(),e.translate(i,n),e.rotate(this.rotation);var s=this.width*this.scale.x*this.anchor.x,o=this.height*this.scale.y*this.anchor.y;e.strokeStyle=t.Color.Black,e.strokeRect(-s,-o,this.width*this.scale.x,this.height*this.scale.y),e.restore()},e.prototype.draw=function(t,e,i){this._dirtyEffect&&(this._applyEffects(),this._dirtyEffect=!1),this.width=this.naturalWidth*this.scale.x,this.height=this.naturalHeight*this.scale.y,t.save();var n=this.width*this.anchor.x,s=this.height*this.anchor.y;t.translate(e,i),t.rotate(this.rotation),this.flipHorizontal&&(t.translate(this.swidth*this.scale.x,0),t.scale(-1,1)),this.flipVertical&&(t.translate(0,this.sheight*this.scale.y),t.scale(1,-1)),this.internalImage&&t.drawImage(this.internalImage,0,0,this.swidth,this.sheight,-n,-s,this.swidth*this.scale.x,this.sheight*this.scale.y),t.restore()},e.prototype.clone=function(){var t=new e(this._texture,this.sx,this.sy,this.swidth,this.sheight);t.scale=this.scale.clone(),t.rotation=this.rotation,t.flipHorizontal=this.flipHorizontal,t.flipVertical=this.flipVertical;var i=0,n=this.effects.length;for(i;n>i;i++)t.addEffect(this.effects[i]);return t},e}();t.Sprite=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s,o){this.image=e,this.columns=i,this.rows=n,this.sprites=[],this._internalImage=e.image,this.sprites=Array(i*n);var r=0,h=0;for(r=0;n>r;r++)for(h=0;i>h;h++)this.sprites[h+r*i]=new t.Sprite(this.image,h*s,r*o,s,o)}return e.prototype.getAnimationByIndices=function(e,i,n){var s=this,o=i.map(function(t){return s.sprites[t]});return o=o.map(function(t){return t.clone()}),new t.Animation(e,o,n)},e.prototype.getAnimationBetween=function(e,i,n,s){var o=this.sprites.slice(i,n);return o=o.map(function(t){return t.clone()}),new t.Animation(e,o,s)},e.prototype.getAnimationForAll=function(e,i){var n=this.sprites.map(function(t){return t.clone()});return new t.Animation(e,n,i)},e.prototype.getSprite=function(t){return t>=0&&this.sprites.length>t?this.sprites[t]:void 0},e}();t.SpriteSheet=e;var i=function(e){function i(i,n,s,o,r,h,a){e.call(this,i,o,r,h,a),this.image=i,this.alphabet=n,this.caseInsensitive=s,this.spWidth=h,this.spHeight=a,this._spriteLookup={},this._colorLookup={},this._currentColor=t.Color.Black.clone(),this._currentOpacity=1,this._sprites={},this._textShadowOn=!1,this._textShadowDirty=!0,this._textShadowColor=t.Color.Black.clone(),this._textShadowSprites={},this._shadowOffsetX=5,this._shadowOffsetY=5,this._sprites=this.getTextSprites()}return __extends(i,e),i.prototype.getTextSprites=function(){for(var t={},e=0;this.alphabet.length>e;e++){var i=this.alphabet[e];this.caseInsensitive&&(i=i.toLowerCase()),t[i]=this.sprites[e].clone()}return t},i.prototype.setTextShadow=function(t,e,i){this._textShadowOn=!0,this._shadowOffsetX=t,this._shadowOffsetY=e,this._textShadowColor=i.clone(),this._textShadowDirty=!0;for(var n in this._sprites)this._textShadowSprites[n]=this._sprites[n].clone()},i.prototype.useTextShadow=function(t){this._textShadowOn=t,t&&this.setTextShadow(5,5,this._textShadowColor)},i.prototype.draw=function(e,i,n,s,o){if(o=this._parseOptions(o),""+this._currentColor!=""+o.color||this._currentOpacity!==o.opacity){this._currentOpacity=o.opacity,this._currentColor=o.color;for(var r in this._sprites)this._sprites[r].clearEffects(),this._sprites[r].fill(o.color),this._sprites[r].opacity(o.opacity)}if(this._textShadowOn&&this._textShadowDirty&&this._textShadowColor){for(var h in this._textShadowSprites)this._textShadowSprites[h].clearEffects(),this._textShadowSprites[h].addEffect(new t.Effects.Fill(this._textShadowColor.clone()));this._textShadowDirty=!1}var a=this.sprites[0],c=a.sheight,u=o.fontSize/c,l=i.length*a.swidth*u+i.length*o.letterSpacing,p=n;o.textAlign===t.TextAlign.Left||o.textAlign===t.TextAlign.Start?p=n:o.textAlign===t.TextAlign.Right||o.textAlign===t.TextAlign.End?p=n-l:o.textAlign===t.TextAlign.Center&&(p=n-l/2);var d=s-c*u;o.baseAlign===t.BaseAlign.Top||o.baseAlign===t.BaseAlign.Hanging?d=s:o.baseAlign===t.BaseAlign.Ideographic||o.baseAlign===t.BaseAlign.Bottom||o.baseAlign===t.BaseAlign.Alphabetic?d=s-c*u:o.baseAlign===t.BaseAlign.Middle&&(d=s-c*u/2);for(var f=0;i.length>f;f++){var g=i[f];this.caseInsensitive&&(g=g.toLowerCase());try{this._textShadowOn&&(this._textShadowSprites[g].scale.x=u,this._textShadowSprites[g].scale.y=u,this._textShadowSprites[g].draw(e,p+this._shadowOffsetX,d+this._shadowOffsetY));var _=this._sprites[g];_.scale.x=u,_.scale.y=u,_.draw(e,p,d),p+=_.width+o.letterSpacing}catch(y){t.Logger.getInstance().error("SpriteFont Error drawing char "+g)}}},i.prototype._parseOptions=function(e){return{fontSize:e.fontSize||10,letterSpacing:e.letterSpacing||0,color:e.color||t.Color.Black.clone(),textAlign:void 0===typeof e.textAlign?t.TextAlign.Left:e.textAlign,baseAlign:void 0===typeof e.baseAlign?t.BaseAlign.Bottom:e.baseAlign,maxWidth:e.maxWidth||-1,opacity:e.opacity||0}},i}(e);t.SpriteFont=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,s,o,r,h){var a=this;this.x=e,this.y=i,this.cellWidth=s,this.cellHeight=o,this.rows=r,this.cols=h,this._collidingX=-1,this._collidingY=-1,this._onScreenXStart=0,this._onScreenXEnd=9999,this._onScreenYStart=0,this._onScreenYEnd=9999,this._spriteSheets={},this.logger=t.Logger.getInstance(),this.data=[],this.data=Array(r*h);for(var c=0;h>c;c++)for(var u=0;r>u;u++)(function(){var t=new n(c*s+e,u*o+i,s,o,c+u*h);a.data[c+u*h]=t})()}return e.prototype.registerSpriteSheet=function(t,e){this._spriteSheets[t]=e},e.prototype.collides=function(e){for(var i=e.x+e.getWidth(),n=e.y+e.getHeight(),s=e.getBounds(),o=[],r=s.left;i>=r;r+=Math.min(e.getWidth()/2,this.cellWidth/2))for(var h=s.top;n>=h;h+=Math.min(e.getHeight()/2,this.cellHeight/2)){var a=this.getCellByPoint(r,h);if(a&&a.solid){var c=s.collides(a.getBounds()),u=e.getCenter().minus(a.getCenter());c&&c.dot(u)>0&&o.push(c)}}if(0===o.length)return null;var l=o.reduce(function(e,i){var n=e.x,s=e.y;return Math.abs(e.x)t||0>e||t>=this.cols||e>=this.rows?null:this.data[t+e*this.cols]},e.prototype.getCellByPoint=function(t,e){t=Math.floor((t-this.x)/this.cellWidth),e=Math.floor((e-this.y)/this.cellHeight);var i=this.getCell(t,e);return t>=0&&e>=0&&this.cols>t&&this.rows>e&&i?i:null},e.prototype.update=function(e){var i=e.screenToWorldCoordinates(new t.Point(0,0)),n=e.screenToWorldCoordinates(new t.Point(e.canvas.clientWidth,e.canvas.clientHeight));this._onScreenXStart=Math.max(Math.floor(i.x/this.cellWidth)-2,0),this._onScreenYStart=Math.max(Math.floor((i.y-this.y)/this.cellHeight)-2,0),this._onScreenXEnd=Math.max(Math.floor(n.x/this.cellWidth)+2,0),this._onScreenYEnd=Math.max(Math.floor((n.y-this.y)/this.cellHeight)+2,0)},e.prototype.draw=function(t){t.save(),t.translate(this.x,this.y);var e,i,n,s=this._onScreenXStart,o=Math.min(this._onScreenXEnd,this.cols),r=this._onScreenYStart,h=Math.min(this._onScreenYEnd,this.rows);for(s;o>s;s++){for(r;h>r;r++)for(e=this.getCell(s,r).sprites.filter(function(t){return t.spriteId>-1}),i=0,n=e.length;n>i;i++){var a=this._spriteSheets[e[i].spriteSheetKey];if(a){var c=a.getSprite(e[i].spriteId);c?c.draw(t,s*this.cellWidth,r*this.cellHeight):this.logger.warn("Sprite does not exist for id",e[i].spriteId,"in sprite sheet",e[i].spriteSheetKey,c,a)}else this.logger.warn("Sprite sheet",e[i].spriteSheetKey,"does not exist",a)}r=this._onScreenYStart}t.restore()},e.prototype.debugDraw=function(e){var i=this.cols*this.cellWidth,n=this.rows*this.cellHeight;e.save(),e.strokeStyle=""+t.Color.Red;for(var s=0;this.cols+1>s;s++)e.beginPath(),e.moveTo(this.x+s*this.cellWidth,this.y),e.lineTo(this.x+s*this.cellWidth,this.y+n),e.stroke();for(var o=0;this.rows+1>o;o++)e.beginPath(),e.moveTo(this.x,this.y+o*this.cellHeight),e.lineTo(this.x+i,this.y+o*this.cellHeight),e.stroke();var r=t.Color.Red.clone();r.a=.3,this.data.filter(function(t){return t.solid}).forEach(function(t){e.fillStyle=""+r,e.fillRect(t.x,t.y,t.width,t.height)}),this._collidingY>-1&&this._collidingX>-1&&(e.fillStyle=""+t.Color.Cyan,e.fillRect(this.x+this._collidingX*this.cellWidth,this.y+this._collidingY*this.cellHeight,this.cellWidth,this.cellHeight)),e.restore()},e}();t.TileMap=e;var i=function(){function t(t,e){this.spriteSheetKey=t,this.spriteId=e}return t}();t.TileSprite=i;var n=function(){function e(e,i,n,s,o,r,h){void 0===r&&(r=!1),void 0===h&&(h=[]),this.x=e,this.y=i,this.width=n,this.height=s,this.index=o,this.solid=r,this.sprites=h,this._bounds=new t.BoundingBox(this.x,this.y,this.x+this.width,this.y+this.height)}return e.prototype.getBounds=function(){return this._bounds},e.prototype.getCenter=function(){return new t.Vector(this.x+this.width/2,this.y+this.height/2)},e.prototype.pushSprite=function(t){this.sprites.push(t)},e.prototype.removeSprite=function(t){var e=-1;(e=this.sprites.indexOf(t))>-1&&this.sprites.splice(e,1)},e.prototype.clearSprites=function(){this.sprites.length=0},e}();t.Cell=n})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Naive=0]="Naive",t[t.DynamicAABBTree=1]="DynamicAABBTree",t[t.SeparatingAxis=2]="SeparatingAxis"})(t.CollisionStrategy||(t.CollisionStrategy={})),t.CollisionStrategy;var e=function(){function e(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=0),this.left=t,this.top=e,this.right=i,this.bottom=n}return e.prototype.getWidth=function(){return this.right-this.left},e.prototype.getHeight=function(){return this.bottom-this.top},e.prototype.getPerimeter=function(){var t=this.getWidth(),e=this.getHeight();return 2*(t+e)},e.prototype.contains=function(i){return i instanceof t.Point?this.left<=i.x&&this.top<=i.y&&this.bottom>=i.y&&this.right>=i.x:i instanceof e?this.left=n.left&&this.right<=n.right?n.left-this.right:n.right-this.left;var r=0;return r=this.top<=n.bottom&&this.top>=n.top?n.bottom-this.top:n.top-this.bottom,Math.abs(o)n;n++)e.push(new t.Line(this._points[n],this._points[(n+1)%i]));return e},e.prototype.getAxes=function(){for(var t=[],e=this._points.length,i=0;e>i;i++)t.push(this._points[i].minus(this._points[(i+1)%e]).normal());return t},e.prototype.project=function(e){for(var i=[],n=this._points.length,s=0;n>s;s++)i.push(this._points[s].dot(e));return new t.Projection(Math.min.apply(Math,i),Math.max.apply(Math,i))},e.prototype.getWidth=function(){var t=this._points.reduce(function(t,e){return Math.min(t,e.x)},1/0),e=this._points.reduce(function(t,e){return Math.max(t,e.x)},-1/0);return e-t},e.prototype.getHeight=function(){var t=this._points.reduce(function(t,e){return Math.min(t,e.y)},1/0),e=this._points.reduce(function(t,e){return Math.max(t,e.y)},-1/0);return t-e},e.prototype.contains=function(e){var i=new t.Ray(e,new t.Vector(1,0)),n=this.getSides().reduce(function(t,e){return i.intersect(e)>=0?t+1:t},0);return 0===n%2?!1:!0},e.prototype.collides=function(t){if(t instanceof e){var i=t,n=this.getAxes();n=i.getAxes().concat(n);for(var s=99999,o=null,r=0;n.length>r;r++){var h=this.project(n[r]),a=i.project(n[r]),c=h.getOverlap(a);if(0===c)return null;s>=c&&(s=c,o=n[r])}return o?o.normalize().scale(s):null}return null},e.prototype.debugDraw=function(e){e.beginPath(),e.lineWidth=2;var i=this._points[0];e.moveTo(i.x,i.y);var n=0,s=this._points.length;for(n;s>n;n++)e.lineTo(this._points[n].x,this._points[n].y);e.lineTo(i.x,i.y),e.closePath(),e.strokeStyle=""+t.Color.Blue,e.stroke()},e}();t.SATBoundingBox=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.eventDispatcher=new t.EventDispatcher(this)}return e.prototype.addEventListener=function(t,e){this.eventDispatcher.subscribe(t,e)},e.prototype.removeEventListener=function(t,e){this.eventDispatcher.unsubscribe(t,e)},e.prototype.on=function(t,e){this.eventDispatcher.subscribe(t,e)},e.prototype.off=function(t,e){this.eventDispatcher.unsubscribe(t,e)},e.prototype.emit=function(t,e){this.eventDispatcher.emit(t,e)},e.extend=function(t){var i,n=this;i=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return n.apply(this,arguments)};var s=function(){this.constructor=i};if(s.prototype=n.prototype,i.prototype=new s,t)for(var o in t)t.hasOwnProperty(o)&&(i.prototype[o]=t[o]);return i.extend=e.extend,i},e}();t.Class=e})(ex||(ex={})); var ex;(function(t){var e=function(){function t(e,i,n){this.id=0,this.interval=10,this.fcn=function(){},this.repeats=!1,this._elapsedTime=0,this._totalTimeAlive=0,this.complete=!1,this.scene=null,this.id=t.id++,this.interval=i||this.interval,this.fcn=e||this.fcn,this.repeats=n||this.repeats}return t.prototype.update=function(t){this._totalTimeAlive+=t,this._elapsedTime+=t,this._elapsedTime>this.interval&&(this.fcn.call(this),this.repeats?this._elapsedTime=0:this.complete=!0)},t.prototype.getTimeRunning=function(){return this._totalTimeAlive},t.prototype.cancel=function(){this.scene&&this.scene.cancelTimer(this)},t.id=0,t}();t.Timer=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){}return e.prototype.register=function(){},e.prototype.remove=function(){},e.prototype.evaluate=function(e){for(var i,n,s=e.filter(function(e){return!e.isKilled()&&e.collisionType!==t.CollisionType.PreventCollision}),o=[],r=0,h=s.length;h>r;r++){i=s[r];for(var a=r+1;h>a;a++){n=s[a];var c;if(c=i.collides(n)){var u=i.getSideFromIntersect(c),l=new t.CollisionPair(i,n,c,u);o.some(function(t){return t.equals(l)})||o.push(l)}}}var p=0,d=o.length;for(p;d>p;p++)o[p].evaluate();return o},e.prototype.update=function(){return 0},e.prototype.debugDraw=function(){},e}();t.NaiveCollisionResolver=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this.parent=e,this.parent=e||null,this.actor=null,this.bounds=new t.BoundingBox,this.left=null,this.right=null,this.height=0}return e.prototype.isLeaf=function(){return!this.left&&!this.right},e}();t.TreeNode=e;var i=function(){function t(){this.root=null,this.nodes={}}return t.prototype.insert=function(t){if(null===this.root)return this.root=t,this.root.parent=null,void 0;for(var i=t.bounds,n=this.root;!n.isLeaf();){var s,o,r=n.left,h=n.right,a=n.bounds.getPerimeter(),c=n.bounds.combine(i),u=c.getPerimeter(),l=2*u,p=2*(u-a),d=0,f=i.combine(r.bounds);r.isLeaf()?d=f.getPerimeter()+p:(o=r.bounds.getPerimeter(),s=f.getPerimeter(),d=s-o+p);var g=0,_=i.combine(h.bounds);if(h.isLeaf()?g=_.getPerimeter()+p:(o=h.bounds.getPerimeter(),s=_.getPerimeter(),g=s-o+p),d>l&&g>l)break;n=g>d?r:h}var y=n.parent,A=new e(y);A.bounds=i.combine(n.bounds),A.height=n.height+1,null!==y?(y.left===n?y.left=A:y.right=A,A.left=n,A.right=t,n.parent=A,t.parent=A):(A.left=n,A.right=t,n.parent=A,t.parent=A,this.root=A);for(var v=t.parent;v;){if(v=this.balance(v),!v.left)throw Error("Parent of current leaf cannot have a null left child"+v);if(!v.right)throw Error("Parent of current leaf cannot have a null right child"+v);v.height=1+Math.max(v.left.height,v.right.height),v.bounds=v.left.bounds.combine(v.right.bounds),v=v.parent}},t.prototype.remove=function(t){if(t===this.root)return this.root=null,void 0;var e,i=t.parent,n=i.parent;if(e=i.left===t?i.right:i.left,n){n.left===i?n.left=e:n.right=e,e.parent=n;for(var s=n;s;)s=this.balance(s),s.bounds=s.left.bounds.combine(s.right.bounds),s.height=1+Math.max(s.left.height,s.right.height),s=s.parent}else this.root=e,e.parent=null},t.prototype.registerActor=function(t){var i=new e;i.actor=t,i.bounds=t.getBounds(),i.bounds.left-=2,i.bounds.top-=2,i.bounds.right+=2,i.bounds.bottom+=2,this.nodes[t.id]=i,this.insert(i)},t.prototype.updateActor=function(t){var e=this.nodes[t.id];if(e){var i=t.getBounds();if(e.bounds.contains(i))return!1;this.remove(e),i.left-=5,i.top-=5,i.right+=5,i.bottom+=5;var n=2*t.dx,s=2*t.dy;return 0>n?i.left+=n:i.right+=n,0>s?i.top+=s:i.bottom+=s,e.bounds=i,this.insert(e),!0}},t.prototype.removeActor=function(t){var e=this.nodes[t.id];e&&(this.remove(e),this.nodes[t.id]=null,delete this.nodes[t.id])},t.prototype.balance=function(t){if(null===t)throw Error("Cannot balance at null node");if(t.isLeaf()||2>t.height)return t;var e=t.left,i=t.right,n=t,s=e,o=i,r=e.left,h=e.right,a=i.left,c=i.right,u=o.height-s.height;if(u>1)return o.left=n,o.parent=n.parent,n.parent=o,o.parent?o.parent.left===n?o.parent.left=o:o.parent.right=o:this.root=o,a.height>c.height?(o.right=a,n.right=c,c.parent=n,n.bounds=s.bounds.combine(c.bounds),o.bounds=n.bounds.combine(a.bounds),n.height=1+Math.max(s.height,c.height),o.height=1+Math.max(n.height,a.height)):(o.right=c,n.right=a,a.parent=n,n.bounds=s.bounds.combine(a.bounds),o.bounds=n.bounds.combine(c.bounds),n.height=1+Math.max(s.height,a.height),o.height=1+Math.max(n.height,c.height)),o;if(-1>u){if(s.left=n,s.parent=n.parent,n.parent=s,s.parent)if(s.parent.left===n)s.parent.left=s;else{if(s.parent.right!==n)throw"Error rotating Dynamic Tree";s.parent.right=s}else this.root=s;return r.height>h.height?(s.right=r,n.left=h,h.parent=n,n.bounds=o.bounds.combine(h.bounds),s.bounds=n.bounds.combine(r.bounds),n.height=1+Math.max(o.height,h.height),s.height=1+Math.max(n.height,r.height)):(s.right=h,n.left=r,r.parent=n,n.bounds=o.bounds.combine(r.bounds),s.bounds=n.bounds.combine(h.bounds),n.height=1+Math.max(o.height,r.height),s.height=1+Math.max(n.height,h.height)),s}return t},t.prototype.getHeight=function(){return null===this.root?0:this.root.height},t.prototype.query=function(t,e){var i=t.getBounds(),n=function(s){return s&&s.bounds.collides(i)?s.isLeaf()&&s.actor!==t?e.call(t,s.actor)?!0:void 0:n(s.left)||n(s.right):null};return n(this.root)},t.prototype.rayCast=function(){return null},t.prototype.getNodes=function(){var t=function(e){return e?[e].concat(t(e.left),t(e.right)):[]};return t(this.root)},t.prototype.debugDraw=function(t){var e=function(i){i&&(t.strokeStyle=i.isLeaf()?"green":"white",i.bounds.debugDraw(t),i.left&&e(i.left),i.right&&e(i.right))};e(this.root)},t}();t.DynamicTree=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this._dynamicCollisionTree=new t.DynamicTree}return e.prototype.register=function(t){this._dynamicCollisionTree.registerActor(t)},e.prototype.remove=function(t){this._dynamicCollisionTree.removeActor(t)},e.prototype.evaluate=function(e){for(var i,n=e.filter(function(e){return!e.isKilled()&&e.collisionType!==t.CollisionType.PreventCollision}),s=[],o=0,r=n.length;r>o;o++)i=n[o],this._dynamicCollisionTree.query(i,function(e){if(e.collisionType===t.CollisionType.PreventCollision||e.isKilled())return!1;var n;if(n=i.collides(e)){var o=i.getSideFromIntersect(n),r=new t.CollisionPair(i,e,n,o);return s.some(function(t){return t.equals(r)})||s.push(r),!0}return!1});var h=0,a=s.length;for(h;a>h;h++)s[h].evaluate();return s},e.prototype.update=function(t){var e=0,i=0,n=t.length;for(i;n>i;i++)this._dynamicCollisionTree.updateActor(t[i])&&e++;return e},e.prototype.debugDraw=function(t,e){this._dynamicCollisionTree.debugDraw(t,e)},e}();t.DynamicTreeCollisionResolver=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(t,e,i,n){this.left=t,this.right=e,this.intersect=i,this.side=n}return e.prototype.equals=function(t){return t.left===this.left&&t.right===this.right||t.right===this.left&&t.left===this.right},e.prototype.evaluate=function(){this.left.eventDispatcher.emit("collision",new t.CollisionEvent(this.left,this.right,this.side,this.intersect)),this.right.eventDispatcher.emit("collision",new t.CollisionEvent(this.right,this.left,t.Util.getOppositeSide(this.side),this.intersect.scale(-1)));var e=this.side;this.left.collisionType!==t.CollisionType.Active&&this.left.collisionType!==t.CollisionType.Elastic||this.right.collisionType===t.CollisionType.Passive||(this.left.y+=this.intersect.y,this.left.x+=this.intersect.x,this.left.collisionType===t.CollisionType.Elastic?e===t.Side.Left?this.left.dx=Math.abs(this.left.dx):e===t.Side.Right?this.left.dx=-Math.abs(this.left.dx):e===t.Side.Top?this.left.dy=Math.abs(this.left.dy):e===t.Side.Bottom&&(this.left.dy=-Math.abs(this.left.dy)):(0!==this.intersect.x&&(this.left.dx=0>=this.left.dx&&0>=this.right.dx?Math.max(this.left.dx,this.right.dx):this.left.dx>=0&&this.right.dx>=0?Math.min(this.left.dx,this.right.dx):0),0!==this.intersect.y&&(this.left.dy=0>=this.left.dy&&0>=this.right.dy?Math.max(this.left.dy,this.right.dy):this.left.dy>=0&&this.right.dy>=0?Math.min(this.left.dy,this.right.dy):0)));var i=t.Util.getOppositeSide(this.side),n=this.intersect.scale(-1);this.right.collisionType!==t.CollisionType.Active&&this.right.collisionType!==t.CollisionType.Elastic||this.left.collisionType===t.CollisionType.Passive||(this.right.y+=n.y,this.right.x+=n.x,this.right.collisionType===t.CollisionType.Elastic?i===t.Side.Left?this.right.dx=Math.abs(this.right.dx):i===t.Side.Right?this.right.dx=-Math.abs(this.right.dx):i===t.Side.Top?this.right.dy=Math.abs(this.right.dy):i===t.Side.Bottom&&(this.right.dy=-Math.abs(this.right.dy)):(0!==n.x&&(this.right.dx=0>=this.right.dx&&0>=this.left.dx?Math.max(this.left.dx,this.right.dx):this.left.dx>=0&&this.right.dx>=0?Math.min(this.left.dx,this.right.dx):0),0!==n.y&&(this.right.dy=0>=this.right.dy&&0>=this.left.dy?Math.max(this.left.dy,this.right.dy):this.left.dy>=0&&this.right.dy>=0?Math.min(this.left.dy,this.right.dy):0)))},e}();t.CollisionPair=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.focus=new t.Point(0,0),this.lerp=!1,this.x=0,this.y=0,this.z=1,this.dx=0,this.dy=0,this.dz=0,this.ax=0,this.ay=0,this.az=0,this.rotation=0,this.rx=0,this._cameraMoving=!1,this._currentLerpTime=0,this._lerpDuration=1e3,this._totalLerpTime=0,this._lerpStart=null,this._lerpEnd=null,this._isShaking=!1,this._shakeMagnitudeX=0,this._shakeMagnitudeY=0,this._shakeDuration=0,this._elapsedShakeTime=0,this._isZooming=!1,this._currentZoomScale=1,this._maxZoomScale=1,this._zoomDuration=0,this._elapsedZoomTime=0,this._zoomIncrement=.01}return e.prototype._easeInOutCubic=function(t,e,i,n){return i-=e,t/=n/2,1>t?i/2*t*t*t+e:(t-=2,i/2*(t*t*t+2)+e)},e.prototype.setActorToFollow=function(t){this._follow=t},e.prototype.getFocus=function(){return new t.Point(this.x,this.y)},e.prototype.setFocus=function(e,i){this._follow||this.lerp||(this.x=e,this.y=i),this.lerp&&(this._lerpStart=this.getFocus().clone(),this._lerpEnd=new t.Point(e,i),this._currentLerpTime=0,this._cameraMoving=!0)},e.prototype.shake=function(t,e,i){this._isShaking=!0,this._shakeMagnitudeX=t,this._shakeMagnitudeY=e,this._shakeDuration=i},e.prototype.zoom=function(t,e){void 0===e&&(e=0),this._isZooming=!0,this._maxZoomScale=t,this._zoomDuration=e,e&&(this._zoomIncrement=1e3*(Math.abs(this._maxZoomScale-this._currentZoomScale)/e)),1>this._maxZoomScale?e?this._zoomIncrement=-1*this._zoomIncrement:(this._isZooming=!1,this._setCurrentZoomScale(this._maxZoomScale)):e||(this._isZooming=!1,this._setCurrentZoomScale(this._maxZoomScale))},e.prototype.getZoom=function(){return this.z},e.prototype._setCurrentZoomScale=function(t){this.z=t},e.prototype.update=function(t,e){this.x+=this.dx*e/1e3,this.y+=this.dy*e/1e3,this.z+=this.dz*e/1e3,this.dx+=this.ax*e/1e3,this.dy+=this.ay*e/1e3,this.dz+=this.az*e/1e3,this.rotation+=this.rx*e/1e3;var i=this.getFocus(),n=0,s=0,o=t.canvas.width,r=t.canvas.height,h=o/this.getZoom(),a=r/this.getZoom();this.lerp&&(this._currentLerpTime=this._shakeDuration},e.prototype._isDoneZooming=function(){return 0!==this._zoomDuration?this._elapsedZoomTime>=this._zoomDuration:1>this._maxZoomScale?this._currentZoomScale<=this._maxZoomScale:this._currentZoomScale>=this._maxZoomScale},e}();t.BaseCamera=e;var i=function(e){function i(){e.apply(this,arguments)}return __extends(i,e),i.prototype.getFocus=function(){return this._follow?new t.Point(this._follow.x+this._follow.getWidth()/2,this.focus.y):this.focus},i}(e);t.SideCamera=i;var n=function(e){function i(){e.apply(this,arguments)}return __extends(i,e),i.prototype.getFocus=function(){return this._follow?new t.Point(this._follow.x+this._follow.getWidth()/2,this._follow.y+this._follow.getHeight()/2):this.focus},i}(e);t.LockedCamera=n})(ex||(ex={}));var ex;(function(t){(function(t){t[t.ShortestPath=0]="ShortestPath",t[t.LongestPath=1]="LongestPath",t[t.Clockwise=2]="Clockwise",t[t.CounterClockwise=3]="CounterClockwise"})(t.RotationType||(t.RotationType={})),t.RotationType})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i;(function(e){var i=function(){function e(e,i,n,s,o){this.actor=e,this.easingFcn=o,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=new t.Point(0,0),this._lerpEnd=new t.Point(0,0),this._initialized=!1,this._stopped=!1,this._distance=0,this._lerpDuration=s,this._lerpEnd=new t.Point(i,n)}return e.prototype._initialize=function(){this._lerpStart=new t.Point(this.actor.x,this.actor.y),this._currentLerpTime=0,this._distance=this._lerpStart.toVector().distance(this._lerpEnd.toVector())},e.prototype.update=function(t){this._initialized||(this._initialize(),this._initialized=!0);var e=this.actor.x,i=this.actor.y;this._currentLerpTime=this._distance},e.prototype.reset=function(){this._initialized=!1},e.prototype.stop=function(){this._stopped=!0},e}();e.EaseTo=i;var n=function(){function e(e,i,n,s){this._started=!1,this._stopped=!1,this._actor=e,this._end=new t.Vector(i,n),this._speed=s}return e.prototype.update=function(){this._started||(this._started=!0,this._start=new t.Vector(this._actor.x,this._actor.y),this._distance=this._start.distance(this._end),this._dir=this._end.minus(this._start).normalize());var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y,this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.isComplete=function(e){return this._stopped||new t.Vector(e.x,e.y).distance(this._start)>=this._distance},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.MoveTo=n;var s=function(){function e(e,i,n,s){if(this._started=!1,this._stopped=!1,this._actor=e,this._end=new t.Vector(i,n),0>=s)throw t.Logger.getInstance().error("Attempted to moveBy time less than or equal to zero : "+s),Error("Cannot move in time <= 0");this._time=s}return e.prototype.update=function(){this._started||(this._started=!0,this._start=new t.Vector(this._actor.x,this._actor.y),this._distance=this._start.distance(this._end),this._dir=this._end.minus(this._start).normalize(),this._speed=this._distance/(this._time/1e3));var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y,this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.isComplete=function(e){return this._stopped||new t.Vector(e.x,e.y).distance(this._start)>=this._distance},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.MoveBy=s;var o=function(){function e(e,i,n){this._started=!1,this._stopped=!1,this._actor=e,this._actorToFollow=i,this._current=new t.Vector(this._actor.x,this._actor.y),this._end=new t.Vector(i.x,i.y),this._maximumDistance=void 0!==n?n:this._current.distance(this._end),this._speed=0}return e.prototype.update=function(){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize());var t=Math.sqrt(Math.pow(this._actorToFollow.dx,2)+Math.pow(this._actorToFollow.dy,2));if(0!==t&&(this._speed=t),this._current.x=this._actor.x,this._current.y=this._actor.y,this._end.x=this._actorToFollow.x,this._end.y=this._actorToFollow.y,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize(),this._distanceBetween>=this._maximumDistance){var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y}else this._actor.dx=0,this._actor.dy=0;this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.isComplete=function(){return this._stopped},e.prototype.reset=function(){this._started=!1},e}();e.Follow=o;var r=function(){function e(e,i,n){this._started=!1,this._stopped=!1,this._speedWasSpecified=!1,this._actor=e,this._actorToMeet=i,this._current=new t.Vector(this._actor.x,this._actor.y),this._end=new t.Vector(i.x,i.y),this._speed=n||0,void 0!==n&&(this._speedWasSpecified=!0)}return e.prototype.update=function(){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize());var t=Math.sqrt(Math.pow(this._actorToMeet.dx,2)+Math.pow(this._actorToMeet.dy,2));0===t||this._speedWasSpecified||(this._speed=t),this._current.x=this._actor.x,this._current.y=this._actor.y,this._end.x=this._actorToMeet.x,this._end.y=this._actorToMeet.y,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize();var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y,this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.isComplete=function(){return this._stopped||1>=this._distanceBetween},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.Meet=r;var h=function(){function e(e,i,n,s){this._started=!1,this._stopped=!1,this._actor=e,this._end=i,this._speed=n,this._rotationType=s||t.RotationType.ShortestPath}return e.prototype.update=function(){if(!this._started){this._started=!0,this._start=this._actor.rotation;var e=Math.abs(this._end-this._start),i=t.Util.TwoPI-e;switch(e>i?(this._shortDistance=i,this._longDistance=e):(this._shortDistance=e,this._longDistance=i),this._shortestPathIsPositive=(this._start-this._end+t.Util.TwoPI)%t.Util.TwoPI>=Math.PI,this._rotationType){case t.RotationType.ShortestPath:this._distance=this._shortDistance,this._direction=this._shortestPathIsPositive?1:-1;break;case t.RotationType.LongestPath:this._distance=this._longDistance,this._direction=this._shortestPathIsPositive?-1:1;break;case t.RotationType.Clockwise:this._direction=1,this._distance=this._shortestPathIsPositive?this._shortDistance:this._longDistance;break;case t.RotationType.CounterClockwise:this._direction=-1,this._distance=this._shortestPathIsPositive?this._longDistance:this._shortDistance}}this._actor.rx=this._direction*this._speed,this.isComplete(this._actor)&&(this._actor.rotation=this._end,this._actor.rx=0,this._stopped=!0)},e.prototype.isComplete=function(){var t=Math.abs(this._actor.rotation-this._start);return this._stopped||t>=Math.abs(this._distance)},e.prototype.stop=function(){this._actor.rx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.RotateTo=h;var a=function(){function e(e,i,n,s){this._started=!1,this._stopped=!1,this._actor=e,this._end=i,this._time=n,this._rotationType=s||t.RotationType.ShortestPath}return e.prototype.update=function(){if(!this._started){this._started=!0,this._start=this._actor.rotation;var e=Math.abs(this._end-this._start),i=t.Util.TwoPI-e;switch(e>i?(this._shortDistance=i,this._longDistance=e):(this._shortDistance=e,this._longDistance=i),this._shortestPathIsPositive=(this._start-this._end+t.Util.TwoPI)%t.Util.TwoPI>=Math.PI,this._rotationType){case t.RotationType.ShortestPath:this._distance=this._shortDistance,this._direction=this._shortestPathIsPositive?1:-1;break;case t.RotationType.LongestPath:this._distance=this._longDistance,this._direction=this._shortestPathIsPositive?-1:1;break;case t.RotationType.Clockwise:this._direction=1,this._distance=this._shortDistance>=0?this._shortDistance:this._longDistance;break;case t.RotationType.CounterClockwise:this._direction=-1,this._distance=0>=this._shortDistance?this._shortDistance:this._longDistance}this._speed=Math.abs(1e3*(this._distance/this._time))}this._actor.rx=this._direction*this._speed,this.isComplete(this._actor)&&(this._actor.rotation=this._end,this._actor.rx=0,this._stopped=!0)},e.prototype.isComplete=function(){var t=Math.abs(this._actor.rotation-this._start);return this._stopped||t>=Math.abs(this._distance)},e.prototype.stop=function(){this._actor.rx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.RotateBy=a;var c=function(){function t(t,e,i,n,s){this._started=!1,this._stopped=!1,this._actor=t,this._endX=e,this._endY=i,this._speedX=n,this._speedY=s}return t.prototype.update=function(){if(this._started||(this._started=!0,this._startX=this._actor.scale.x,this._startY=this._actor.scale.y,this._distanceX=Math.abs(this._endX-this._startX),this._distanceY=Math.abs(this._endY-this._startY)),Math.abs(this._actor.scale.x-this._startX)>=this._distanceX)this._actor.sx=0;else{var t=this._endY=this._distanceY)this._actor.sy=0;else{var e=this._endY=this._distanceX&&Math.abs(this._actor.scale.y-this._startY)>=this._distanceY},t.prototype.stop=function(){this._actor.sx=0,this._actor.sy=0,this._stopped=!0},t.prototype.reset=function(){this._started=!1},t}();e.ScaleTo=c;var u=function(){function t(t,e,i,n){this._started=!1,this._stopped=!1,this._actor=t,this._endX=e,this._endY=i,this._time=n,this._speedX=1e3*((this._endX-this._actor.scale.x)/n),this._speedY=1e3*((this._endY-this._actor.scale.y)/n)}return t.prototype.update=function(){this._started||(this._started=!0,this._startX=this._actor.scale.x,this._startY=this._actor.scale.y,this._distanceX=Math.abs(this._endX-this._startX),this._distanceY=Math.abs(this._endY-this._startY));var t=this._endX=this._distanceX&&Math.abs(this._actor.scale.y-this._startY)>=this._distanceY},t.prototype.stop=function(){this._actor.sx=0,this._actor.sy=0,this._stopped=!0},t.prototype.reset=function(){this._started=!1},t}();e.ScaleBy=u;var l=function(){function t(t,e){this._elapsedTime=0,this._started=!1,this._stopped=!1,this._actor=t,this._delay=e}return t.prototype.update=function(t){this._started||(this._started=!0),this.x=this._actor.x,this.y=this._actor.y,this._elapsedTime+=t},t.prototype.isComplete=function(){return this._stopped||this._elapsedTime>=this._delay},t.prototype.stop=function(){this._stopped=!0},t.prototype.reset=function(){this._elapsedTime=0,this._started=!1},t}();e.Delay=l;var p=function(){function t(t,e,i,n){void 0===n&&(n=1),this._timeVisible=0,this._timeNotVisible=0,this._elapsedTime=0,this._totalTime=0,this._stopped=!1,this._started=!1,this._actor=t,this._timeVisible=e,this._timeNotVisible=i,this._duration=(e+i)*n}return t.prototype.update=function(t){this._started||(this._started=!0),this._elapsedTime+=t,this._totalTime+=t,this._actor.visible&&this._elapsedTime>=this._timeVisible&&(this._actor.visible=!1,this._elapsedTime=0),!this._actor.visible&&this._elapsedTime>=this._timeNotVisible&&(this._actor.visible=!0,this._elapsedTime=0),this.isComplete(this._actor)&&(this._actor.visible=!0)},t.prototype.isComplete=function(){return this._stopped||this._totalTime>=this._duration},t.prototype.stop=function(){this._actor.visible=!0,this._stopped=!0},t.prototype.reset=function(){this._started=!1,this._elapsedTime=0,this._totalTime=0},t}();e.Blink=p;var d=function(){function e(t,e,i){this._multiplyer=1,this._started=!1,this._stopped=!1,this._actor=t,this._endOpacity=e,this._speed=i,t.opacity>e&&(this._multiplyer=-1)}return e.prototype.update=function(e){this._started||(this._started=!0),this._speed>0&&(this._actor.opacity+=this._multiplyer*Math.abs(this._actor.opacity-this._endOpacity)*e/this._speed),this._speed-=e,t.Logger.getInstance().debug("actor opacity: "+this._actor.opacity),this.isComplete(this._actor)&&(this._actor.opacity=this._endOpacity)},e.prototype.isComplete=function(){return this._stopped||.05>Math.abs(this._actor.opacity-this._endOpacity)},e.prototype.stop=function(){this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.Fade=d;var f=function(){function t(t){this._started=!1,this._stopped=!1,this._actor=t}return t.prototype.update=function(){this._actor.actionQueue.clearActions(),this._actor.kill(),this._stopped=!0},t.prototype.isComplete=function(){return this._stopped},t.prototype.stop=function(){},t.prototype.reset=function(){},t}();e.Die=f;var g=function(){function t(t,e){this._method=null,this._actor=null,this._hasBeenCalled=!1,this._actor=t,this._method=e}return t.prototype.update=function(){this._method.call(this._actor),this._hasBeenCalled=!0},t.prototype.isComplete=function(){return this._hasBeenCalled},t.prototype.reset=function(){this._hasBeenCalled=!1},t.prototype.stop=function(){this._hasBeenCalled=!0},t}();e.CallMethod=g;var _=function(){function t(t,e,i){this._stopped=!1,this._actor=t,this._actionQueue=new A(t),this._repeat=e,this._originalRepeat=e;var n=0,s=i.length;for(n;s>n;n++)i[n].reset(),this._actionQueue.add(i[n])}return t.prototype.update=function(t){this.x=this._actor.x,this.y=this._actor.y,this._actionQueue.hasNext()||(this._actionQueue.reset(),this._repeat--),this._actionQueue.update(t)},t.prototype.isComplete=function(){return this._stopped||0>=this._repeat},t.prototype.stop=function(){this._stopped=!0},t.prototype.reset=function(){this._repeat=this._originalRepeat},t}();e.Repeat=_;var y=function(){function t(t,e){this._stopped=!1,this._actor=t,this._actionQueue=new A(t);var i=0,n=e.length;for(i;n>i;i++)e[i].reset(),this._actionQueue.add(e[i])}return t.prototype.update=function(t){this.x=this._actor.x,this.y=this._actor.y,this._stopped||(this._actionQueue.hasNext()||this._actionQueue.reset(),this._actionQueue.update(t))},t.prototype.isComplete=function(){return this._stopped},t.prototype.stop=function(){this._stopped=!0,this._actionQueue.clearActions()},t.prototype.reset=function(){},t}();e.RepeatForever=y;var A=function(){function t(t){this._actions=[],this._completedActions=[],this._actor=t}return t.prototype.add=function(t){this._actions.push(t)},t.prototype.remove=function(t){var e=this._actions.indexOf(t);this._actions.splice(e,1)},t.prototype.clearActions=function(){this._actions.length=0,this._completedActions.length=0,this._currentAction&&this._currentAction.stop()},t.prototype.getActions=function(){return this._actions.concat(this._completedActions)},t.prototype.hasNext=function(){return this._actions.length>0},t.prototype.reset=function(){this._actions=this.getActions();var t=0,e=this._actions.length;for(t;e>t;t++)this._actions[t].reset();this._completedActions=[]},t.prototype.update=function(t){this._actions.length>0&&(this._currentAction=this._actions[0],this._currentAction.update(t),this._currentAction.isComplete(this._actor)&&this._completedActions.push(this._actions.shift()))},t}();e.ActionQueue=A})(i=e.Actions||(e.Actions={}))})(e=t.Internal||(t.Internal={}))})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this._actors=[],this._queues=[],null!==arguments&&(this._actors=Array.prototype.slice.call(arguments,0),this._queues=this._actors.map(function(t){return t.actionQueue}))}return e.prototype.clearActions=function(){var t=0,e=this._queues.length;for(t;e>t;t++)this._queues[t].clearActions()},e.prototype.addActorToContext=function(t){this._actors.push(t),this._queues.push(t.actionQueue)},e.prototype.removeActorFromContext=function(t){var e=this._actors.indexOf(t);e>-1&&(this._actors.splice(e,1),this._queues.splice(e,1))},e.prototype.easeTo=function(e,i,n,s){void 0===s&&(s=t.EasingFunctions.Linear);var o=0,r=this._queues.length;for(o;r>o;o++)this._queues[o].add(new t.Internal.Actions.EaseTo(this._actors[o],e,i,n,s));return this},e.prototype.moveTo=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.MoveTo(this._actors[s],e,i,n));return this},e.prototype.moveBy=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.MoveBy(this._actors[s],e,i,n));return this},e.prototype.rotateTo=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.RotateTo(this._actors[s],e,i,n));return this},e.prototype.rotateBy=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.RotateBy(this._actors[s],e,i,n));return this},e.prototype.scaleTo=function(e,i,n,s){var o=0,r=this._queues.length;for(o;r>o;o++)this._queues[o].add(new t.Internal.Actions.ScaleTo(this._actors[o],e,i,n,s));return this},e.prototype.scaleBy=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.ScaleBy(this._actors[s],e,i,n));return this},e.prototype.blink=function(e,i,n){void 0===n&&(n=1);var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.Blink(this._actors[s],e,i,n));return this},e.prototype.fade=function(e,i){var n=0,s=this._queues.length;for(n;s>n;n++)this._queues[n].add(new t.Internal.Actions.Fade(this._actors[n],e,i));return this},e.prototype.delay=function(e){var i=0,n=this._queues.length;for(i;n>i;i++)this._queues[i].add(new t.Internal.Actions.Delay(this._actors[i],e));return this},e.prototype.die=function(){var e=0,i=this._queues.length;for(e;i>e;e++)this._queues[e].add(new t.Internal.Actions.Die(this._actors[e]));return this},e.prototype.callMethod=function(e){var i=0,n=this._queues.length;for(i;n>i;i++)this._queues[i].add(new t.Internal.Actions.CallMethod(this._actors[i],e));return this},e.prototype.repeat=function(e){if(!e)return this.repeatForever(),this;var i=0,n=this._queues.length;for(i;n>i;i++)this._queues[i].add(new t.Internal.Actions.Repeat(this._actors[i],e,this._actors[i].actionQueue.getActions())); return this},e.prototype.repeatForever=function(){var e=0,i=this._queues.length;for(e;i>e;e++)this._queues[e].add(new t.Internal.Actions.RepeatForever(this._actors[e],this._actors[e].actionQueue.getActions()));return this},e.prototype.follow=function(e,i){var n=0,s=this._queues.length;for(n;s>n;n++)void 0===i?this._queues[n].add(new t.Internal.Actions.Follow(this._actors[n],e)):this._queues[n].add(new t.Internal.Actions.Follow(this._actors[n],e,i));return this},e.prototype.meet=function(e,i){var n=0,s=this._queues.length;for(n;s>n;n++)void 0===i?this._queues[n].add(new t.Internal.Actions.Meet(this._actors[n],e)):this._queues[n].add(new t.Internal.Actions.Meet(this._actors[n],e,i));return this},e.prototype.asPromise=function(){var e=this,i=this._queues.map(function(i,n){var s=new t.Promise;return i.add(new t.Internal.Actions.CallMethod(e._actors[n],function(){s.resolve()})),s});return t.Promise.join.apply(this,i)},e}();t.ActionContext=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n){if(e.call(this),this.name=i,this.scene=n,this._logger=t.Logger.getInstance(),this._members=[],this.actions=new t.ActionContext,null==n)this._logger.error("Invalid constructor arguments passed to Group: ",i,", scene must not be null!");else{var s=n.groups[i];s&&this._logger.warn("Group with name",i,"already exists. This new group will replace it."),n.groups[i]=this}}return __extends(i,e),i.prototype.add=function(e){e instanceof t.Actor&&(e=[].concat(e));var i,n=0,s=e.length;for(n;s>n;n++)i=this.getMembers().indexOf(e[n]),-1===i&&(this._members.push(e[n]),this.scene.add(e[n]),this.actions.addActorToContext(e[n]),this.eventDispatcher.wire(e[n].eventDispatcher))},i.prototype.remove=function(t){var e=this._members.indexOf(t);e>-1&&(this._members.splice(e,1),this.actions.removeActorFromContext(t),this.eventDispatcher.unwire(t.eventDispatcher))},i.prototype.move=function(e){var i=0,n=this.getMembers(),s=n.length;if(1===arguments.length&&e instanceof t.Vector)for(i;s>i;i++)n[i].x+=e.x,n[i].y+=e.y;else if("number"==typeof arguments[0]&&"number"==typeof arguments[1]){var o=arguments[0],r=arguments[1];for(i;s>i;i++)n[i].x+=o,n[i].y+=r}else this._logger.error("Invalid arguments passed to group move",this.name,"args:",arguments)},i.prototype.rotate=function(){if("number"==typeof arguments[0]){var t=arguments[0],e=0,i=this.getMembers(),n=i.length;for(e;n>e;e++)i[e].rotation+=t}else this._logger.error("Invalid arguments passed to group rotate",this.name,"args:",arguments)},i.prototype.on=function(t,e){this.eventDispatcher.subscribe(t,e)},i.prototype.off=function(t,e){this.eventDispatcher.unsubscribe(t,e)},i.prototype.emit=function(t,e){this.eventDispatcher.emit(t,e)},i.prototype.contains=function(t){return this.getMembers().indexOf(t)>-1},i.prototype.getMembers=function(){return this._members},i.prototype.getRandomMember=function(){return this._members[Math.floor(Math.random()*this._members.length)]},i.prototype.getBounds=function(){return this.getMembers().map(function(t){return t.getBounds()}).reduce(function(t,e){return t.combine(e)})},i}(t.Class);t.Group=e})(ex||(ex={}));var ex;(function(t){var e=function(){function t(t){this._getComparable=t}return t.prototype.find=function(t){return this._find(this._root,t)},t.prototype._find=function(t,e){return null==t?!1:this._getComparable.call(e)===t.getKey()?t.getData().indexOf(e)>-1?!0:!1:this._getComparable.call(e)e?this._get(t.getLeft(),e):this._get(t.getRight(),e)},t.prototype.add=function(t){return null==this._root?(this._root=new i(this._getComparable.call(t),[t],null,null),!0):this._insert(this._root,t)},t.prototype._insert=function(t,e){return null!=t?this._getComparable.call(e)===t.getKey()?t.getData().indexOf(e)>-1?!1:(t.getData().push(e),!0):this._getComparable.call(e)-1){if(t.getData().splice(i,1),0===t.getData().length){if(null==t.getLeft()&&null==t.getRight())return null;if(null==t.getLeft())return t.getRight();if(null==t.getRight())return t.getLeft();var n=this._findMinNode(t.getRight());return t.setKey(n.getKey()),t.setData(n.getData()),t.setRight(this._cleanup(t.getRight(),n)),t}return t}},t.prototype._cleanup=function(t,e){var i=e.getKey();if(null==t)return null;if(i===t.getKey()){if(null==t.getLeft()&&null==t.getRight())return null;if(null==t.getLeft())return t.getRight();if(null==t.getRight())return t.getLeft();var n=this._findMinNode(t.getRight());return t.setKey(n.getKey()),t.setData(n.getData()),t.setRight(this._cleanup(t.getRight(),n)),t}return this._getComparable.call(e)n;n++)this.uiActors[n].update(e,i);for(n=0,s=this.tileMaps.length;s>n;n++)this.tileMaps[n].update(e,i);for(n=0,s=this.children.length;s>n;n++)this.children[n].update(e,i);this._collisionResolver&&(this._collisionResolver.update(this.children),this._collisionResolver.evaluate(this.children));var o;for(n=0,s=this._killQueue.length;s>n;n++)o=this.children.indexOf(this._killQueue[n]),o>-1&&(this._sortedDrawingTree.removeByComparable(this._killQueue[n]),this.children.splice(o,1));for(this._killQueue.length=0,n=0,s=this._cancelQueue.length;s>n;n++)this.removeTimer(this._cancelQueue[n]);this._cancelQueue.length=0,this._timers=this._timers.filter(function(t){return t.update(i),!t.complete}),this.emit("postupdate",new t.PostUpdateEvent(e,i,this))},i.prototype.draw=function(e,i){this.emit("predraw",new t.PreDrawEvent(e,i,this)),e.save(),this.camera&&this.camera.update(e,i);var n,s;for(n=0,s=this.tileMaps.length;s>n;n++)this.tileMaps[n].draw(e,i);var o=this._sortedDrawingTree.list();for(n=0,s=o.length;s>n;n++)o[n].visible&&!o[n].isOffScreen&&o[n].draw(e,i);for(this.engine&&this.engine.isDebug&&(e.strokeStyle="yellow",this.debugDraw(e)),e.restore(),n=0,s=this.uiActors.length;s>n;n++)this.uiActors[n].visible&&this.uiActors[n].draw(e,i);if(this.engine&&this.engine.isDebug)for(n=0,s=this.uiActors.length;s>n;n++)this.uiActors[n].debugDraw(e);this.emit("postdraw",new t.PreDrawEvent(e,i,this))},i.prototype.debugDraw=function(e){this.emit("predebugdraw",new t.PreDebugDrawEvent(e,this));var i,n;for(i=0,n=this.tileMaps.length;n>i;i++)this.tileMaps[i].debugDraw(e);for(i=0,n=this.children.length;n>i;i++)this.children[i].debugDraw(e);this.camera.debugDraw(e),this.emit("postdebugdraw",new t.PostDebugDrawEvent(e,this))},i.prototype.contains=function(t){return this.children.indexOf(t)>-1},i.prototype.add=function(e){return e instanceof t.Actor&&e.unkill(),e instanceof t.UIActor?(t.Util.contains(this.uiActors,e)||this.addUIActor(e),void 0):e instanceof t.Actor?(t.Util.contains(this.children,e)||(this.addChild(e),this._sortedDrawingTree.add(e)),void 0):e instanceof t.Timer?(t.Util.contains(this._timers,e)||this.addTimer(e),void 0):(e instanceof t.TileMap&&(t.Util.contains(this.tileMaps,e)||this.addTileMap(e)),void 0)},i.prototype.remove=function(e){return e instanceof t.UIActor?(this.removeUIActor(e),void 0):(e instanceof t.Actor&&(this._collisionResolver.remove(e),this.removeChild(e)),e instanceof t.Timer&&this.removeTimer(e),e instanceof t.TileMap&&this.removeTileMap(e),void 0)},i.prototype.addUIActor=function(t){this.uiActors.push(t),t.scene=this},i.prototype.removeUIActor=function(t){var e=this.uiActors.indexOf(t);e>-1&&this.uiActors.splice(e,1)},i.prototype.addChild=function(t){this._collisionResolver.register(t),t.scene=this,this.children.push(t),this._sortedDrawingTree.add(t),t.parent=this.actor},i.prototype.addTileMap=function(t){this.tileMaps.push(t)},i.prototype.removeTileMap=function(t){var e=this.tileMaps.indexOf(t);e>-1&&this.tileMaps.splice(e,1)},i.prototype.removeChild=function(t){this._collisionResolver.remove(t),this._killQueue.push(t),t.parent=null},i.prototype.addTimer=function(t){return this._timers.push(t),t.scene=this,t},i.prototype.removeTimer=function(t){var e=this._timers.indexOf(t);return-1!==e&&this._timers.splice(e,1),t},i.prototype.cancelTimer=function(t){return this._cancelQueue.push(t),t},i.prototype.isTimerActive=function(t){return this._timers.indexOf(t)>-1},i.prototype.createGroup=function(e){return new t.Group(e,this)},i.prototype.getGroup=function(t){return this.groups[t]},i.prototype.removeGroup=function(e){"string"==typeof e?delete this.groups[e]:e instanceof t.Group?delete this.groups[e.name]:this._logger.error("Invalid arguments to removeGroup",e)},i.prototype.cleanupDrawTree=function(t){this._sortedDrawingTree.removeByComparable(t)},i.prototype.updateDrawTree=function(t){this._sortedDrawingTree.add(t)},i}(t.Class);t.Scene=e})(ex||(ex={}));var ex;(function(t){var e=function(){function t(){}return t.Linear=function(t,e,i,n){return i-=e,i*t/n+e},t.EaseInQuad=function(t,e,i,n){t/=n},t.EaseOutQuad=function(t,e,i,n){return t/=n,-i*t*(t-2)+e},t.EaseInOutQuad=function(t,e,i,n){return i-=e,t/=n/2,1>t?i/2*t*t+e:(t--,-i/2*(t*(t-2)-1)+e)},t.EaseInCubic=function(t,e,i,n){return i-=e,t/=n,i*t*t*t+e},t.EaseOutCubic=function(t,e,i,n){return i-=e,t/=n,i*(t*t*t+1)+e},t.EaseInOutCubic=function(t,e,i,n){return i-=e,t/=n/2,1>t?i/2*t*t*t+e:(t-=2,i/2*(t*t*t+2)+e)},t}();t.EasingFunctions=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function n(s,o,r,h,a){e.call(this),this.id=n.maxId++,this.x=0,this.y=0,this._height=0,this._width=0,this.rotation=0,this.rx=0,this.scale=new t.Vector(1,1),this.sx=0,this.sy=0,this.dx=0,this.dy=0,this.ax=0,this.ay=0,this.isOffScreen=!1,this.visible=!0,this.opacity=1,this.previousOpacity=1,this.logger=t.Logger.getInstance(),this.scene=null,this.parent=null,this.children=[],this.collisionType=i.PreventCollision,this.collisionGroups=[],this._collisionHandlers={},this._isInitialized=!1,this.frames={},this.currentDrawing=null,this.centerDrawingX=!0,this.centerDrawingY=!0,this.traits=[],this.enableCapturePointer=!1,this.capturePointer={captureMoveEvents:!1},this._zIndex=0,this._isKilled=!1,this.x=s||0,this.y=o||0,this._width=r||0,this._height=h||0,a&&(this.color=a.clone(),this.opacity=a.a),this.traits.push(new t.Traits.Movement),this.traits.push(new t.Traits.CollisionDetection),this.traits.push(new t.Traits.OffscreenCulling),this.traits.push(new t.Traits.CapturePointer),this.actionQueue=new t.Internal.Actions.ActionQueue(this),this.actions=new t.ActionContext(this),this.anchor=new t.Point(.5,.5)}return __extends(n,e),n.prototype.onInitialize=function(){},n.prototype._checkForPointerOptIn=function(t){!t||"pointerdown"!==t.toLowerCase()&&"pointerdown"!==t.toLowerCase()&&"pointermove"!==t.toLowerCase()||(this.enableCapturePointer=!0,"pointermove"===t.toLowerCase()&&(this.capturePointer.captureMoveEvents=!0))},n.prototype.addEventListener=function(t,i){this._checkForPointerOptIn(t),e.prototype.addEventListener.call(this,t,i)},n.prototype.on=function(t,e){this._checkForPointerOptIn(t),this.eventDispatcher.subscribe(t,e)},n.prototype.kill=function(){this.scene?(this.emit("kill",new t.KillEvent(this)),this.scene.remove(this),this._isKilled=!0):this.logger.warn("Cannot kill actor, it was never added to the Scene")},n.prototype.unkill=function(){this._isKilled=!1},n.prototype.isKilled=function(){return this._isKilled},n.prototype.add=function(e){e.collisionType=i.PreventCollision,t.Util.addItemToArray(e,this.children)&&(e.parent=this)},n.prototype.remove=function(e){t.Util.removeItemToArray(e,this.children)&&(e.parent=null)},n.prototype.setDrawing=function(e){e=""+e,this.currentDrawing!==this.frames[e]&&(null!=this.frames[e]?(this.frames[e].reset(),this.currentDrawing=this.frames[e]):t.Logger.getInstance().error("the specified drawing key '"+e+"' does not exist"))},n.prototype.addDrawing=function(){2===arguments.length?(this.frames[arguments[0]]=arguments[1],this.currentDrawing||(this.currentDrawing=arguments[1])):(arguments[0]instanceof t.Sprite&&this.addDrawing("default",arguments[0]),arguments[0]instanceof t.Texture&&this.addDrawing("default",arguments[0].asSprite()))},n.prototype.getZIndex=function(){return this._zIndex},n.prototype.setZIndex=function(t){this.scene.cleanupDrawTree(this),this._zIndex=t,this.scene.updateDrawTree(this)},n.prototype.addCollisionGroup=function(t){this.collisionGroups.push(t)},n.prototype.removeCollisionGroup=function(t){var e=this.collisionGroups.indexOf(t);-1!==e&&this.collisionGroups.splice(e,1)},n.prototype.getCenter=function(){return new t.Vector(this.x+this.getWidth()/2-this.anchor.x*this.getWidth(),this.y+this.getHeight()/2-this.anchor.y*this.getHeight())},n.prototype.getWidth=function(){return this._width*this.scale.x},n.prototype.setWidth=function(t){this._width=t/this.scale.x},n.prototype.getHeight=function(){return this._height*this.scale.y},n.prototype.setHeight=function(t){this._height=t/this.scale.y},n.prototype.setCenterDrawing=function(t){this.centerDrawingY=t,this.centerDrawingX=t},n.prototype.getLeft=function(){return this.getBounds().left},n.prototype.getRight=function(){return this.getBounds().right},n.prototype.getTop=function(){return this.getBounds().top},n.prototype.getBottom=function(){return this.getBounds().bottom},n.prototype.getWorldX=function(){return this.parent?this.x*this.parent.scale.x+this.parent.getWorldX():this.x},n.prototype.getWorldY=function(){return this.parent?this.y*this.parent.scale.y+this.parent.getWorldY():this.y},n.prototype.getGlobalScale=function(){if(!this.parent)return new t.Point(this.scale.x,this.scale.y);var e=this.parent.getGlobalScale();return new t.Point(this.scale.x*e.x,this.scale.y*e.y)},n.prototype.getBounds=function(){var e=this._getCalculatedAnchor();return new t.BoundingBox(this.getWorldX()-e.x,this.getWorldY()-e.y,this.getWorldX()+this.getWidth()-e.x,this.getWorldY()+this.getHeight()-e.y)},n.prototype.contains=function(e,i,n){void 0===n&&(n=!1);var s=this.getBounds().contains(new t.Point(e,i));return n?s||this.children.some(function(t){return t.contains(e,i,!0)}):s},n.prototype.getSideFromIntersect=function(e){return e?Math.abs(e.x)>Math.abs(e.y)?0>e.x?t.Side.Right:t.Side.Left:0>e.y?t.Side.Bottom:t.Side.Top:t.Side.None},n.prototype.collidesWithSide=function(e){var i=this.collides(e);return i?Math.abs(i.x)>Math.abs(i.y)?this.x=Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},n.prototype.clearActions=function(){this.actionQueue.clearActions()},n.prototype.easeTo=function(e,i,n,s){return void 0===s&&(s=t.EasingFunctions.Linear),this.actionQueue.add(new t.Internal.Actions.EaseTo(this,e,i,n,s)),this},n.prototype.moveTo=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.MoveTo(this,e,i,n)),this},n.prototype.moveBy=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.MoveBy(this,e,i,n)),this},n.prototype.rotateTo=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.RotateTo(this,e,i,n)),this},n.prototype.rotateBy=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.RotateBy(this,e,i,n)),this},n.prototype.scaleTo=function(e,i,n,s){return this.actionQueue.add(new t.Internal.Actions.ScaleTo(this,e,i,n,s)),this},n.prototype.scaleBy=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.ScaleBy(this,e,i,n)),this},n.prototype.blink=function(e,i,n){return void 0===n&&(n=1),this.actionQueue.add(new t.Internal.Actions.Blink(this,e,i,n)),this},n.prototype.fade=function(e,i){return this.actionQueue.add(new t.Internal.Actions.Fade(this,e,i)),this},n.prototype.delay=function(e){return this.actionQueue.add(new t.Internal.Actions.Delay(this,e)),this},n.prototype.die=function(){return this.actionQueue.add(new t.Internal.Actions.Die(this)),this},n.prototype.callMethod=function(e){return this.actionQueue.add(new t.Internal.Actions.CallMethod(this,e)),this},n.prototype.repeat=function(e){return e?(this.actionQueue.add(new t.Internal.Actions.Repeat(this,e,this.actionQueue.getActions())),this):(this.repeatForever(),this)},n.prototype.repeatForever=function(){return this.actionQueue.add(new t.Internal.Actions.RepeatForever(this,this.actionQueue.getActions())),this},n.prototype.follow=function(e,i){return i===void 0?this.actionQueue.add(new t.Internal.Actions.Follow(this,e)):this.actionQueue.add(new t.Internal.Actions.Follow(this,e,i)),this},n.prototype.meet=function(e,i){return i===void 0?this.actionQueue.add(new t.Internal.Actions.Meet(this,e)):this.actionQueue.add(new t.Internal.Actions.Meet(this,e,i)),this},n.prototype.asPromise=function(){var e=new t.Promise;return this.callMethod(function(){e.resolve()}),e},n.prototype._getCalculatedAnchor=function(){return new t.Point(this.getWidth()*this.anchor.x,this.getHeight()*this.anchor.y)},n.prototype.update=function(e,i){this._isInitialized||(this.onInitialize(e),this.eventDispatcher.emit("initialize",new t.InitializeEvent(e)),this._isInitialized=!0),this.emit("preupdate",new t.PreUpdateEvent(e,i,this));var n=this.eventDispatcher;this.actionQueue.update(i),this.color&&(this.color.a=this.opacity);for(var s=0;this.traits.length>s;s++)this.traits[s].update(this,e,i);n.emit("update",new t.UpdateEvent(i)),this.emit("postupdate",new t.PostUpdateEvent(e,i,this))},n.prototype.draw=function(e,i){var n=this._getCalculatedAnchor();if(e.save(),e.translate(this.x,this.y),e.scale(this.scale.x,this.scale.y),e.rotate(this.rotation),this.emit("predraw",new t.PreDrawEvent(e,i,this)),this.previousOpacity!==this.opacity){for(var s in this.frames)this.frames[s].addEffect(new t.Effects.Opacity(this.opacity));this.previousOpacity=this.opacity}if(this.currentDrawing){var o=0,r=0;this.centerDrawingX&&(o=(this.currentDrawing.naturalWidth*this.currentDrawing.scale.x-this.getWidth())/2-this.currentDrawing.naturalWidth*this.currentDrawing.scale.x*this.currentDrawing.anchor.x),this.centerDrawingY&&(r=(this.currentDrawing.naturalHeight*this.currentDrawing.scale.y-this.getHeight())/2-this.currentDrawing.naturalHeight*this.currentDrawing.scale.y*this.currentDrawing.anchor.y),this.currentDrawing.draw(e,-n.x-o,-n.y-r)}else this.color&&(e.fillStyle=""+this.color,e.fillRect(-n.x,-n.y,this._width,this._height));for(var h=0;this.children.length>h;h++)this.children[h].visible&&this.children[h].draw(e,i);this.emit("postdraw",new t.PostDrawEvent(e,i,this)),e.restore()},n.prototype.debugDraw=function(e){this.emit("predebugdraw",new t.PreDebugDrawEvent(e,this));var i=this.getBounds();i.debugDraw(e),e.fillText("id: "+this.id,i.left+3,i.top+10),e.fillStyle=""+t.Color.Yellow,e.beginPath(),e.arc(this.getWorldX(),this.getWorldY(),3,0,2*Math.PI),e.closePath(),e.fill();for(var n=0;this.traits.length>n;n++)this.traits[n]instanceof t.Traits.OffscreenCulling&&this.traits[n].cullingBox.debugDraw(e);e.strokeStyle=""+t.Color.Yellow,e.beginPath();var s=Math.min(this.getWidth(),this.getHeight());e.arc(this.getWorldX(),this.getWorldY(),s,0,2*Math.PI),e.closePath(),e.stroke();var o={"0 Pi":0,"Pi/2":Math.PI/2,Pi:Math.PI,"3/2 Pi":3*Math.PI/2},r=e.font;for(var h in o)e.fillStyle=""+t.Color.Yellow,e.font="14px",e.textAlign="center",e.fillText(h,this.getWorldX()+Math.cos(o[h])*(s+10),this.getWorldY()+Math.sin(o[h])*(s+10));e.font=r,e.save(),e.translate(this.x,this.y),e.rotate(this.rotation);for(var a=0;this.children.length>a;a++)this.children[a].debugDraw(e);e.restore(),this.emit("postdebugdraw",new t.PostDebugDrawEvent(e,this))},n.maxId=0,n}(t.Class);t.Actor=e,function(t){t[t.PreventCollision=0]="PreventCollision",t[t.Passive=1]="Passive",t[t.Active=2]="Active",t[t.Elastic=3]="Elastic",t[t.Fixed=4]="Fixed"}(t.CollisionType||(t.CollisionType={}));var i=t.CollisionType})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Debug=0]="Debug",t[t.Info=1]="Info",t[t.Warn=2]="Warn",t[t.Error=3]="Error",t[t.Fatal=4]="Fatal"})(t.LogLevel||(t.LogLevel={}));var e=t.LogLevel,i=function(){function t(){if(this._appenders=[],this.defaultLevel=e.Info,t._instance)throw Error("Logger is a singleton");return t._instance=this,t._instance.addAppender(new n),t._instance}return t.getInstance=function(){return null==t._instance&&(t._instance=new t),t._instance},t.prototype.addAppender=function(t){this._appenders.push(t)},t.prototype.clearAppenders=function(){this._appenders.length=0},t.prototype._log=function(t,e){null==t&&(t=this.defaultLevel);var i=0,n=this._appenders.length;for(i;n>i;i++)t>=this.defaultLevel&&this._appenders[i].log(t,e)},t.prototype.debug=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Debug,t)},t.prototype.info=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Info,t)},t.prototype.warn=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Warn,t)},t.prototype.error=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Error,t)},t.prototype.fatal=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Fatal,t)},t._instance=null,t}();t.Logger=i;var n=function(){function t(){}return t.prototype.log=function(t,i){if(console||console.log||!console.warn||!console.error){var n=[];n.unshift.apply(n,i),n.unshift("["+e[t]+"] : "),e.Warn>t?console.log.apply?console.log.apply(console,n):console.log(n.join(" ")):e.Error>t?console.warn.apply?console.warn.apply(console,n):console.warn(n.join(" ")):console.error.apply?console.error.apply(console,n):console.error(n.join(" "))}},t}();t.ConsoleAppender=n;var s=function(){function t(t,e){this._messages=[],this._canvas=document.createElement("canvas"),this._canvas.width=t||window.innerWidth,this._canvas.height=e||window.innerHeight,this._canvas.style.position="absolute",this._ctx=this._canvas.getContext("2d"),document.body.appendChild(this._canvas)}return t.prototype.log=function(t,i){var n=i.join(",");this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._messages.unshift("["+e[t]+"] : "+n);for(var s=10,o=1,r=0;this._messages.length>r;r++)this._ctx.fillStyle="rgba(255,255,255,"+o.toFixed(2)+")",this._ctx.fillText(this._messages[r],200,s),s+=10,o=o>0?o-.05:0},t}();t.ScreenAppender=s})(ex||(ex={}));var ex;(function(t){var e=function(){function t(){}return t}();t.GameEvent=e;var i=function(t){function e(e){t.call(this),this.target=e}return __extends(e,t),e}(e);t.KillEvent=i;var n=function(t){function e(e,i,n){t.call(this),this.ctx=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PreDrawEvent=n;var s=function(t){function e(e,i,n){t.call(this),this.ctx=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PostDrawEvent=s;var o=function(t){function e(e,i){t.call(this),this.ctx=e,this.target=i}return __extends(e,t),e}(e);t.PreDebugDrawEvent=o;var r=function(t){function e(e,i){t.call(this),this.ctx=e,this.target=i}return __extends(e,t),e}(e);t.PostDebugDrawEvent=r;var h=function(t){function e(e,i,n){t.call(this),this.engine=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PreUpdateEvent=h;var a=function(t){function e(e,i,n){t.call(this),this.engine=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PostUpdateEvent=a;var c=function(t){function e(e,i){t.call(this),this.index=e,this.gamepad=i}return __extends(e,t),e}(e);t.GamepadConnectEvent=c;var u=function(t){function e(e){t.call(this),this.index=e}return __extends(e,t),e}(e);t.GamepadDisconnectEvent=u;var l=function(t){function e(e,i){t.call(this),this.button=e,this.value=i}return __extends(e,t),e}(t.GameEvent);t.GamepadButtonEvent=l;var p=function(t){function e(e,i){t.call(this),this.axis=e,this.value=i}return __extends(e,t),e}(t.GameEvent);t.GamepadAxisEvent=p;var d=function(t){function e(e,i){t.call(this),this.topic=e,this.handler=i}return __extends(e,t),e}(e);t.SubscribeEvent=d;var f=function(t){function e(e,i){t.call(this),this.topic=e,this.handler=i}return __extends(e,t),e}(e);t.UnsubscribeEvent=f;var g=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.VisibleEvent=g;var _=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.HiddenEvent=_;var y=function(t){function e(e,i,n,s){t.call(this),this.actor=e,this.other=i,this.side=n,this.intersection=s}return __extends(e,t),e}(e);t.CollisionEvent=y;var A=function(t){function e(e){t.call(this),this.delta=e}return __extends(e,t),e}(e);t.UpdateEvent=A;var v=function(t){function e(e){t.call(this),this.engine=e}return __extends(e,t),e}(e);t.InitializeEvent=v;var m=function(t){function e(e){t.call(this),this.oldScene=e}return __extends(e,t),e}(e);t.ActivateEvent=m;var x=function(t){function e(e){t.call(this),this.newScene=e}return __extends(e,t),e}(e);t.DeactivateEvent=x;var w=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.ExitViewPortEvent=w;var b=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.EnterViewPortEvent=b})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this._handlers={},this._wiredEventDispatchers=[],this._log=t.Logger.getInstance(),this._target=e}return e.prototype.publish=function(e,i){if(e){e=e.toLowerCase();var n=this._target;i||(i=new t.GameEvent),i.target=n;var s,o;if(this._handlers[e])for(s=0,o=this._handlers[e].length,s;o>s;s++)this._handlers[e][s].call(n,i);for(s=0,o=this._wiredEventDispatchers.length,s;o>s;s++)this._wiredEventDispatchers[s].emit(e,i)}},e.prototype.emit=function(t,e){this.publish(t,e)},e.prototype.subscribe=function(e,i){e=e.toLowerCase(),this._handlers[e]||(this._handlers[e]=[]),this._handlers[e].push(i),"unsubscribe"!==e&&"subscribe"!==e&&this.emit("subscribe",new t.SubscribeEvent(e,i))},e.prototype.unsubscribe=function(e,i){e=e.toLowerCase();var n=this._handlers[e];if(n)if(i){var s=n.indexOf(i);this._handlers[e].splice(s,1)}else this._handlers[e].length=0;"unsubscribe"!==e&&"subscribe"!==e&&this.emit("unsubscribe",new t.UnsubscribeEvent(e,i))},e.prototype.wire=function(t){t._wiredEventDispatchers.push(this)},e.prototype.unwire=function(t){var e=t._wiredEventDispatchers.indexOf(this);e>-1&&t._wiredEventDispatchers.splice(e,1)},e}();t.EventDispatcher=e})(ex||(ex={}));var ex;(function(t){var e=function(){function t(t,e,i,n){this.r=t,this.g=e,this.b=i,this.a=null!=n?n:1}return t.fromRGB=function(e,i,n,s){return new t(e,i,n,s)},t.fromHex=function(e){var i=/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i,n=null;if(n=e.match(i)){var s=parseInt(n[1],16),o=parseInt(n[2],16),r=parseInt(n[3],16),h=1;return n[4]&&(h=parseInt(n[4],16)/255),new t(s,o,r,h)}throw Error("Invalid hex string: "+e)},t.fromHSL=function(t,e,n,s){void 0===s&&(s=1);var o=new i(t,e,n,s);return o.toRGBA()},t.prototype.lighten=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.l+=e.l*t,e.toRGBA()},t.prototype.darken=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.l-=e.l*t,e.toRGBA()},t.prototype.saturate=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.s+=e.s*t,e.toRGBA()},t.prototype.desaturate=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.s-=e.s*t,e.toRGBA()},t.prototype.mulitiply=function(e){var i=255*(e.r/255*this.r/255),n=255*(e.g/255*this.g/255),s=255*(e.b/255*this.b/255),o=e.a*this.a;return new t(i,n,s,o)},t.prototype.screen=function(t){var e=t.invert(),i=t.invert();return e.mulitiply(i).invert()},t.prototype.invert=function(){return new t(255-this.r,255-this.g,255-this.b,1-this.a)},t.prototype.average=function(e){var i=(e.r+this.r)/2,n=(e.g+this.g)/2,s=(e.b+this.b)/2,o=(e.a+this.a)/2;return new t(i,n,s,o)},t.prototype.toString=function(){var t=this.r.toFixed(0)+""+", "+(this.g.toFixed(0)+"")+", "+(this.b.toFixed(0)+"");return void 0!==this.a||null!==this.a?"rgba("+t+", "+(this.a+"")+")":"rgb("+t+")"},t.prototype.fillStyle=function(){return""+this},t.prototype.clone=function(){return new t(this.r,this.g,this.b,this.a)},t.Black=t.fromHex("#000000"),t.White=t.fromHex("#FFFFFF"),t.Gray=t.fromHex("#808080"),t.LightGray=t.fromHex("#D3D3D3"),t.DarkGray=t.fromHex("#A9A9A9"),t.Yellow=t.fromHex("#FFFF00"),t.Orange=t.fromHex("#FFA500"),t.Red=t.fromHex("#FF0000"),t.Vermillion=t.fromHex("#FF5B31"),t.Rose=t.fromHex("#FF007F"),t.Magenta=t.fromHex("#FF00FF"),t.Violet=t.fromHex("#7F00FF"),t.Blue=t.fromHex("#0000FF"),t.Azure=t.fromHex("#007FFF"),t.Cyan=t.fromHex("#00FFFF"),t.Viridian=t.fromHex("#59978F"),t.Green=t.fromHex("#00FF00"),t.Chartreuse=t.fromHex("#7FFF00"),t.Transparent=t.fromHex("#FFFFFF00"),t}();t.Color=e;var i=function(){function t(t,e,i,n){this.h=t,this.s=e,this.l=i,this.a=n}return t.fromRGBA=function(e,i,n,s){e/=255,i/=255,n/=255;var o,r,h=Math.max(e,i,n),a=Math.min(e,i,n),c=(h+a)/2;if(h===a)o=r=0;else{var u=h-a;switch(r=c>.5?u/(2-h-a):u/(h+a),h){case e:o=(i-n)/u+(n>i?6:0);break;case i:o=(n-e)/u+2;break;case n:o=(e-i)/u+4}o/=6}return new t(o,r,c,s)},t.prototype.toRGBA=function(){function t(t,e,i){return 0>i&&(i+=1),i>1&&(i-=1),1/6>i?t+6*(e-t)*i:.5>i?e:2/3>i?t+6*(e-t)*(2/3-i):t}var i,n,s;if(0===this.s)i=n=s=this.l;else{var o=.5>this.l?this.l*(1+this.s):this.l+this.s-this.l*this.s,r=2*this.l-o;i=t(r,o,this.h+1/3),n=t(r,o,this.h),s=t(r,o,this.h-1/3)}return new e(255*i,255*n,255*s,this.a)},t}() -})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o){e.call(this,i,n,s,o),this.traits=[],this.traits.push(new t.Traits.Movement),this.traits.push(new t.Traits.CapturePointer),this.anchor.setTo(0,0),this.collisionType=t.CollisionType.PreventCollision,this.enableCapturePointer=!0}return __extends(i,e),i.prototype.onInitialize=function(t){this._engine=t},i.prototype.contains=function(i,n,s){if(void 0===s&&(s=!0),s)return e.prototype.contains.call(this,i,n);var o=this._engine.worldToScreenCoordinates(new t.Point(i,n));return e.prototype.contains.call(this,o.x,o.y)},i}(t.Actor);t.UIActor=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o,r,h){e.call(this,i,n,s,o),this._action=function(){},this.repeats=1,this.target=null,this.repeats=h||this.repeats,this._action=r||this._action,this.collisionType=t.CollisionType.PreventCollision,this.eventDispatcher=new t.EventDispatcher(this),this.actionQueue=new t.Internal.Actions.ActionQueue(this)}return __extends(i,e),i.prototype.update=function(e,i){if(this.actionQueue.update(i),this.x+=this.dx*i/1e3,this.y+=this.dy*i/1e3,this.rotation+=this.rx*i/1e3,this.scale.x+=this.sx*i/1e3,this.scale.y+=this.sy*i/1e3,this.target)this.collides(this.target)&&this._dispatchAction();else for(var n=0;e.currentScene.children.length>n;n++){var s=e.currentScene.children[n];s!==this&&s.collisionType!==t.CollisionType.PreventCollision&&this.collides(s)&&this._dispatchAction()}0===this.repeats&&this.kill()},i.prototype._dispatchAction=function(){this._action.call(this),this.repeats--},i.prototype.draw=function(){},i.prototype.debugDraw=function(i){e.prototype.debugDraw.call(this,i),i.save(),i.translate(this.x,this.y);var n=this.getBounds();n.left=n.left-this.getWorldX(),n.right=n.right-this.getWorldX(),n.top=n.top-this.getWorldY(),n.bottom=n.bottom-this.getWorldY(),i.fillStyle=""+t.Color.Violet,i.strokeStyle=""+t.Color.Violet,i.fillText("Trigger",10,10),n.debugDraw(i),i.restore()},i}(t.Actor);t.Trigger=e})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Circle=0]="Circle",t[t.Rectangle=1]="Rectangle"})(t.EmitterType||(t.EmitterType={}));var e=t.EmitterType,i=function(){function e(e,i,n,s,o,r,h,a,c,u){this.position=new t.Vector(0,0),this.velocity=new t.Vector(0,0),this.acceleration=new t.Vector(0,0),this.particleRotationalVelocity=0,this.currentRotation=0,this.focus=null,this.focusAccel=0,this.opacity=1,this.beginColor=t.Color.White.clone(),this.endColor=t.Color.White.clone(),this.life=300,this.fadeFlag=!1,this._rRate=1,this._gRate=1,this._bRate=1,this._aRate=0,this._currentColor=t.Color.White.clone(),this.emitter=null,this.particleSize=5,this.particleSprite=null,this.sizeRate=0,this.elapsedMultiplier=0,this.emitter=e,this.life=i||this.life,this.opacity=n||this.opacity,this.endColor=o||this.endColor.clone(),this.beginColor=s||this.beginColor.clone(),this._currentColor=this.beginColor.clone(),this.position=r||this.position,this.velocity=h||this.velocity,this.acceleration=a||this.acceleration,this._rRate=(this.endColor.r-this.beginColor.r)/this.life,this._gRate=(this.endColor.g-this.beginColor.g)/this.life,this._bRate=(this.endColor.b-this.beginColor.b)/this.life,this._aRate=this.opacity/this.life,this.startSize=c||0,this.endSize=u||0,this.endSize>0&&this.startSize>0&&(this.sizeRate=(this.endSize-this.startSize)/this.life,this.particleSize=this.startSize)}return e.prototype.kill=function(){this.emitter.removeParticle(this)},e.prototype.update=function(e){if(this.life=this.life-e,this.elapsedMultiplier=this.elapsedMultiplier+e,0>this.life&&this.kill(),this.fadeFlag&&(this.opacity=t.Util.clamp(this._aRate*this.life,1e-4,1)),this.startSize>0&&this.endSize>0&&(this.particleSize=t.Util.clamp(this.sizeRate*e+this.particleSize,Math.min(this.startSize,this.endSize),Math.max(this.startSize,this.endSize))),this._currentColor.r=t.Util.clamp(this._currentColor.r+this._rRate*e,0,255),this._currentColor.g=t.Util.clamp(this._currentColor.g+this._gRate*e,0,255),this._currentColor.b=t.Util.clamp(this._currentColor.b+this._bRate*e,0,255),this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),this.focus){var i=this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(e/1e3);this.velocity=this.velocity.add(i)}else this.velocity=this.velocity.add(this.acceleration.scale(e/1e3));this.position=this.position.add(this.velocity.scale(e/1e3)),this.particleRotationalVelocity&&(this.currentRotation=(this.currentRotation+this.particleRotationalVelocity*e/1e3)%(2*Math.PI))},e.prototype.draw=function(e){return this.particleSprite?(this.particleSprite.rotation=this.currentRotation,this.particleSprite.scale.setTo(this.particleSize,this.particleSize),this.particleSprite.draw(e,this.position.x,this.position.y),void 0):(this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),e.fillStyle=""+this._currentColor,e.beginPath(),e.arc(this.position.x,this.position.y,this.particleSize,0,2*Math.PI),e.fill(),e.closePath(),void 0)},e}();t.Particle=i;var n=function(n){function s(i,s,o,r){n.call(this,i,s,o,r,t.Color.White),this._particlesToEmit=0,this.numParticles=0,this.isEmitting=!0,this.particles=null,this.deadParticles=null,this.minVel=0,this.maxVel=0,this.acceleration=new t.Vector(0,0),this.minAngle=0,this.maxAngle=0,this.emitRate=1,this.particleLife=2e3,this.opacity=1,this.fadeFlag=!1,this.focus=null,this.focusAccel=1,this.startSize=null,this.endSize=null,this.minSize=5,this.maxSize=5,this.beginColor=t.Color.White,this.endColor=t.Color.White,this.particleSprite=null,this.emitterType=e.Rectangle,this.radius=0,this.particleRotationalVelocity=0,this.randomRotation=!1,this.collisionType=t.CollisionType.PreventCollision,this.particles=new t.Util.Collection,this.deadParticles=new t.Util.Collection;for(var h in this.traits)this.traits[h]instanceof t.Traits.OffscreenCulling&&this.traits.splice(h,1)}return __extends(s,n),s.prototype.removeParticle=function(t){this.deadParticles.push(t)},s.prototype.emitParticles=function(t){for(var e=0;t>e;e++)this.particles.push(this._createParticle())},s.prototype.clearParticles=function(){this.particles.clear()},s.prototype._createParticle=function(){var n=0,s=0,o=t.Util.randomInRange(this.minAngle,this.maxAngle),r=t.Util.randomInRange(this.minVel,this.maxVel),h=this.startSize||t.Util.randomInRange(this.minSize,this.maxSize),a=r*Math.cos(o),c=r*Math.sin(o);if(this.emitterType===e.Rectangle)n=t.Util.randomInRange(this.x,this.x+this.getWidth()),s=t.Util.randomInRange(this.y,this.y+this.getHeight());else if(this.emitterType===e.Circle){var u=t.Util.randomInRange(0,this.radius);n=u*Math.cos(o)+this.x,s=u*Math.sin(o)+this.y}var l=new i(this,this.particleLife,this.opacity,this.beginColor,this.endColor,new t.Vector(n,s),new t.Vector(a,c),this.acceleration,this.startSize,this.endSize);return l.fadeFlag=this.fadeFlag,l.particleSize=h,this.particleSprite&&(l.particleSprite=this.particleSprite),l.particleRotationalVelocity=this.particleRotationalVelocity,this.randomRotation&&(l.currentRotation=t.Util.randomInRange(0,2*Math.PI)),this.focus&&(l.focus=this.focus.add(new t.Vector(this.x,this.y)),l.focusAccel=this.focusAccel),l},s.prototype.update=function(t,e){var i=this;n.prototype.update.call(this,t,e),this.isEmitting&&(this._particlesToEmit+=this.emitRate*(e/1e3),this._particlesToEmit>1&&(this.emitParticles(Math.floor(this._particlesToEmit)),this._particlesToEmit=this._particlesToEmit-Math.floor(this._particlesToEmit))),this.particles.forEach(function(t){return t.update(e)}),this.deadParticles.forEach(function(t){return i.particles.removeElement(t)}),this.deadParticles.clear()},s.prototype.draw=function(t){this.particles.forEach(function(e){return e.draw(t)})},s.prototype.debugDraw=function(e){n.prototype.debugDraw.call(this,e),e.fillStyle=""+t.Color.Black,e.fillText("Particles: "+this.particles.count(),this.x,this.y+20),this.focus&&(e.fillRect(this.focus.x+this.x,this.focus.y+this.y,3,3),t.Util.drawLine(e,"yellow",this.focus.x+this.x,this.focus.y+this.y,n.prototype.getCenter.call(this).x,n.prototype.getCenter.call(this).y),e.fillText("Focus",this.focus.x+this.x,this.focus.y+this.y))},s}(t.Actor);t.ParticleEmitter=n})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s){this.currentFrame=0,this._oldTime=Date.now(),this.anchor=new t.Point(0,0),this.rotation=0,this.scale=new t.Point(1,1),this.loop=!1,this.freezeFrame=-1,this.flipVertical=!1,this.flipHorizontal=!1,this.width=0,this.height=0,this.naturalWidth=0,this.naturalHeight=0,this.sprites=i,this.speed=n,this._engine=e,null!=s&&(this.loop=s),i&&i[0]&&(this.height=i[0]?i[0].height:0,this.width=i[0]?i[0].width:0,this.naturalWidth=i[0]?i[0].naturalWidth:0,this.naturalHeight=i[0]?i[0].naturalHeight:0,this.freezeFrame=i.length-1)}return e.prototype.opacity=function(e){this.addEffect(new t.Effects.Opacity(e))},e.prototype.grayscale=function(){this.addEffect(new t.Effects.Grayscale)},e.prototype.invert=function(){this.addEffect(new t.Effects.Invert)},e.prototype.fill=function(e){this.addEffect(new t.Effects.Fill(e))},e.prototype.colorize=function(e){this.addEffect(new t.Effects.Colorize(e))},e.prototype.lighten=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Lighten(e))},e.prototype.darken=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Darken(e))},e.prototype.saturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Saturate(e))},e.prototype.desaturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Desaturate(e))},e.prototype.addEffect=function(t){for(var e in this.sprites)this.sprites[e].addEffect(t)},e.prototype.removeEffect=function(t){for(var e in this.sprites)this.sprites[e].removeEffect(t)},e.prototype.clearEffects=function(){for(var t in this.sprites)this.sprites[t].clearEffects()},e.prototype._setAnchor=function(t){for(var e in this.sprites)this.sprites[e].anchor.setTo(t.x,t.y)},e.prototype._setRotation=function(t){for(var e in this.sprites)this.sprites[e].rotation=t},e.prototype._setScale=function(t){for(var e in this.sprites)this.sprites[e].scale=t},e.prototype.reset=function(){this.currentFrame=0},e.prototype.isDone=function(){return!this.loop&&this.currentFrame>=this.sprites.length},e.prototype.tick=function(){var t=Date.now();t-this._oldTime>this.speed&&(this.currentFrame=this.loop?(this.currentFrame+1)%this.sprites.length:this.currentFrame+1,this._oldTime=t)},e.prototype._updateValues=function(){this._setAnchor(this.anchor),this._setRotation(this.rotation),this._setScale(this.scale)},e.prototype.skip=function(t){this.currentFrame=(this.currentFrame+t)%this.sprites.length},e.prototype.draw=function(e,i,n){this.tick(),this._updateValues();var s;this.currentFrame=this.sprites.length&&(s=this.sprites[t.Util.clamp(this.freezeFrame,0,this.sprites.length-1)],s.draw(e,i,n)),s&&(this.width=s.width,this.height=s.height)},e.prototype.play=function(t,e){this.reset(),this._engine.playAnimation(this,t,e)},e}();t.Animation=e})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(){function e(e,i){this.path=e,this._log=t.Logger.getInstance(),this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},window.AudioContext?(this._log.debug("Using new Web Audio Api for "+e),this._soundImpl=new o(e,i)):(this._log.debug("Falling back to Audio Element for "+e),this._soundImpl=new n(e,i))}return e.prototype.setVolume=function(t){this._soundImpl.setVolume(t)},e.prototype.setLoop=function(t){this._soundImpl.setLoop(t)},e.prototype.load=function(){this._soundImpl.onload=this.onload,this._soundImpl.onprogress=this.onprogress,this._soundImpl.onerror=this.onerror,this._soundImpl.load()},e.prototype.processData=function(t){return this._soundImpl.processData(t)},e.prototype.getData=function(){return this._soundImpl.getData()},e.prototype.setData=function(t){this._soundImpl.setData(t)},e.prototype.isPlaying=function(){return this._soundImpl.isPlaying()},e.prototype.play=function(){return this._soundImpl.play()},e.prototype.pause=function(){this._soundImpl.pause()},e.prototype.stop=function(){this._soundImpl.stop()},e}();e.FallbackAudio=i;var n=function(){function e(e,i){var n=this;this.path=e,this._audioElements=Array(5),this._loadedAudio=null,this._isLoaded=!1,this._index=0,this._log=t.Logger.getInstance(),this._isPlaying=!1,this._currentOffset=0,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){};for(var s=0;this._audioElements.length>s;s++)(function(t){n._audioElements[t]=new Audio})(s);i?this.setVolume(t.Util.clamp(i,0,1)):this.setVolume(1)}return e.prototype.isPlaying=function(){return this._isPlaying},e.prototype._audioLoaded=function(){this._isLoaded=!0},e.prototype.setVolume=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].volume=t},e.prototype.setLoop=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].loop=t},e.prototype.getLoop=function(){this._audioElements.some(function(t){return t.loop})},e.prototype.load=function(){var t=this;if(!this._loadedAudio){var e=new XMLHttpRequest;e.open("GET",this.path,!0),e.responseType="blob",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(i){return 200!==e.status?(t._log.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t._isLoaded=!0,t.setData(e.response),t.onload(i),void 0)},e.send()}},e.prototype.getData=function(){return this._loadedAudio},e.prototype.setData=function(t){this._isLoaded=!0,this._loadedAudio=this.processData(t)},e.prototype.processData=function(t){var e=URL.createObjectURL(t);return this._audioElements.forEach(function(t){t.src=e}),this._audioLoaded(),e},e.prototype.play=function(){var e=this;this._audioElements[this._index].load(),this._audioElements[this._index].play(),this._currentOffset=0;var i=new t.Promise;return this._isPlaying=!0,this.getLoop()||this._audioElements[this._index].addEventListener("ended",function(){e._isPlaying=!1,i.resolve(!0)}),this._index=(this._index+1)%this._audioElements.length,i},e.prototype.pause=function(){this._index=(this._index-1+this._audioElements.length)%this._audioElements.length,this._currentOffset=this._audioElements[this._index].currentTime,this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e.prototype.stop=function(){this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e}();if(e.AudioTag=n,window.AudioContext)var s=new window.AudioContext;var o=function(){function e(e,i){this.path=e,this._context=s,this._volume=this._context.createGain(),this._buffer=null,this._sound=null,this._isLoaded=!1,this._loop=!1,this._isPlaying=!1,this._isPaused=!1,this._currentOffset=0,this._logger=t.Logger.getInstance(),this._data=null,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},this._volume.gain.value=i?t.Util.clamp(i,0,1):1}return e.prototype.setVolume=function(t){this._volume.gain.value=t},e.prototype.load=function(){var t=this;if(null===this._data){var e=new XMLHttpRequest;e.open("GET",this.path),e.responseType="arraybuffer",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(){return 200!==e.status?(t._logger.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t.setData(e.response),void 0)};try{e.send()}catch(i){console.error("Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.")}}},e.prototype.getData=function(){return this._data},e.prototype.setData=function(t){this._data=this.processData(t)},e.prototype.processData=function(t){var e=this;return this._context.decodeAudioData(t,function(t){e._buffer=t,e._isLoaded=!0,e.onload(e)},function(){e._logger.error("Unable to decode "+e.path+" this browser may not fully support this format, or the file may be corrupt, "+"if this is an mp3 try removing id3 tags and album art from the file."),e._isLoaded=!1,e.onload(e)}),t},e.prototype.setLoop=function(t){this._loop=t},e.prototype.isPlaying=function(){return this._isPlaying},e.prototype.play=function(){var e=this;if(this._isLoaded){this._sound=this._context.createBufferSource(),this._sound.buffer=this._buffer,this._sound.loop=this._loop,this._sound.connect(this._volume),this._volume.connect(this._context.destination),this._sound.start(0,this._currentOffset%this._buffer.duration),this._currentOffset=0;var i;return i=this._isPaused&&this._playPromise?this._playPromise:new t.Promise,this._isPaused=!1,this._isPlaying=!0,this._loop||(this._sound.onended=function(){e._isPlaying=!1,e._isPaused||i.resolve(!0)}.bind(this)),this._playPromise=i,i}return t.Promise.wrap(!0)},e.prototype.pause=function(){if(this._isPlaying)try{window.clearTimeout(this._playingTimer),this._sound.stop(0),this._currentOffset=this._context.currentTime,this._isPlaying=!1,this._isPaused=!0}catch(t){this._logger.warn("The sound clip",this.path,"has already been paused!")}},e.prototype.stop=function(){if(this._sound)try{window.clearTimeout(this._playingTimer),this._currentOffset=0,this._sound.stop(0),this._isPlaying=!1,this._isPaused=!1}catch(t){this._logger.warn("The sound clip",this.path,"has already been stopped!")}},e}();e.WebAudio=o})(e=t.Internal||(t.Internal={}))})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Resolved=0]="Resolved",t[t.Rejected=1]="Rejected",t[t.Pending=2]="Pending"})(t.PromiseState||(t.PromiseState={}));var e=t.PromiseState,i=function(){function i(){this._state=e.Pending,this._successCallbacks=[],this._rejectCallback=function(){},this._logger=t.Logger.getInstance()}return i.wrap=function(t){var e=(new i).resolve(t);return e},i.join=function(){for(var t=[],e=0;arguments.length>e;e++)t[e-0]=arguments[e];var n=new i;if(!t||!t.length)return n.resolve();var s=t.length,o=0,r=0,h=[];return t.forEach(function(t){t.then(function(){o+=1,o===s?n.resolve():o+r+h.length===s&&n.reject(h)},function(){r+=1,o+r+h.length===s&&n.reject(h)}).error(function(t){h.push(t),h.length+o+r===s&&n.reject(h)})}),n},i.prototype.then=function(t,i){if(t&&(this._successCallbacks.push(t),this.state()===e.Resolved))try{t.call(this,this._value)}catch(n){this._handleError(n)}if(i&&(this._rejectCallback=i,this.state()===e.Rejected))try{i.call(this,this._value)}catch(n){this._handleError(n)}return this},i.prototype.error=function(t){return t&&(this._errorCallback=t),this},i.prototype.resolve=function(t){var i=this;if(this._state!==e.Pending)throw Error("Cannot resolve a promise that is not in a pending state!");this._value=t;try{this._state=e.Resolved,this._successCallbacks.forEach(function(t){t.call(i,i._value)})}catch(n){this._handleError(n)}return this},i.prototype.reject=function(t){if(this._state!==e.Pending)throw Error("Cannot reject a promise that is not in a pending state!");this._value=t;try{this._state=e.Rejected,this._rejectCallback.call(this,this._value)}catch(i){this._handleError(i)}return this},i.prototype.state=function(){return this._state},i.prototype._handleError=function(t){if(!this._errorCallback)throw t;this._errorCallback.call(this,t)},i}();t.Promise=i})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s){void 0===s&&(s=!0),e.call(this),this.path=i,this.responseType=n,this.bustCache=s,this.data=null,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){}}return __extends(i,e),i.prototype.isLoaded=function(){return null!==this.data},i.prototype.wireEngine=function(t){this._engine=t},i.prototype._cacheBust=function(t){var e=/\?\w*=\w*/;return t+=e.test(t)?"&__="+Date.now():"?__="+Date.now()},i.prototype._start=function(){this.logger.debug("Started loading resource "+this.path)},i.prototype.load=function(){var e=this,i=new t.Promise;if(null!==this.data)return this.logger.debug("Already have data for resource",this.path),i.resolve(this.data),this.oncomplete(),i;var n=new XMLHttpRequest;return n.open("GET",this.bustCache?this._cacheBust(this.path):this.path,!0),n.responseType=this.responseType,n.onloadstart=function(t){e._start(t)},n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load resource ",e.path," server responded with error code",n.status),e.onerror(n.response),i.resolve(n.response),void 0):(e.data=e.processData(n.response),e.oncomplete(),e.logger.debug("Completed loading resource",e.path),i.resolve(e.data),void 0)},n.send(),i},i.prototype.getData=function(){return this.data},i.prototype.setData=function(t){this.data=this.processData(t)},i.prototype.processData=function(t){return URL.createObjectURL(t)},i}(t.Class);t.Resource=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n){void 0===n&&(n=!0),e.call(this,i,"blob",n),this.path=i,this.bustCache=n,this.loaded=new t.Promise,this._isLoaded=!1,this._sprite=null,this._sprite=new t.Sprite(this,0,0,0,0)}return __extends(i,e),i.prototype.isLoaded=function(){return this._isLoaded},i.prototype.load=function(){var i=this,n=new t.Promise,s=e.prototype.load.call(this);return s.then(function(){i.image=new Image,i.image.addEventListener("load",function(){i._isLoaded=!0,i.width=i._sprite.swidth=i._sprite.naturalWidth=i._sprite.width=i.image.naturalWidth,i.height=i._sprite.sheight=i._sprite.naturalHeight=i._sprite.height=i.image.naturalHeight,i.loaded.resolve(i.image),n.resolve(i.image)}),i.image.src=e.prototype.getData.call(i)},function(){n.reject("Error loading texture.")}),n},i.prototype.asSprite=function(){return this._sprite},i}(t.Resource);t.Texture=e;var i=function(){function e(){for(var i=[],n=0;arguments.length>n;n++)i[n-0]=arguments[n];this._logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this.onload=function(){},this._isLoaded=!1,this._wasPlayingOnHidden=!1,this.path="";for(var s=0;i.length>s;s++)if(e.canPlayFile(i[s])){this.path=i[s];break}this.path||(this._logger.warn("This browser does not support any of the audio files specified:",i.join(", ")),this._logger.warn("Attempting to use",i[0]),this.path=i[0]),this.sound=new t.Internal.FallbackAudio(this.path,1)}return e.canPlayFile=function(e){try{var i=new Audio,n=/.*\.([A-Za-z0-9]+)$/,s=e.match(n)[1];return i.canPlayType("audio/"+s)?!0:!1}catch(o){return t.Logger.getInstance().warn("Cannot determine audio support, assuming no support for the Audio Tag",o),!1}},e.prototype.wireEngine=function(t){var e=this;t&&(this._engine=t,this._engine.on("hidden",function(){t.pauseAudioWhenHidden&&e.isPlaying()&&(e._wasPlayingOnHidden=!0,e.pause())}),this._engine.on("visible",function(){t.pauseAudioWhenHidden&&e._wasPlayingOnHidden&&(e.play(),e._wasPlayingOnHidden=!1)}))},e.prototype.setVolume=function(t){this.sound&&this.sound.setVolume(t)},e.prototype.setLoop=function(t){this.sound&&this.sound.setLoop(t)},e.prototype.isPlaying=function(){return this.sound?this.sound.isPlaying():void 0},e.prototype.play=function(){return this.sound?this.sound.play():void 0},e.prototype.pause=function(){this.sound&&this.sound.pause()},e.prototype.stop=function(){this.sound&&this.sound.stop()},e.prototype.isLoaded=function(){return this._isLoaded},e.prototype.load=function(){var e=this,i=new t.Promise;return null!==this.sound.getData()?(this._logger.debug("Already have data for resource",this.path),i.resolve(this.sound),i):(this._logger.debug("Started loading sound",this.path),this.sound.onprogress=this.onprogress,this.sound.onload=function(){e.oncomplete(),e._isLoaded=!0,e._logger.debug("Completed loading sound",e.path),i.resolve(e.sound)},this.sound.onerror=function(t){e.onerror(t),i.resolve(t)},this.sound.load(),i)},e.prototype.getData=function(){return this.sound.getData()},e.prototype.setData=function(t){this.sound.setData(t)},e.prototype.processData=function(t){return this.sound.processData(t)},e}();t.Sound=i;var n=function(){function e(t){this._resourceList=[],this._index=0,this._resourceCount=0,this._numLoaded=0,this._progressCounts={},this._totalCounts={},this.getData=function(){},this.setData=function(){},this.processData=function(){},this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},t&&this.addResources(t)}return e.prototype.wireEngine=function(t){this._engine=t},e.prototype.addResource=function(t){var e=this._index++;this._resourceList.push(t),this._progressCounts[e]=0,this._totalCounts[e]=1,this._resourceCount++},e.prototype.addResources=function(t){var e=0,i=t.length;for(e;i>e;e++)this.addResource(t[e])},e.prototype._sumCounts=function(t){var e=0;for(var i in t)e+=0|t[i];return e},e.prototype.isLoaded=function(){return this._numLoaded===this._resourceCount},e.prototype.load=function(){function e(t,i){t[i]&&t[i].load().then(function(){e(t,i+1)})}var i=this,n=new t.Promise,s=this;if(0===this._resourceList.length)return s.oncomplete.call(s),n;var o=Array(this._resourceList.length),r=this._resourceList.length;return this._resourceList.forEach(function(t,e){i._engine&&t.wireEngine(i._engine),t.onprogress=function(t){var i=t.total,n=t.loaded;o[e]={loaded:n/i*(100/r),total:100};var h=o.reduce(function(t,e){return{loaded:t.loaded+e.loaded,total:100}},{loaded:0,total:100});s.onprogress.call(s,h)},t.oncomplete=t.onerror=function(){s._numLoaded++,s._numLoaded===s._resourceCount&&(s.onprogress.call(s,{loaded:100,total:100}),s.oncomplete.call(s),n.resolve())}}),e(this._resourceList,0),n},e}();t.Loader=n})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.failedTests=[],this._criticalTests={canvasSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("2d"))},arrayBufferSupport:function(){var t=new XMLHttpRequest;t.open("GET","/");try{t.responseType="arraybuffer"}catch(e){return!1}return"arraybuffer"===t.responseType},dataUrlSupport:function(){var t=document.createElement("canvas");return 0===t.toDataURL("image/png").indexOf("data:image/png")},objectUrlSupport:function(){return"URL"in window&&"revokeObjectURL"in URL&&"createObjectURL"in URL},rgbaSupport:function(){var t=document.createElement("a").style;return t.cssText="background-color:rgba(150,255,150,.5)",(""+t.backgroundColor).indexOf("rgba")>-1}},this._warningTest={webAudioSupport:function(){return!!(window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext)},webglSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("webgl"))}}}return e.prototype.test=function(){var e=!1;for(var i in this._criticalTests)this._criticalTests[i]()||(this.failedTests.push(i),t.Logger.getInstance().error("Critical browser feature missing, Excalibur requires:",i),e=!0);if(e)return!1;for(var n in this._warningTest)this._warningTest[n]()||t.Logger.getInstance().warn("Warning browser feature missing, Excalibur will have reduced performance:",n);return!0},e}();t.Detector=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this.path=e,this._isLoaded=!1,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this._innerElement=document.createElement("div"),this._innerElement.className="excalibur-template"}return e.prototype.wireEngine=function(t){this._engine=t},e.prototype.getTemplateString=function(){return this._isLoaded?this._htmlString:""},e.prototype._compile=function(){this._innerElement.innerHTML=this._htmlString,this._styleElements=this._innerElement.querySelectorAll("[data-style]"),this._textElements=this._innerElement.querySelectorAll("[data-text]")},e.prototype._evaluateExpresion=function(t,e){var i=Function("return "+t+";"),n=i.call(e);return n},e.prototype.apply=function(t){for(var e=this,i=0;this._styleElements.length>i;i++)(function(){var n={};e._styleElements[i].dataset.style.split(";").forEach(function(t){if(t){var e=t.split(":");n[e[0].trim()]=e[1].trim()}});for(var s in n)(function(){var o=n[s];e._styleElements[i].style[s]=e._evaluateExpresion(o,t)})()})();for(var n=0;this._textElements.length>n;n++)(function(){var i=e._textElements[n].dataset.text;e._textElements[n].innerText=e._evaluateExpresion(i,t)})();return 1===this._innerElement.children.length&&(this._innerElement=this._innerElement.firstChild),this._innerElement},e.prototype.load=function(){var e=this,i=new t.Promise,n=new XMLHttpRequest;return n.open("GET",this.path,!0),n.responseType="text",n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load html template resource ",e.path," server responded with error code",n.status),e.onerror(n.response),e._isLoaded=!1,i.resolve("error"),void 0):(e.setData(n.response),e.oncomplete(),e.logger.debug("Completed loading template",e.path),i.resolve(e._htmlString),void 0)},n.overrideMimeType&&n.overrideMimeType("text/plain; charset=x-user-defined"),n.send(),i},e.prototype.getData=function(){return this._htmlString},e.prototype.setData=function(t){this._htmlString=this.processData(t),this._compile(),this._isLoaded=!0},e.prototype.processData=function(t){return t},e.prototype.isLoaded=function(){return this._isLoaded},e}();t.Template=e;var i=function(){function t(t,e,i){this.parent=document.getElementById(t),this.template=e,this._ctx=i,this.update()}return t.prototype.listen=function(t,e,i){var n=this;i||(i=function(){n.update()}),t.addEventListener&&e.forEach(function(e){t.addEventListener(e,i)})},t.prototype.update=function(){var t=this._applyTemplate(this.template,this._ctx);t instanceof String&&(this.parent.innerHTML=t),t instanceof Node&&this.parent.lastChild!==t&&this.parent.appendChild(t)},t.prototype._applyTemplate=function(t,e){return t.isLoaded()?t.apply(e):void 0},t}();t.Binding=i})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Em=0]="Em",t[t.Rem=1]="Rem",t[t.Px=2]="Px",t[t.Pt=3]="Pt",t[t.Percent=4]="Percent"})(t.FontUnit||(t.FontUnit={}));var e=t.FontUnit;(function(t){t[t.Left=0]="Left",t[t.Right=1]="Right",t[t.Center=2]="Center",t[t.Start=3]="Start",t[t.End=4]="End"})(t.TextAlign||(t.TextAlign={}));var i=t.TextAlign;(function(t){t[t.Top=0]="Top",t[t.Hanging=1]="Hanging",t[t.Middle=2]="Middle",t[t.Alphabetic=3]="Alphabetic",t[t.Ideographic=4]="Ideographic",t[t.Bottom=5]="Bottom"})(t.BaseAlign||(t.BaseAlign={}));var n=t.BaseAlign,s=function(s){function o(o,r,h,a,c){s.call(this,r,h),this.fontSize=10,this.fontUnit=e.Px,this.textAlign=i.Left,this.baseAlign=n.Bottom,this.letterSpacing=0,this.caseInsensitive=!0,this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone(),this._shadowColorDirty=!1,this._textSprites={},this._shadowSprites={},this._color=t.Color.Black.clone(),this.text=o||"",this.color=t.Color.Black.clone(),this.spriteFont=c,this.collisionType=t.CollisionType.PreventCollision,this.fontFamily=a||"10px sans-serif"}return __extends(o,s),o.prototype.getTextWidth=function(t){var e=t.font;t.font=this.fontFamily;var i=t.measureText(this.text).width;return t.font=e,i},o.prototype._lookupFontUnit=function(t){switch(t){case e.Em:return"em";case e.Rem:return"rem";case e.Pt:return"pt";case e.Px:return"px";case e.Percent:return"%";default:return"px"}},o.prototype._lookupTextAlign=function(t){switch(t){case i.Left:return"left";case i.Right:return"right";case i.Center:return"center";case i.End:return"end";case i.Start:return"start";default:return"start"}},o.prototype._lookupBaseAlign=function(t){switch(t){case n.Alphabetic:return"alphabetic";case n.Bottom:return"bottom";case n.Hanging:return"hangin";case n.Ideographic:return"ideographic";case n.Middle:return"middle";case n.Top:return"top";default:return"alphabetic"}},o.prototype.setTextShadow=function(t,e,i){this.spriteFont.setTextShadow(t,e,i)},o.prototype.useTextShadow=function(t){this.spriteFont.useTextShadow(t)},o.prototype.clearTextShadow=function(){this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone() -},o.prototype.update=function(t,e){s.prototype.update.call(this,t,e)},o.prototype.draw=function(t,e){t.save(),t.translate(this.x,this.y),t.scale(this.scale.x,this.scale.y),t.rotate(this.rotation),this._textShadowOn&&(t.save(),t.translate(this._shadowOffsetX,this._shadowOffsetY),this._fontDraw(t,e,this._shadowSprites),t.restore()),this._fontDraw(t,e,this._textSprites),s.prototype.draw.call(this,t,e),t.restore()},o.prototype._fontDraw=function(t){if(this.spriteFont)this.spriteFont.draw(t,this.text,0,0,{color:this.color.clone(),baseAlign:this.baseAlign,textAlign:this.textAlign,fontSize:this.fontSize,letterSpacing:this.letterSpacing,opacity:this.opacity});else{var e=t.textAlign,i=t.textBaseline;t.textAlign=this._lookupTextAlign(this.textAlign),t.textBaseline=this._lookupBaseAlign(this.baseAlign),this.color&&(this.color.a=this.opacity),t.fillStyle=""+this.color,t.font=""+this.fontSize+this._lookupFontUnit(this.fontUnit)+" "+this.fontFamily,this.maxWidth?t.fillText(this.text,0,0,this.maxWidth):t.fillText(this.text,0,0),t.textAlign=e,t.textBaseline=i}},o.prototype.debugDraw=function(t){s.prototype.debugDraw.call(this,t)},o}(t.Actor);t.Label=s})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Touch=0]="Touch",t[t.Mouse=1]="Mouse",t[t.Pen=2]="Pen",t[t.Unknown=3]="Unknown"})(e.PointerType||(e.PointerType={}));var i=e.PointerType;(function(t){t[t.Left=0]="Left",t[t.Middle=1]="Middle",t[t.Right=2]="Right",t[t.Unknown=3]="Unknown"})(e.PointerButton||(e.PointerButton={}));var n=e.PointerButton;(function(t){t[t.Canvas=0]="Canvas",t[t.Document=1]="Document"})(e.PointerScope||(e.PointerScope={}));var s=e.PointerScope,o=function(t){function e(e,i,n,s,o,r){t.call(this),this.x=e,this.y=i,this.index=n,this.pointerType=s,this.button=o,this.ev=r}return __extends(e,t),e}(t.GameEvent);e.PointerEvent=o;var r=function(e){function r(t){e.call(this),this._pointerDown=[],this._pointerUp=[],this._pointerMove=[],this._pointerCancel=[],this._pointers=[],this._activePointers=[],this._engine=t,this._pointers.push(new h),this._activePointers=[-1],this.primary=this._pointers[0]}return __extends(r,e),r.prototype.init=function(t){void 0===t&&(t=s.Document);var e=document;e=t===s.Document?document:this._engine.canvas,e.addEventListener("touchstart",this._handleTouchEvent("down",this._pointerDown)),e.addEventListener("touchend",this._handleTouchEvent("up",this._pointerUp)),e.addEventListener("touchmove",this._handleTouchEvent("move",this._pointerMove)),e.addEventListener("touchcancel",this._handleTouchEvent("cancel",this._pointerCancel)),window.PointerEvent?(this._engine.canvas.style.touchAction="none",e.addEventListener("pointerdown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("pointerup",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("pointermove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("pointercancel",this._handlePointerEvent("cancel",this._pointerMove))):window.MSPointerEvent?(this._engine.canvas.style.msTouchAction="none",e.addEventListener("MSPointerDown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("MSPointerUp",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("MSPointerMove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("MSPointerCancel",this._handlePointerEvent("cancel",this._pointerMove))):(e.addEventListener("mousedown",this._handleMouseEvent("down",this._pointerDown)),e.addEventListener("mouseup",this._handleMouseEvent("up",this._pointerUp)),e.addEventListener("mousemove",this._handleMouseEvent("move",this._pointerMove)))},r.prototype.update=function(){this._pointerUp.length=0,this._pointerDown.length=0,this._pointerMove.length=0,this._pointerCancel.length=0},r.prototype.at=function(t){if(t>=this._pointers.length)for(var e=this._pointers.length-1,i=t;i>e;e++)this._pointers.push(new h),this._activePointers.push(-1);return this._pointers[t]},r.prototype.count=function(){return this._pointers.length},r.prototype.propogate=function(e){var i=e instanceof t.UIActor,n=0,s=this._pointerUp.length;for(n;s>n;n++)e.contains(this._pointerUp[n].x,this._pointerUp[n].y,!i)&&e.eventDispatcher.emit("pointerup",this._pointerUp[n]);for(n=0,s=this._pointerDown.length,n;s>n;n++)e.contains(this._pointerDown[n].x,this._pointerDown[n].y,!i)&&e.eventDispatcher.emit("pointerdown",this._pointerDown[n]);if(e.capturePointer.captureMoveEvents)for(n=0,s=this._pointerMove.length,n;s>n;n++)e.contains(this._pointerMove[n].x,this._pointerMove[n].y,!i)&&e.eventDispatcher.emit("pointermove",this._pointerMove[n]);for(n=0,s=this._pointerCancel.length,n;s>n;n++)e.contains(this._pointerCancel[n].x,this._pointerCancel[n].y,!i)&&e.eventDispatcher.emit("pointercancel",this._pointerCancel[n])},r.prototype._handleMouseEvent=function(e,n){var s=this;return function(r){r.preventDefault();var h=r.pageX-t.Util.getPosition(s._engine.canvas).x,a=r.pageY-t.Util.getPosition(s._engine.canvas).y,c=s._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,0,i.Mouse,r.button,r);n.push(u),s.at(0).eventDispatcher.emit(e,u)}},r.prototype._handleTouchEvent=function(e,s){var r=this;return function(h){h.preventDefault();for(var a=0,c=h.changedTouches.length;c>a;a++){var u=r._pointers.length>1?r._getPointerIndex(h.changedTouches[a].identifier):0;if(-1!==u){var l=h.changedTouches[a].pageX-t.Util.getPosition(r._engine.canvas).x,p=h.changedTouches[a].pageY-t.Util.getPosition(r._engine.canvas).y,d=r._engine.screenToWorldCoordinates(new t.Point(l,p)),f=new o(d.x,d.y,u,i.Touch,n.Unknown,h);s.push(f),r.at(u).eventDispatcher.emit(e,f),r._pointers.length>1&&("up"===e?r._activePointers[u]=-1:"down"===e&&(r._activePointers[u]=h.changedTouches[a].identifier))}}}},r.prototype._handlePointerEvent=function(e,i){var n=this;return function(s){s.preventDefault();var r=n._pointers.length>1?n._getPointerIndex(s.pointerId):0;if(-1!==r){var h=s.pageX-t.Util.getPosition(n._engine.canvas).x,a=s.pageY-t.Util.getPosition(n._engine.canvas).y,c=n._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,r,n._stringToPointerType(s.pointerType),s.button,s);i.push(u),n.at(r).eventDispatcher.emit(e,u),n._pointers.length>1&&("up"===e?n._activePointers[r]=-1:"down"===e&&(n._activePointers[r]=s.pointerId))}}},r.prototype._getPointerIndex=function(t){var e;if((e=this._activePointers.indexOf(t))>-1)return e;for(var i=0;this._activePointers.length>i;i++)if(-1===this._activePointers[i])return i;return-1},r.prototype._stringToPointerType=function(t){switch(t){case"touch":return i.Touch;case"mouse":return i.Mouse;case"pen":return i.Pen;default:return i.Unknown}},r}(t.Class);e.Pointers=r;var h=function(t){function e(){t.apply(this,arguments)}return __extends(e,t),e}(t.Class);e.Pointer=h})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Num1=97]="Num1",t[t.Num2=98]="Num2",t[t.Num3=99]="Num3",t[t.Num4=100]="Num4",t[t.Num5=101]="Num5",t[t.Num6=102]="Num6",t[t.Num7=103]="Num7",t[t.Num8=104]="Num8",t[t.Num9=105]="Num9",t[t.Num0=96]="Num0",t[t.Numlock=144]="Numlock",t[t.Semicolon=186]="Semicolon",t[t.A=65]="A",t[t.B=66]="B",t[t.C=67]="C",t[t.D=68]="D",t[t.E=69]="E",t[t.F=70]="F",t[t.G=71]="G",t[t.H=72]="H",t[t.I=73]="I",t[t.J=74]="J",t[t.K=75]="K",t[t.L=76]="L",t[t.M=77]="M",t[t.N=78]="N",t[t.O=79]="O",t[t.P=80]="P",t[t.Q=81]="Q",t[t.R=82]="R",t[t.S=83]="S",t[t.T=84]="T",t[t.U=85]="U",t[t.V=86]="V",t[t.W=87]="W",t[t.X=88]="X",t[t.Y=89]="Y",t[t.Z=90]="Z",t[t.Shift=16]="Shift",t[t.Alt=18]="Alt",t[t.Up=38]="Up",t[t.Down=40]="Down",t[t.Left=37]="Left",t[t.Right=39]="Right",t[t.Space=32]="Space",t[t.Esc=27]="Esc"})(e.Keys||(e.Keys={})),e.Keys;var i=function(t){function e(e){t.call(this),this.key=e}return __extends(e,t),e}(t.GameEvent);e.KeyEvent=i;var n=function(t){function e(e){t.call(this),this._keys=[],this._keysUp=[],this._keysDown=[],this._engine=e}return __extends(e,t),e.prototype.init=function(){var t=this;window.addEventListener("blur",function(){t._keys.length=0}),window.addEventListener("keyup",function(e){var n=t._keys.indexOf(e.keyCode);t._keys.splice(n,1),t._keysUp.push(e.keyCode);var s=new i(e.keyCode);t.eventDispatcher.emit("up",s),t.eventDispatcher.emit("release",s)}),window.addEventListener("keydown",function(e){if(-1===t._keys.indexOf(e.keyCode)){t._keys.push(e.keyCode),t._keysDown.push(e.keyCode);var n=new i(e.keyCode);t.eventDispatcher.emit("down",n),t.eventDispatcher.emit("press",n)}})},e.prototype.update=function(){this._keysDown.length=0,this._keysUp.length=0;for(var t=0;this._keys.length>t;t++)this.eventDispatcher.emit("hold",new i(this._keys[t]))},e.prototype.getKeys=function(){return this._keys},e.prototype.wasPressed=function(t){return this._keysDown.indexOf(t)>-1},e.prototype.isHeld=function(t){return this._keys.indexOf(t)>-1},e.prototype.wasReleased=function(t){return this._keysUp.indexOf(t)>-1},e}(t.Class);e.Keyboard=n})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(e){function i(t){e.call(this),this.enabled=!1,this.supported=!!navigator.getGamepads,this._gamePadTimeStamps=[0,0,0,0],this._oldPads=[],this._pads=[],this._initSuccess=!1,this._navigator=navigator,this._minimumConfiguration=null,this._engine=t}return __extends(i,e),i.prototype.init=function(){this.supported&&(this._initSuccess||(this._oldPads=this._clonePads(this._navigator.getGamepads()),this._oldPads.length&&this._oldPads[0]&&(this._initSuccess=!0)))},i.prototype.setMinimumGamepadConfiguration=function(t){this._enableAndUpdate(),this._minimumConfiguration=t},i.prototype._enableAndUpdate=function(){this.enabled||(this.enabled=!0,this.update(100))},i.prototype._isGamepadValid=function(t){if(!this._minimumConfiguration)return!0;if(!t)return!1;var e=t.axes.filter(function(t){return void 0!==typeof t}).length,i=t.buttons.filter(function(t){return void 0!==typeof t}).length;return e>=this._minimumConfiguration.axis&&i>=this._minimumConfiguration.buttons&&t.connected},i.prototype.on=function(t,i){this._enableAndUpdate(),e.prototype.on.call(this,t,i)},i.prototype.off=function(t,i){this._enableAndUpdate(),e.prototype.off.call(this,t,i)},i.prototype.update=function(){if(this.enabled&&this.supported){this.init();for(var e=this._navigator.getGamepads(),i=0;e.length>i;i++)if(e[i]){if(!this.at(i).connected&&this._isGamepadValid(e[i])&&this.eventDispatcher.emit("connect",new t.GamepadConnectEvent(i,this.at(i))),this.at(i).connected=!0,!e[i].timestamp||e[i].timestamp!==this._gamePadTimeStamps[i]){this._gamePadTimeStamps[i]=e[i].timestamp,this.at(i).navigatorGamepad=e[i];var n,r,h,a,c;for(n in s)"number"==typeof s[n]&&(a=s[n],e[i].buttons[a]&&(h=e[i].buttons[a].value,h!==this._oldPads[i].getButton(a)&&(e[i].buttons[a].pressed?(this.at(i).updateButton(a,h),this.at(i).eventDispatcher.publish("button",new t.GamepadButtonEvent(a,h))):this.at(i).updateButton(a,0))));for(r in o)"number"==typeof o[r]&&(c=o[r],h=e[i].axes[c],h!==this._oldPads[i].getAxes(c)&&(this.at(i).updateAxes(c,h),this.at(i).eventDispatcher.emit("axis",new t.GamepadAxisEvent(c,h))));this._oldPads[i]=this._clonePad(e[i])}}else this.at(i).connected&&this.eventDispatcher.emit("disconnect",new t.GamepadDisconnectEvent(i)),this.at(i).connected=!1}},i.prototype.at=function(t){if(this._enableAndUpdate(),t>=this._pads.length)for(var e=this._pads.length-1,i=t;i>e;e++)this._pads.push(new n),this._oldPads.push(new n);return this._pads[t]},i.prototype.getValidGamepads=function(){this._enableAndUpdate();for(var t=[],e=0;this._pads.length>e;e++)this._isGamepadValid(this.at(e).navigatorGamepad)&&this.at(e).connected&&t.push(this.at(e));return t},i.prototype.count=function(){return this._pads.filter(function(t){return t.connected}).length},i.prototype._clonePads=function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(this._clonePad(t[i]));return e},i.prototype._clonePad=function(t){var e,i,s=new n;if(!t)return s;for(e=0,i=t.buttons.length;i>e;e++)t.buttons[e]&&s.updateButton(e,t.buttons[e].value);for(e=0,i=t.axes.length;i>e;e++)s.updateAxes(e,t.axes[e]);return s},i.MinAxisMoveThreshold=.05,i}(t.Class);e.Gamepads=i;var n=function(t){function e(){t.call(this),this.connected=!1,this._buttons=Array(16),this._axes=Array(4);var e;for(e=0;this._buttons.length>e;e++)this._buttons[e]=0;for(e=0;this._axes.length>e;e++)this._axes[e]=0}return __extends(e,t),e.prototype.isButtonPressed=function(t,e){return void 0===e&&(e=1),this._buttons[t]>=e},e.prototype.getButton=function(t){return this._buttons[t]},e.prototype.getAxes=function(t){var e=this._axes[t];return Math.abs(e)n;n++)this._animations[n].animation.draw(i,this._animations[n].x,this._animations[n].y);if(this.fps=1/(e/1e3),this.isDebug){this.ctx.font="Consolas",this.ctx.fillStyle=""+this.debugColor;for(var o=this.input.keyboard.getKeys(),r=0;o.length>r;r++)this.ctx.fillText(""+o[r]+" : "+(t.Input.Keys[o[r]]?t.Input.Keys[o[r]]:"Not Mapped"),100,10*r+10);this.ctx.fillText("FPS:"+(""+this.fps.toFixed(2)),10,10)}for(var h=0;this.postProcessors.length>h;h++)this.postProcessors[h].process(this.ctx.getImageData(0,0,this.width,this.height),this.ctx);this.emit("postdraw",new t.PreDrawEvent(i,e,this))},s.prototype.start=function(e){if(!this._compatible){var i=new t.Promise;return i.reject("Excalibur is incompatible with your browser")}var n;if(e?(e.wireEngine(this),n=this.load(e)):n=t.Promise.wrap(),!this._hasStarted){this._hasStarted=!0,this._logger.debug("Starting game...");var s=Date.now(),o=this;(function r(){if(o._hasStarted)try{o._requestId=window.requestAnimationFrame(r);var t=Date.now(),e=Math.floor(t-s)||1;e>200&&(e=1),o._update(e),o._draw(e),s=t}catch(i){window.cancelAnimationFrame(o._requestId),o.stop(),o.onFatalException(i)}})(),this._logger.debug("Game started")}return n},s.prototype.stop=function(){this._hasStarted&&(this._hasStarted=!1,this._logger.debug("Game stopped"))},s.prototype.screenshot=function(){var t=new Image,e=this.canvas.toDataURL("image/png");return t.src=e,t},s.prototype._drawLoadingBar=function(t,e,i){if(this._loadingDraw)return this._loadingDraw(t,e,i),void 0;var n=this.canvas.height/2,s=this.canvas.width/3,o=s,r=new Image;r.src="data:image/png;base64,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"; -var h=3*s/8,a=this.getAntialiasing();this.setAntialiasing(!0),t.drawImage(r,0,0,800,300,o,n-h-20,s,h),t.strokeStyle="white",t.lineWidth=2,t.strokeRect(o,n,s,20);var c=s*(e/i);t.fillStyle="white";var u=5,l=c-2*u,p=20-2*u;t.fillRect(o+u,n+u,l>0?l:0,p),this.setAntialiasing(a)},s.prototype.setLoadingDrawFunction=function(t){this._loadingDraw=t},s.prototype.load=function(e){var i=this,n=new t.Promise;return this._isLoading=!0,e.onprogress=function(t){i._progress=t.loaded,i._total=t.total,i._logger.debug("Loading "+(100*i._progress/i._total).toFixed(0))},e.oncomplete=function(){setTimeout(function(){i._isLoading=!1,n.resolve()},500)},e.load(),n},s}(t.Class);t.Engine=e,function(t){t[t.FullScreen=0]="FullScreen",t[t.Container=1]="Container",t[t.Fixed=2]="Fixed"}(t.DisplayMode||(t.DisplayMode={}));var i=t.DisplayMode,n=function(){function t(t,e,i){this.animation=t,this.x=e,this.y=i}return t}()})(ex||(ex={})); +})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s){void 0===s&&(s=!0),e.call(this),this.path=i,this.responseType=n,this.bustCache=s,this.data=null,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){}}return __extends(i,e),i.prototype.isLoaded=function(){return null!==this.data},i.prototype.wireEngine=function(t){this._engine=t},i.prototype._cacheBust=function(t){var e=/\?\w*=\w*/;return t+=e.test(t)?"&__="+Date.now():"?__="+Date.now()},i.prototype._start=function(){this.logger.debug("Started loading resource "+this.path)},i.prototype.load=function(){var e=this,i=new t.Promise;if(null!==this.data)return this.logger.debug("Already have data for resource",this.path),i.resolve(this.data),this.oncomplete(),i;var n=new XMLHttpRequest;return n.open("GET",this.bustCache?this._cacheBust(this.path):this.path,!0),n.responseType=this.responseType,n.onloadstart=function(t){e._start(t)},n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load resource ",e.path," server responded with error code",n.status),e.onerror(n.response),i.resolve(n.response),void 0):(e.data=e.processData(n.response),e.oncomplete(),e.logger.debug("Completed loading resource",e.path),i.resolve(e.data),void 0)},n.send(),i},i.prototype.getData=function(){return this.data},i.prototype.setData=function(t){this.data=this.processData(t)},i.prototype.processData=function(t){return URL.createObjectURL(t)},i}(t.Class);t.Resource=e})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Resolved=0]="Resolved",t[t.Rejected=1]="Rejected",t[t.Pending=2]="Pending"})(t.PromiseState||(t.PromiseState={}));var e=t.PromiseState,i=function(){function i(){this._state=e.Pending,this._successCallbacks=[],this._rejectCallback=function(){},this._logger=t.Logger.getInstance()}return i.wrap=function(t){var e=(new i).resolve(t);return e},i.join=function(){for(var t=[],e=0;arguments.length>e;e++)t[e-0]=arguments[e];var n=new i;if(!t||!t.length)return n.resolve();var s=t.length,o=0,r=0,h=[];return t.forEach(function(t){t.then(function(){o+=1,o===s?n.resolve():o+r+h.length===s&&n.reject(h)},function(){r+=1,o+r+h.length===s&&n.reject(h)}).error(function(t){h.push(t),h.length+o+r===s&&n.reject(h)})}),n},i.prototype.then=function(t,i){if(t&&(this._successCallbacks.push(t),this.state()===e.Resolved))try{t.call(this,this._value)}catch(n){this._handleError(n)}if(i&&(this._rejectCallback=i,this.state()===e.Rejected))try{i.call(this,this._value)}catch(n){this._handleError(n)}return this},i.prototype.error=function(t){return t&&(this._errorCallback=t),this},i.prototype.resolve=function(t){var i=this;if(this._state!==e.Pending)throw Error("Cannot resolve a promise that is not in a pending state!");this._value=t;try{this._state=e.Resolved,this._successCallbacks.forEach(function(t){t.call(i,i._value)})}catch(n){this._handleError(n)}return this},i.prototype.reject=function(t){if(this._state!==e.Pending)throw Error("Cannot reject a promise that is not in a pending state!");this._value=t;try{this._state=e.Rejected,this._rejectCallback.call(this,this._value)}catch(i){this._handleError(i)}return this},i.prototype.state=function(){return this._state},i.prototype._handleError=function(t){if(!this._errorCallback)throw t;this._errorCallback.call(this,t)},i}();t.Promise=i})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n){void 0===n&&(n=!0),e.call(this,i,"blob",n),this.path=i,this.bustCache=n,this.loaded=new t.Promise,this._isLoaded=!1,this._sprite=null,this._sprite=new t.Sprite(this,0,0,0,0)}return __extends(i,e),i.prototype.isLoaded=function(){return this._isLoaded},i.prototype.load=function(){var i=this,n=new t.Promise,s=e.prototype.load.call(this);return s.then(function(){i.image=new Image,i.image.addEventListener("load",function(){i._isLoaded=!0,i.width=i._sprite.swidth=i._sprite.naturalWidth=i._sprite.width=i.image.naturalWidth,i.height=i._sprite.sheight=i._sprite.naturalHeight=i._sprite.height=i.image.naturalHeight,i.loaded.resolve(i.image),n.resolve(i.image)}),i.image.src=e.prototype.getData.call(i)},function(){n.reject("Error loading texture.")}),n},i.prototype.asSprite=function(){return this._sprite},i}(t.Resource);t.Texture=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){for(var i=[],n=0;arguments.length>n;n++)i[n-0]=arguments[n];this._logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this.onload=function(){},this._isLoaded=!1,this._wasPlayingOnHidden=!1,this.path="";for(var s=0;i.length>s;s++)if(e.canPlayFile(i[s])){this.path=i[s];break}this.path||(this._logger.warn("This browser does not support any of the audio files specified:",i.join(", ")),this._logger.warn("Attempting to use",i[0]),this.path=i[0]),this.sound=new t.Internal.FallbackAudio(this.path,1)}return e.canPlayFile=function(e){try{var i=new Audio,n=/.*\.([A-Za-z0-9]+)$/,s=e.match(n)[1];return i.canPlayType("audio/"+s)?!0:!1}catch(o){return t.Logger.getInstance().warn("Cannot determine audio support, assuming no support for the Audio Tag",o),!1}},e.prototype.wireEngine=function(t){var e=this;t&&(this._engine=t,this._engine.on("hidden",function(){t.pauseAudioWhenHidden&&e.isPlaying()&&(e._wasPlayingOnHidden=!0,e.pause())}),this._engine.on("visible",function(){t.pauseAudioWhenHidden&&e._wasPlayingOnHidden&&(e.play(),e._wasPlayingOnHidden=!1)}))},e.prototype.setVolume=function(t){this.sound&&this.sound.setVolume(t)},e.prototype.setLoop=function(t){this.sound&&this.sound.setLoop(t)},e.prototype.isPlaying=function(){return this.sound?this.sound.isPlaying():void 0},e.prototype.play=function(){return this.sound?this.sound.play():void 0},e.prototype.pause=function(){this.sound&&this.sound.pause()},e.prototype.stop=function(){this.sound&&this.sound.stop()},e.prototype.isLoaded=function(){return this._isLoaded},e.prototype.load=function(){var e=this,i=new t.Promise;return null!==this.sound.getData()?(this._logger.debug("Already have data for resource",this.path),i.resolve(this.sound),i):(this._logger.debug("Started loading sound",this.path),this.sound.onprogress=this.onprogress,this.sound.onload=function(){e.oncomplete(),e._isLoaded=!0,e._logger.debug("Completed loading sound",e.path),i.resolve(e.sound)},this.sound.onerror=function(t){e.onerror(t),i.resolve(t)},this.sound.load(),i)},e.prototype.getData=function(){return this.sound.getData()},e.prototype.setData=function(t){this.sound.setData(t)},e.prototype.processData=function(t){return this.sound.processData(t)},e}();t.Sound=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o){e.call(this,i,n,s,o),this.traits=[],this.traits.push(new t.Traits.Movement),this.traits.push(new t.Traits.CapturePointer),this.anchor.setTo(0,0),this.collisionType=t.CollisionType.PreventCollision,this.enableCapturePointer=!0}return __extends(i,e),i.prototype.onInitialize=function(t){this._engine=t},i.prototype.contains=function(i,n,s){if(void 0===s&&(s=!0),s)return e.prototype.contains.call(this,i,n);var o=this._engine.worldToScreenCoordinates(new t.Point(i,n));return e.prototype.contains.call(this,o.x,o.y)},i}(t.Actor);t.UIActor=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o,r,h){e.call(this,i,n,s,o),this._action=function(){},this.repeats=1,this.target=null,this.repeats=h||this.repeats,this._action=r||this._action,this.collisionType=t.CollisionType.PreventCollision,this.eventDispatcher=new t.EventDispatcher(this),this.actionQueue=new t.Internal.Actions.ActionQueue(this)}return __extends(i,e),i.prototype.update=function(e,i){if(this.actionQueue.update(i),this.x+=this.dx*i/1e3,this.y+=this.dy*i/1e3,this.rotation+=this.rx*i/1e3,this.scale.x+=this.sx*i/1e3,this.scale.y+=this.sy*i/1e3,this.target)this.collides(this.target)&&this._dispatchAction();else for(var n=0;e.currentScene.children.length>n;n++){var s=e.currentScene.children[n];s!==this&&s.collisionType!==t.CollisionType.PreventCollision&&this.collides(s)&&this._dispatchAction()}0===this.repeats&&this.kill()},i.prototype._dispatchAction=function(){this._action.call(this),this.repeats--},i.prototype.draw=function(){},i.prototype.debugDraw=function(i){e.prototype.debugDraw.call(this,i),i.save(),i.translate(this.x,this.y);var n=this.getBounds();n.left=n.left-this.getWorldX(),n.right=n.right-this.getWorldX(),n.top=n.top-this.getWorldY(),n.bottom=n.bottom-this.getWorldY(),i.fillStyle=""+t.Color.Violet,i.strokeStyle=""+t.Color.Violet,i.fillText("Trigger",10,10),n.debugDraw(i),i.restore()},i}(t.Actor);t.Trigger=e})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Circle=0]="Circle",t[t.Rectangle=1]="Rectangle"})(t.EmitterType||(t.EmitterType={}));var e=t.EmitterType,i=function(){function e(e,i,n,s,o,r,h,a,c,u){this.position=new t.Vector(0,0),this.velocity=new t.Vector(0,0),this.acceleration=new t.Vector(0,0),this.particleRotationalVelocity=0,this.currentRotation=0,this.focus=null,this.focusAccel=0,this.opacity=1,this.beginColor=t.Color.White.clone(),this.endColor=t.Color.White.clone(),this.life=300,this.fadeFlag=!1,this._rRate=1,this._gRate=1,this._bRate=1,this._aRate=0,this._currentColor=t.Color.White.clone(),this.emitter=null,this.particleSize=5,this.particleSprite=null,this.sizeRate=0,this.elapsedMultiplier=0,this.emitter=e,this.life=i||this.life,this.opacity=n||this.opacity,this.endColor=o||this.endColor.clone(),this.beginColor=s||this.beginColor.clone(),this._currentColor=this.beginColor.clone(),this.position=r||this.position,this.velocity=h||this.velocity,this.acceleration=a||this.acceleration,this._rRate=(this.endColor.r-this.beginColor.r)/this.life,this._gRate=(this.endColor.g-this.beginColor.g)/this.life,this._bRate=(this.endColor.b-this.beginColor.b)/this.life,this._aRate=this.opacity/this.life,this.startSize=c||0,this.endSize=u||0,this.endSize>0&&this.startSize>0&&(this.sizeRate=(this.endSize-this.startSize)/this.life,this.particleSize=this.startSize)}return e.prototype.kill=function(){this.emitter.removeParticle(this)},e.prototype.update=function(e){if(this.life=this.life-e,this.elapsedMultiplier=this.elapsedMultiplier+e,0>this.life&&this.kill(),this.fadeFlag&&(this.opacity=t.Util.clamp(this._aRate*this.life,1e-4,1)),this.startSize>0&&this.endSize>0&&(this.particleSize=t.Util.clamp(this.sizeRate*e+this.particleSize,Math.min(this.startSize,this.endSize),Math.max(this.startSize,this.endSize))),this._currentColor.r=t.Util.clamp(this._currentColor.r+this._rRate*e,0,255),this._currentColor.g=t.Util.clamp(this._currentColor.g+this._gRate*e,0,255),this._currentColor.b=t.Util.clamp(this._currentColor.b+this._bRate*e,0,255),this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),this.focus){var i=this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(e/1e3);this.velocity=this.velocity.add(i)}else this.velocity=this.velocity.add(this.acceleration.scale(e/1e3));this.position=this.position.add(this.velocity.scale(e/1e3)),this.particleRotationalVelocity&&(this.currentRotation=(this.currentRotation+this.particleRotationalVelocity*e/1e3)%(2*Math.PI))},e.prototype.draw=function(e){return this.particleSprite?(this.particleSprite.rotation=this.currentRotation,this.particleSprite.scale.setTo(this.particleSize,this.particleSize),this.particleSprite.draw(e,this.position.x,this.position.y),void 0):(this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),e.fillStyle=""+this._currentColor,e.beginPath(),e.arc(this.position.x,this.position.y,this.particleSize,0,2*Math.PI),e.fill(),e.closePath(),void 0)},e}();t.Particle=i;var n=function(n){function s(i,s,o,r){n.call(this,i,s,o,r,t.Color.White),this._particlesToEmit=0,this.numParticles=0,this.isEmitting=!0,this.particles=null,this.deadParticles=null,this.minVel=0,this.maxVel=0,this.acceleration=new t.Vector(0,0),this.minAngle=0,this.maxAngle=0,this.emitRate=1,this.particleLife=2e3,this.opacity=1,this.fadeFlag=!1,this.focus=null,this.focusAccel=1,this.startSize=null,this.endSize=null,this.minSize=5,this.maxSize=5,this.beginColor=t.Color.White,this.endColor=t.Color.White,this.particleSprite=null,this.emitterType=e.Rectangle,this.radius=0,this.particleRotationalVelocity=0,this.randomRotation=!1,this.collisionType=t.CollisionType.PreventCollision,this.particles=new t.Util.Collection,this.deadParticles=new t.Util.Collection;for(var h in this.traits)this.traits[h]instanceof t.Traits.OffscreenCulling&&this.traits.splice(h,1)}return __extends(s,n),s.prototype.removeParticle=function(t){this.deadParticles.push(t)},s.prototype.emitParticles=function(t){for(var e=0;t>e;e++)this.particles.push(this._createParticle())},s.prototype.clearParticles=function(){this.particles.clear()},s.prototype._createParticle=function(){var n=0,s=0,o=t.Util.randomInRange(this.minAngle,this.maxAngle),r=t.Util.randomInRange(this.minVel,this.maxVel),h=this.startSize||t.Util.randomInRange(this.minSize,this.maxSize),a=r*Math.cos(o),c=r*Math.sin(o);if(this.emitterType===e.Rectangle)n=t.Util.randomInRange(this.x,this.x+this.getWidth()),s=t.Util.randomInRange(this.y,this.y+this.getHeight());else if(this.emitterType===e.Circle){var u=t.Util.randomInRange(0,this.radius);n=u*Math.cos(o)+this.x,s=u*Math.sin(o)+this.y}var l=new i(this,this.particleLife,this.opacity,this.beginColor,this.endColor,new t.Vector(n,s),new t.Vector(a,c),this.acceleration,this.startSize,this.endSize);return l.fadeFlag=this.fadeFlag,l.particleSize=h,this.particleSprite&&(l.particleSprite=this.particleSprite),l.particleRotationalVelocity=this.particleRotationalVelocity,this.randomRotation&&(l.currentRotation=t.Util.randomInRange(0,2*Math.PI)),this.focus&&(l.focus=this.focus.add(new t.Vector(this.x,this.y)),l.focusAccel=this.focusAccel),l},s.prototype.update=function(t,e){var i=this;n.prototype.update.call(this,t,e),this.isEmitting&&(this._particlesToEmit+=this.emitRate*(e/1e3),this._particlesToEmit>1&&(this.emitParticles(Math.floor(this._particlesToEmit)),this._particlesToEmit=this._particlesToEmit-Math.floor(this._particlesToEmit))),this.particles.forEach(function(t){return t.update(e)}),this.deadParticles.forEach(function(t){return i.particles.removeElement(t)}),this.deadParticles.clear()},s.prototype.draw=function(t){this.particles.forEach(function(e){return e.draw(t)})},s.prototype.debugDraw=function(e){n.prototype.debugDraw.call(this,e),e.fillStyle=""+t.Color.Black,e.fillText("Particles: "+this.particles.count(),this.x,this.y+20),this.focus&&(e.fillRect(this.focus.x+this.x,this.focus.y+this.y,3,3),t.Util.drawLine(e,"yellow",this.focus.x+this.x,this.focus.y+this.y,n.prototype.getCenter.call(this).x,n.prototype.getCenter.call(this).y),e.fillText("Focus",this.focus.x+this.x,this.focus.y+this.y))},s}(t.Actor);t.ParticleEmitter=n})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s){this.currentFrame=0,this._oldTime=Date.now(),this.anchor=new t.Point(0,0),this.rotation=0,this.scale=new t.Point(1,1),this.loop=!1,this.freezeFrame=-1,this.flipVertical=!1,this.flipHorizontal=!1,this.width=0,this.height=0,this.naturalWidth=0,this.naturalHeight=0,this.sprites=i,this.speed=n,this._engine=e,null!=s&&(this.loop=s),i&&i[0]&&(this.height=i[0]?i[0].height:0,this.width=i[0]?i[0].width:0,this.naturalWidth=i[0]?i[0].naturalWidth:0,this.naturalHeight=i[0]?i[0].naturalHeight:0,this.freezeFrame=i.length-1)}return e.prototype.opacity=function(e){this.addEffect(new t.Effects.Opacity(e))},e.prototype.grayscale=function(){this.addEffect(new t.Effects.Grayscale)},e.prototype.invert=function(){this.addEffect(new t.Effects.Invert)},e.prototype.fill=function(e){this.addEffect(new t.Effects.Fill(e))},e.prototype.colorize=function(e){this.addEffect(new t.Effects.Colorize(e))},e.prototype.lighten=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Lighten(e))},e.prototype.darken=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Darken(e))},e.prototype.saturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Saturate(e))},e.prototype.desaturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Desaturate(e))},e.prototype.addEffect=function(t){for(var e in this.sprites)this.sprites[e].addEffect(t)},e.prototype.removeEffect=function(t){for(var e in this.sprites)this.sprites[e].removeEffect(t)},e.prototype.clearEffects=function(){for(var t in this.sprites)this.sprites[t].clearEffects()},e.prototype._setAnchor=function(t){for(var e in this.sprites)this.sprites[e].anchor.setTo(t.x,t.y)},e.prototype._setRotation=function(t){for(var e in this.sprites)this.sprites[e].rotation=t},e.prototype._setScale=function(t){for(var e in this.sprites)this.sprites[e].scale=t},e.prototype.reset=function(){this.currentFrame=0},e.prototype.isDone=function(){return!this.loop&&this.currentFrame>=this.sprites.length},e.prototype.tick=function(){var t=Date.now();t-this._oldTime>this.speed&&(this.currentFrame=this.loop?(this.currentFrame+1)%this.sprites.length:this.currentFrame+1,this._oldTime=t)},e.prototype._updateValues=function(){this._setAnchor(this.anchor),this._setRotation(this.rotation),this._setScale(this.scale)},e.prototype.skip=function(t){this.currentFrame=(this.currentFrame+t)%this.sprites.length},e.prototype.draw=function(e,i,n){this.tick(),this._updateValues();var s;this.currentFrame=this.sprites.length&&(s=this.sprites[t.Util.clamp(this.freezeFrame,0,this.sprites.length-1)],s.draw(e,i,n)),s&&(this.width=s.width,this.height=s.height)},e.prototype.play=function(t,e){this.reset(),this._engine.playAnimation(this,t,e)},e}();t.Animation=e})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(){function e(e,i){this.path=e,this._log=t.Logger.getInstance(),this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},window.AudioContext?(this._log.debug("Using new Web Audio Api for "+e),this._soundImpl=new o(e,i)):(this._log.debug("Falling back to Audio Element for "+e),this._soundImpl=new n(e,i))}return e.prototype.setVolume=function(t){this._soundImpl.setVolume(t)},e.prototype.setLoop=function(t){this._soundImpl.setLoop(t)},e.prototype.load=function(){this._soundImpl.onload=this.onload,this._soundImpl.onprogress=this.onprogress,this._soundImpl.onerror=this.onerror,this._soundImpl.load()},e.prototype.processData=function(t){return this._soundImpl.processData(t)},e.prototype.getData=function(){return this._soundImpl.getData()},e.prototype.setData=function(t){this._soundImpl.setData(t)},e.prototype.isPlaying=function(){return this._soundImpl.isPlaying()},e.prototype.play=function(){return this._soundImpl.play()},e.prototype.pause=function(){this._soundImpl.pause()},e.prototype.stop=function(){this._soundImpl.stop()},e}();e.FallbackAudio=i;var n=function(){function e(e,i){var n=this;this.path=e,this._audioElements=Array(5),this._loadedAudio=null,this._isLoaded=!1,this._index=0,this._log=t.Logger.getInstance(),this._isPlaying=!1,this._currentOffset=0,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){};for(var s=0;this._audioElements.length>s;s++)(function(t){n._audioElements[t]=new Audio})(s);i?this.setVolume(t.Util.clamp(i,0,1)):this.setVolume(1)}return e.prototype.isPlaying=function(){return this._isPlaying},e.prototype._audioLoaded=function(){this._isLoaded=!0},e.prototype.setVolume=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].volume=t},e.prototype.setLoop=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].loop=t},e.prototype.getLoop=function(){this._audioElements.some(function(t){return t.loop})},e.prototype.load=function(){var t=this;if(!this._loadedAudio){var e=new XMLHttpRequest;e.open("GET",this.path,!0),e.responseType="blob",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(i){return 200!==e.status?(t._log.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t._isLoaded=!0,t.setData(e.response),t.onload(i),void 0)},e.send()}},e.prototype.getData=function(){return this._loadedAudio},e.prototype.setData=function(t){this._isLoaded=!0,this._loadedAudio=this.processData(t)},e.prototype.processData=function(t){var e=URL.createObjectURL(t);return this._audioElements.forEach(function(t){t.src=e}),this._audioLoaded(),e},e.prototype.play=function(){var e=this;this._audioElements[this._index].load(),this._audioElements[this._index].play(),this._currentOffset=0;var i=new t.Promise;return this._isPlaying=!0,this.getLoop()||this._audioElements[this._index].addEventListener("ended",function(){e._isPlaying=!1,i.resolve(!0)}),this._index=(this._index+1)%this._audioElements.length,i},e.prototype.pause=function(){this._index=(this._index-1+this._audioElements.length)%this._audioElements.length,this._currentOffset=this._audioElements[this._index].currentTime,this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e.prototype.stop=function(){this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e}();if(e.AudioTag=n,window.AudioContext)var s=new window.AudioContext;var o=function(){function e(e,i){this.path=e,this._context=s,this._volume=this._context.createGain(),this._buffer=null,this._sound=null,this._isLoaded=!1,this._loop=!1,this._isPlaying=!1,this._isPaused=!1,this._currentOffset=0,this._logger=t.Logger.getInstance(),this._data=null,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},this._volume.gain.value=i?t.Util.clamp(i,0,1):1}return e.prototype.setVolume=function(t){this._volume.gain.value=t},e.prototype.load=function(){var t=this;if(null===this._data){var e=new XMLHttpRequest;e.open("GET",this.path),e.responseType="arraybuffer",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(){return 200!==e.status?(t._logger.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t.setData(e.response),void 0)};try{e.send()}catch(i){console.error("Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.")}}},e.prototype.getData=function(){return this._data},e.prototype.setData=function(t){this._data=this.processData(t)},e.prototype.processData=function(t){var e=this;return this._context.decodeAudioData(t,function(t){e._buffer=t,e._isLoaded=!0,e.onload(e)},function(){e._logger.error("Unable to decode "+e.path+" this browser may not fully support this format, or the file may be corrupt, "+"if this is an mp3 try removing id3 tags and album art from the file."),e._isLoaded=!1,e.onload(e)}),t},e.prototype.setLoop=function(t){this._loop=t},e.prototype.isPlaying=function(){return this._isPlaying},e.prototype.play=function(){var e=this;if(this._isLoaded){this._sound=this._context.createBufferSource(),this._sound.buffer=this._buffer,this._sound.loop=this._loop,this._sound.connect(this._volume),this._volume.connect(this._context.destination),this._sound.start(0,this._currentOffset%this._buffer.duration),this._currentOffset=0;var i;return i=this._isPaused&&this._playPromise?this._playPromise:new t.Promise,this._isPaused=!1,this._isPlaying=!0,this._loop||(this._sound.onended=function(){e._isPlaying=!1,e._isPaused||i.resolve(!0)}.bind(this)),this._playPromise=i,i}return t.Promise.wrap(!0)},e.prototype.pause=function(){if(this._isPlaying)try{window.clearTimeout(this._playingTimer),this._sound.stop(0),this._currentOffset=this._context.currentTime,this._isPlaying=!1,this._isPaused=!0}catch(t){this._logger.warn("The sound clip",this.path,"has already been paused!")}},e.prototype.stop=function(){if(this._sound)try{window.clearTimeout(this._playingTimer),this._currentOffset=0,this._sound.stop(0),this._isPlaying=!1,this._isPaused=!1}catch(t){this._logger.warn("The sound clip",this.path,"has already been stopped!")}},e.unlock=function(){if(!this._unlocked&&s){var t=s.createBuffer(1,1,22050),e=s.createBufferSource();e.buffer=t,e.connect(s.destination),e.noteOn?e.noteOn(0):e.start(0),setTimeout(function(){(e.playbackState===e.PLAYING_STATE||e.playbackState===e.FINISHED_STATE)&&(this._unlocked=!0)},0)}},e.isUnlocked=function(){return this._unlocked},e._unlocked=!1,e}();e.WebAudio=o})(e=t.Internal||(t.Internal={}))})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i){e.call(this),this._resourceList=[],this._index=0,this._resourceCount=0,this._numLoaded=0,this._progressCounts={},this._totalCounts={},this.getData=function(){},this.setData=function(){},this.processData=function(){},this.onprogress=function(e){t.Logger.getInstance().debug("[ex.Loader] Loading "+(100*e.loaded/e.total).toFixed(0))},this.oncomplete=function(){},this.onerror=function(){},i&&this.addResources(i)}return __extends(i,e),i.prototype.wireEngine=function(t){this._engine=t},i.prototype.addResource=function(t){var e=this._index++;this._resourceList.push(t),this._progressCounts[e]=0,this._totalCounts[e]=1,this._resourceCount++},i.prototype.addResources=function(t){var e=0,i=t.length;for(e;i>e;e++)this.addResource(t[e])},i.prototype._sumCounts=function(t){var e=0;for(var i in t)e+=0|t[i];return e},i.prototype.isLoaded=function(){return this._numLoaded===this._resourceCount},i.prototype.load=function(){function e(t,i){t[i]&&t[i].load().then(function(){e(t,i+1)})}var i=this,n=new t.Promise,s=this;if(0===this._resourceList.length)return s.oncomplete.call(s),n;var o=Array(this._resourceList.length),r=this._resourceList.length;return this._resourceList.forEach(function(t,e){i._engine&&t.wireEngine(i._engine),t.onprogress=function(t){var i=t.total,n=t.loaded;o[e]={loaded:n/i*(100/r),total:100};var h=o.reduce(function(t,e){return{loaded:t.loaded+e.loaded,total:100}},{loaded:0,total:100});s.onprogress.call(s,h)},t.oncomplete=t.onerror=function(){s._numLoaded++,s._numLoaded===s._resourceCount&&(s.oncomplete.call(s),n.resolve())}}),e(this._resourceList,0),n},i.prototype.draw=function(t){t.fillStyle="black",t.fillRect(0,0,this._engine.width,this._engine.height);var e=this._engine.canvas.height/2,i=this._engine.canvas.width/3,n=i,s=new Image;s.src="data:image/png;base64,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"; +var o=3*i/8,r=this._engine.getAntialiasing();this._engine.setAntialiasing(!0),t.drawImage(s,0,0,800,300,n,e-o-20,i,o),t.strokeStyle="white",t.lineWidth=2,t.strokeRect(n,e,i,20);var h=i*(this._numLoaded/this._resourceCount);t.fillStyle="white";var a=5,c=h-2*a,u=20-2*a;t.fillRect(n+a,e+a,c>0?c:0,u),this._engine.setAntialiasing(r)},i.prototype.update=function(){},i}(t.Class);t.Loader=e;var i=function(e){function i(i,n){var s=this;e.call(this,n),this._handleOnTrigger=function(){return s._waitPromise.state()!==t.PromiseState.Pending?!1:(t.Internal.WebAudio.unlock(),s._waitPromise.resolve(s._loadedValue),s._playTrigger.style.display="none",!1)},this._playTrigger=document.getElementById(i),this._playTrigger.addEventListener("click",this._handleOnTrigger)}return __extends(i,e),i.prototype.load=function(){var i=this;return this._waitPromise=new t.Promise,e.prototype.load.call(this).then(function(t){i._loaded=!0,i._loadedValue=t,i._playTrigger.style.display="block"},function(t){i._waitPromise.reject(t)}),this._waitPromise},i}(e);t.PauseAfterLoader=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.failedTests=[],this._criticalTests={canvasSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("2d"))},arrayBufferSupport:function(){var t=new XMLHttpRequest;t.open("GET","/");try{t.responseType="arraybuffer"}catch(e){return!1}return"arraybuffer"===t.responseType},dataUrlSupport:function(){var t=document.createElement("canvas");return 0===t.toDataURL("image/png").indexOf("data:image/png")},objectUrlSupport:function(){return"URL"in window&&"revokeObjectURL"in URL&&"createObjectURL"in URL},rgbaSupport:function(){var t=document.createElement("a").style;return t.cssText="background-color:rgba(150,255,150,.5)",(""+t.backgroundColor).indexOf("rgba")>-1}},this._warningTest={webAudioSupport:function(){return!!(window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext)},webglSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("webgl"))}}}return e.prototype.test=function(){var e=!1;for(var i in this._criticalTests)this._criticalTests[i]()||(this.failedTests.push(i),t.Logger.getInstance().error("Critical browser feature missing, Excalibur requires:",i),e=!0);if(e)return!1;for(var n in this._warningTest)this._warningTest[n]()||t.Logger.getInstance().warn("Warning browser feature missing, Excalibur will have reduced performance:",n);return!0},e}();t.Detector=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this.path=e,this._isLoaded=!1,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this._innerElement=document.createElement("div"),this._innerElement.className="excalibur-template"}return e.prototype.wireEngine=function(t){this._engine=t},e.prototype.getTemplateString=function(){return this._isLoaded?this._htmlString:""},e.prototype._compile=function(){this._innerElement.innerHTML=this._htmlString,this._styleElements=this._innerElement.querySelectorAll("[data-style]"),this._textElements=this._innerElement.querySelectorAll("[data-text]")},e.prototype._evaluateExpresion=function(t,e){var i=Function("return "+t+";"),n=i.call(e);return n},e.prototype.apply=function(t){for(var e=this,i=0;this._styleElements.length>i;i++)(function(){var n={};e._styleElements[i].dataset.style.split(";").forEach(function(t){if(t){var e=t.split(":");n[e[0].trim()]=e[1].trim()}});for(var s in n)(function(){var o=n[s];e._styleElements[i].style[s]=e._evaluateExpresion(o,t)})()})();for(var n=0;this._textElements.length>n;n++)(function(){var i=e._textElements[n].dataset.text;e._textElements[n].innerText=e._evaluateExpresion(i,t)})();return 1===this._innerElement.children.length&&(this._innerElement=this._innerElement.firstChild),this._innerElement},e.prototype.load=function(){var e=this,i=new t.Promise,n=new XMLHttpRequest;return n.open("GET",this.path,!0),n.responseType="text",n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load html template resource ",e.path," server responded with error code",n.status),e.onerror(n.response),e._isLoaded=!1,i.resolve("error"),void 0):(e.setData(n.response),e.oncomplete(),e.logger.debug("Completed loading template",e.path),i.resolve(e._htmlString),void 0)},n.overrideMimeType&&n.overrideMimeType("text/plain; charset=x-user-defined"),n.send(),i},e.prototype.getData=function(){return this._htmlString},e.prototype.setData=function(t){this._htmlString=this.processData(t),this._compile(),this._isLoaded=!0},e.prototype.processData=function(t){return t},e.prototype.isLoaded=function(){return this._isLoaded},e}();t.Template=e;var i=function(){function t(t,e,i){this.parent=document.getElementById(t),this.template=e,this._ctx=i,this.update()}return t.prototype.listen=function(t,e,i){var n=this;i||(i=function(){n.update()}),t.addEventListener&&e.forEach(function(e){t.addEventListener(e,i)})},t.prototype.update=function(){var t=this._applyTemplate(this.template,this._ctx);t instanceof String&&(this.parent.innerHTML=t),t instanceof Node&&this.parent.lastChild!==t&&this.parent.appendChild(t)},t.prototype._applyTemplate=function(t,e){return t.isLoaded()?t.apply(e):void 0},t}();t.Binding=i})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Em=0]="Em",t[t.Rem=1]="Rem",t[t.Px=2]="Px",t[t.Pt=3]="Pt",t[t.Percent=4]="Percent"})(t.FontUnit||(t.FontUnit={}));var e=t.FontUnit;(function(t){t[t.Left=0]="Left",t[t.Right=1]="Right",t[t.Center=2]="Center",t[t.Start=3]="Start",t[t.End=4]="End"})(t.TextAlign||(t.TextAlign={}));var i=t.TextAlign;(function(t){t[t.Top=0]="Top",t[t.Hanging=1]="Hanging",t[t.Middle=2]="Middle",t[t.Alphabetic=3]="Alphabetic",t[t.Ideographic=4]="Ideographic",t[t.Bottom=5]="Bottom"})(t.BaseAlign||(t.BaseAlign={}));var n=t.BaseAlign,s=function(s){function o(o,r,h,a,c){s.call(this,r,h),this.fontSize=10,this.fontUnit=e.Px,this.textAlign=i.Left,this.baseAlign=n.Bottom,this.letterSpacing=0,this.caseInsensitive=!0,this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone(),this._shadowColorDirty=!1,this._textSprites={},this._shadowSprites={},this._color=t.Color.Black.clone(),this.text=o||"",this.color=t.Color.Black.clone(),this.spriteFont=c,this.collisionType=t.CollisionType.PreventCollision,this.fontFamily=a||"10px sans-serif"}return __extends(o,s),o.prototype.getTextWidth=function(t){var e=t.font;t.font=this.fontFamily;var i=t.measureText(this.text).width;return t.font=e,i},o.prototype._lookupFontUnit=function(t){switch(t){case e.Em:return"em";case e.Rem:return"rem";case e.Pt:return"pt";case e.Px:return"px";case e.Percent:return"%";default:return"px"}},o.prototype._lookupTextAlign=function(t){switch(t){case i.Left:return"left";case i.Right:return"right";case i.Center:return"center";case i.End:return"end";case i.Start:return"start";default:return"start"}},o.prototype._lookupBaseAlign=function(t){switch(t){case n.Alphabetic:return"alphabetic";case n.Bottom:return"bottom";case n.Hanging:return"hangin";case n.Ideographic:return"ideographic";case n.Middle:return"middle";case n.Top:return"top";default:return"alphabetic"}},o.prototype.setTextShadow=function(t,e,i){this.spriteFont.setTextShadow(t,e,i)},o.prototype.useTextShadow=function(t){this.spriteFont.useTextShadow(t)},o.prototype.clearTextShadow=function(){this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone()},o.prototype.update=function(t,e){s.prototype.update.call(this,t,e)},o.prototype.draw=function(t,e){t.save(),t.translate(this.x,this.y),t.scale(this.scale.x,this.scale.y),t.rotate(this.rotation),this._textShadowOn&&(t.save(),t.translate(this._shadowOffsetX,this._shadowOffsetY),this._fontDraw(t,e,this._shadowSprites),t.restore()),this._fontDraw(t,e,this._textSprites),s.prototype.draw.call(this,t,e),t.restore()},o.prototype._fontDraw=function(t){if(this.spriteFont)this.spriteFont.draw(t,this.text,0,0,{color:this.color.clone(),baseAlign:this.baseAlign,textAlign:this.textAlign,fontSize:this.fontSize,letterSpacing:this.letterSpacing,opacity:this.opacity});else{var e=t.textAlign,i=t.textBaseline;t.textAlign=this._lookupTextAlign(this.textAlign),t.textBaseline=this._lookupBaseAlign(this.baseAlign),this.color&&(this.color.a=this.opacity),t.fillStyle=""+this.color,t.font=""+this.fontSize+this._lookupFontUnit(this.fontUnit)+" "+this.fontFamily,this.maxWidth?t.fillText(this.text,0,0,this.maxWidth):t.fillText(this.text,0,0),t.textAlign=e,t.textBaseline=i}},o.prototype.debugDraw=function(t){s.prototype.debugDraw.call(this,t)},o}(t.Actor);t.Label=s})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Touch=0]="Touch",t[t.Mouse=1]="Mouse",t[t.Pen=2]="Pen",t[t.Unknown=3]="Unknown"})(e.PointerType||(e.PointerType={}));var i=e.PointerType;(function(t){t[t.Left=0]="Left",t[t.Middle=1]="Middle",t[t.Right=2]="Right",t[t.Unknown=3]="Unknown"})(e.PointerButton||(e.PointerButton={}));var n=e.PointerButton;(function(t){t[t.Canvas=0]="Canvas",t[t.Document=1]="Document"})(e.PointerScope||(e.PointerScope={}));var s=e.PointerScope,o=function(t){function e(e,i,n,s,o,r){t.call(this),this.x=e,this.y=i,this.index=n,this.pointerType=s,this.button=o,this.ev=r}return __extends(e,t),e}(t.GameEvent);e.PointerEvent=o;var r=function(e){function r(t){e.call(this),this._pointerDown=[],this._pointerUp=[],this._pointerMove=[],this._pointerCancel=[],this._pointers=[],this._activePointers=[],this._engine=t,this._pointers.push(new h),this._activePointers=[-1],this.primary=this._pointers[0]}return __extends(r,e),r.prototype.init=function(t){void 0===t&&(t=s.Document);var e=document;e=t===s.Document?document:this._engine.canvas,e.addEventListener("touchstart",this._handleTouchEvent("down",this._pointerDown)),e.addEventListener("touchend",this._handleTouchEvent("up",this._pointerUp)),e.addEventListener("touchmove",this._handleTouchEvent("move",this._pointerMove)),e.addEventListener("touchcancel",this._handleTouchEvent("cancel",this._pointerCancel)),window.PointerEvent?(this._engine.canvas.style.touchAction="none",e.addEventListener("pointerdown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("pointerup",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("pointermove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("pointercancel",this._handlePointerEvent("cancel",this._pointerMove))):window.MSPointerEvent?(this._engine.canvas.style.msTouchAction="none",e.addEventListener("MSPointerDown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("MSPointerUp",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("MSPointerMove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("MSPointerCancel",this._handlePointerEvent("cancel",this._pointerMove))):(e.addEventListener("mousedown",this._handleMouseEvent("down",this._pointerDown)),e.addEventListener("mouseup",this._handleMouseEvent("up",this._pointerUp)),e.addEventListener("mousemove",this._handleMouseEvent("move",this._pointerMove)))},r.prototype.update=function(){this._pointerUp.length=0,this._pointerDown.length=0,this._pointerMove.length=0,this._pointerCancel.length=0},r.prototype.at=function(t){if(t>=this._pointers.length)for(var e=this._pointers.length-1,i=t;i>e;e++)this._pointers.push(new h),this._activePointers.push(-1);return this._pointers[t]},r.prototype.count=function(){return this._pointers.length},r.prototype.propogate=function(e){var i=e instanceof t.UIActor,n=0,s=this._pointerUp.length;for(n;s>n;n++)e.contains(this._pointerUp[n].x,this._pointerUp[n].y,!i)&&e.eventDispatcher.emit("pointerup",this._pointerUp[n]);for(n=0,s=this._pointerDown.length,n;s>n;n++)e.contains(this._pointerDown[n].x,this._pointerDown[n].y,!i)&&e.eventDispatcher.emit("pointerdown",this._pointerDown[n]);if(e.capturePointer.captureMoveEvents)for(n=0,s=this._pointerMove.length,n;s>n;n++)e.contains(this._pointerMove[n].x,this._pointerMove[n].y,!i)&&e.eventDispatcher.emit("pointermove",this._pointerMove[n]);for(n=0,s=this._pointerCancel.length,n;s>n;n++)e.contains(this._pointerCancel[n].x,this._pointerCancel[n].y,!i)&&e.eventDispatcher.emit("pointercancel",this._pointerCancel[n])},r.prototype._handleMouseEvent=function(e,n){var s=this;return function(r){r.preventDefault();var h=r.pageX-t.Util.getPosition(s._engine.canvas).x,a=r.pageY-t.Util.getPosition(s._engine.canvas).y,c=s._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,0,i.Mouse,r.button,r);n.push(u),s.at(0).eventDispatcher.emit(e,u)}},r.prototype._handleTouchEvent=function(e,s){var r=this;return function(h){h.preventDefault();for(var a=0,c=h.changedTouches.length;c>a;a++){var u=r._pointers.length>1?r._getPointerIndex(h.changedTouches[a].identifier):0;if(-1!==u){var l=h.changedTouches[a].pageX-t.Util.getPosition(r._engine.canvas).x,p=h.changedTouches[a].pageY-t.Util.getPosition(r._engine.canvas).y,d=r._engine.screenToWorldCoordinates(new t.Point(l,p)),f=new o(d.x,d.y,u,i.Touch,n.Unknown,h);s.push(f),r.at(u).eventDispatcher.emit(e,f),r._pointers.length>1&&("up"===e?r._activePointers[u]=-1:"down"===e&&(r._activePointers[u]=h.changedTouches[a].identifier))}}}},r.prototype._handlePointerEvent=function(e,i){var n=this;return function(s){s.preventDefault();var r=n._pointers.length>1?n._getPointerIndex(s.pointerId):0;if(-1!==r){var h=s.pageX-t.Util.getPosition(n._engine.canvas).x,a=s.pageY-t.Util.getPosition(n._engine.canvas).y,c=n._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,r,n._stringToPointerType(s.pointerType),s.button,s);i.push(u),n.at(r).eventDispatcher.emit(e,u),n._pointers.length>1&&("up"===e?n._activePointers[r]=-1:"down"===e&&(n._activePointers[r]=s.pointerId))}}},r.prototype._getPointerIndex=function(t){var e;if((e=this._activePointers.indexOf(t))>-1)return e;for(var i=0;this._activePointers.length>i;i++)if(-1===this._activePointers[i])return i;return-1},r.prototype._stringToPointerType=function(t){switch(t){case"touch":return i.Touch;case"mouse":return i.Mouse;case"pen":return i.Pen;default:return i.Unknown}},r}(t.Class);e.Pointers=r;var h=function(t){function e(){t.apply(this,arguments)}return __extends(e,t),e}(t.Class);e.Pointer=h})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Num1=97]="Num1",t[t.Num2=98]="Num2",t[t.Num3=99]="Num3",t[t.Num4=100]="Num4",t[t.Num5=101]="Num5",t[t.Num6=102]="Num6",t[t.Num7=103]="Num7",t[t.Num8=104]="Num8",t[t.Num9=105]="Num9",t[t.Num0=96]="Num0",t[t.Numlock=144]="Numlock",t[t.Semicolon=186]="Semicolon",t[t.A=65]="A",t[t.B=66]="B",t[t.C=67]="C",t[t.D=68]="D",t[t.E=69]="E",t[t.F=70]="F",t[t.G=71]="G",t[t.H=72]="H",t[t.I=73]="I",t[t.J=74]="J",t[t.K=75]="K",t[t.L=76]="L",t[t.M=77]="M",t[t.N=78]="N",t[t.O=79]="O",t[t.P=80]="P",t[t.Q=81]="Q",t[t.R=82]="R",t[t.S=83]="S",t[t.T=84]="T",t[t.U=85]="U",t[t.V=86]="V",t[t.W=87]="W",t[t.X=88]="X",t[t.Y=89]="Y",t[t.Z=90]="Z",t[t.Shift=16]="Shift",t[t.Alt=18]="Alt",t[t.Up=38]="Up",t[t.Down=40]="Down",t[t.Left=37]="Left",t[t.Right=39]="Right",t[t.Space=32]="Space",t[t.Esc=27]="Esc"})(e.Keys||(e.Keys={})),e.Keys;var i=function(t){function e(e){t.call(this),this.key=e}return __extends(e,t),e}(t.GameEvent);e.KeyEvent=i;var n=function(t){function e(e){t.call(this),this._keys=[],this._keysUp=[],this._keysDown=[],this._engine=e}return __extends(e,t),e.prototype.init=function(){var t=this;window.addEventListener("blur",function(){t._keys.length=0}),window.addEventListener("keyup",function(e){var n=t._keys.indexOf(e.keyCode);t._keys.splice(n,1),t._keysUp.push(e.keyCode);var s=new i(e.keyCode);t.eventDispatcher.emit("up",s),t.eventDispatcher.emit("release",s)}),window.addEventListener("keydown",function(e){if(-1===t._keys.indexOf(e.keyCode)){t._keys.push(e.keyCode),t._keysDown.push(e.keyCode);var n=new i(e.keyCode);t.eventDispatcher.emit("down",n),t.eventDispatcher.emit("press",n)}})},e.prototype.update=function(){this._keysDown.length=0,this._keysUp.length=0;for(var t=0;this._keys.length>t;t++)this.eventDispatcher.emit("hold",new i(this._keys[t]))},e.prototype.getKeys=function(){return this._keys},e.prototype.wasPressed=function(t){return this._keysDown.indexOf(t)>-1},e.prototype.isHeld=function(t){return this._keys.indexOf(t)>-1},e.prototype.wasReleased=function(t){return this._keysUp.indexOf(t)>-1},e}(t.Class);e.Keyboard=n})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(e){function i(t){e.call(this),this.enabled=!1,this.supported=!!navigator.getGamepads,this._gamePadTimeStamps=[0,0,0,0],this._oldPads=[],this._pads=[],this._initSuccess=!1,this._navigator=navigator,this._minimumConfiguration=null,this._engine=t}return __extends(i,e),i.prototype.init=function(){this.supported&&(this._initSuccess||(this._oldPads=this._clonePads(this._navigator.getGamepads()),this._oldPads.length&&this._oldPads[0]&&(this._initSuccess=!0)))},i.prototype.setMinimumGamepadConfiguration=function(t){this._enableAndUpdate(),this._minimumConfiguration=t},i.prototype._enableAndUpdate=function(){this.enabled||(this.enabled=!0,this.update(100))},i.prototype._isGamepadValid=function(t){if(!this._minimumConfiguration)return!0;if(!t)return!1;var e=t.axes.filter(function(t){return void 0!==typeof t}).length,i=t.buttons.filter(function(t){return void 0!==typeof t}).length;return e>=this._minimumConfiguration.axis&&i>=this._minimumConfiguration.buttons&&t.connected},i.prototype.on=function(t,i){this._enableAndUpdate(),e.prototype.on.call(this,t,i)},i.prototype.off=function(t,i){this._enableAndUpdate(),e.prototype.off.call(this,t,i)},i.prototype.update=function(){if(this.enabled&&this.supported){this.init();for(var e=this._navigator.getGamepads(),i=0;e.length>i;i++)if(e[i]){if(!this.at(i).connected&&this._isGamepadValid(e[i])&&this.eventDispatcher.emit("connect",new t.GamepadConnectEvent(i,this.at(i))),this.at(i).connected=!0,!e[i].timestamp||e[i].timestamp!==this._gamePadTimeStamps[i]){this._gamePadTimeStamps[i]=e[i].timestamp,this.at(i).navigatorGamepad=e[i];var n,r,h,a,c;for(n in s)"number"==typeof s[n]&&(a=s[n],e[i].buttons[a]&&(h=e[i].buttons[a].value,h!==this._oldPads[i].getButton(a)&&(e[i].buttons[a].pressed?(this.at(i).updateButton(a,h),this.at(i).eventDispatcher.publish("button",new t.GamepadButtonEvent(a,h))):this.at(i).updateButton(a,0))));for(r in o)"number"==typeof o[r]&&(c=o[r],h=e[i].axes[c],h!==this._oldPads[i].getAxes(c)&&(this.at(i).updateAxes(c,h),this.at(i).eventDispatcher.emit("axis",new t.GamepadAxisEvent(c,h))));this._oldPads[i]=this._clonePad(e[i])}}else this.at(i).connected&&this.eventDispatcher.emit("disconnect",new t.GamepadDisconnectEvent(i)),this.at(i).connected=!1}},i.prototype.at=function(t){if(this._enableAndUpdate(),t>=this._pads.length)for(var e=this._pads.length-1,i=t;i>e;e++)this._pads.push(new n),this._oldPads.push(new n);return this._pads[t]},i.prototype.getValidGamepads=function(){this._enableAndUpdate();for(var t=[],e=0;this._pads.length>e;e++)this._isGamepadValid(this.at(e).navigatorGamepad)&&this.at(e).connected&&t.push(this.at(e));return t},i.prototype.count=function(){return this._pads.filter(function(t){return t.connected}).length},i.prototype._clonePads=function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(this._clonePad(t[i]));return e},i.prototype._clonePad=function(t){var e,i,s=new n;if(!t)return s;for(e=0,i=t.buttons.length;i>e;e++)t.buttons[e]&&s.updateButton(e,t.buttons[e].value);for(e=0,i=t.axes.length;i>e;e++)s.updateAxes(e,t.axes[e]);return s},i.MinAxisMoveThreshold=.05,i}(t.Class);e.Gamepads=i;var n=function(t){function e(){t.call(this),this.connected=!1,this._buttons=Array(16),this._axes=Array(4);var e;for(e=0;this._buttons.length>e;e++)this._buttons[e]=0;for(e=0;this._axes.length>e;e++)this._axes[e]=0}return __extends(e,t),e.prototype.isButtonPressed=function(t,e){return void 0===e&&(e=1),this._buttons[t]>=e},e.prototype.getButton=function(t){return this._buttons[t]},e.prototype.getAxes=function(t){var e=this._axes[t];return Math.abs(e)n;n++)this._animations[n].animation.draw(i,this._animations[n].x,this._animations[n].y);if(this.fps=1/(e/1e3),this.isDebug){this.ctx.font="Consolas",this.ctx.fillStyle=""+this.debugColor;for(var o=this.input.keyboard.getKeys(),r=0;o.length>r;r++)this.ctx.fillText(""+o[r]+" : "+(t.Input.Keys[o[r]]?t.Input.Keys[o[r]]:"Not Mapped"),100,10*r+10);this.ctx.fillText("FPS:"+(""+this.fps.toFixed(2)),10,10)}for(var h=0;this.postProcessors.length>h;h++)this.postProcessors[h].process(this.ctx.getImageData(0,0,this.width,this.height),this.ctx);this.emit("postdraw",new t.PreDrawEvent(i,e,this))},s.prototype.start=function(e){if(!this._compatible){var i=new t.Promise;return i.reject("Excalibur is incompatible with your browser")}var n;if(e?(this._loader=e,this._loader.wireEngine(this),n=this.load(this._loader)):n=t.Promise.wrap(),!this._hasStarted){this._hasStarted=!0,this._logger.debug("Starting game...");var s=Date.now(),o=this;(function r(){if(o._hasStarted)try{o._requestId=window.requestAnimationFrame(r);var t=Date.now(),e=Math.floor(t-s)||1;e>200&&(e=1),o._update(e),o._draw(e),s=t}catch(i){window.cancelAnimationFrame(o._requestId),o.stop(),o.onFatalException(i)}})(),this._logger.debug("Game started")}return n},s.prototype.stop=function(){this._hasStarted&&(this._hasStarted=!1,this._logger.debug("Game stopped"))},s.prototype.screenshot=function(){var t=new Image,e=this.canvas.toDataURL("image/png");return t.src=e,t},s.prototype.load=function(e){var i=this,n=new t.Promise;return this._isLoading=!0,e.load().then(function(){setTimeout(function(){i._isLoading=!1,n.resolve()},500)}),n},s}(t.Class);t.Engine=e,function(t){t[t.FullScreen=0]="FullScreen",t[t.Container=1]="Container",t[t.Fixed=2]="Fixed"}(t.DisplayMode||(t.DisplayMode={}));var i=t.DisplayMode,n=function(){function t(t,e,i){this.animation=t,this.x=e,this.y=i}return t}()})(ex||(ex={})); ; // Concatenated onto excalibur after build // Exports the excalibur module so it can be used with browserify diff --git a/dist/excalibur-0.6.0.d.ts b/dist/excalibur-0.6.0.d.ts index b57e6b106..32b7a494b 100644 --- a/dist/excalibur-0.6.0.d.ts +++ b/dist/excalibur-0.6.0.d.ts @@ -4300,947 +4300,965 @@ declare module ex { } declare module ex { /** - * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does - * not participate in collisions. Drawn on top of all other actors. + * Loadables + * + * An interface describing loadable resources in Excalibur. Built-in loadable + * resources include [[Texture]], [[Sound]], and a generic [[Resource]]. + * + * ## Advanced: Custom loadables + * + * You can implement the [[ILoadable]] interface to create your own custom loadables. + * This is an advanced feature, as the [[Resource]] class already wraps logic around + * blob/plain data for usages like JSON, configuration, levels, etc through XHR (Ajax). + * + * However, as long as you implement the facets of a loadable, you can create your + * own. */ - class UIActor extends Actor { - protected _engine: Engine; + interface ILoadable { /** - * @param x The starting x coordinate of the actor - * @param y The starting y coordinate of the actor - * @param width The starting width of the actor - * @param height The starting height of the actor + * Begins loading the resource and returns a promise to be resolved on completion */ - constructor(x?: number, y?: number, width?: number, height?: number); - onInitialize(engine: Engine): void; - contains(x: number, y: number, useWorld?: boolean): boolean; + load(): Promise; + getData(): any; + setData(data: any): void; + /** + * Processes the downloaded data. Meant to be overridden. + */ + processData(data: any): any; + /** + * Wires engine into loadable to receive game level events + */ + wireEngine(engine: Engine): void; + /** + * onprogress handler + */ + onprogress: (e: any) => void; + /** + * oncomplete handler + */ + oncomplete: () => void; + /** + * onerror handler + */ + onerror: (e: any) => void; + /** + * Returns true if the loadable is loaded + */ + isLoaded(): boolean; } } declare module ex { /** - * Triggers + * Generic Resources * - * Triggers are a method of firing arbitrary code on collision. These are useful - * as 'buttons', 'switches', or to trigger effects in a game. By default triggers - * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * The [[Resource]] type allows games built in Excalibur to load generic resources. + * For any type of remote resource it is recommended to use [[Resource]] for preloading. * - * ## Creating a trigger + * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before + * a level or game. * - * ```js - * var game = new ex.Game(); + * Example usages: JSON, compressed files, blobs. * - * // create a handler - * function onTrigger() { + * ## Pre-loading generic resources * - * // `this` will be the Trigger instance - * ex.Logger.getInstance().info("Trigger was triggered!", this); - * } + * ```js + * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); + * var loader = new ex.Loader(resLevel1); * - * // set a trigger at (100, 100) that is 40x40px - * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * // attach a handler to process once loaded + * resLevel1.processData = function (data) { * - * // create an actor across from the trigger - * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * // process JSON + * var json = JSON.parse(data); * - * // tell the actor to move towards the trigger over 3 seconds - * actor.moveTo(100, 200, 3000); + * // create a new level (inherits Scene) with the JSON configuration + * var level = new Level(json); * - * game.add(trigger); - * game.add(actor); + * // add a new scene + * game.add(level.name, level); + * } * - * game.start(); + * game.start(loader); * ``` */ - class Trigger extends Actor { - private _action; - repeats: number; - target: Actor; + class Resource extends Class implements ILoadable { + path: string; + responseType: string; + bustCache: boolean; + data: T; + logger: Logger; + private _engine; /** - * @param x The x position of the trigger - * @param y The y position of the trigger - * @param width The width of the trigger - * @param height The height of the trigger - * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance - * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely + * @param path Path to the remote resource + * @param responseType The Content-Type to expect (e.g. `application/json`) + * @param bustCache Whether or not to cache-bust requests */ - constructor(x?: number, y?: number, width?: number, height?: number, action?: () => void, repeats?: number); - update(engine: Engine, delta: number): void; - private _dispatchAction(); - draw(ctx: CanvasRenderingContext2D, delta: number): void; - debugDraw(ctx: CanvasRenderingContext2D): void; - } -} -declare module ex { - /** - * An enum that represents the types of emitter nozzles - */ - enum EmitterType { + constructor(path: string, responseType: string, bustCache?: boolean); /** - * Constant for the circular emitter type + * Returns true if the Resource is completely loaded and is ready + * to be drawn. */ - Circle = 0, + isLoaded(): boolean; + wireEngine(engine: Engine): void; + private _cacheBust(uri); + private _start(e); /** - * Constant for the rectangular emitter type + * Begin loading the resource and returns a promise to be resolved on completion */ - Rectangle = 1, + load(): Promise; + /** + * Returns the loaded data once the resource is loaded + */ + getData(): any; + /** + * Sets the data for this resource directly + */ + setData(data: any): void; + /** + * This method is meant to be overriden to handle any additional + * processing. Such as decoding downloaded audio bits. + */ + processData(data: T): any; + onprogress: (e: any) => void; + oncomplete: () => void; + onerror: (e: any) => void; } +} +declare module ex { /** - * Particle is used in a [[ParticleEmitter]] + * Valid states for a promise to be in */ - class Particle { - position: Vector; - velocity: Vector; - acceleration: Vector; - particleRotationalVelocity: number; - currentRotation: number; - focus: Vector; - focusAccel: number; - opacity: number; - beginColor: Color; - endColor: Color; - life: number; - fadeFlag: boolean; - private _rRate; - private _gRate; - private _bRate; - private _aRate; - private _currentColor; - emitter: ParticleEmitter; - particleSize: number; - particleSprite: Sprite; - startSize: number; - endSize: number; - sizeRate: number; - elapsedMultiplier: number; - constructor(emitter: ParticleEmitter, life?: number, opacity?: number, beginColor?: Color, endColor?: Color, position?: Vector, velocity?: Vector, acceleration?: Vector, startSize?: number, endSize?: number); - kill(): void; - update(delta: number): void; - draw(ctx: CanvasRenderingContext2D): void; + enum PromiseState { + Resolved = 0, + Rejected = 1, + Pending = 2, + } + interface IPromise { + then(successCallback?: (value?: T) => any, rejectCallback?: (value?: T) => any): IPromise; + error(rejectCallback?: (value?: any) => any): IPromise; + resolve(value?: T): IPromise; + reject(value?: any): IPromise; + state(): PromiseState; } /** - * Particle Emitters + * Promises/A+ spec implementation of promises * - * Using a particle emitter is a great way to create interesting effects - * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` - * extend [[Actor]] allowing you to use all of the features that come with. + * Promises are used to do asynchronous work and they are useful for + * creating a chain of actions. In Excalibur they are used for loading, + * sounds, animation, actions, and more. * - * The easiest way to create a `ParticleEmitter` is to use the - * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. + * ## A Promise Chain * - * ## Example: Adding an emitter + * Promises can be chained together and can be useful for creating a queue + * of functions to be called when something is done. * - * ```js - * var actor = new ex.Actor(...); - * var emitter = new ex.ParticleEmitter(...); + * The first [[Promise]] you will encounter is probably [[Engine.start]] + * which resolves when the game has finished loading. * - * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle - * emitter.radius = 5; - * emitter.minVel = 100; - * emitter.maxVel = 200; - * emitter.minAngle = 0; - * emitter.maxAngle = Math.PI * 2; - * emitter.emitRate = 300; // 300 particles/second - * emitter.opacity = 0.5; - * emitter.fadeFlag = true; // fade particles overtime - * emitter.particleLife = 1000; // in milliseconds = 1 sec - * emitter.maxSize = 10; // in pixels - * emitter.minSize = 1; - * emitter.particleColor = ex.Color.Rose; + * ```js + * var game = new ex.Engine(); * - * // set emitter settings - * emitter.isEmitting = true; // should the emitter be emitting + * // perform start-up logic once game is ready + * game.start().then(function () { * - * // add the emitter as a child actor, it will draw on top of the parent actor - * // and move with the parent - * actor.add(emitter); + * // start-up & initialization logic * - * // or, alternatively, add it to the current scene - * engine.add(emitter); + * }); * ``` - */ - class ParticleEmitter extends Actor { - private _particlesToEmit; - numParticles: number; - /** - * Gets or sets the isEmitting flag - */ - isEmitting: boolean; - /** - * Gets or sets the backing particle collection - */ - particles: Util.Collection; - /** - * Gets or sets the backing deadParticle collection - */ - deadParticles: Util.Collection; - /** - * Gets or sets the minimum partical velocity - */ - minVel: number; - /** - * Gets or sets the maximum partical velocity - */ - maxVel: number; - /** - * Gets or sets the acceleration vector for all particles - */ - acceleration: Vector; - /** - * Gets or sets the minimum angle in radians - */ - minAngle: number; - /** - * Gets or sets the maximum angle in radians - */ - maxAngle: number; - /** - * Gets or sets the emission rate for particles (particles/sec) - */ - emitRate: number; - /** - * Gets or sets the life of each particle in milliseconds - */ - particleLife: number; - /** - * Gets or sets the opacity of each particle from 0 to 1.0 - */ - opacity: number; + * + * ## Handling errors + * + * You can optionally pass an error handler to [[Promise.then]] which will handle + * any errors that occur during Promise execution. + * + * ```js + * var game = new ex.Engine(); + * + * game.start().then( + * // success handler + * function () { + * }, + * + * // error handler + * function (err) { + * } + * ); + * ``` + * + * Any errors that go unhandled will be bubbled up to the browser. + */ + class Promise implements IPromise { + private _state; + private _value; + private _successCallbacks; + private _rejectCallback; + private _errorCallback; + private _logger; /** - * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. + * Wrap a value in a resolved promise + * @param value An optional value to wrap in a resolved promise */ - fadeFlag: boolean; + static wrap(value?: T): Promise; /** - * Gets or sets the optional focus where all particles should accelerate towards + * Returns a new promise that resolves when all the promises passed to it resolve, or rejects + * when at least 1 promise rejects. */ - focus: Vector; + static join(...promises: Promise[]): Promise; /** - * Gets or sets the acceleration for focusing particles if a focus has been specified + * Chain success and reject callbacks after the promise is resovled + * @param successCallback Call on resolution of promise + * @param rejectCallback Call on rejection of promise */ - focusAccel: number; - startSize: number; - endSize: number; + then(successCallback?: (value?: T) => any, rejectCallback?: (value?: any) => any): Promise; /** - * Gets or sets the minimum size of all particles + * Add an error callback to the promise + * @param errorCallback Call if there was an error in a callback */ - minSize: number; + error(errorCallback?: (value?: any) => any): Promise; /** - * Gets or sets the maximum size of all particles + * Resolve the promise and pass an option value to the success callbacks + * @param value Value to pass to the success callbacks */ - maxSize: number; + resolve(value?: T): Promise; /** - * Gets or sets the beginning color of all particles + * Reject the promise and pass an option value to the reject callbacks + * @param value Value to pass to the reject callbacks */ - beginColor: Color; + reject(value?: any): Promise; /** - * Gets or sets the ending color of all particles + * Inpect the current state of a promise */ - endColor: Color; + state(): PromiseState; + private _handleError(e); + } +} +declare module ex { + /** + * Textures + * + * The [[Texture]] object allows games built in Excalibur to load image resources. + * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] + * to pre-load before starting a level or game. + * + * Textures are the raw image so to add a drawing to a game, you must create + * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite + * instance. + * + * ## Pre-loading textures + * + * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] + * is loaded, you can generate a [[Sprite]] with it. + * + * ```js + * var txPlayer = new ex.Texture("/assets/tx/player.png"); + * + * var loader = new ex.Loader(txPlayer); + * + * game.start(loader).then(function () { + * + * var player = new ex.Actor(); + * + * player.addDrawing(txPlayer); + * + * game.add(player); + * }); + * ``` + */ + class Texture extends Resource { + path: string; + bustCache: boolean; /** - * Gets or sets the sprite that a particle should use - * @warning Performance intensive + * The width of the texture in pixels */ - particleSprite: ex.Sprite; + width: number; /** - * Gets or sets the emitter type for the particle emitter + * The height of the texture in pixels */ - emitterType: ex.EmitterType; + height: number; /** - * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] + * A [[Promise]] that resolves when the Texture is loaded. */ - radius: number; + loaded: Promise; + private _isLoaded; + private _sprite; /** - * Gets or sets the particle rotational speed velocity + * Populated once loading is complete */ - particleRotationalVelocity: number; + image: HTMLImageElement; + private _progressCallback; + private _doneCallback; + private _errorCallback; /** - * Indicates whether particles should start with a random rotation + * @param path Path to the image resource + * @param bustCache Optionally load texture with cache busting */ - randomRotation: boolean; + constructor(path: string, bustCache?: boolean); /** - * @param x The x position of the emitter - * @param y The y position of the emitter - * @param width The width of the emitter - * @param height The height of the emitter + * Returns true if the Texture is completely loaded and is ready + * to be drawn. */ - constructor(x?: number, y?: number, width?: number, height?: number); - removeParticle(particle: Particle): void; + isLoaded(): boolean; /** - * Causes the emitter to emit particles - * @param particleCount Number of particles to emit right now + * Begins loading the texture and returns a promise to be resolved on completion */ - emitParticles(particleCount: number): void; - clearParticles(): void; - private _createParticle(); - update(engine: Engine, delta: number): void; - draw(ctx: CanvasRenderingContext2D, delta: number): void; - debugDraw(ctx: CanvasRenderingContext2D): void; + load(): Promise; + asSprite(): Sprite; } } declare module ex { /** - * Animations + * Sounds * - * Animations allow you to display a series of images one after another, - * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. + * The [[Sound]] object allows games built in Excalibur to load audio + * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] + * which means it can be passed to a [[Loader]] to pre-load before a game or level. * - * ## Creating an animation + * ## Pre-loading sounds * - * Create a [[Texture]] that contains the frames of your animation. Once the texture - * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] - * and using [[SpriteSheet.getAnimationForAll]]. + * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] + * is loaded, you can [[Sound.play|play]] it. * * ```js - * var game = new ex.Engine(); - * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); + * // define multiple sources (such as mp3/wav/ogg) as a browser fallback + * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); * - * // load assets - * var loader = new ex.Loader(txAnimPlayerIdle); + * var loader = new ex.Loader(sndPlayerDeath); * - * // start game * game.start(loader).then(function () { - * var player = new ex.Actor(); - * - * // create sprite sheet with 5 columns, 1 row, 80x80 frames - * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); - * - * // create animation (125ms frame speed) - * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); * - * // add drawing to player as "idle" - * player.addDrawing("idle", playerIdleAnimation); - * - * // add player to game - * game.add(player); + * sndPlayerDeath.play(); * }); * ``` - * - * ## Sprite effects - * - * You can add [[SpriteEffect|sprite effects]] to an animation through methods - * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this - * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - class Animation implements IDrawable { + class Sound implements ILoadable, ex.Internal.ISound { + private _logger; + path: string; + onprogress: (e: any) => void; + oncomplete: () => void; + onerror: (e: any) => void; + onload: (e: any) => void; + private _isLoaded; + private _engine; + private _wasPlayingOnHidden; /** - * The sprite frames to play, in order. See [[SpriteSheet.getAnimationForAll]] to quickly - * generate an [[Animation]]. + * Populated once loading is complete */ - sprites: Sprite[]; + sound: ex.Internal.FallbackAudio; /** - * Duration to show each frame (in milliseconds) + * Whether or not the browser can play this file as HTML5 Audio */ - speed: number; + static canPlayFile(file: string): boolean; /** - * Current frame index being shown + * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. */ - currentFrame: number; - private _oldTime; - anchor: Point; - rotation: number; - scale: Point; - /** - * Indicates whether the animation should loop after it is completed + constructor(...paths: string[]); + wireEngine(engine: Engine): void; + /** + * Sets the volume of the sound clip + * @param volume A volume value between 0-1.0 */ - loop: boolean; + setVolume(volume: number): void; /** - * Indicates the frame index the animation should freeze on for a non-looping - * animation. By default it is the last frame. + * Indicates whether the clip should loop when complete + * @param loop Set the looping flag */ - freezeFrame: number; - private _engine; + setLoop(loop: boolean): void; /** - * Flip each frame vertically. Sets [[Sprite.flipVertical]]. + * Whether or not the sound is playing right now */ - flipVertical: boolean; + isPlaying(): boolean; /** - * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + * Play the sound, returns a promise that resolves when the sound is done playing */ - flipHorizontal: boolean; - width: number; - height: number; - naturalWidth: number; - naturalHeight: number; + play(): ex.Promise; /** - * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. - * - * @param engine Reference to the current game engine - * @param images An array of sprites to create the frames for the animation - * @param speed The number in milliseconds to display each frame in the animation - * @param loop Indicates whether the animation should loop after it is completed + * Stop the sound, and do not rewind */ - constructor(engine: Engine, images: Sprite[], speed: number, loop?: boolean); + pause(): void; /** - * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + * Stop the sound and rewind */ - opacity(value: number): void; + stop(): void; /** - * Applies the grayscale effect to a sprite, removing color information. + * Returns true if the sound is loaded */ - grayscale(): void; + isLoaded(): boolean; /** - * Applies the invert effect to a sprite, inverting the pixel colors. + * Begins loading the sound and returns a promise to be resolved on completion */ - invert(): void; + load(): Promise; + getData(): any; + setData(data: any): void; + processData(data: any): any; + } +} +declare module ex { + /** + * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does + * not participate in collisions. Drawn on top of all other actors. + */ + class UIActor extends Actor { + protected _engine: Engine; /** - * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color + * @param x The starting x coordinate of the actor + * @param y The starting y coordinate of the actor + * @param width The starting width of the actor + * @param height The starting height of the actor */ - fill(color: Color): void; + constructor(x?: number, y?: number, width?: number, height?: number); + onInitialize(engine: Engine): void; + contains(x: number, y: number, useWorld?: boolean): boolean; + } +} +declare module ex { + /** + * Triggers + * + * Triggers are a method of firing arbitrary code on collision. These are useful + * as 'buttons', 'switches', or to trigger effects in a game. By default triggers + * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * + * ## Creating a trigger + * + * ```js + * var game = new ex.Game(); + * + * // create a handler + * function onTrigger() { + * + * // `this` will be the Trigger instance + * ex.Logger.getInstance().info("Trigger was triggered!", this); + * } + * + * // set a trigger at (100, 100) that is 40x40px + * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * + * // create an actor across from the trigger + * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * + * // tell the actor to move towards the trigger over 3 seconds + * actor.moveTo(100, 200, 3000); + * + * game.add(trigger); + * game.add(actor); + * + * game.start(); + * ``` + */ + class Trigger extends Actor { + private _action; + repeats: number; + target: Actor; /** - * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the - * provided color. + * @param x The x position of the trigger + * @param y The y position of the trigger + * @param width The width of the trigger + * @param height The height of the trigger + * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance + * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely */ - colorize(color: Color): void; + constructor(x?: number, y?: number, width?: number, height?: number, action?: () => void, repeats?: number); + update(engine: Engine, delta: number): void; + private _dispatchAction(); + draw(ctx: CanvasRenderingContext2D, delta: number): void; + debugDraw(ctx: CanvasRenderingContext2D): void; + } +} +declare module ex { + /** + * An enum that represents the types of emitter nozzles + */ + enum EmitterType { /** - * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl + * Constant for the circular emitter type */ - lighten(factor?: number): void; + Circle = 0, /** - * Applies the darken effect to a sprite, changes the darkness of the color according to hsl + * Constant for the rectangular emitter type */ - darken(factor?: number): void; + Rectangle = 1, + } + /** + * Particle is used in a [[ParticleEmitter]] + */ + class Particle { + position: Vector; + velocity: Vector; + acceleration: Vector; + particleRotationalVelocity: number; + currentRotation: number; + focus: Vector; + focusAccel: number; + opacity: number; + beginColor: Color; + endColor: Color; + life: number; + fadeFlag: boolean; + private _rRate; + private _gRate; + private _bRate; + private _aRate; + private _currentColor; + emitter: ParticleEmitter; + particleSize: number; + particleSprite: Sprite; + startSize: number; + endSize: number; + sizeRate: number; + elapsedMultiplier: number; + constructor(emitter: ParticleEmitter, life?: number, opacity?: number, beginColor?: Color, endColor?: Color, position?: Vector, velocity?: Vector, acceleration?: Vector, startSize?: number, endSize?: number); + kill(): void; + update(delta: number): void; + draw(ctx: CanvasRenderingContext2D): void; + } + /** + * Particle Emitters + * + * Using a particle emitter is a great way to create interesting effects + * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` + * extend [[Actor]] allowing you to use all of the features that come with. + * + * The easiest way to create a `ParticleEmitter` is to use the + * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. + * + * ## Example: Adding an emitter + * + * ```js + * var actor = new ex.Actor(...); + * var emitter = new ex.ParticleEmitter(...); + * + * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle + * emitter.radius = 5; + * emitter.minVel = 100; + * emitter.maxVel = 200; + * emitter.minAngle = 0; + * emitter.maxAngle = Math.PI * 2; + * emitter.emitRate = 300; // 300 particles/second + * emitter.opacity = 0.5; + * emitter.fadeFlag = true; // fade particles overtime + * emitter.particleLife = 1000; // in milliseconds = 1 sec + * emitter.maxSize = 10; // in pixels + * emitter.minSize = 1; + * emitter.particleColor = ex.Color.Rose; + * + * // set emitter settings + * emitter.isEmitting = true; // should the emitter be emitting + * + * // add the emitter as a child actor, it will draw on top of the parent actor + * // and move with the parent + * actor.add(emitter); + * + * // or, alternatively, add it to the current scene + * engine.add(emitter); + * ``` + */ + class ParticleEmitter extends Actor { + private _particlesToEmit; + numParticles: number; /** - * Applies the saturate effect to a sprite, saturates the color acccording to hsl + * Gets or sets the isEmitting flag */ - saturate(factor?: number): void; + isEmitting: boolean; /** - * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl + * Gets or sets the backing particle collection */ - desaturate(factor?: number): void; + particles: Util.Collection; /** - * Add a [[ISpriteEffect]] manually + * Gets or sets the backing deadParticle collection */ - addEffect(effect: Effects.ISpriteEffect): void; + deadParticles: Util.Collection; /** - * Removes an [[ISpriteEffect]] from this animation. - * @param effect Effect to remove from this animation + * Gets or sets the minimum partical velocity */ - removeEffect(effect: Effects.ISpriteEffect): void; + minVel: number; /** - * Removes an effect given the index from this animation. - * @param index Index of the effect to remove from this animation + * Gets or sets the maximum partical velocity */ - removeEffect(index: number): void; + maxVel: number; /** - * Clear all sprite effects + * Gets or sets the acceleration vector for all particles */ - clearEffects(): void; - private _setAnchor(point); - private _setRotation(radians); - private _setScale(scale); + acceleration: Vector; /** - * Resets the animation to first frame. + * Gets or sets the minimum angle in radians */ - reset(): void; + minAngle: number; /** - * Indicates whether the animation is complete, animations that loop are never complete. + * Gets or sets the maximum angle in radians */ - isDone(): boolean; + maxAngle: number; /** - * Not meant to be called by game developers. Ticks the animation forward internally and - * calculates whether to change to the frame. - * @internal + * Gets or sets the emission rate for particles (particles/sec) */ - tick(): void; - private _updateValues(); + emitRate: number; /** - * Skips ahead a specified number of frames in the animation - * @param frames Frames to skip ahead + * Gets or sets the life of each particle in milliseconds */ - skip(frames: number): void; - draw(ctx: CanvasRenderingContext2D, x: number, y: number): void; + particleLife: number; /** - * Plays an animation at an arbitrary location in the game. - * @param x The x position in the game to play - * @param y The y position in the game to play + * Gets or sets the opacity of each particle from 0 to 1.0 */ - play(x: number, y: number): void; - } -} -declare module ex.Internal { - interface ISound { - setVolume(volume: number): any; - setLoop(loop: boolean): any; - isPlaying(): boolean; - play(): ex.Promise; - pause(): any; - stop(): any; - load(): any; - setData(data: any): any; - getData(): any; - processData(data: any): any; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - path: string; - } - class FallbackAudio implements ISound { - path: string; - private _soundImpl; - private _log; - constructor(path: string, volume?: number); - setVolume(volume: number): void; - setLoop(loop: boolean): void; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - load(): void; - processData(data: any): any; - getData(): any; - setData(data: any): void; - isPlaying(): boolean; - play(): ex.Promise; - pause(): void; - stop(): void; - } - class AudioTag implements ISound { - path: string; - private _audioElements; - private _loadedAudio; - private _isLoaded; - private _index; - private _log; - private _isPlaying; - private _playingTimer; - private _currentOffset; - constructor(path: string, volume?: number); - isPlaying(): boolean; - private _audioLoaded(); - setVolume(volume: number): void; - setLoop(loop: boolean): void; - getLoop(): void; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - load(): void; - getData(): any; - setData(data: any): void; - processData(data: any): any; - play(): Promise; - pause(): void; - stop(): void; - } - class WebAudio implements ISound { - path: string; - private _context; - private _volume; - private _buffer; - private _sound; - private _isLoaded; - private _loop; - private _isPlaying; - private _isPaused; - private _playingTimer; - private _currentOffset; - private _playPromise; - private _logger; - private _data; - constructor(path: string, volume?: number); - setVolume(volume: number): void; - onload: (e: any) => void; - onprogress: (e: any) => void; - onerror: (e: any) => void; - load(): void; - getData(): any; - setData(data: any): void; - processData(data: any): any; - setLoop(loop: boolean): void; - isPlaying(): boolean; - play(): Promise; - pause(): void; - stop(): void; - } -} -declare module ex { - /** - * Valid states for a promise to be in - */ - enum PromiseState { - Resolved = 0, - Rejected = 1, - Pending = 2, - } - interface IPromise { - then(successCallback?: (value?: T) => any, rejectCallback?: (value?: T) => any): IPromise; - error(rejectCallback?: (value?: any) => any): IPromise; - resolve(value?: T): IPromise; - reject(value?: any): IPromise; - state(): PromiseState; - } - /** - * Promises/A+ spec implementation of promises - * - * Promises are used to do asynchronous work and they are useful for - * creating a chain of actions. In Excalibur they are used for loading, - * sounds, animation, actions, and more. - * - * ## A Promise Chain - * - * Promises can be chained together and can be useful for creating a queue - * of functions to be called when something is done. - * - * The first [[Promise]] you will encounter is probably [[Engine.start]] - * which resolves when the game has finished loading. - * - * ```js - * var game = new ex.Engine(); - * - * // perform start-up logic once game is ready - * game.start().then(function () { - * - * // start-up & initialization logic - * - * }); - * ``` - * - * ## Handling errors - * - * You can optionally pass an error handler to [[Promise.then]] which will handle - * any errors that occur during Promise execution. - * - * ```js - * var game = new ex.Engine(); - * - * game.start().then( - * // success handler - * function () { - * }, - * - * // error handler - * function (err) { - * } - * ); - * ``` - * - * Any errors that go unhandled will be bubbled up to the browser. - */ - class Promise implements IPromise { - private _state; - private _value; - private _successCallbacks; - private _rejectCallback; - private _errorCallback; - private _logger; + opacity: number; /** - * Wrap a value in a resolved promise - * @param value An optional value to wrap in a resolved promise + * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. */ - static wrap(value?: T): Promise; + fadeFlag: boolean; /** - * Returns a new promise that resolves when all the promises passed to it resolve, or rejects - * when at least 1 promise rejects. + * Gets or sets the optional focus where all particles should accelerate towards */ - static join(...promises: Promise[]): Promise; + focus: Vector; /** - * Chain success and reject callbacks after the promise is resovled - * @param successCallback Call on resolution of promise - * @param rejectCallback Call on rejection of promise + * Gets or sets the acceleration for focusing particles if a focus has been specified */ - then(successCallback?: (value?: T) => any, rejectCallback?: (value?: any) => any): Promise; + focusAccel: number; + startSize: number; + endSize: number; /** - * Add an error callback to the promise - * @param errorCallback Call if there was an error in a callback + * Gets or sets the minimum size of all particles */ - error(errorCallback?: (value?: any) => any): Promise; + minSize: number; /** - * Resolve the promise and pass an option value to the success callbacks - * @param value Value to pass to the success callbacks + * Gets or sets the maximum size of all particles */ - resolve(value?: T): Promise; + maxSize: number; /** - * Reject the promise and pass an option value to the reject callbacks - * @param value Value to pass to the reject callbacks + * Gets or sets the beginning color of all particles */ - reject(value?: any): Promise; + beginColor: Color; /** - * Inpect the current state of a promise + * Gets or sets the ending color of all particles */ - state(): PromiseState; - private _handleError(e); - } -} -declare module ex { - /** - * Loadables - * - * An interface describing loadable resources in Excalibur. Built-in loadable - * resources include [[Texture]], [[Sound]], and a generic [[Resource]]. - * - * ## Advanced: Custom loadables - * - * You can implement the [[ILoadable]] interface to create your own custom loadables. - * This is an advanced feature, as the [[Resource]] class already wraps logic around - * blob/plain data for usages like JSON, configuration, levels, etc through XHR (Ajax). - * - * However, as long as you implement the facets of a loadable, you can create your - * own. - */ - interface ILoadable { + endColor: Color; /** - * Begins loading the resource and returns a promise to be resolved on completion + * Gets or sets the sprite that a particle should use + * @warning Performance intensive */ - load(): Promise; - getData(): any; - setData(data: any): void; + particleSprite: ex.Sprite; /** - * Processes the downloaded data. Meant to be overridden. + * Gets or sets the emitter type for the particle emitter */ - processData(data: any): any; + emitterType: ex.EmitterType; /** - * Wires engine into loadable to receive game level events + * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] */ - wireEngine(engine: Engine): void; + radius: number; /** - * onprogress handler + * Gets or sets the particle rotational speed velocity */ - onprogress: (e: any) => void; + particleRotationalVelocity: number; /** - * oncomplete handler + * Indicates whether particles should start with a random rotation */ - oncomplete: () => void; + randomRotation: boolean; /** - * onerror handler + * @param x The x position of the emitter + * @param y The y position of the emitter + * @param width The width of the emitter + * @param height The height of the emitter */ - onerror: (e: any) => void; + constructor(x?: number, y?: number, width?: number, height?: number); + removeParticle(particle: Particle): void; /** - * Returns true if the loadable is loaded + * Causes the emitter to emit particles + * @param particleCount Number of particles to emit right now */ - isLoaded(): boolean; + emitParticles(particleCount: number): void; + clearParticles(): void; + private _createParticle(); + update(engine: Engine, delta: number): void; + draw(ctx: CanvasRenderingContext2D, delta: number): void; + debugDraw(ctx: CanvasRenderingContext2D): void; } } declare module ex { /** - * Generic Resources - * - * The [[Resource]] type allows games built in Excalibur to load generic resources. - * For any type of remote resource it is recommended to use [[Resource]] for preloading. + * Animations * - * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before - * a level or game. + * Animations allow you to display a series of images one after another, + * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. * - * Example usages: JSON, compressed files, blobs. + * ## Creating an animation * - * ## Pre-loading generic resources + * Create a [[Texture]] that contains the frames of your animation. Once the texture + * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] + * and using [[SpriteSheet.getAnimationForAll]]. * * ```js - * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); - * var loader = new ex.Loader(resLevel1); + * var game = new ex.Engine(); + * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); * - * // attach a handler to process once loaded - * resLevel1.processData = function (data) { + * // load assets + * var loader = new ex.Loader(txAnimPlayerIdle); * - * // process JSON - * var json = JSON.parse(data); + * // start game + * game.start(loader).then(function () { + * var player = new ex.Actor(); * - * // create a new level (inherits Scene) with the JSON configuration - * var level = new Level(json); + * // create sprite sheet with 5 columns, 1 row, 80x80 frames + * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); * - * // add a new scene - * game.add(level.name, level); - * } + * // create animation (125ms frame speed) + * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); * - * game.start(loader); + * // add drawing to player as "idle" + * player.addDrawing("idle", playerIdleAnimation); + * + * // add player to game + * game.add(player); + * }); * ``` + * + * ## Sprite effects + * + * You can add [[SpriteEffect|sprite effects]] to an animation through methods + * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this + * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - class Resource extends Class implements ILoadable { - path: string; - responseType: string; - bustCache: boolean; - data: T; - logger: Logger; - private _engine; + class Animation implements IDrawable { /** - * @param path Path to the remote resource - * @param responseType The Content-Type to expect (e.g. `application/json`) - * @param bustCache Whether or not to cache-bust requests + * The sprite frames to play, in order. See [[SpriteSheet.getAnimationForAll]] to quickly + * generate an [[Animation]]. */ - constructor(path: string, responseType: string, bustCache?: boolean); + sprites: Sprite[]; /** - * Returns true if the Resource is completely loaded and is ready - * to be drawn. + * Duration to show each frame (in milliseconds) */ - isLoaded(): boolean; - wireEngine(engine: Engine): void; - private _cacheBust(uri); - private _start(e); + speed: number; /** - * Begin loading the resource and returns a promise to be resolved on completion + * Current frame index being shown */ - load(): Promise; + currentFrame: number; + private _oldTime; + anchor: Point; + rotation: number; + scale: Point; /** - * Returns the loaded data once the resource is loaded + * Indicates whether the animation should loop after it is completed */ - getData(): any; + loop: boolean; /** - * Sets the data for this resource directly + * Indicates the frame index the animation should freeze on for a non-looping + * animation. By default it is the last frame. */ - setData(data: any): void; + freezeFrame: number; + private _engine; /** - * This method is meant to be overriden to handle any additional - * processing. Such as decoding downloaded audio bits. + * Flip each frame vertically. Sets [[Sprite.flipVertical]]. */ - processData(data: T): any; - onprogress: (e: any) => void; - oncomplete: () => void; - onerror: (e: any) => void; - } -} -declare module ex { - /** - * Textures - * - * The [[Texture]] object allows games built in Excalibur to load image resources. - * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] - * to pre-load before starting a level or game. - * - * Textures are the raw image so to add a drawing to a game, you must create - * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite - * instance. - * - * ## Pre-loading textures - * - * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] - * is loaded, you can generate a [[Sprite]] with it. - * - * ```js - * var txPlayer = new ex.Texture("/assets/tx/player.png"); - * - * var loader = new ex.Loader(txPlayer); - * - * game.start(loader).then(function () { - * - * var player = new ex.Actor(); - * - * player.addDrawing(txPlayer); - * - * game.add(player); - * }); - * ``` - */ - class Texture extends Resource { - path: string; - bustCache: boolean; + flipVertical: boolean; /** - * The width of the texture in pixels + * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. */ + flipHorizontal: boolean; width: number; + height: number; + naturalWidth: number; + naturalHeight: number; /** - * The height of the texture in pixels + * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. + * + * @param engine Reference to the current game engine + * @param images An array of sprites to create the frames for the animation + * @param speed The number in milliseconds to display each frame in the animation + * @param loop Indicates whether the animation should loop after it is completed */ - height: number; + constructor(engine: Engine, images: Sprite[], speed: number, loop?: boolean); /** - * A [[Promise]] that resolves when the Texture is loaded. + * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value */ - loaded: Promise; - private _isLoaded; - private _sprite; + opacity(value: number): void; + /** + * Applies the grayscale effect to a sprite, removing color information. + */ + grayscale(): void; + /** + * Applies the invert effect to a sprite, inverting the pixel colors. + */ + invert(): void; /** - * Populated once loading is complete + * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color */ - image: HTMLImageElement; - private _progressCallback; - private _doneCallback; - private _errorCallback; + fill(color: Color): void; /** - * @param path Path to the image resource - * @param bustCache Optionally load texture with cache busting + * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the + * provided color. */ - constructor(path: string, bustCache?: boolean); + colorize(color: Color): void; /** - * Returns true if the Texture is completely loaded and is ready - * to be drawn. + * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl */ - isLoaded(): boolean; + lighten(factor?: number): void; /** - * Begins loading the texture and returns a promise to be resolved on completion + * Applies the darken effect to a sprite, changes the darkness of the color according to hsl */ - load(): Promise; - asSprite(): Sprite; - } - /** - * Sounds - * - * The [[Sound]] object allows games built in Excalibur to load audio - * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] - * which means it can be passed to a [[Loader]] to pre-load before a game or level. - * - * ## Pre-loading sounds - * - * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] - * is loaded, you can [[Sound.play|play]] it. - * - * ```js - * // define multiple sources (such as mp3/wav/ogg) as a browser fallback - * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); - * - * var loader = new ex.Loader(sndPlayerDeath); - * - * game.start(loader).then(function () { - * - * sndPlayerDeath.play(); - * }); - * ``` - */ - class Sound implements ILoadable, ex.Internal.ISound { - private _logger; - path: string; - onprogress: (e: any) => void; - oncomplete: () => void; - onerror: (e: any) => void; - onload: (e: any) => void; - private _isLoaded; - private _engine; - private _wasPlayingOnHidden; + darken(factor?: number): void; /** - * Populated once loading is complete + * Applies the saturate effect to a sprite, saturates the color acccording to hsl */ - sound: ex.Internal.FallbackAudio; + saturate(factor?: number): void; /** - * Whether or not the browser can play this file as HTML5 Audio + * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl */ - static canPlayFile(file: string): boolean; + desaturate(factor?: number): void; /** - * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. + * Add a [[ISpriteEffect]] manually */ - constructor(...paths: string[]); - wireEngine(engine: Engine): void; + addEffect(effect: Effects.ISpriteEffect): void; /** - * Sets the volume of the sound clip - * @param volume A volume value between 0-1.0 + * Removes an [[ISpriteEffect]] from this animation. + * @param effect Effect to remove from this animation */ - setVolume(volume: number): void; + removeEffect(effect: Effects.ISpriteEffect): void; /** - * Indicates whether the clip should loop when complete - * @param loop Set the looping flag + * Removes an effect given the index from this animation. + * @param index Index of the effect to remove from this animation */ - setLoop(loop: boolean): void; + removeEffect(index: number): void; /** - * Whether or not the sound is playing right now + * Clear all sprite effects */ - isPlaying(): boolean; + clearEffects(): void; + private _setAnchor(point); + private _setRotation(radians); + private _setScale(scale); /** - * Play the sound, returns a promise that resolves when the sound is done playing + * Resets the animation to first frame. */ - play(): ex.Promise; + reset(): void; /** - * Stop the sound, and do not rewind + * Indicates whether the animation is complete, animations that loop are never complete. */ - pause(): void; + isDone(): boolean; /** - * Stop the sound and rewind + * Not meant to be called by game developers. Ticks the animation forward internally and + * calculates whether to change to the frame. + * @internal */ - stop(): void; + tick(): void; + private _updateValues(); /** - * Returns true if the sound is loaded + * Skips ahead a specified number of frames in the animation + * @param frames Frames to skip ahead */ - isLoaded(): boolean; + skip(frames: number): void; + draw(ctx: CanvasRenderingContext2D, x: number, y: number): void; /** - * Begins loading the sound and returns a promise to be resolved on completion + * Plays an animation at an arbitrary location in the game. + * @param x The x position in the game to play + * @param y The y position in the game to play */ - load(): Promise; + play(x: number, y: number): void; + } +} +declare module ex.Internal { + interface ISound { + setVolume(volume: number): any; + setLoop(loop: boolean): any; + isPlaying(): boolean; + play(): ex.Promise; + pause(): any; + stop(): any; + load(): any; + setData(data: any): any; + getData(): any; + processData(data: any): any; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + path: string; + } + class FallbackAudio implements ISound { + path: string; + private _soundImpl; + private _log; + constructor(path: string, volume?: number); + setVolume(volume: number): void; + setLoop(loop: boolean): void; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + load(): void; + processData(data: any): any; + getData(): any; + setData(data: any): void; + isPlaying(): boolean; + play(): ex.Promise; + pause(): void; + stop(): void; + } + class AudioTag implements ISound { + path: string; + private _audioElements; + private _loadedAudio; + private _isLoaded; + private _index; + private _log; + private _isPlaying; + private _playingTimer; + private _currentOffset; + constructor(path: string, volume?: number); + isPlaying(): boolean; + private _audioLoaded(); + setVolume(volume: number): void; + setLoop(loop: boolean): void; + getLoop(): void; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + load(): void; + getData(): any; + setData(data: any): void; + processData(data: any): any; + play(): Promise; + pause(): void; + stop(): void; + } + class WebAudio implements ISound { + path: string; + private _context; + private _volume; + private _buffer; + private _sound; + private _isLoaded; + private _loop; + private _isPlaying; + private _isPaused; + private _playingTimer; + private _currentOffset; + private _playPromise; + private _logger; + private _data; + constructor(path: string, volume?: number); + setVolume(volume: number): void; + onload: (e: any) => void; + onprogress: (e: any) => void; + onerror: (e: any) => void; + load(): void; getData(): any; setData(data: any): void; processData(data: any): any; + setLoop(loop: boolean): void; + isPlaying(): boolean; + play(): Promise; + pause(): void; + stop(): void; + private static _unlocked; + /** + * Play an empty sound to unlock Safari WebAudio context. Call this function + * right after a user interaction event. Typically used by [[PauseAfterLoader]] + * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/ + */ + static unlock(): void; + static isUnlocked(): boolean; + } +} +declare module ex { + interface ILoader extends ILoadable { + draw(ctx: CanvasRenderingContext2D, delta: number): any; + update(engine: Engine, delta: number): any; } +} +declare module ex { /** * Pre-loading assets * @@ -5275,7 +5293,7 @@ declare module ex { * }); * ``` */ - class Loader implements ILoadable { + class Loader extends Class implements ILoader { private _resourceList; private _index; private _resourceCount; @@ -5308,6 +5326,15 @@ declare module ex { * that resolves when loading of all is complete */ load(): Promise; + /** + * Loader draw function. Draws the default Excalibur loading screen. Override to customize the drawing. + */ + draw(ctx: CanvasRenderingContext2D, delta: number): void; + /** + * Perform any calculations or logic in the `update` method. The default `Loader` does not + * do anything in this method so it is safe to override. + */ + update(engine: ex.Engine, delta: number): void; getData: () => any; setData: (data: any) => any; processData: (data: any) => any; @@ -5315,6 +5342,91 @@ declare module ex { oncomplete: () => void; onerror: () => void; } + /** + * A [[Loader]] that pauses after loading to allow user + * to proceed to play the game. Typically you will + * want to use this loader for iOS to allow sounds + * to play after loading (Apple Safari requires user + * interaction to allow sounds, even for games) + * + * **Note:** Because Loader is not part of a Scene, you must + * call `update` and `draw` manually on "child" objects. + * + * ## Implementing a Trigger + * + * The `PauseAfterLoader` requires an element to act as the trigger button + * to start the game. + * + * For example, let's create an `` tag to be our trigger and call it `tap-to-play`. + * + * ```html + * + * ``` + * + * We've put it inside a wrapper to position it properly over the game canvas. + * + * Now let's add some CSS to style it (insert into ``): + * + * ```html + * + * ``` + * + * Now we can create a `PauseAfterLoader` with a reference to our trigger button: + * + * ```ts + * var loader = new ex.PauseAfterLoader('tap-to-play', [...]); + * ``` + * + * ## Use PauseAfterLoader for iOS + * + * The primary use case for pausing before starting the game is to + * pass Apple's requirement of user interaction. The Web Audio context + * in Safari is disabled by default until user interaction. + * + * Therefore, you can use this snippet to only use PauseAfterLoader when + * iOS is detected (see [this thread](http://stackoverflow.com/questions/9038625/detect-if-device-is-ios) + * for more techniques). + * + * ```ts + * var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window).MSStream; + * var loader: ex.Loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); + * + * loader.addResource(...); + * ``` + */ + class PauseAfterLoader extends Loader { + private _loaded; + private _loadedValue; + private _waitPromise; + private _playTrigger; + constructor(triggerElementId: string, loadables?: ILoadable[]); + load(): Promise; + private _handleOnTrigger; + } } declare module ex { class Detector { @@ -6828,9 +6940,6 @@ declare module ex { private _compatible; private _loader; private _isLoading; - private _progress; - private _total; - private _loadingDraw; /** * Creates a new game using the given [[IEngineOptions]] */ @@ -7036,10 +7145,10 @@ declare module ex { /** * Starts the internal game loop for Excalibur after loading * any provided assets. - * @param loader Optional resources to load before starting the main loop. Some [[ILoadable]] such as a [[Loader]] collection, - * [[Sound]], or [[Texture]]. + * @param loader Optional [[ILoader]] to use to load resources. The default loader is [[Loader]], override to provide your own + * custom loader. */ - start(loader?: ILoadable): Promise; + start(loader?: ILoader): Promise; /** * Stops Excalibur's main loop, useful for pausing the game. */ @@ -7049,19 +7158,6 @@ declare module ex { * HTML Image Element. */ screenshot(): HTMLImageElement; - /** - * Draws the Excalibur loading bar - * @param ctx The canvas rendering context - * @param loaded Number of bytes loaded - * @param total Total number of bytes to load - */ - private _drawLoadingBar(ctx, loaded, total); - /** - * Sets the loading screen draw function if you want to customize the draw - * @param fcn Callback to draw the loading screen which is passed a rendering context, the number of bytes loaded, and the total - * number of bytes to load. - */ - setLoadingDrawFunction(fcn: (ctx: CanvasRenderingContext2D, loaded: number, total: number) => void): void; /** * Another option available to you to load resources into the game. * Immediately after calling this the game will pause and the loading screen diff --git a/dist/excalibur-0.6.0.js b/dist/excalibur-0.6.0.js index b62b46962..d36c58af0 100644 --- a/dist/excalibur-0.6.0.js +++ b/dist/excalibur-0.6.0.js @@ -8213,1769 +8213,1816 @@ var ex; return HSLColor; })(); })(ex || (ex = {})); -/// -var ex; -(function (ex) { - /** - * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does - * not participate in collisions. Drawn on top of all other actors. - */ - var UIActor = (function (_super) { - __extends(UIActor, _super); - /** - * @param x The starting x coordinate of the actor - * @param y The starting y coordinate of the actor - * @param width The starting width of the actor - * @param height The starting height of the actor - */ - function UIActor(x, y, width, height) { - _super.call(this, x, y, width, height); - this.traits = []; - this.traits.push(new ex.Traits.Movement()); - this.traits.push(new ex.Traits.CapturePointer()); - this.anchor.setTo(0, 0); - this.collisionType = ex.CollisionType.PreventCollision; - this.enableCapturePointer = true; - } - UIActor.prototype.onInitialize = function (engine) { - this._engine = engine; - }; - UIActor.prototype.contains = function (x, y, useWorld) { - if (useWorld === void 0) { useWorld = true; } - if (useWorld) { - return _super.prototype.contains.call(this, x, y); - } - var coords = this._engine.worldToScreenCoordinates(new ex.Point(x, y)); - return _super.prototype.contains.call(this, coords.x, coords.y); - }; - return UIActor; - })(ex.Actor); - ex.UIActor = UIActor; -})(ex || (ex = {})); -/// -/// +/// var ex; (function (ex) { /** - * Triggers + * Generic Resources * - * Triggers are a method of firing arbitrary code on collision. These are useful - * as 'buttons', 'switches', or to trigger effects in a game. By default triggers - * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * The [[Resource]] type allows games built in Excalibur to load generic resources. + * For any type of remote resource it is recommended to use [[Resource]] for preloading. * - * ## Creating a trigger + * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before + * a level or game. * - * ```js - * var game = new ex.Game(); + * Example usages: JSON, compressed files, blobs. * - * // create a handler - * function onTrigger() { + * ## Pre-loading generic resources * - * // `this` will be the Trigger instance - * ex.Logger.getInstance().info("Trigger was triggered!", this); - * } + * ```js + * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); + * var loader = new ex.Loader(resLevel1); * - * // set a trigger at (100, 100) that is 40x40px - * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * // attach a handler to process once loaded + * resLevel1.processData = function (data) { * - * // create an actor across from the trigger - * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * // process JSON + * var json = JSON.parse(data); * - * // tell the actor to move towards the trigger over 3 seconds - * actor.moveTo(100, 200, 3000); + * // create a new level (inherits Scene) with the JSON configuration + * var level = new Level(json); * - * game.add(trigger); - * game.add(actor); + * // add a new scene + * game.add(level.name, level); + * } * - * game.start(); + * game.start(loader); * ``` */ - var Trigger = (function (_super) { - __extends(Trigger, _super); + var Resource = (function (_super) { + __extends(Resource, _super); /** - * @param x The x position of the trigger - * @param y The y position of the trigger - * @param width The width of the trigger - * @param height The height of the trigger - * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance - * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely + * @param path Path to the remote resource + * @param responseType The Content-Type to expect (e.g. `application/json`) + * @param bustCache Whether or not to cache-bust requests */ - function Trigger(x, y, width, height, action, repeats) { - _super.call(this, x, y, width, height); - this._action = function () { return; }; - this.repeats = 1; - this.target = null; - this.repeats = repeats || this.repeats; - this._action = action || this._action; - this.collisionType = ex.CollisionType.PreventCollision; - this.eventDispatcher = new ex.EventDispatcher(this); - this.actionQueue = new ex.Internal.Actions.ActionQueue(this); + function Resource(path, responseType, bustCache) { + if (bustCache === void 0) { bustCache = true; } + _super.call(this); + this.path = path; + this.responseType = responseType; + this.bustCache = bustCache; + this.data = null; + this.logger = ex.Logger.getInstance(); + this.onprogress = function () { return; }; + this.oncomplete = function () { return; }; + this.onerror = function () { return; }; } - Trigger.prototype.update = function (engine, delta) { - // Update action queue - this.actionQueue.update(delta); - // Update placements based on linear algebra - this.x += this.dx * delta / 1000; - this.y += this.dy * delta / 1000; - this.rotation += this.rx * delta / 1000; - this.scale.x += this.sx * delta / 1000; - this.scale.y += this.sy * delta / 1000; - // check for trigger collisions - if (this.target) { - if (this.collides(this.target)) { - this._dispatchAction(); - } + /** + * Returns true if the Resource is completely loaded and is ready + * to be drawn. + */ + Resource.prototype.isLoaded = function () { + return this.data !== null; + }; + Resource.prototype.wireEngine = function (engine) { + this._engine = engine; + }; + Resource.prototype._cacheBust = function (uri) { + var query = /\?\w*=\w*/; + if (query.test(uri)) { + uri += ('&__=' + Date.now()); } else { - for (var i = 0; i < engine.currentScene.children.length; i++) { - var other = engine.currentScene.children[i]; - if (other !== this && - other.collisionType !== ex.CollisionType.PreventCollision && - this.collides(other)) { - this._dispatchAction(); - } - } + uri += ('?__=' + Date.now()); } - // remove trigger if its done, -1 repeat forever - if (this.repeats === 0) { - this.kill(); + return uri; + }; + Resource.prototype._start = function (e) { + this.logger.debug('Started loading resource ' + this.path); + }; + /** + * Begin loading the resource and returns a promise to be resolved on completion + */ + Resource.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + // Exit early if we already have data + if (this.data !== null) { + this.logger.debug('Already have data for resource', this.path); + complete.resolve(this.data); + this.oncomplete(); + return complete; } + var request = new XMLHttpRequest(); + request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true); + request.responseType = this.responseType; + request.onloadstart = function (e) { _this._start(e); }; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function (e) { + if (request.status !== 200) { + _this.logger.error('Failed to load resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + complete.resolve(request.response); + return; + } + _this.data = _this.processData(request.response); + _this.oncomplete(); + _this.logger.debug('Completed loading resource', _this.path); + complete.resolve(_this.data); + }; + request.send(); + return complete; }; - Trigger.prototype._dispatchAction = function () { - this._action.call(this); - this.repeats--; + /** + * Returns the loaded data once the resource is loaded + */ + Resource.prototype.getData = function () { + return this.data; }; - Trigger.prototype.draw = function (ctx, delta) { - // does not draw - return; + /** + * Sets the data for this resource directly + */ + Resource.prototype.setData = function (data) { + this.data = this.processData(data); }; - Trigger.prototype.debugDraw = function (ctx) { - _super.prototype.debugDraw.call(this, ctx); - // Meant to draw debug information about actors - ctx.save(); - ctx.translate(this.x, this.y); - var bb = this.getBounds(); - bb.left = bb.left - this.getWorldX(); - bb.right = bb.right - this.getWorldX(); - bb.top = bb.top - this.getWorldY(); - bb.bottom = bb.bottom - this.getWorldY(); - // Currently collision primitives cannot rotate - // ctx.rotate(this.rotation); - ctx.fillStyle = ex.Color.Violet.toString(); - ctx.strokeStyle = ex.Color.Violet.toString(); - ctx.fillText('Trigger', 10, 10); - bb.debugDraw(ctx); - ctx.restore(); + /** + * This method is meant to be overriden to handle any additional + * processing. Such as decoding downloaded audio bits. + */ + Resource.prototype.processData = function (data) { + // Handle any additional loading after the xhr has completed. + return URL.createObjectURL(data); }; - return Trigger; - })(ex.Actor); - ex.Trigger = Trigger; + return Resource; + })(ex.Class); + ex.Resource = Resource; })(ex || (ex = {})); -/// -/// -/// -/// +/// +// Promises/A+ Spec http://promises-aplus.github.io/promises-spec/ var ex; (function (ex) { /** - * An enum that represents the types of emitter nozzles + * Valid states for a promise to be in */ - (function (EmitterType) { - /** - * Constant for the circular emitter type - */ - EmitterType[EmitterType["Circle"] = 0] = "Circle"; - /** - * Constant for the rectangular emitter type - */ - EmitterType[EmitterType["Rectangle"] = 1] = "Rectangle"; - })(ex.EmitterType || (ex.EmitterType = {})); - var EmitterType = ex.EmitterType; - /** - * Particle is used in a [[ParticleEmitter]] - */ - var Particle = (function () { - function Particle(emitter, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) { - this.position = new ex.Vector(0, 0); - this.velocity = new ex.Vector(0, 0); - this.acceleration = new ex.Vector(0, 0); - this.particleRotationalVelocity = 0; - this.currentRotation = 0; - this.focus = null; - this.focusAccel = 0; - this.opacity = 1; - this.beginColor = ex.Color.White.clone(); - this.endColor = ex.Color.White.clone(); - // Life is counted in ms - this.life = 300; - this.fadeFlag = false; - // Color transitions - this._rRate = 1; - this._gRate = 1; - this._bRate = 1; - this._aRate = 0; - this._currentColor = ex.Color.White.clone(); - this.emitter = null; - this.particleSize = 5; - this.particleSprite = null; - this.sizeRate = 0; - this.elapsedMultiplier = 0; - this.emitter = emitter; - this.life = life || this.life; - this.opacity = opacity || this.opacity; - this.endColor = endColor || this.endColor.clone(); - this.beginColor = beginColor || this.beginColor.clone(); - this._currentColor = this.beginColor.clone(); - this.position = position || this.position; - this.velocity = velocity || this.velocity; - this.acceleration = acceleration || this.acceleration; - this._rRate = (this.endColor.r - this.beginColor.r) / this.life; - this._gRate = (this.endColor.g - this.beginColor.g) / this.life; - this._bRate = (this.endColor.b - this.beginColor.b) / this.life; - this._aRate = this.opacity / this.life; - this.startSize = startSize || 0; - this.endSize = endSize || 0; - if ((this.endSize > 0) && (this.startSize > 0)) { - this.sizeRate = (this.endSize - this.startSize) / this.life; - this.particleSize = this.startSize; - } - } - Particle.prototype.kill = function () { - this.emitter.removeParticle(this); - }; - Particle.prototype.update = function (delta) { - this.life = this.life - delta; - this.elapsedMultiplier = this.elapsedMultiplier + delta; - if (this.life < 0) { - this.kill(); - } - if (this.fadeFlag) { - this.opacity = ex.Util.clamp(this._aRate * this.life, 0.0001, 1); - } - if ((this.startSize > 0) && (this.endSize > 0)) { - this.particleSize = ex.Util.clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize)); - } - this._currentColor.r = ex.Util.clamp(this._currentColor.r + this._rRate * delta, 0, 255); - this._currentColor.g = ex.Util.clamp(this._currentColor.g + this._gRate * delta, 0, 255); - this._currentColor.b = ex.Util.clamp(this._currentColor.b + this._bRate * delta, 0, 255); - this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); - if (this.focus) { - var accel = this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(delta / 1000); - this.velocity = this.velocity.add(accel); - } - else { - this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000)); - } - this.position = this.position.add(this.velocity.scale(delta / 1000)); - if (this.particleRotationalVelocity) { - this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI); - } - }; - Particle.prototype.draw = function (ctx) { - if (this.particleSprite) { - this.particleSprite.rotation = this.currentRotation; - this.particleSprite.scale.setTo(this.particleSize, this.particleSize); - this.particleSprite.draw(ctx, this.position.x, this.position.y); - return; - } - this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); - ctx.fillStyle = this._currentColor.toString(); - ctx.beginPath(); - ctx.arc(this.position.x, this.position.y, this.particleSize, 0, Math.PI * 2); - ctx.fill(); - ctx.closePath(); - }; - return Particle; - })(); - ex.Particle = Particle; + (function (PromiseState) { + PromiseState[PromiseState["Resolved"] = 0] = "Resolved"; + PromiseState[PromiseState["Rejected"] = 1] = "Rejected"; + PromiseState[PromiseState["Pending"] = 2] = "Pending"; + })(ex.PromiseState || (ex.PromiseState = {})); + var PromiseState = ex.PromiseState; /** - * Particle Emitters + * Promises/A+ spec implementation of promises * - * Using a particle emitter is a great way to create interesting effects - * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` - * extend [[Actor]] allowing you to use all of the features that come with. + * Promises are used to do asynchronous work and they are useful for + * creating a chain of actions. In Excalibur they are used for loading, + * sounds, animation, actions, and more. * - * The easiest way to create a `ParticleEmitter` is to use the - * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. + * ## A Promise Chain * - * ## Example: Adding an emitter + * Promises can be chained together and can be useful for creating a queue + * of functions to be called when something is done. + * + * The first [[Promise]] you will encounter is probably [[Engine.start]] + * which resolves when the game has finished loading. * * ```js - * var actor = new ex.Actor(...); - * var emitter = new ex.ParticleEmitter(...); + * var game = new ex.Engine(); * - * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle - * emitter.radius = 5; - * emitter.minVel = 100; - * emitter.maxVel = 200; - * emitter.minAngle = 0; - * emitter.maxAngle = Math.PI * 2; - * emitter.emitRate = 300; // 300 particles/second - * emitter.opacity = 0.5; - * emitter.fadeFlag = true; // fade particles overtime - * emitter.particleLife = 1000; // in milliseconds = 1 sec - * emitter.maxSize = 10; // in pixels - * emitter.minSize = 1; - * emitter.particleColor = ex.Color.Rose; + * // perform start-up logic once game is ready + * game.start().then(function () { * - * // set emitter settings - * emitter.isEmitting = true; // should the emitter be emitting + * // start-up & initialization logic * - * // add the emitter as a child actor, it will draw on top of the parent actor - * // and move with the parent - * actor.add(emitter); + * }); + * ``` * - * // or, alternatively, add it to the current scene - * engine.add(emitter); + * ## Handling errors + * + * You can optionally pass an error handler to [[Promise.then]] which will handle + * any errors that occur during Promise execution. + * + * ```js + * var game = new ex.Engine(); + * + * game.start().then( + * // success handler + * function () { + * }, + * + * // error handler + * function (err) { + * } + * ); * ``` + * + * Any errors that go unhandled will be bubbled up to the browser. */ - var ParticleEmitter = (function (_super) { - __extends(ParticleEmitter, _super); + var Promise = (function () { + function Promise() { + this._state = PromiseState.Pending; + this._successCallbacks = []; + this._rejectCallback = function () { return; }; + this._logger = ex.Logger.getInstance(); + } /** - * @param x The x position of the emitter - * @param y The y position of the emitter - * @param width The width of the emitter - * @param height The height of the emitter + * Wrap a value in a resolved promise + * @param value An optional value to wrap in a resolved promise */ - function ParticleEmitter(x, y, width, height) { - _super.call(this, x, y, width, height, ex.Color.White); - this._particlesToEmit = 0; - this.numParticles = 0; - /** - * Gets or sets the isEmitting flag - */ - this.isEmitting = true; - /** - * Gets or sets the backing particle collection - */ - this.particles = null; - /** - * Gets or sets the backing deadParticle collection - */ - this.deadParticles = null; - /** - * Gets or sets the minimum partical velocity - */ - this.minVel = 0; - /** - * Gets or sets the maximum partical velocity - */ - this.maxVel = 0; - /** - * Gets or sets the acceleration vector for all particles - */ - this.acceleration = new ex.Vector(0, 0); - /** - * Gets or sets the minimum angle in radians - */ - this.minAngle = 0; - /** - * Gets or sets the maximum angle in radians - */ - this.maxAngle = 0; - /** - * Gets or sets the emission rate for particles (particles/sec) - */ - this.emitRate = 1; //particles/sec - /** - * Gets or sets the life of each particle in milliseconds - */ - this.particleLife = 2000; - /** - * Gets or sets the opacity of each particle from 0 to 1.0 - */ - this.opacity = 1; - /** - * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. - */ - this.fadeFlag = false; - /** - * Gets or sets the optional focus where all particles should accelerate towards - */ - this.focus = null; - /** - * Gets or sets the acceleration for focusing particles if a focus has been specified - */ - this.focusAccel = 1; - /* - * Gets or sets the optional starting size for the particles - */ - this.startSize = null; - /* - * Gets or sets the optional ending size for the particles - */ - this.endSize = null; - /** - * Gets or sets the minimum size of all particles - */ - this.minSize = 5; - /** - * Gets or sets the maximum size of all particles - */ - this.maxSize = 5; - /** - * Gets or sets the beginning color of all particles - */ - this.beginColor = ex.Color.White; - /** - * Gets or sets the ending color of all particles - */ - this.endColor = ex.Color.White; - /** - * Gets or sets the sprite that a particle should use - * @warning Performance intensive - */ - this.particleSprite = null; - /** - * Gets or sets the emitter type for the particle emitter - */ - this.emitterType = EmitterType.Rectangle; - /** - * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] - */ - this.radius = 0; - /** - * Gets or sets the particle rotational speed velocity - */ - this.particleRotationalVelocity = 0; - /** - * Indicates whether particles should start with a random rotation - */ - this.randomRotation = false; - this.collisionType = ex.CollisionType.PreventCollision; - this.particles = new ex.Util.Collection(); - this.deadParticles = new ex.Util.Collection(); - // Remove offscreen culling from particle emitters - for (var trait in this.traits) { - if (this.traits[trait] instanceof ex.Traits.OffscreenCulling) { - this.traits.splice(trait, 1); - } - } - } - ParticleEmitter.prototype.removeParticle = function (particle) { - this.deadParticles.push(particle); + Promise.wrap = function (value) { + var promise = (new Promise()).resolve(value); + return promise; }; /** - * Causes the emitter to emit particles - * @param particleCount Number of particles to emit right now + * Returns a new promise that resolves when all the promises passed to it resolve, or rejects + * when at least 1 promise rejects. */ - ParticleEmitter.prototype.emitParticles = function (particleCount) { - for (var i = 0; i < particleCount; i++) { - this.particles.push(this._createParticle()); + Promise.join = function () { + var promises = []; + for (var _i = 0; _i < arguments.length; _i++) { + promises[_i - 0] = arguments[_i]; } + var joinedPromise = new Promise(); + if (!promises || !promises.length) { + return joinedPromise.resolve(); + } + var total = promises.length; + var successes = 0; + var rejects = 0; + var errors = []; + promises.forEach(function (p) { + p.then(function () { + successes += 1; + if (successes === total) { + joinedPromise.resolve(); + } + else if (successes + rejects + errors.length === total) { + joinedPromise.reject(errors); + } + }, function () { + rejects += 1; + if (successes + rejects + errors.length === total) { + joinedPromise.reject(errors); + } + }).error(function (e) { + errors.push(e); + if ((errors.length + successes + rejects) === total) { + joinedPromise.reject(errors); + } + }); + }); + return joinedPromise; }; - ParticleEmitter.prototype.clearParticles = function () { - this.particles.clear(); - }; - // Creates a new particle given the contraints of the emitter - ParticleEmitter.prototype._createParticle = function () { - // todo implement emitter contraints; - var ranX = 0; - var ranY = 0; - var angle = ex.Util.randomInRange(this.minAngle, this.maxAngle); - var vel = ex.Util.randomInRange(this.minVel, this.maxVel); - var size = this.startSize || ex.Util.randomInRange(this.minSize, this.maxSize); - var dx = vel * Math.cos(angle); - var dy = vel * Math.sin(angle); - if (this.emitterType === EmitterType.Rectangle) { - ranX = ex.Util.randomInRange(this.x, this.x + this.getWidth()); - ranY = ex.Util.randomInRange(this.y, this.y + this.getHeight()); + /** + * Chain success and reject callbacks after the promise is resovled + * @param successCallback Call on resolution of promise + * @param rejectCallback Call on rejection of promise + */ + Promise.prototype.then = function (successCallback, rejectCallback) { + if (successCallback) { + this._successCallbacks.push(successCallback); + // If the promise is already resovled call immediately + if (this.state() === PromiseState.Resolved) { + try { + successCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); + } + } } - else if (this.emitterType === EmitterType.Circle) { - var radius = ex.Util.randomInRange(0, this.radius); - ranX = radius * Math.cos(angle) + this.x; - ranY = radius * Math.sin(angle) + this.y; + if (rejectCallback) { + this._rejectCallback = rejectCallback; + // If the promise is already rejected call immediately + if (this.state() === PromiseState.Rejected) { + try { + rejectCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); + } + } } - var p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new ex.Vector(ranX, ranY), new ex.Vector(dx, dy), this.acceleration, this.startSize, this.endSize); - p.fadeFlag = this.fadeFlag; - p.particleSize = size; - if (this.particleSprite) { - p.particleSprite = this.particleSprite; + return this; + }; + /** + * Add an error callback to the promise + * @param errorCallback Call if there was an error in a callback + */ + Promise.prototype.error = function (errorCallback) { + if (errorCallback) { + this._errorCallback = errorCallback; } - p.particleRotationalVelocity = this.particleRotationalVelocity; - if (this.randomRotation) { - p.currentRotation = ex.Util.randomInRange(0, Math.PI * 2); + return this; + }; + /** + * Resolve the promise and pass an option value to the success callbacks + * @param value Value to pass to the success callbacks + */ + Promise.prototype.resolve = function (value) { + var _this = this; + if (this._state === PromiseState.Pending) { + this._value = value; + try { + this._state = PromiseState.Resolved; + this._successCallbacks.forEach(function (cb) { + cb.call(_this, _this._value); + }); + } + catch (e) { + this._handleError(e); + } } - if (this.focus) { - p.focus = this.focus.add(new ex.Vector(this.x, this.y)); - p.focusAccel = this.focusAccel; + else { + throw new Error('Cannot resolve a promise that is not in a pending state!'); } - return p; + return this; }; - ParticleEmitter.prototype.update = function (engine, delta) { - var _this = this; - _super.prototype.update.call(this, engine, delta); - if (this.isEmitting) { - this._particlesToEmit += this.emitRate * (delta / 1000); - //var numParticles = Math.ceil(this.emitRate * delta / 1000); - if (this._particlesToEmit > 1.0) { - this.emitParticles(Math.floor(this._particlesToEmit)); - this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit); + /** + * Reject the promise and pass an option value to the reject callbacks + * @param value Value to pass to the reject callbacks + */ + Promise.prototype.reject = function (value) { + if (this._state === PromiseState.Pending) { + this._value = value; + try { + this._state = PromiseState.Rejected; + this._rejectCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); } } - this.particles.forEach(function (p) { return p.update(delta); }); - this.deadParticles.forEach(function (p) { return _this.particles.removeElement(p); }); - this.deadParticles.clear(); + else { + throw new Error('Cannot reject a promise that is not in a pending state!'); + } + return this; }; - ParticleEmitter.prototype.draw = function (ctx, delta) { - // todo is there a more efficient to draw - // possibly use a webgl offscreen canvas and shaders to do particles? - this.particles.forEach(function (p) { return p.draw(ctx); }); + /** + * Inpect the current state of a promise + */ + Promise.prototype.state = function () { + return this._state; }; - ParticleEmitter.prototype.debugDraw = function (ctx) { - _super.prototype.debugDraw.call(this, ctx); - ctx.fillStyle = ex.Color.Black.toString(); - ctx.fillText('Particles: ' + this.particles.count(), this.x, this.y + 20); - if (this.focus) { - ctx.fillRect(this.focus.x + this.x, this.focus.y + this.y, 3, 3); - ex.Util.drawLine(ctx, 'yellow', this.focus.x + this.x, this.focus.y + this.y, _super.prototype.getCenter.call(this).x, _super.prototype.getCenter.call(this).y); - ctx.fillText('Focus', this.focus.x + this.x, this.focus.y + this.y); + Promise.prototype._handleError = function (e) { + if (this._errorCallback) { + this._errorCallback.call(this, e); + } + else { + // rethrow error + throw e; } }; - return ParticleEmitter; - })(ex.Actor); - ex.ParticleEmitter = ParticleEmitter; + return Promise; + })(); + ex.Promise = Promise; })(ex || (ex = {})); +/// +/// +/// +/// var ex; (function (ex) { /** - * Animations + * Textures * - * Animations allow you to display a series of images one after another, - * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. + * The [[Texture]] object allows games built in Excalibur to load image resources. + * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] + * to pre-load before starting a level or game. * - * ## Creating an animation + * Textures are the raw image so to add a drawing to a game, you must create + * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite + * instance. * - * Create a [[Texture]] that contains the frames of your animation. Once the texture - * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] - * and using [[SpriteSheet.getAnimationForAll]]. + * ## Pre-loading textures * - * ```js - * var game = new ex.Engine(); - * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); + * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] + * is loaded, you can generate a [[Sprite]] with it. * - * // load assets - * var loader = new ex.Loader(txAnimPlayerIdle); + * ```js + * var txPlayer = new ex.Texture("/assets/tx/player.png"); * - * // start game - * game.start(loader).then(function () { - * var player = new ex.Actor(); + * var loader = new ex.Loader(txPlayer); * - * // create sprite sheet with 5 columns, 1 row, 80x80 frames - * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); + * game.start(loader).then(function () { * - * // create animation (125ms frame speed) - * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); + * var player = new ex.Actor(); * - * // add drawing to player as "idle" - * player.addDrawing("idle", playerIdleAnimation); + * player.addDrawing(txPlayer); * - * // add player to game * game.add(player); * }); * ``` - * - * ## Sprite effects - * - * You can add [[SpriteEffect|sprite effects]] to an animation through methods - * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this - * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - var Animation = (function () { + var Texture = (function (_super) { + __extends(Texture, _super); /** - * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. - * - * @param engine Reference to the current game engine - * @param images An array of sprites to create the frames for the animation - * @param speed The number in milliseconds to display each frame in the animation - * @param loop Indicates whether the animation should loop after it is completed + * @param path Path to the image resource + * @param bustCache Optionally load texture with cache busting */ - function Animation(engine, images, speed, loop) { - /** - * Current frame index being shown - */ - this.currentFrame = 0; - this._oldTime = Date.now(); - this.anchor = new ex.Point(0.0, 0.0); - this.rotation = 0.0; - this.scale = new ex.Point(1, 1); - /** - * Indicates whether the animation should loop after it is completed - */ - this.loop = false; - /** - * Indicates the frame index the animation should freeze on for a non-looping - * animation. By default it is the last frame. - */ - this.freezeFrame = -1; - /** - * Flip each frame vertically. Sets [[Sprite.flipVertical]]. - */ - this.flipVertical = false; + function Texture(path, bustCache) { + if (bustCache === void 0) { bustCache = true; } + _super.call(this, path, 'blob', bustCache); + this.path = path; + this.bustCache = bustCache; /** - * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + * A [[Promise]] that resolves when the Texture is loaded. */ - this.flipHorizontal = false; - this.width = 0; - this.height = 0; - this.naturalWidth = 0; - this.naturalHeight = 0; - this.sprites = images; - this.speed = speed; - this._engine = engine; - if (loop != null) { - this.loop = loop; - } - if (images && images[0]) { - this.height = images[0] ? images[0].height : 0; - this.width = images[0] ? images[0].width : 0; - this.naturalWidth = images[0] ? images[0].naturalWidth : 0; - this.naturalHeight = images[0] ? images[0].naturalHeight : 0; - this.freezeFrame = images.length - 1; - } + this.loaded = new ex.Promise(); + this._isLoaded = false; + this._sprite = null; + this._sprite = new ex.Sprite(this, 0, 0, 0, 0); } /** - * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + * Returns true if the Texture is completely loaded and is ready + * to be drawn. */ - Animation.prototype.opacity = function (value) { - this.addEffect(new ex.Effects.Opacity(value)); + Texture.prototype.isLoaded = function () { + return this._isLoaded; }; /** - * Applies the grayscale effect to a sprite, removing color information. + * Begins loading the texture and returns a promise to be resolved on completion */ - Animation.prototype.grayscale = function () { - this.addEffect(new ex.Effects.Grayscale()); + Texture.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + var loaded = _super.prototype.load.call(this); + loaded.then(function () { + _this.image = new Image(); + _this.image.addEventListener('load', function () { + _this._isLoaded = true; + _this.width = _this._sprite.swidth = _this._sprite.naturalWidth = _this._sprite.width = _this.image.naturalWidth; + _this.height = _this._sprite.sheight = _this._sprite.naturalHeight = _this._sprite.height = _this.image.naturalHeight; + _this.loaded.resolve(_this.image); + complete.resolve(_this.image); + }); + _this.image.src = _super.prototype.getData.call(_this); + }, function () { + complete.reject('Error loading texture.'); + }); + return complete; }; - /** - * Applies the invert effect to a sprite, inverting the pixel colors. - */ - Animation.prototype.invert = function () { - this.addEffect(new ex.Effects.Invert()); + Texture.prototype.asSprite = function () { + return this._sprite; }; + return Texture; + })(ex.Resource); + ex.Texture = Texture; +})(ex || (ex = {})); +/// +/// +/// +/// +var ex; +(function (ex) { + /** + * Sounds + * + * The [[Sound]] object allows games built in Excalibur to load audio + * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] + * which means it can be passed to a [[Loader]] to pre-load before a game or level. + * + * ## Pre-loading sounds + * + * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] + * is loaded, you can [[Sound.play|play]] it. + * + * ```js + * // define multiple sources (such as mp3/wav/ogg) as a browser fallback + * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); + * + * var loader = new ex.Loader(sndPlayerDeath); + * + * game.start(loader).then(function () { + * + * sndPlayerDeath.play(); + * }); + * ``` + */ + var Sound = (function () { /** - * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color + * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. */ - Animation.prototype.fill = function (color) { - this.addEffect(new ex.Effects.Fill(color)); - }; + function Sound() { + var paths = []; + for (var _i = 0; _i < arguments.length; _i++) { + paths[_i - 0] = arguments[_i]; + } + this._logger = ex.Logger.getInstance(); + this.onprogress = function () { return; }; + this.oncomplete = function () { return; }; + this.onerror = function () { return; }; + this.onload = function () { return; }; + this._isLoaded = false; + this._wasPlayingOnHidden = false; + /* Chrome : MP3, WAV, Ogg + * Firefox : WAV, Ogg, + * IE : MP3, WAV coming soon + * Safari MP3, WAV, Ogg + */ + this.path = ''; + for (var i = 0; i < paths.length; i++) { + if (Sound.canPlayFile(paths[i])) { + this.path = paths[i]; + break; + } + } + if (!this.path) { + this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); + this._logger.warn('Attempting to use', paths[0]); + this.path = paths[0]; // select the first specified + } + this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); + } /** - * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the - * provided color. + * Whether or not the browser can play this file as HTML5 Audio */ - Animation.prototype.colorize = function (color) { - this.addEffect(new ex.Effects.Colorize(color)); + Sound.canPlayFile = function (file) { + try { + var a = new Audio(); + var filetype = /.*\.([A-Za-z0-9]+)$/; + var type = file.match(filetype)[1]; + if (a.canPlayType('audio/' + type)) { + return true; + } + { + return false; + } + } + catch (e) { + ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); + return false; + } + }; + Sound.prototype.wireEngine = function (engine) { + var _this = this; + if (engine) { + this._engine = engine; + this._engine.on('hidden', function () { + if (engine.pauseAudioWhenHidden && _this.isPlaying()) { + _this._wasPlayingOnHidden = true; + _this.pause(); + } + }); + this._engine.on('visible', function () { + if (engine.pauseAudioWhenHidden && _this._wasPlayingOnHidden) { + _this.play(); + _this._wasPlayingOnHidden = false; + } + }); + } }; /** - * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl + * Sets the volume of the sound clip + * @param volume A volume value between 0-1.0 */ - Animation.prototype.lighten = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Lighten(factor)); + Sound.prototype.setVolume = function (volume) { + if (this.sound) { + this.sound.setVolume(volume); + } }; /** - * Applies the darken effect to a sprite, changes the darkness of the color according to hsl + * Indicates whether the clip should loop when complete + * @param loop Set the looping flag */ - Animation.prototype.darken = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Darken(factor)); + Sound.prototype.setLoop = function (loop) { + if (this.sound) { + this.sound.setLoop(loop); + } }; /** - * Applies the saturate effect to a sprite, saturates the color acccording to hsl + * Whether or not the sound is playing right now */ - Animation.prototype.saturate = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Saturate(factor)); + Sound.prototype.isPlaying = function () { + if (this.sound) { + return this.sound.isPlaying(); + } }; /** - * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl + * Play the sound, returns a promise that resolves when the sound is done playing */ - Animation.prototype.desaturate = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Desaturate(factor)); + Sound.prototype.play = function () { + if (this.sound) { + return this.sound.play(); + } }; /** - * Add a [[ISpriteEffect]] manually + * Stop the sound, and do not rewind */ - Animation.prototype.addEffect = function (effect) { - for (var i in this.sprites) { - this.sprites[i].addEffect(effect); + Sound.prototype.pause = function () { + if (this.sound) { + this.sound.pause(); } }; - Animation.prototype.removeEffect = function (param) { - for (var i in this.sprites) { - this.sprites[i].removeEffect(param); + /** + * Stop the sound and rewind + */ + Sound.prototype.stop = function () { + if (this.sound) { + this.sound.stop(); } }; /** - * Clear all sprite effects + * Returns true if the sound is loaded */ - Animation.prototype.clearEffects = function () { - for (var i in this.sprites) { - this.sprites[i].clearEffects(); - } + Sound.prototype.isLoaded = function () { + return this._isLoaded; }; - Animation.prototype._setAnchor = function (point) { - //if (!this.anchor.equals(point)) { - for (var i in this.sprites) { - this.sprites[i].anchor.setTo(point.x, point.y); + /** + * Begins loading the sound and returns a promise to be resolved on completion + */ + Sound.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + if (this.sound.getData() !== null) { + this._logger.debug('Already have data for resource', this.path); + complete.resolve(this.sound); + return complete; } - //} + this._logger.debug('Started loading sound', this.path); + this.sound.onprogress = this.onprogress; + this.sound.onload = function () { + _this.oncomplete(); + _this._isLoaded = true; + _this._logger.debug('Completed loading sound', _this.path); + complete.resolve(_this.sound); + }; + this.sound.onerror = function (e) { + _this.onerror(e); + complete.resolve(e); + }; + this.sound.load(); + return complete; }; - Animation.prototype._setRotation = function (radians) { - //if (this.rotation !== radians) { - for (var i in this.sprites) { - this.sprites[i].rotation = radians; - } - //} + Sound.prototype.getData = function () { + return this.sound.getData(); }; - Animation.prototype._setScale = function (scale) { - //if (!this.scale.equals(scale)) { - for (var i in this.sprites) { - this.sprites[i].scale = scale; - } - //} + Sound.prototype.setData = function (data) { + this.sound.setData(data); }; - /** - * Resets the animation to first frame. - */ - Animation.prototype.reset = function () { - this.currentFrame = 0; + Sound.prototype.processData = function (data) { + return this.sound.processData(data); }; + return Sound; + })(); + ex.Sound = Sound; +})(ex || (ex = {})); +/// +var ex; +(function (ex) { + /** + * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does + * not participate in collisions. Drawn on top of all other actors. + */ + var UIActor = (function (_super) { + __extends(UIActor, _super); /** - * Indicates whether the animation is complete, animations that loop are never complete. + * @param x The starting x coordinate of the actor + * @param y The starting y coordinate of the actor + * @param width The starting width of the actor + * @param height The starting height of the actor */ - Animation.prototype.isDone = function () { - return (!this.loop && this.currentFrame >= this.sprites.length); + function UIActor(x, y, width, height) { + _super.call(this, x, y, width, height); + this.traits = []; + this.traits.push(new ex.Traits.Movement()); + this.traits.push(new ex.Traits.CapturePointer()); + this.anchor.setTo(0, 0); + this.collisionType = ex.CollisionType.PreventCollision; + this.enableCapturePointer = true; + } + UIActor.prototype.onInitialize = function (engine) { + this._engine = engine; }; - /** - * Not meant to be called by game developers. Ticks the animation forward internally and - * calculates whether to change to the frame. - * @internal - */ - Animation.prototype.tick = function () { - var time = Date.now(); - if ((time - this._oldTime) > this.speed) { - this.currentFrame = (this.loop ? (this.currentFrame + 1) % this.sprites.length : this.currentFrame + 1); - this._oldTime = time; + UIActor.prototype.contains = function (x, y, useWorld) { + if (useWorld === void 0) { useWorld = true; } + if (useWorld) { + return _super.prototype.contains.call(this, x, y); } + var coords = this._engine.worldToScreenCoordinates(new ex.Point(x, y)); + return _super.prototype.contains.call(this, coords.x, coords.y); }; - Animation.prototype._updateValues = function () { - this._setAnchor(this.anchor); - this._setRotation(this.rotation); - this._setScale(this.scale); - }; + return UIActor; + })(ex.Actor); + ex.UIActor = UIActor; +})(ex || (ex = {})); +/// +/// +var ex; +(function (ex) { + /** + * Triggers + * + * Triggers are a method of firing arbitrary code on collision. These are useful + * as 'buttons', 'switches', or to trigger effects in a game. By default triggers + * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * + * ## Creating a trigger + * + * ```js + * var game = new ex.Game(); + * + * // create a handler + * function onTrigger() { + * + * // `this` will be the Trigger instance + * ex.Logger.getInstance().info("Trigger was triggered!", this); + * } + * + * // set a trigger at (100, 100) that is 40x40px + * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * + * // create an actor across from the trigger + * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * + * // tell the actor to move towards the trigger over 3 seconds + * actor.moveTo(100, 200, 3000); + * + * game.add(trigger); + * game.add(actor); + * + * game.start(); + * ``` + */ + var Trigger = (function (_super) { + __extends(Trigger, _super); /** - * Skips ahead a specified number of frames in the animation - * @param frames Frames to skip ahead + * @param x The x position of the trigger + * @param y The y position of the trigger + * @param width The width of the trigger + * @param height The height of the trigger + * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance + * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely */ - Animation.prototype.skip = function (frames) { - this.currentFrame = (this.currentFrame + frames) % this.sprites.length; - }; - Animation.prototype.draw = function (ctx, x, y) { - this.tick(); - this._updateValues(); - var currSprite; - if (this.currentFrame < this.sprites.length) { - currSprite = this.sprites[this.currentFrame]; - if (this.flipVertical) { - currSprite.flipVertical = this.flipVertical; - } - if (this.flipHorizontal) { - currSprite.flipHorizontal = this.flipHorizontal; + function Trigger(x, y, width, height, action, repeats) { + _super.call(this, x, y, width, height); + this._action = function () { return; }; + this.repeats = 1; + this.target = null; + this.repeats = repeats || this.repeats; + this._action = action || this._action; + this.collisionType = ex.CollisionType.PreventCollision; + this.eventDispatcher = new ex.EventDispatcher(this); + this.actionQueue = new ex.Internal.Actions.ActionQueue(this); + } + Trigger.prototype.update = function (engine, delta) { + // Update action queue + this.actionQueue.update(delta); + // Update placements based on linear algebra + this.x += this.dx * delta / 1000; + this.y += this.dy * delta / 1000; + this.rotation += this.rx * delta / 1000; + this.scale.x += this.sx * delta / 1000; + this.scale.y += this.sy * delta / 1000; + // check for trigger collisions + if (this.target) { + if (this.collides(this.target)) { + this._dispatchAction(); } - currSprite.draw(ctx, x, y); } - if (this.freezeFrame !== -1 && this.currentFrame >= this.sprites.length) { - currSprite = this.sprites[ex.Util.clamp(this.freezeFrame, 0, this.sprites.length - 1)]; - currSprite.draw(ctx, x, y); + else { + for (var i = 0; i < engine.currentScene.children.length; i++) { + var other = engine.currentScene.children[i]; + if (other !== this && + other.collisionType !== ex.CollisionType.PreventCollision && + this.collides(other)) { + this._dispatchAction(); + } + } } - // add the calculated width - if (currSprite) { - this.width = currSprite.width; - this.height = currSprite.height; + // remove trigger if its done, -1 repeat forever + if (this.repeats === 0) { + this.kill(); } }; - /** - * Plays an animation at an arbitrary location in the game. - * @param x The x position in the game to play - * @param y The y position in the game to play - */ - Animation.prototype.play = function (x, y) { - this.reset(); - this._engine.playAnimation(this, x, y); + Trigger.prototype._dispatchAction = function () { + this._action.call(this); + this.repeats--; }; - return Animation; - })(); - ex.Animation = Animation; + Trigger.prototype.draw = function (ctx, delta) { + // does not draw + return; + }; + Trigger.prototype.debugDraw = function (ctx) { + _super.prototype.debugDraw.call(this, ctx); + // Meant to draw debug information about actors + ctx.save(); + ctx.translate(this.x, this.y); + var bb = this.getBounds(); + bb.left = bb.left - this.getWorldX(); + bb.right = bb.right - this.getWorldX(); + bb.top = bb.top - this.getWorldY(); + bb.bottom = bb.bottom - this.getWorldY(); + // Currently collision primitives cannot rotate + // ctx.rotate(this.rotation); + ctx.fillStyle = ex.Color.Violet.toString(); + ctx.strokeStyle = ex.Color.Violet.toString(); + ctx.fillText('Trigger', 10, 10); + bb.debugDraw(ctx); + ctx.restore(); + }; + return Trigger; + })(ex.Actor); + ex.Trigger = Trigger; })(ex || (ex = {})); -/// +/// +/// /// -/// +/// var ex; (function (ex) { - var Internal; - (function (Internal) { - var FallbackAudio = (function () { - function FallbackAudio(path, volume) { - this.path = path; - this._log = ex.Logger.getInstance(); - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - if (window.AudioContext) { - this._log.debug('Using new Web Audio Api for ' + path); - this._soundImpl = new WebAudio(path, volume); - } - else { - this._log.debug('Falling back to Audio Element for ' + path); - this._soundImpl = new AudioTag(path, volume); - } + /** + * An enum that represents the types of emitter nozzles + */ + (function (EmitterType) { + /** + * Constant for the circular emitter type + */ + EmitterType[EmitterType["Circle"] = 0] = "Circle"; + /** + * Constant for the rectangular emitter type + */ + EmitterType[EmitterType["Rectangle"] = 1] = "Rectangle"; + })(ex.EmitterType || (ex.EmitterType = {})); + var EmitterType = ex.EmitterType; + /** + * Particle is used in a [[ParticleEmitter]] + */ + var Particle = (function () { + function Particle(emitter, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) { + this.position = new ex.Vector(0, 0); + this.velocity = new ex.Vector(0, 0); + this.acceleration = new ex.Vector(0, 0); + this.particleRotationalVelocity = 0; + this.currentRotation = 0; + this.focus = null; + this.focusAccel = 0; + this.opacity = 1; + this.beginColor = ex.Color.White.clone(); + this.endColor = ex.Color.White.clone(); + // Life is counted in ms + this.life = 300; + this.fadeFlag = false; + // Color transitions + this._rRate = 1; + this._gRate = 1; + this._bRate = 1; + this._aRate = 0; + this._currentColor = ex.Color.White.clone(); + this.emitter = null; + this.particleSize = 5; + this.particleSprite = null; + this.sizeRate = 0; + this.elapsedMultiplier = 0; + this.emitter = emitter; + this.life = life || this.life; + this.opacity = opacity || this.opacity; + this.endColor = endColor || this.endColor.clone(); + this.beginColor = beginColor || this.beginColor.clone(); + this._currentColor = this.beginColor.clone(); + this.position = position || this.position; + this.velocity = velocity || this.velocity; + this.acceleration = acceleration || this.acceleration; + this._rRate = (this.endColor.r - this.beginColor.r) / this.life; + this._gRate = (this.endColor.g - this.beginColor.g) / this.life; + this._bRate = (this.endColor.b - this.beginColor.b) / this.life; + this._aRate = this.opacity / this.life; + this.startSize = startSize || 0; + this.endSize = endSize || 0; + if ((this.endSize > 0) && (this.startSize > 0)) { + this.sizeRate = (this.endSize - this.startSize) / this.life; + this.particleSize = this.startSize; } - FallbackAudio.prototype.setVolume = function (volume) { - this._soundImpl.setVolume(volume); - }; - FallbackAudio.prototype.setLoop = function (loop) { - this._soundImpl.setLoop(loop); - }; - FallbackAudio.prototype.load = function () { - this._soundImpl.onload = this.onload; - this._soundImpl.onprogress = this.onprogress; - this._soundImpl.onerror = this.onerror; - this._soundImpl.load(); - }; - FallbackAudio.prototype.processData = function (data) { - return this._soundImpl.processData(data); - }; - FallbackAudio.prototype.getData = function () { - return this._soundImpl.getData(); - }; - FallbackAudio.prototype.setData = function (data) { - this._soundImpl.setData(data); - }; - FallbackAudio.prototype.isPlaying = function () { - return this._soundImpl.isPlaying(); - }; - FallbackAudio.prototype.play = function () { - return this._soundImpl.play(); - }; - FallbackAudio.prototype.pause = function () { - this._soundImpl.pause(); - }; - FallbackAudio.prototype.stop = function () { - this._soundImpl.stop(); - }; - return FallbackAudio; - })(); - Internal.FallbackAudio = FallbackAudio; - var AudioTag = (function () { - function AudioTag(path, volume) { - var _this = this; - this.path = path; - this._audioElements = new Array(5); - this._loadedAudio = null; - this._isLoaded = false; - this._index = 0; - this._log = ex.Logger.getInstance(); - this._isPlaying = false; - this._currentOffset = 0; - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - for (var i = 0; i < this._audioElements.length; i++) { - (function (i) { - _this._audioElements[i] = new Audio(); - })(i); - } - if (volume) { - this.setVolume(ex.Util.clamp(volume, 0, 1.0)); - } - else { - this.setVolume(1.0); - } + } + Particle.prototype.kill = function () { + this.emitter.removeParticle(this); + }; + Particle.prototype.update = function (delta) { + this.life = this.life - delta; + this.elapsedMultiplier = this.elapsedMultiplier + delta; + if (this.life < 0) { + this.kill(); } - AudioTag.prototype.isPlaying = function () { - return this._isPlaying; - }; - AudioTag.prototype._audioLoaded = function () { - this._isLoaded = true; - }; - AudioTag.prototype.setVolume = function (volume) { - var i = 0, len = this._audioElements.length; - for (i; i < len; i++) { - this._audioElements[i].volume = volume; - } - }; - AudioTag.prototype.setLoop = function (loop) { - var i = 0, len = this._audioElements.length; - for (i; i < len; i++) { - this._audioElements[i].loop = loop; - } - }; - AudioTag.prototype.getLoop = function () { - this._audioElements.some(function (a) { return a.loop; }); - }; - AudioTag.prototype.load = function () { - var _this = this; - if (!!this._loadedAudio) { - return; - } - var request = new XMLHttpRequest(); - request.open('GET', this.path, true); - request.responseType = 'blob'; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function (e) { - if (request.status !== 200) { - _this._log.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - _this._isLoaded = false; - return; - } - _this._isLoaded = true; - _this.setData(request.response); - _this.onload(e); - }; - request.send(); - }; - AudioTag.prototype.getData = function () { - return this._loadedAudio; - }; - AudioTag.prototype.setData = function (data) { - this._isLoaded = true; - this._loadedAudio = this.processData(data); - }; - AudioTag.prototype.processData = function (data) { - var blobUrl = URL.createObjectURL(data); - this._audioElements.forEach(function (a) { - a.src = blobUrl; - }); - this._audioLoaded(); - return blobUrl; - }; - AudioTag.prototype.play = function () { - var _this = this; - this._audioElements[this._index].load(); - //this.audioElements[this.index].currentTime = this._currentOffset; - this._audioElements[this._index].play(); - this._currentOffset = 0; - var done = new ex.Promise(); - this._isPlaying = true; - if (!this.getLoop()) { - this._audioElements[this._index].addEventListener('ended', function () { - _this._isPlaying = false; - done.resolve(true); - }); - } - this._index = (this._index + 1) % this._audioElements.length; - return done; - }; - AudioTag.prototype.pause = function () { - this._index = (this._index - 1 + this._audioElements.length) % this._audioElements.length; - this._currentOffset = this._audioElements[this._index].currentTime; - this._audioElements.forEach(function (a) { - a.pause(); - }); - this._isPlaying = false; - }; - AudioTag.prototype.stop = function () { - this._audioElements.forEach(function (a) { - a.pause(); - //a.currentTime = 0; - }); - this._isPlaying = false; - }; - return AudioTag; - })(); - Internal.AudioTag = AudioTag; - if (window.AudioContext) { - var audioContext = new window.AudioContext(); - } - var WebAudio = (function () { - function WebAudio(path, volume) { - this.path = path; - this._context = audioContext; - this._volume = this._context.createGain(); - this._buffer = null; - this._sound = null; - this._isLoaded = false; - this._loop = false; - this._isPlaying = false; - this._isPaused = false; - this._currentOffset = 0; - this._logger = ex.Logger.getInstance(); - this._data = null; - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - if (volume) { - this._volume.gain.value = ex.Util.clamp(volume, 0, 1.0); - } - else { - this._volume.gain.value = 1.0; // max volume - } + if (this.fadeFlag) { + this.opacity = ex.Util.clamp(this._aRate * this.life, 0.0001, 1); } - WebAudio.prototype.setVolume = function (volume) { - this._volume.gain.value = volume; - }; - WebAudio.prototype.load = function () { - var _this = this; - // Exit early if we already have data - if (this._data !== null) { - return; - } - var request = new XMLHttpRequest(); - request.open('GET', this.path); - request.responseType = 'arraybuffer'; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function () { - if (request.status !== 200) { - _this._logger.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - _this._isLoaded = false; - return; - } - _this.setData(request.response); - }; - try { - request.send(); - } - catch (e) { - console.error('Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.'); - } - }; - WebAudio.prototype.getData = function () { - return this._data; - }; - WebAudio.prototype.setData = function (data) { - this._data = this.processData(data); - }; - WebAudio.prototype.processData = function (data) { - var _this = this; - this._context.decodeAudioData(data, function (buffer) { - _this._buffer = buffer; - _this._isLoaded = true; - _this.onload(_this); - }, function (e) { - _this._logger.error('Unable to decode ' + _this.path + - ' this browser may not fully support this format, or the file may be corrupt, ' + - 'if this is an mp3 try removing id3 tags and album art from the file.'); - _this._isLoaded = false; - _this.onload(_this); - }); - return data; - }; - WebAudio.prototype.setLoop = function (loop) { - this._loop = loop; - }; - WebAudio.prototype.isPlaying = function () { - return this._isPlaying; - }; - WebAudio.prototype.play = function () { - var _this = this; - if (this._isLoaded) { - this._sound = this._context.createBufferSource(); - this._sound.buffer = this._buffer; - this._sound.loop = this._loop; - this._sound.connect(this._volume); - this._volume.connect(this._context.destination); - this._sound.start(0, this._currentOffset % this._buffer.duration); - this._currentOffset = 0; - var done; - if (!this._isPaused || !this._playPromise) { - done = new ex.Promise(); - } - else { - done = this._playPromise; - } - this._isPaused = false; - this._isPlaying = true; - if (!this._loop) { - this._sound.onended = (function () { - _this._isPlaying = false; - if (!_this._isPaused) { - done.resolve(true); - } - }).bind(this); - } - this._playPromise = done; - return done; - } - else { - return ex.Promise.wrap(true); - } - }; - WebAudio.prototype.pause = function () { - if (this._isPlaying) { - try { - window.clearTimeout(this._playingTimer); - this._sound.stop(0); - this._currentOffset = this._context.currentTime; - this._isPlaying = false; - this._isPaused = true; - } - catch (e) { - this._logger.warn('The sound clip', this.path, 'has already been paused!'); - } - } - }; - WebAudio.prototype.stop = function () { - if (this._sound) { - try { - window.clearTimeout(this._playingTimer); - this._currentOffset = 0; - this._sound.stop(0); - this._isPlaying = false; - this._isPaused = false; - } - catch (e) { - this._logger.warn('The sound clip', this.path, 'has already been stopped!'); - } - } - }; - return WebAudio; - })(); - Internal.WebAudio = WebAudio; - })(Internal = ex.Internal || (ex.Internal = {})); -})(ex || (ex = {})); -/// -// Promises/A+ Spec http://promises-aplus.github.io/promises-spec/ -var ex; -(function (ex) { - /** - * Valid states for a promise to be in - */ - (function (PromiseState) { - PromiseState[PromiseState["Resolved"] = 0] = "Resolved"; - PromiseState[PromiseState["Rejected"] = 1] = "Rejected"; - PromiseState[PromiseState["Pending"] = 2] = "Pending"; - })(ex.PromiseState || (ex.PromiseState = {})); - var PromiseState = ex.PromiseState; + if ((this.startSize > 0) && (this.endSize > 0)) { + this.particleSize = ex.Util.clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize)); + } + this._currentColor.r = ex.Util.clamp(this._currentColor.r + this._rRate * delta, 0, 255); + this._currentColor.g = ex.Util.clamp(this._currentColor.g + this._gRate * delta, 0, 255); + this._currentColor.b = ex.Util.clamp(this._currentColor.b + this._bRate * delta, 0, 255); + this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); + if (this.focus) { + var accel = this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(delta / 1000); + this.velocity = this.velocity.add(accel); + } + else { + this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000)); + } + this.position = this.position.add(this.velocity.scale(delta / 1000)); + if (this.particleRotationalVelocity) { + this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI); + } + }; + Particle.prototype.draw = function (ctx) { + if (this.particleSprite) { + this.particleSprite.rotation = this.currentRotation; + this.particleSprite.scale.setTo(this.particleSize, this.particleSize); + this.particleSprite.draw(ctx, this.position.x, this.position.y); + return; + } + this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); + ctx.fillStyle = this._currentColor.toString(); + ctx.beginPath(); + ctx.arc(this.position.x, this.position.y, this.particleSize, 0, Math.PI * 2); + ctx.fill(); + ctx.closePath(); + }; + return Particle; + })(); + ex.Particle = Particle; /** - * Promises/A+ spec implementation of promises - * - * Promises are used to do asynchronous work and they are useful for - * creating a chain of actions. In Excalibur they are used for loading, - * sounds, animation, actions, and more. + * Particle Emitters * - * ## A Promise Chain + * Using a particle emitter is a great way to create interesting effects + * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` + * extend [[Actor]] allowing you to use all of the features that come with. * - * Promises can be chained together and can be useful for creating a queue - * of functions to be called when something is done. + * The easiest way to create a `ParticleEmitter` is to use the + * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. * - * The first [[Promise]] you will encounter is probably [[Engine.start]] - * which resolves when the game has finished loading. + * ## Example: Adding an emitter * * ```js - * var game = new ex.Engine(); - * - * // perform start-up logic once game is ready - * game.start().then(function () { - * - * // start-up & initialization logic + * var actor = new ex.Actor(...); + * var emitter = new ex.ParticleEmitter(...); * - * }); - * ``` - * - * ## Handling errors - * - * You can optionally pass an error handler to [[Promise.then]] which will handle - * any errors that occur during Promise execution. + * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle + * emitter.radius = 5; + * emitter.minVel = 100; + * emitter.maxVel = 200; + * emitter.minAngle = 0; + * emitter.maxAngle = Math.PI * 2; + * emitter.emitRate = 300; // 300 particles/second + * emitter.opacity = 0.5; + * emitter.fadeFlag = true; // fade particles overtime + * emitter.particleLife = 1000; // in milliseconds = 1 sec + * emitter.maxSize = 10; // in pixels + * emitter.minSize = 1; + * emitter.particleColor = ex.Color.Rose; * - * ```js - * var game = new ex.Engine(); + * // set emitter settings + * emitter.isEmitting = true; // should the emitter be emitting * - * game.start().then( - * // success handler - * function () { - * }, + * // add the emitter as a child actor, it will draw on top of the parent actor + * // and move with the parent + * actor.add(emitter); * - * // error handler - * function (err) { - * } - * ); + * // or, alternatively, add it to the current scene + * engine.add(emitter); * ``` - * - * Any errors that go unhandled will be bubbled up to the browser. */ - var Promise = (function () { - function Promise() { - this._state = PromiseState.Pending; - this._successCallbacks = []; - this._rejectCallback = function () { return; }; - this._logger = ex.Logger.getInstance(); - } - /** - * Wrap a value in a resolved promise - * @param value An optional value to wrap in a resolved promise - */ - Promise.wrap = function (value) { - var promise = (new Promise()).resolve(value); - return promise; - }; - /** - * Returns a new promise that resolves when all the promises passed to it resolve, or rejects - * when at least 1 promise rejects. - */ - Promise.join = function () { - var promises = []; - for (var _i = 0; _i < arguments.length; _i++) { - promises[_i - 0] = arguments[_i]; - } - var joinedPromise = new Promise(); - if (!promises || !promises.length) { - return joinedPromise.resolve(); - } - var total = promises.length; - var successes = 0; - var rejects = 0; - var errors = []; - promises.forEach(function (p) { - p.then(function () { - successes += 1; - if (successes === total) { - joinedPromise.resolve(); - } - else if (successes + rejects + errors.length === total) { - joinedPromise.reject(errors); - } - }, function () { - rejects += 1; - if (successes + rejects + errors.length === total) { - joinedPromise.reject(errors); - } - }).error(function (e) { - errors.push(e); - if ((errors.length + successes + rejects) === total) { - joinedPromise.reject(errors); - } - }); - }); - return joinedPromise; - }; + var ParticleEmitter = (function (_super) { + __extends(ParticleEmitter, _super); /** - * Chain success and reject callbacks after the promise is resovled - * @param successCallback Call on resolution of promise - * @param rejectCallback Call on rejection of promise + * @param x The x position of the emitter + * @param y The y position of the emitter + * @param width The width of the emitter + * @param height The height of the emitter */ - Promise.prototype.then = function (successCallback, rejectCallback) { - if (successCallback) { - this._successCallbacks.push(successCallback); - // If the promise is already resovled call immediately - if (this.state() === PromiseState.Resolved) { - try { - successCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); - } - } - } - if (rejectCallback) { - this._rejectCallback = rejectCallback; - // If the promise is already rejected call immediately - if (this.state() === PromiseState.Rejected) { - try { - rejectCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); - } + function ParticleEmitter(x, y, width, height) { + _super.call(this, x, y, width, height, ex.Color.White); + this._particlesToEmit = 0; + this.numParticles = 0; + /** + * Gets or sets the isEmitting flag + */ + this.isEmitting = true; + /** + * Gets or sets the backing particle collection + */ + this.particles = null; + /** + * Gets or sets the backing deadParticle collection + */ + this.deadParticles = null; + /** + * Gets or sets the minimum partical velocity + */ + this.minVel = 0; + /** + * Gets or sets the maximum partical velocity + */ + this.maxVel = 0; + /** + * Gets or sets the acceleration vector for all particles + */ + this.acceleration = new ex.Vector(0, 0); + /** + * Gets or sets the minimum angle in radians + */ + this.minAngle = 0; + /** + * Gets or sets the maximum angle in radians + */ + this.maxAngle = 0; + /** + * Gets or sets the emission rate for particles (particles/sec) + */ + this.emitRate = 1; //particles/sec + /** + * Gets or sets the life of each particle in milliseconds + */ + this.particleLife = 2000; + /** + * Gets or sets the opacity of each particle from 0 to 1.0 + */ + this.opacity = 1; + /** + * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. + */ + this.fadeFlag = false; + /** + * Gets or sets the optional focus where all particles should accelerate towards + */ + this.focus = null; + /** + * Gets or sets the acceleration for focusing particles if a focus has been specified + */ + this.focusAccel = 1; + /* + * Gets or sets the optional starting size for the particles + */ + this.startSize = null; + /* + * Gets or sets the optional ending size for the particles + */ + this.endSize = null; + /** + * Gets or sets the minimum size of all particles + */ + this.minSize = 5; + /** + * Gets or sets the maximum size of all particles + */ + this.maxSize = 5; + /** + * Gets or sets the beginning color of all particles + */ + this.beginColor = ex.Color.White; + /** + * Gets or sets the ending color of all particles + */ + this.endColor = ex.Color.White; + /** + * Gets or sets the sprite that a particle should use + * @warning Performance intensive + */ + this.particleSprite = null; + /** + * Gets or sets the emitter type for the particle emitter + */ + this.emitterType = EmitterType.Rectangle; + /** + * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] + */ + this.radius = 0; + /** + * Gets or sets the particle rotational speed velocity + */ + this.particleRotationalVelocity = 0; + /** + * Indicates whether particles should start with a random rotation + */ + this.randomRotation = false; + this.collisionType = ex.CollisionType.PreventCollision; + this.particles = new ex.Util.Collection(); + this.deadParticles = new ex.Util.Collection(); + // Remove offscreen culling from particle emitters + for (var trait in this.traits) { + if (this.traits[trait] instanceof ex.Traits.OffscreenCulling) { + this.traits.splice(trait, 1); } } - return this; + } + ParticleEmitter.prototype.removeParticle = function (particle) { + this.deadParticles.push(particle); }; /** - * Add an error callback to the promise - * @param errorCallback Call if there was an error in a callback + * Causes the emitter to emit particles + * @param particleCount Number of particles to emit right now */ - Promise.prototype.error = function (errorCallback) { - if (errorCallback) { - this._errorCallback = errorCallback; + ParticleEmitter.prototype.emitParticles = function (particleCount) { + for (var i = 0; i < particleCount; i++) { + this.particles.push(this._createParticle()); } - return this; }; - /** - * Resolve the promise and pass an option value to the success callbacks - * @param value Value to pass to the success callbacks - */ - Promise.prototype.resolve = function (value) { - var _this = this; - if (this._state === PromiseState.Pending) { - this._value = value; - try { - this._state = PromiseState.Resolved; - this._successCallbacks.forEach(function (cb) { - cb.call(_this, _this._value); - }); - } - catch (e) { - this._handleError(e); - } + ParticleEmitter.prototype.clearParticles = function () { + this.particles.clear(); + }; + // Creates a new particle given the contraints of the emitter + ParticleEmitter.prototype._createParticle = function () { + // todo implement emitter contraints; + var ranX = 0; + var ranY = 0; + var angle = ex.Util.randomInRange(this.minAngle, this.maxAngle); + var vel = ex.Util.randomInRange(this.minVel, this.maxVel); + var size = this.startSize || ex.Util.randomInRange(this.minSize, this.maxSize); + var dx = vel * Math.cos(angle); + var dy = vel * Math.sin(angle); + if (this.emitterType === EmitterType.Rectangle) { + ranX = ex.Util.randomInRange(this.x, this.x + this.getWidth()); + ranY = ex.Util.randomInRange(this.y, this.y + this.getHeight()); } - else { - throw new Error('Cannot resolve a promise that is not in a pending state!'); + else if (this.emitterType === EmitterType.Circle) { + var radius = ex.Util.randomInRange(0, this.radius); + ranX = radius * Math.cos(angle) + this.x; + ranY = radius * Math.sin(angle) + this.y; } - return this; + var p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new ex.Vector(ranX, ranY), new ex.Vector(dx, dy), this.acceleration, this.startSize, this.endSize); + p.fadeFlag = this.fadeFlag; + p.particleSize = size; + if (this.particleSprite) { + p.particleSprite = this.particleSprite; + } + p.particleRotationalVelocity = this.particleRotationalVelocity; + if (this.randomRotation) { + p.currentRotation = ex.Util.randomInRange(0, Math.PI * 2); + } + if (this.focus) { + p.focus = this.focus.add(new ex.Vector(this.x, this.y)); + p.focusAccel = this.focusAccel; + } + return p; }; - /** - * Reject the promise and pass an option value to the reject callbacks - * @param value Value to pass to the reject callbacks - */ - Promise.prototype.reject = function (value) { - if (this._state === PromiseState.Pending) { - this._value = value; - try { - this._state = PromiseState.Rejected; - this._rejectCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); + ParticleEmitter.prototype.update = function (engine, delta) { + var _this = this; + _super.prototype.update.call(this, engine, delta); + if (this.isEmitting) { + this._particlesToEmit += this.emitRate * (delta / 1000); + //var numParticles = Math.ceil(this.emitRate * delta / 1000); + if (this._particlesToEmit > 1.0) { + this.emitParticles(Math.floor(this._particlesToEmit)); + this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit); } } - else { - throw new Error('Cannot reject a promise that is not in a pending state!'); - } - return this; + this.particles.forEach(function (p) { return p.update(delta); }); + this.deadParticles.forEach(function (p) { return _this.particles.removeElement(p); }); + this.deadParticles.clear(); }; - /** - * Inpect the current state of a promise - */ - Promise.prototype.state = function () { - return this._state; + ParticleEmitter.prototype.draw = function (ctx, delta) { + // todo is there a more efficient to draw + // possibly use a webgl offscreen canvas and shaders to do particles? + this.particles.forEach(function (p) { return p.draw(ctx); }); }; - Promise.prototype._handleError = function (e) { - if (this._errorCallback) { - this._errorCallback.call(this, e); - } - else { - // rethrow error - throw e; + ParticleEmitter.prototype.debugDraw = function (ctx) { + _super.prototype.debugDraw.call(this, ctx); + ctx.fillStyle = ex.Color.Black.toString(); + ctx.fillText('Particles: ' + this.particles.count(), this.x, this.y + 20); + if (this.focus) { + ctx.fillRect(this.focus.x + this.x, this.focus.y + this.y, 3, 3); + ex.Util.drawLine(ctx, 'yellow', this.focus.x + this.x, this.focus.y + this.y, _super.prototype.getCenter.call(this).x, _super.prototype.getCenter.call(this).y); + ctx.fillText('Focus', this.focus.x + this.x, this.focus.y + this.y); } }; - return Promise; - })(); - ex.Promise = Promise; + return ParticleEmitter; + })(ex.Actor); + ex.ParticleEmitter = ParticleEmitter; })(ex || (ex = {})); -/// var ex; (function (ex) { /** - * Generic Resources - * - * The [[Resource]] type allows games built in Excalibur to load generic resources. - * For any type of remote resource it is recommended to use [[Resource]] for preloading. + * Animations * - * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before - * a level or game. + * Animations allow you to display a series of images one after another, + * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. * - * Example usages: JSON, compressed files, blobs. + * ## Creating an animation * - * ## Pre-loading generic resources + * Create a [[Texture]] that contains the frames of your animation. Once the texture + * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] + * and using [[SpriteSheet.getAnimationForAll]]. * * ```js - * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); - * var loader = new ex.Loader(resLevel1); + * var game = new ex.Engine(); + * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); * - * // attach a handler to process once loaded - * resLevel1.processData = function (data) { + * // load assets + * var loader = new ex.Loader(txAnimPlayerIdle); * - * // process JSON - * var json = JSON.parse(data); + * // start game + * game.start(loader).then(function () { + * var player = new ex.Actor(); * - * // create a new level (inherits Scene) with the JSON configuration - * var level = new Level(json); + * // create sprite sheet with 5 columns, 1 row, 80x80 frames + * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); * - * // add a new scene - * game.add(level.name, level); - * } + * // create animation (125ms frame speed) + * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); * - * game.start(loader); + * // add drawing to player as "idle" + * player.addDrawing("idle", playerIdleAnimation); + * + * // add player to game + * game.add(player); + * }); * ``` + * + * ## Sprite effects + * + * You can add [[SpriteEffect|sprite effects]] to an animation through methods + * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this + * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - var Resource = (function (_super) { - __extends(Resource, _super); - /** - * @param path Path to the remote resource - * @param responseType The Content-Type to expect (e.g. `application/json`) - * @param bustCache Whether or not to cache-bust requests - */ - function Resource(path, responseType, bustCache) { - if (bustCache === void 0) { bustCache = true; } - _super.call(this); - this.path = path; - this.responseType = responseType; - this.bustCache = bustCache; - this.data = null; - this.logger = ex.Logger.getInstance(); - this.onprogress = function () { return; }; - this.oncomplete = function () { return; }; - this.onerror = function () { return; }; - } + var Animation = (function () { /** - * Returns true if the Resource is completely loaded and is ready - * to be drawn. + * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. + * + * @param engine Reference to the current game engine + * @param images An array of sprites to create the frames for the animation + * @param speed The number in milliseconds to display each frame in the animation + * @param loop Indicates whether the animation should loop after it is completed */ - Resource.prototype.isLoaded = function () { - return this.data !== null; - }; - Resource.prototype.wireEngine = function (engine) { + function Animation(engine, images, speed, loop) { + /** + * Current frame index being shown + */ + this.currentFrame = 0; + this._oldTime = Date.now(); + this.anchor = new ex.Point(0.0, 0.0); + this.rotation = 0.0; + this.scale = new ex.Point(1, 1); + /** + * Indicates whether the animation should loop after it is completed + */ + this.loop = false; + /** + * Indicates the frame index the animation should freeze on for a non-looping + * animation. By default it is the last frame. + */ + this.freezeFrame = -1; + /** + * Flip each frame vertically. Sets [[Sprite.flipVertical]]. + */ + this.flipVertical = false; + /** + * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + */ + this.flipHorizontal = false; + this.width = 0; + this.height = 0; + this.naturalWidth = 0; + this.naturalHeight = 0; + this.sprites = images; + this.speed = speed; this._engine = engine; - }; - Resource.prototype._cacheBust = function (uri) { - var query = /\?\w*=\w*/; - if (query.test(uri)) { - uri += ('&__=' + Date.now()); + if (loop != null) { + this.loop = loop; } - else { - uri += ('?__=' + Date.now()); + if (images && images[0]) { + this.height = images[0] ? images[0].height : 0; + this.width = images[0] ? images[0].width : 0; + this.naturalWidth = images[0] ? images[0].naturalWidth : 0; + this.naturalHeight = images[0] ? images[0].naturalHeight : 0; + this.freezeFrame = images.length - 1; } - return uri; + } + /** + * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + */ + Animation.prototype.opacity = function (value) { + this.addEffect(new ex.Effects.Opacity(value)); }; - Resource.prototype._start = function (e) { - this.logger.debug('Started loading resource ' + this.path); + /** + * Applies the grayscale effect to a sprite, removing color information. + */ + Animation.prototype.grayscale = function () { + this.addEffect(new ex.Effects.Grayscale()); }; /** - * Begin loading the resource and returns a promise to be resolved on completion + * Applies the invert effect to a sprite, inverting the pixel colors. */ - Resource.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - // Exit early if we already have data - if (this.data !== null) { - this.logger.debug('Already have data for resource', this.path); - complete.resolve(this.data); - this.oncomplete(); - return complete; - } - var request = new XMLHttpRequest(); - request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true); - request.responseType = this.responseType; - request.onloadstart = function (e) { _this._start(e); }; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function (e) { - if (request.status !== 200) { - _this.logger.error('Failed to load resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - complete.resolve(request.response); - return; - } - _this.data = _this.processData(request.response); - _this.oncomplete(); - _this.logger.debug('Completed loading resource', _this.path); - complete.resolve(_this.data); - }; - request.send(); - return complete; + Animation.prototype.invert = function () { + this.addEffect(new ex.Effects.Invert()); }; /** - * Returns the loaded data once the resource is loaded + * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color */ - Resource.prototype.getData = function () { - return this.data; + Animation.prototype.fill = function (color) { + this.addEffect(new ex.Effects.Fill(color)); }; /** - * Sets the data for this resource directly + * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the + * provided color. */ - Resource.prototype.setData = function (data) { - this.data = this.processData(data); + Animation.prototype.colorize = function (color) { + this.addEffect(new ex.Effects.Colorize(color)); }; /** - * This method is meant to be overriden to handle any additional - * processing. Such as decoding downloaded audio bits. + * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl */ - Resource.prototype.processData = function (data) { - // Handle any additional loading after the xhr has completed. - return URL.createObjectURL(data); + Animation.prototype.lighten = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Lighten(factor)); }; - return Resource; - })(ex.Class); - ex.Resource = Resource; -})(ex || (ex = {})); -/// -/// -/// -/// -/// -var ex; -(function (ex) { - /** - * Textures - * - * The [[Texture]] object allows games built in Excalibur to load image resources. - * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] - * to pre-load before starting a level or game. - * - * Textures are the raw image so to add a drawing to a game, you must create - * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite - * instance. - * - * ## Pre-loading textures - * - * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] - * is loaded, you can generate a [[Sprite]] with it. - * - * ```js - * var txPlayer = new ex.Texture("/assets/tx/player.png"); - * - * var loader = new ex.Loader(txPlayer); - * - * game.start(loader).then(function () { - * - * var player = new ex.Actor(); - * - * player.addDrawing(txPlayer); - * - * game.add(player); - * }); - * ``` - */ - var Texture = (function (_super) { - __extends(Texture, _super); /** - * @param path Path to the image resource - * @param bustCache Optionally load texture with cache busting + * Applies the darken effect to a sprite, changes the darkness of the color according to hsl */ - function Texture(path, bustCache) { - if (bustCache === void 0) { bustCache = true; } - _super.call(this, path, 'blob', bustCache); - this.path = path; - this.bustCache = bustCache; - /** - * A [[Promise]] that resolves when the Texture is loaded. - */ - this.loaded = new ex.Promise(); - this._isLoaded = false; - this._sprite = null; - this._sprite = new ex.Sprite(this, 0, 0, 0, 0); - } + Animation.prototype.darken = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Darken(factor)); + }; /** - * Returns true if the Texture is completely loaded and is ready - * to be drawn. + * Applies the saturate effect to a sprite, saturates the color acccording to hsl */ - Texture.prototype.isLoaded = function () { - return this._isLoaded; + Animation.prototype.saturate = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Saturate(factor)); }; /** - * Begins loading the texture and returns a promise to be resolved on completion + * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl */ - Texture.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - var loaded = _super.prototype.load.call(this); - loaded.then(function () { - _this.image = new Image(); - _this.image.addEventListener('load', function () { - _this._isLoaded = true; - _this.width = _this._sprite.swidth = _this._sprite.naturalWidth = _this._sprite.width = _this.image.naturalWidth; - _this.height = _this._sprite.sheight = _this._sprite.naturalHeight = _this._sprite.height = _this.image.naturalHeight; - _this.loaded.resolve(_this.image); - complete.resolve(_this.image); - }); - _this.image.src = _super.prototype.getData.call(_this); - }, function () { - complete.reject('Error loading texture.'); - }); - return complete; + Animation.prototype.desaturate = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Desaturate(factor)); }; - Texture.prototype.asSprite = function () { - return this._sprite; + /** + * Add a [[ISpriteEffect]] manually + */ + Animation.prototype.addEffect = function (effect) { + for (var i in this.sprites) { + this.sprites[i].addEffect(effect); + } + }; + Animation.prototype.removeEffect = function (param) { + for (var i in this.sprites) { + this.sprites[i].removeEffect(param); + } }; - return Texture; - })(ex.Resource); - ex.Texture = Texture; - /** - * Sounds - * - * The [[Sound]] object allows games built in Excalibur to load audio - * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] - * which means it can be passed to a [[Loader]] to pre-load before a game or level. - * - * ## Pre-loading sounds - * - * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] - * is loaded, you can [[Sound.play|play]] it. - * - * ```js - * // define multiple sources (such as mp3/wav/ogg) as a browser fallback - * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); - * - * var loader = new ex.Loader(sndPlayerDeath); - * - * game.start(loader).then(function () { - * - * sndPlayerDeath.play(); - * }); - * ``` - */ - var Sound = (function () { /** - * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. + * Clear all sprite effects */ - function Sound() { - var paths = []; - for (var _i = 0; _i < arguments.length; _i++) { - paths[_i - 0] = arguments[_i]; + Animation.prototype.clearEffects = function () { + for (var i in this.sprites) { + this.sprites[i].clearEffects(); } - this._logger = ex.Logger.getInstance(); - this.onprogress = function () { return; }; - this.oncomplete = function () { return; }; - this.onerror = function () { return; }; - this.onload = function () { return; }; - this._isLoaded = false; - this._wasPlayingOnHidden = false; - /* Chrome : MP3, WAV, Ogg - * Firefox : WAV, Ogg, - * IE : MP3, WAV coming soon - * Safari MP3, WAV, Ogg + }; + Animation.prototype._setAnchor = function (point) { + //if (!this.anchor.equals(point)) { + for (var i in this.sprites) { + this.sprites[i].anchor.setTo(point.x, point.y); + } + //} + }; + Animation.prototype._setRotation = function (radians) { + //if (this.rotation !== radians) { + for (var i in this.sprites) { + this.sprites[i].rotation = radians; + } + //} + }; + Animation.prototype._setScale = function (scale) { + //if (!this.scale.equals(scale)) { + for (var i in this.sprites) { + this.sprites[i].scale = scale; + } + //} + }; + /** + * Resets the animation to first frame. + */ + Animation.prototype.reset = function () { + this.currentFrame = 0; + }; + /** + * Indicates whether the animation is complete, animations that loop are never complete. + */ + Animation.prototype.isDone = function () { + return (!this.loop && this.currentFrame >= this.sprites.length); + }; + /** + * Not meant to be called by game developers. Ticks the animation forward internally and + * calculates whether to change to the frame. + * @internal + */ + Animation.prototype.tick = function () { + var time = Date.now(); + if ((time - this._oldTime) > this.speed) { + this.currentFrame = (this.loop ? (this.currentFrame + 1) % this.sprites.length : this.currentFrame + 1); + this._oldTime = time; + } + }; + Animation.prototype._updateValues = function () { + this._setAnchor(this.anchor); + this._setRotation(this.rotation); + this._setScale(this.scale); + }; + /** + * Skips ahead a specified number of frames in the animation + * @param frames Frames to skip ahead + */ + Animation.prototype.skip = function (frames) { + this.currentFrame = (this.currentFrame + frames) % this.sprites.length; + }; + Animation.prototype.draw = function (ctx, x, y) { + this.tick(); + this._updateValues(); + var currSprite; + if (this.currentFrame < this.sprites.length) { + currSprite = this.sprites[this.currentFrame]; + if (this.flipVertical) { + currSprite.flipVertical = this.flipVertical; + } + if (this.flipHorizontal) { + currSprite.flipHorizontal = this.flipHorizontal; + } + currSprite.draw(ctx, x, y); + } + if (this.freezeFrame !== -1 && this.currentFrame >= this.sprites.length) { + currSprite = this.sprites[ex.Util.clamp(this.freezeFrame, 0, this.sprites.length - 1)]; + currSprite.draw(ctx, x, y); + } + // add the calculated width + if (currSprite) { + this.width = currSprite.width; + this.height = currSprite.height; + } + }; + /** + * Plays an animation at an arbitrary location in the game. + * @param x The x position in the game to play + * @param y The y position in the game to play + */ + Animation.prototype.play = function (x, y) { + this.reset(); + this._engine.playAnimation(this, x, y); + }; + return Animation; + })(); + ex.Animation = Animation; +})(ex || (ex = {})); +/// +/// +/// +var ex; +(function (ex) { + var Internal; + (function (Internal) { + var FallbackAudio = (function () { + function FallbackAudio(path, volume) { + this.path = path; + this._log = ex.Logger.getInstance(); + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + if (window.AudioContext) { + this._log.debug('Using new Web Audio Api for ' + path); + this._soundImpl = new WebAudio(path, volume); + } + else { + this._log.debug('Falling back to Audio Element for ' + path); + this._soundImpl = new AudioTag(path, volume); + } + } + FallbackAudio.prototype.setVolume = function (volume) { + this._soundImpl.setVolume(volume); + }; + FallbackAudio.prototype.setLoop = function (loop) { + this._soundImpl.setLoop(loop); + }; + FallbackAudio.prototype.load = function () { + this._soundImpl.onload = this.onload; + this._soundImpl.onprogress = this.onprogress; + this._soundImpl.onerror = this.onerror; + this._soundImpl.load(); + }; + FallbackAudio.prototype.processData = function (data) { + return this._soundImpl.processData(data); + }; + FallbackAudio.prototype.getData = function () { + return this._soundImpl.getData(); + }; + FallbackAudio.prototype.setData = function (data) { + this._soundImpl.setData(data); + }; + FallbackAudio.prototype.isPlaying = function () { + return this._soundImpl.isPlaying(); + }; + FallbackAudio.prototype.play = function () { + return this._soundImpl.play(); + }; + FallbackAudio.prototype.pause = function () { + this._soundImpl.pause(); + }; + FallbackAudio.prototype.stop = function () { + this._soundImpl.stop(); + }; + return FallbackAudio; + })(); + Internal.FallbackAudio = FallbackAudio; + var AudioTag = (function () { + function AudioTag(path, volume) { + var _this = this; + this.path = path; + this._audioElements = new Array(5); + this._loadedAudio = null; + this._isLoaded = false; + this._index = 0; + this._log = ex.Logger.getInstance(); + this._isPlaying = false; + this._currentOffset = 0; + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + for (var i = 0; i < this._audioElements.length; i++) { + (function (i) { + _this._audioElements[i] = new Audio(); + })(i); + } + if (volume) { + this.setVolume(ex.Util.clamp(volume, 0, 1.0)); + } + else { + this.setVolume(1.0); + } + } + AudioTag.prototype.isPlaying = function () { + return this._isPlaying; + }; + AudioTag.prototype._audioLoaded = function () { + this._isLoaded = true; + }; + AudioTag.prototype.setVolume = function (volume) { + var i = 0, len = this._audioElements.length; + for (i; i < len; i++) { + this._audioElements[i].volume = volume; + } + }; + AudioTag.prototype.setLoop = function (loop) { + var i = 0, len = this._audioElements.length; + for (i; i < len; i++) { + this._audioElements[i].loop = loop; + } + }; + AudioTag.prototype.getLoop = function () { + this._audioElements.some(function (a) { return a.loop; }); + }; + AudioTag.prototype.load = function () { + var _this = this; + if (!!this._loadedAudio) { + return; + } + var request = new XMLHttpRequest(); + request.open('GET', this.path, true); + request.responseType = 'blob'; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function (e) { + if (request.status !== 200) { + _this._log.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + _this._isLoaded = false; + return; + } + _this._isLoaded = true; + _this.setData(request.response); + _this.onload(e); + }; + request.send(); + }; + AudioTag.prototype.getData = function () { + return this._loadedAudio; + }; + AudioTag.prototype.setData = function (data) { + this._isLoaded = true; + this._loadedAudio = this.processData(data); + }; + AudioTag.prototype.processData = function (data) { + var blobUrl = URL.createObjectURL(data); + this._audioElements.forEach(function (a) { + a.src = blobUrl; + }); + this._audioLoaded(); + return blobUrl; + }; + AudioTag.prototype.play = function () { + var _this = this; + this._audioElements[this._index].load(); + //this.audioElements[this.index].currentTime = this._currentOffset; + this._audioElements[this._index].play(); + this._currentOffset = 0; + var done = new ex.Promise(); + this._isPlaying = true; + if (!this.getLoop()) { + this._audioElements[this._index].addEventListener('ended', function () { + _this._isPlaying = false; + done.resolve(true); + }); + } + this._index = (this._index + 1) % this._audioElements.length; + return done; + }; + AudioTag.prototype.pause = function () { + this._index = (this._index - 1 + this._audioElements.length) % this._audioElements.length; + this._currentOffset = this._audioElements[this._index].currentTime; + this._audioElements.forEach(function (a) { + a.pause(); + }); + this._isPlaying = false; + }; + AudioTag.prototype.stop = function () { + this._audioElements.forEach(function (a) { + a.pause(); + //a.currentTime = 0; + }); + this._isPlaying = false; + }; + return AudioTag; + })(); + Internal.AudioTag = AudioTag; + if (window.AudioContext) { + var audioContext = new window.AudioContext(); + } + var WebAudio = (function () { + function WebAudio(path, volume) { + this.path = path; + this._context = audioContext; + this._volume = this._context.createGain(); + this._buffer = null; + this._sound = null; + this._isLoaded = false; + this._loop = false; + this._isPlaying = false; + this._isPaused = false; + this._currentOffset = 0; + this._logger = ex.Logger.getInstance(); + this._data = null; + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + if (volume) { + this._volume.gain.value = ex.Util.clamp(volume, 0, 1.0); + } + else { + this._volume.gain.value = 1.0; // max volume + } + } + WebAudio.prototype.setVolume = function (volume) { + this._volume.gain.value = volume; + }; + WebAudio.prototype.load = function () { + var _this = this; + // Exit early if we already have data + if (this._data !== null) { + return; + } + var request = new XMLHttpRequest(); + request.open('GET', this.path); + request.responseType = 'arraybuffer'; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function () { + if (request.status !== 200) { + _this._logger.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + _this._isLoaded = false; + return; + } + _this.setData(request.response); + }; + try { + request.send(); + } + catch (e) { + console.error('Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.'); + } + }; + WebAudio.prototype.getData = function () { + return this._data; + }; + WebAudio.prototype.setData = function (data) { + this._data = this.processData(data); + }; + WebAudio.prototype.processData = function (data) { + var _this = this; + this._context.decodeAudioData(data, function (buffer) { + _this._buffer = buffer; + _this._isLoaded = true; + _this.onload(_this); + }, function (e) { + _this._logger.error('Unable to decode ' + _this.path + + ' this browser may not fully support this format, or the file may be corrupt, ' + + 'if this is an mp3 try removing id3 tags and album art from the file.'); + _this._isLoaded = false; + _this.onload(_this); + }); + return data; + }; + WebAudio.prototype.setLoop = function (loop) { + this._loop = loop; + }; + WebAudio.prototype.isPlaying = function () { + return this._isPlaying; + }; + WebAudio.prototype.play = function () { + var _this = this; + if (this._isLoaded) { + this._sound = this._context.createBufferSource(); + this._sound.buffer = this._buffer; + this._sound.loop = this._loop; + this._sound.connect(this._volume); + this._volume.connect(this._context.destination); + this._sound.start(0, this._currentOffset % this._buffer.duration); + this._currentOffset = 0; + var done; + if (!this._isPaused || !this._playPromise) { + done = new ex.Promise(); + } + else { + done = this._playPromise; + } + this._isPaused = false; + this._isPlaying = true; + if (!this._loop) { + this._sound.onended = (function () { + _this._isPlaying = false; + if (!_this._isPaused) { + done.resolve(true); + } + }).bind(this); + } + this._playPromise = done; + return done; + } + else { + return ex.Promise.wrap(true); + } + }; + WebAudio.prototype.pause = function () { + if (this._isPlaying) { + try { + window.clearTimeout(this._playingTimer); + this._sound.stop(0); + this._currentOffset = this._context.currentTime; + this._isPlaying = false; + this._isPaused = true; + } + catch (e) { + this._logger.warn('The sound clip', this.path, 'has already been paused!'); + } + } + }; + WebAudio.prototype.stop = function () { + if (this._sound) { + try { + window.clearTimeout(this._playingTimer); + this._currentOffset = 0; + this._sound.stop(0); + this._isPlaying = false; + this._isPaused = false; + } + catch (e) { + this._logger.warn('The sound clip', this.path, 'has already been stopped!'); + } + } + }; + /** + * Play an empty sound to unlock Safari WebAudio context. Call this function + * right after a user interaction event. Typically used by [[PauseAfterLoader]] + * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/ */ - this.path = ''; - for (var i = 0; i < paths.length; i++) { - if (Sound.canPlayFile(paths[i])) { - this.path = paths[i]; - break; + WebAudio.unlock = function () { + if (this._unlocked || !audioContext) { + return; } - } - if (!this.path) { - this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); - this._logger.warn('Attempting to use', paths[0]); - this.path = paths[0]; // select the first specified - } - this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); - } - /** - * Whether or not the browser can play this file as HTML5 Audio - */ - Sound.canPlayFile = function (file) { - try { - var a = new Audio(); - var filetype = /.*\.([A-Za-z0-9]+)$/; - var type = file.match(filetype)[1]; - if (a.canPlayType('audio/' + type)) { - return true; + // create empty buffer and play it + var buffer = audioContext.createBuffer(1, 1, 22050); + var source = audioContext.createBufferSource(); + source.buffer = buffer; + source.connect(audioContext.destination); + if (source.noteOn) { + source.noteOn(0); } - { - return false; + else { + source.start(0); } - } - catch (e) { - ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); - return false; - } - }; - Sound.prototype.wireEngine = function (engine) { - var _this = this; - if (engine) { - this._engine = engine; - this._engine.on('hidden', function () { - if (engine.pauseAudioWhenHidden && _this.isPlaying()) { - _this._wasPlayingOnHidden = true; - _this.pause(); - } - }); - this._engine.on('visible', function () { - if (engine.pauseAudioWhenHidden && _this._wasPlayingOnHidden) { - _this.play(); - _this._wasPlayingOnHidden = false; + // by checking the play state after some time, we know if we're really unlocked + setTimeout(function () { + if (source.playbackState === source.PLAYING_STATE || + source.playbackState === source.FINISHED_STATE) { + this._unlocked = true; } - }); - } - }; - /** - * Sets the volume of the sound clip - * @param volume A volume value between 0-1.0 - */ - Sound.prototype.setVolume = function (volume) { - if (this.sound) { - this.sound.setVolume(volume); - } - }; - /** - * Indicates whether the clip should loop when complete - * @param loop Set the looping flag - */ - Sound.prototype.setLoop = function (loop) { - if (this.sound) { - this.sound.setLoop(loop); - } - }; - /** - * Whether or not the sound is playing right now - */ - Sound.prototype.isPlaying = function () { - if (this.sound) { - return this.sound.isPlaying(); - } - }; - /** - * Play the sound, returns a promise that resolves when the sound is done playing - */ - Sound.prototype.play = function () { - if (this.sound) { - return this.sound.play(); - } - }; - /** - * Stop the sound, and do not rewind - */ - Sound.prototype.pause = function () { - if (this.sound) { - this.sound.pause(); - } - }; - /** - * Stop the sound and rewind - */ - Sound.prototype.stop = function () { - if (this.sound) { - this.sound.stop(); - } - }; - /** - * Returns true if the sound is loaded - */ - Sound.prototype.isLoaded = function () { - return this._isLoaded; - }; - /** - * Begins loading the sound and returns a promise to be resolved on completion - */ - Sound.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - if (this.sound.getData() !== null) { - this._logger.debug('Already have data for resource', this.path); - complete.resolve(this.sound); - return complete; - } - this._logger.debug('Started loading sound', this.path); - this.sound.onprogress = this.onprogress; - this.sound.onload = function () { - _this.oncomplete(); - _this._isLoaded = true; - _this._logger.debug('Completed loading sound', _this.path); - complete.resolve(_this.sound); + }, 0); }; - this.sound.onerror = function (e) { - _this.onerror(e); - complete.resolve(e); + WebAudio.isUnlocked = function () { + return this._unlocked; }; - this.sound.load(); - return complete; - }; - Sound.prototype.getData = function () { - return this.sound.getData(); - }; - Sound.prototype.setData = function (data) { - this.sound.setData(data); - }; - Sound.prototype.processData = function (data) { - return this.sound.processData(data); - }; - return Sound; - })(); - ex.Sound = Sound; + WebAudio._unlocked = false; + return WebAudio; + })(); + Internal.WebAudio = WebAudio; + })(Internal = ex.Internal || (ex.Internal = {})); +})(ex || (ex = {})); +/// +/// +/// +/// +/// +/// +var ex; +(function (ex) { /** * Pre-loading assets * @@ -10010,11 +10057,13 @@ var ex; * }); * ``` */ - var Loader = (function () { + var Loader = (function (_super) { + __extends(Loader, _super); /** * @param loadables Optionally provide the list of resources you want to load at constructor time */ function Loader(loadables) { + _super.call(this); this._resourceList = []; this._index = 0; this._resourceCount = 0; @@ -10024,7 +10073,10 @@ var ex; this.getData = function () { return; }; this.setData = function (data) { return; }; this.processData = function (data) { return; }; - this.onprogress = function () { return; }; + this.onprogress = function (e) { + ex.Logger.getInstance().debug('[ex.Loader] Loading ' + (100 * e.loaded / e.total).toFixed(0)); + return; + }; this.oncomplete = function () { return; }; this.onerror = function () { return; }; if (loadables) { @@ -10099,7 +10151,6 @@ var ex; r.oncomplete = r.onerror = function () { me._numLoaded++; if (me._numLoaded === me._resourceCount) { - me.onprogress.call(me, { loaded: 100, total: 100 }); me.oncomplete.call(me); complete.resolve(); } @@ -10116,9 +10167,160 @@ var ex; loadNext(this._resourceList, 0); return complete; }; + /** + * Loader draw function. Draws the default Excalibur loading screen. Override to customize the drawing. + */ + Loader.prototype.draw = function (ctx, delta) { + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, this._engine.width, this._engine.height); + var y = this._engine.canvas.height / 2; + var width = this._engine.canvas.width / 3; + var x = width; + // loading image + var image = new Image(); + /* tslint:disable:max-line-length */ + // 64 bit string encoding of the excalibur logo + image.src = 'data:image/png;base64,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'; + /* tslint:enable:max-line-length */ + var imageHeight = width * 3 / 8; + var oldAntialias = this._engine.getAntialiasing(); + this._engine.setAntialiasing(true); + ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); + // loading box + ctx.strokeStyle = 'white'; + ctx.lineWidth = 2; + ctx.strokeRect(x, y, width, 20); + var progress = width * (this._numLoaded / this._resourceCount); + ctx.fillStyle = 'white'; + var margin = 5; + var progressWidth = progress - margin * 2; + var height = 20 - margin * 2; + ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); + this._engine.setAntialiasing(oldAntialias); + }; + /** + * Perform any calculations or logic in the `update` method. The default `Loader` does not + * do anything in this method so it is safe to override. + */ + Loader.prototype.update = function (engine, delta) { + // overridable update + }; return Loader; - })(); + })(ex.Class); ex.Loader = Loader; + /** + * A [[Loader]] that pauses after loading to allow user + * to proceed to play the game. Typically you will + * want to use this loader for iOS to allow sounds + * to play after loading (Apple Safari requires user + * interaction to allow sounds, even for games) + * + * **Note:** Because Loader is not part of a Scene, you must + * call `update` and `draw` manually on "child" objects. + * + * ## Implementing a Trigger + * + * The `PauseAfterLoader` requires an element to act as the trigger button + * to start the game. + * + * For example, let's create an `` tag to be our trigger and call it `tap-to-play`. + * + * ```html + * + * ``` + * + * We've put it inside a wrapper to position it properly over the game canvas. + * + * Now let's add some CSS to style it (insert into ``): + * + * ```html + * + * ``` + * + * Now we can create a `PauseAfterLoader` with a reference to our trigger button: + * + * ```ts + * var loader = new ex.PauseAfterLoader('tap-to-play', [...]); + * ``` + * + * ## Use PauseAfterLoader for iOS + * + * The primary use case for pausing before starting the game is to + * pass Apple's requirement of user interaction. The Web Audio context + * in Safari is disabled by default until user interaction. + * + * Therefore, you can use this snippet to only use PauseAfterLoader when + * iOS is detected (see [this thread](http://stackoverflow.com/questions/9038625/detect-if-device-is-ios) + * for more techniques). + * + * ```ts + * var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window).MSStream; + * var loader: ex.Loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); + * + * loader.addResource(...); + * ``` + */ + var PauseAfterLoader = (function (_super) { + __extends(PauseAfterLoader, _super); + function PauseAfterLoader(triggerElementId, loadables) { + var _this = this; + _super.call(this, loadables); + this._handleOnTrigger = function () { + if (_this._waitPromise.state() !== ex.PromiseState.Pending) { + return false; + } + // unlock Safari WebAudio context + ex.Internal.WebAudio.unlock(); + // continue to play game + _this._waitPromise.resolve(_this._loadedValue); + // hide DOM element + _this._playTrigger.style.display = 'none'; + return false; + }; + this._playTrigger = document.getElementById(triggerElementId); + this._playTrigger.addEventListener('click', this._handleOnTrigger); + } + PauseAfterLoader.prototype.load = function () { + var _this = this; + this._waitPromise = new ex.Promise(); + // wait until user indicates to proceed before finishing load + var superLoad = _super.prototype.load.call(this).then(function (value) { + _this._loaded = true; + _this._loadedValue = value; + // show element + _this._playTrigger.style.display = 'block'; + }, function (value) { + _this._waitPromise.reject(value); + }); + return this._waitPromise; + }; + return PauseAfterLoader; + })(Loader); + ex.PauseAfterLoader = PauseAfterLoader; })(ex || (ex = {})); /// var ex; @@ -11936,6 +12138,9 @@ var ex; /// /// /// +/// +/// +/// /// /// /// @@ -12259,8 +12464,6 @@ var ex; this.onFatalException = function (e) { ex.Logger.getInstance().fatal(e); }; this._isSmoothingEnabled = true; this._isLoading = false; - this._progress = 0; - this._total = 1; var width; var height; var canvasElementId; @@ -12651,6 +12854,11 @@ var ex; Engine.prototype._update = function (delta) { if (this._isLoading) { // suspend updates untill loading is finished + this._loader.update(this, delta); + // Update input listeners + this.input.keyboard.update(delta); + this.input.pointers.update(delta); + this.input.gamepads.update(delta); return; } this.emit('preupdate', new ex.PreUpdateEvent(this, delta, this)); @@ -12676,9 +12884,7 @@ var ex; var ctx = this.ctx; this.emit('predraw', new ex.PreDrawEvent(ctx, delta, this)); if (this._isLoading) { - ctx.fillStyle = 'black'; - ctx.fillRect(0, 0, this.width, this.height); - this._drawLoadingBar(ctx, this._progress, this._total); + this._loader.draw(ctx, delta); // Drawing nothing else while loading return; } @@ -12711,8 +12917,8 @@ var ex; /** * Starts the internal game loop for Excalibur after loading * any provided assets. - * @param loader Optional resources to load before starting the main loop. Some [[ILoadable]] such as a [[Loader]] collection, - * [[Sound]], or [[Texture]]. + * @param loader Optional [[ILoader]] to use to load resources. The default loader is [[Loader]], override to provide your own + * custom loader. */ Engine.prototype.start = function (loader) { if (!this._compatible) { @@ -12721,8 +12927,9 @@ var ex; } var loadingComplete; if (loader) { - loader.wireEngine(this); - loadingComplete = this.load(loader); + this._loader = loader; + this._loader.wireEngine(this); + loadingComplete = this.load(this._loader); } else { loadingComplete = ex.Promise.wrap(); @@ -12784,50 +12991,6 @@ var ex; result.src = raw; return result; }; - /** - * Draws the Excalibur loading bar - * @param ctx The canvas rendering context - * @param loaded Number of bytes loaded - * @param total Total number of bytes to load - */ - Engine.prototype._drawLoadingBar = function (ctx, loaded, total) { - if (this._loadingDraw) { - this._loadingDraw(ctx, loaded, total); - return; - } - var y = this.canvas.height / 2; - var width = this.canvas.width / 3; - var x = width; - // loading image - var image = new Image(); - /* tslint:disable:max-line-length */ - // 64 bit string encoding of the excalibur logo - image.src = 'data:image/png;base64,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'; - /* tslint:enable:max-line-length */ - var imageHeight = width * 3 / 8; - var oldAntialias = this.getAntialiasing(); - this.setAntialiasing(true); - ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); - // loading box - ctx.strokeStyle = 'white'; - ctx.lineWidth = 2; - ctx.strokeRect(x, y, width, 20); - var progress = width * (loaded / total); - ctx.fillStyle = 'white'; - var margin = 5; - var progressWidth = progress - margin * 2; - var height = 20 - margin * 2; - ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); - this.setAntialiasing(oldAntialias); - }; - /** - * Sets the loading screen draw function if you want to customize the draw - * @param fcn Callback to draw the loading screen which is passed a rendering context, the number of bytes loaded, and the total - * number of bytes to load. - */ - Engine.prototype.setLoadingDrawFunction = function (fcn) { - this._loadingDraw = fcn; - }; /** * Another option available to you to load resources into the game. * Immediately after calling this the game will pause and the loading screen @@ -12838,18 +13001,12 @@ var ex; var _this = this; var complete = new ex.Promise(); this._isLoading = true; - loader.onprogress = function (e) { - _this._progress = e.loaded; - _this._total = e.total; - _this._logger.debug('Loading ' + (100 * _this._progress / _this._total).toFixed(0)); - }; - loader.oncomplete = function () { + loader.load().then(function () { setTimeout(function () { _this._isLoading = false; complete.resolve(); }, 500); - }; - loader.load(); + }); return complete; }; return Engine; diff --git a/dist/excalibur-0.6.0.min.js b/dist/excalibur-0.6.0.min.js index 7c48eb354..4ef3804d0 100644 --- a/dist/excalibur-0.6.0.min.js +++ b/dist/excalibur-0.6.0.min.js @@ -4,9 +4,8 @@ "undefined"==typeof window&&(window={audioContext:function(){}}),"undefined"==typeof window||window.requestAnimationFrame||(window.requestAnimationFrame=window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||function(t){window.setInterval(t,1e3/60)}),"undefined"==typeof window||window.cancelAnimationFrame||(window.cancelAnimationFrame=window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||function(){}),"undefined"==typeof window||window.AudioContext||(window.AudioContext=window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){var i,n;if(null==this)throw new TypeError(" this is null or not defined");var s=Object(this),o=s.length>>>0;if("function"!=typeof t)throw new TypeError(t+" is not a function");for(arguments.length>1&&(i=e),n=0;o>n;){var r;n in s&&(r=s[n],t.call(i,r,n,s)),n++}}),Array.prototype.some||(Array.prototype.some=function(t){"use strict";if(void 0===this||null===this)throw new TypeError;var e=Object(this),i=e.length>>>0;if("function"!=typeof t)throw new TypeError;for(var n=arguments.length>=2?arguments[1]:void 0,s=0;i>s;s++)if(s in e&&t.call(n,e[s],s,e))return!0;return!1}),Function.prototype.bind||(Function.prototype.bind=function(t){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var e=Array.prototype.slice.call(arguments,1),i=this,n=function(){},s=function(){return i.apply(this instanceof n&&t?this:t,e.concat(Array.prototype.slice.call(arguments)))};return n.prototype=this.prototype,s.prototype=new n,s});var ex;(function(t){var e;(function(e){var i=function(){function t(){}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data,o=(s[n+0]+s[n+1]+s[n+2])/3;s[n+0]=o,s[n+1]=o,s[n+2]=o},t}();e.Grayscale=i;var n=function(){function t(){}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;s[n+0]=255-s[n+0],s[n+1]=255-s[n+1],s[n+2]=255-s[n+2]},t}();e.Invert=n;var s=function(){function t(t){this.opacity=t}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;0!==s[n+3]&&(s[n+3]=Math.round(255*this.opacity))},t}();e.Opacity=s;var o=function(){function t(t){this.color=t}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;0!==s[n+3]&&(s[n+0]=(s[n+0]+this.color.r)/2,s[n+1]=(s[n+1]+this.color.g)/2,s[n+2]=(s[n+2]+this.color.b)/2)},t}();e.Colorize=o;var r=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).lighten(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Lighten=r;var h=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).darken(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Darken=h;var a=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).saturate(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Saturate=a;var c=function(){function e(t){void 0===t&&(t=.1),this.factor=t}return e.prototype.updatePixel=function(e,i,n){var s=4*(e+i*n.width),o=n.data,r=t.Color.fromRGB(o[s+0],o[s+1],o[s+2],o[s+3]).desaturate(this.factor);o[s+0]=r.r,o[s+1]=r.g,o[s+2]=r.b,o[s+3]=r.a},e}();e.Desaturate=c;var u=function(){function t(t){this.color=t}return t.prototype.updatePixel=function(t,e,i){var n=4*(t+e*i.width),s=i.data;0!==s[n+3]&&(s[n+0]=this.color.r,s[n+1]=this.color.g,s[n+2]=this.color.b)},t}();e.Fill=u})(e=t.Effects||(t.Effects={}))})(ex||(ex={}));var ex;(function(t){var e;(function(t){var e=function(){function t(){}return t.prototype.update=function(t,e,i){t.x+=t.dx*i/1e3,t.y+=t.dy*i/1e3,t.dx+=t.ax*i/1e3,t.dy+=t.ay*i/1e3,t.rotation+=t.rx*i/1e3,t.scale.x+=t.sx*i/1e3,t.scale.y+=t.sy*i/1e3},t}();t.Movement=e})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this._topLeft=new t.Point(0,0),this._topRight=new t.Point(0,0),this._bottomLeft=new t.Point(0,0),this._bottomRight=new t.Point(0,0)}return e.prototype.isSpriteOffScreen=function(e,i){var n=e.currentDrawing.width*e.currentDrawing.scale.x,s=e.currentDrawing.height*e.currentDrawing.scale.y,o=e.rotation,r=e.getCenter().toPoint();this._topLeft.x=e.getWorldX()-n/2,this._topLeft.y=e.getWorldY()-s/2,this._topLeft=this._topLeft.rotate(o,r),this._topRight.x=e.getWorldX()+n/2,this._topRight.y=e.getWorldY()-s/2,this._topRight=this._topRight.rotate(o,r),this._bottomLeft.x=e.getWorldX()-n/2,this._bottomLeft.y=e.getWorldY()+s/2,this._bottomLeft=this._bottomLeft.rotate(o,r),this._bottomRight.x=e.getWorldX()+n/2,this._bottomRight.y=e.getWorldY()+s/2,this._bottomRight=this._bottomRight.rotate(o,r);var h=i.worldToScreenCoordinates(this._topLeft),a=i.worldToScreenCoordinates(this._topRight),c=i.worldToScreenCoordinates(this._bottomLeft),u=i.worldToScreenCoordinates(this._bottomRight);this._xCoords=[],this._yCoords=[],this._xCoords.push(h.x,a.x,c.x,u.x),this._yCoords.push(h.y,a.y,c.y,u.y),this._xMin=Math.min.apply(null,this._xCoords),this._yMin=Math.min.apply(null,this._yCoords),this._xMax=Math.max.apply(null,this._xCoords),this._yMax=Math.max.apply(null,this._yCoords);var l=i.screenToWorldCoordinates(new t.Point(this._xMin,this._yMin)),p=i.screenToWorldCoordinates(new t.Point(this._xMax,this._yMax));this._xMinWorld=l.x,this._yMinWorld=l.y,this._xMaxWorld=p.x,this._yMaxWorld=p.y;var d=[];d.push(new t.Point(this._xMin,this._yMin),new t.Point(this._xMax,this._yMin),new t.Point(this._xMin,this._yMax),new t.Point(this._xMax,this._yMax));for(var f=0;d.length>f;f++)if(d[f].x>0&&d[f].y>0&&d[f].x0&&a.y+h*c>0&&a.xa.x+r*c||0>a.y+h*c||a.x>i.width||a.y>i.height)&&u&&(n.emit("exitviewport",new t.ExitViewPortEvent),e.isOffScreen=!0)},e}();e.OffscreenCulling=i})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){var e;(function(t){var e=function(){function t(){}return t.prototype.update=function(t,e){t.enableCapturePointer&&(t.isKilled()||e.input.pointers.propogate(t))},t}();t.CapturePointer=e})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(){function e(){}return e.prototype.update=function(e,i){var n=e.eventDispatcher;if(e.collisionType!==t.CollisionType.PreventCollision&&i.currentScene&&i.currentScene.tileMaps)for(var s=0;i.currentScene.tileMaps.length>s;s++)for(var o,r=i.currentScene.tileMaps[s],h=t.Side.None,a=2,c=!1;(o=r.collides(e))&&!(0>a--);)h=e.getSideFromIntersect(o),n.emit("collision",new t.CollisionEvent(e,null,h,o)),(e.collisionType===t.CollisionType.Active||e.collisionType===t.CollisionType.Elastic)&&(e.y+=o.y,e.x+=o.x,e.collisionType!==t.CollisionType.Elastic||c||(c=!0,h===t.Side.Left?e.dx=Math.abs(e.dx):h===t.Side.Right?e.dx=-Math.abs(e.dx):h===t.Side.Top?e.dy=Math.abs(e.dy):h===t.Side.Bottom&&(e.dy=-Math.abs(e.dy))))},e}();e.CollisionDetection=i})(e=t.Traits||(t.Traits={}))})(ex||(ex={}));var ex;(function(t){(function(t){t[t.None=0]="None",t[t.Top=1]="Top",t[t.Bottom=2]="Bottom",t[t.Left=3]="Left",t[t.Right=4]="Right"})(t.Side||(t.Side={})),t.Side})(ex||(ex={}));var __extends=this&&this.__extends||function(t,e){function i(){this.constructor=t}for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);t.prototype=null===e?Object.create(e):(i.prototype=e.prototype,new i)},ex;(function(t){var e=function(){function e(t,e){this.x=t,this.y=e}return e.prototype.toVector=function(){return new i(this.x,this.y)},e.prototype.rotate=function(i,n){n||(n=new t.Point(0,0));var s=Math.sin(i),o=Math.cos(i),r=o*(this.x-n.x)-s*(this.y-n.y)+n.x,h=s*(this.x-n.x)+o*(this.y-n.y)+n.y;return new e(r,h)},e.prototype.add=function(t){return new e(this.x+t.x,this.y+t.y)},e.prototype.setTo=function(t,e){this.x=t,this.y=e},e.prototype.clone=function(){return new e(this.x,this.y)},e.prototype.equals=function(t){return this.x===t.x&&this.y===t.y},e}();t.Point=e;var i=function(t){function i(e,i){t.call(this,e,i),this.x=e,this.y=i}return __extends(i,t),i.fromAngle=function(t){return new i(Math.cos(t),Math.sin(t))},i.prototype.distance=function(t){return t||(t=new i(0,0)),Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},i.prototype.normalize=function(){var t=this.distance();return t>0?new i(this.x/t,this.y/t):new i(0,1)},i.prototype.scale=function(t){return new i(this.x*t,this.y*t)},i.prototype.plus=function(t){return this.add(t)},i.prototype.add=function(t){return new i(this.x+t.x,this.y+t.y)},i.prototype.subtract=function(t){return this.minus(t)},i.prototype.minus=function(t){return new i(this.x-t.x,this.y-t.y)},i.prototype.dot=function(t){return this.x*t.x+this.y*t.y},i.prototype.cross=function(t){return this.x*t.y-this.y*t.x},i.prototype.perpendicular=function(){return new i(this.y,-this.x)},i.prototype.normal=function(){return this.perpendicular().normalize()},i.prototype.toAngle=function(){return Math.atan2(this.y,this.x)},i.prototype.toPoint=function(){return new e(this.x,this.y)},i.prototype.rotate=function(e,i){return t.prototype.rotate.call(this,e,i).toVector()},i.prototype.clone=function(){return new i(this.x,this.y)},i.Zero=new i(0,0),i}(e);t.Vector=i;var n=function(){function t(t,e){this.pos=t,this.dir=e.normalize()}return t.prototype.intersect=function(t){var e=t.begin.toVector().minus(this.pos.toVector());if(0===this.dir.cross(t.getSlope())&&0!==e.cross(this.dir))return-1;var i=this.dir.cross(t.getSlope());if(0===i)return-1;var n=e.cross(t.getSlope())/i;if(n>=0){var s=e.cross(this.dir)/i/t.getLength();if(s>=0&&1>=s)return n}return-1},t.prototype.getPoint=function(t){return this.pos.toVector().add(this.dir.scale(t)).toPoint()},t}();t.Ray=n;var s=function(){function t(t,e){this.begin=t,this.end=e}return t.prototype.getSlope=function(){var t=this.begin.toVector(),e=this.end.toVector(),i=t.distance(e);return e.minus(t).scale(1/i)},t.prototype.getLength=function(){var t=this.begin.toVector(),e=this.end.toVector(),i=t.distance(e);return i},t}();t.Line=s;var o=function(){function t(t,e){this.min=t,this.max=e}return t.prototype.overlaps=function(t){return this.max>t.min&&t.max>this.min},t.prototype.getOverlap=function(t){return this.overlaps(t)?this.max>t.max?t.max-this.min:this.max-t.min:0},t}();t.Projection=o})(ex||(ex={}));var ex;(function(t){var e;(function(e){function i(t){for(var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",i="",n=0;t.length>n;){var s,o,r=255&t.charCodeAt(n++),h=255&t.charCodeAt(n++),a=255&t.charCodeAt(n++),c=r>>2,u=(3&r)<<4|h>>4;isNaN(h)?s=o=64:(s=(15&h)<<2|a>>6,o=isNaN(a)?64:63&a),i+=e.charAt(c)+e.charAt(u)+e.charAt(s)+e.charAt(o)}return i}function n(t,e,i){return e>=t?e:t>=i?i:t}function s(t,e,i,n,s,o){t.beginPath(),t.strokeStyle=e,t.moveTo(i,n),t.lineTo(s,o),t.closePath(),t.stroke()}function o(t,e){return t+Math.random()*(e-t)}function r(t,e){return Math.round(o(t,e))}function h(t){var e=t;if(t>this.TwoPI)for(;e>this.TwoPI;)e-=this.TwoPI;if(0>t)for(;0>e;)e+=this.TwoPI;return e}function a(t){return 180/Math.PI*t}function c(t){return t/180*Math.PI}function u(e){var i=0,n=0,s=function(t){i+=t.offsetLeft,t.offsetParent&&s(t.offsetParent)},o=function(t){n+=t.offsetTop,t.offsetParent&&o(t.offsetParent)};return s(e),o(e),new t.Point(i,n)}function l(t,e){return-1===e.indexOf(t)?(e.push(t),!0):!1}function p(t,e){var i=-1;return(i=e.indexOf(t))>-1?(e.splice(i,1),!0):!1}function d(t,e){for(var i=0;t.length>i;i++)if(t[i]===e)return!0;return!1}function f(e){return e===t.Side.Top?t.Side.Bottom:e===t.Side.Bottom?t.Side.Top:e===t.Side.Left?t.Side.Right:e===t.Side.Right?t.Side.Left:t.Side.None}e.TwoPI=2*Math.PI,e.base64Encode=i,e.clamp=n,e.drawLine=s,e.randomInRange=o,e.randomIntInRange=r,e.canonicalizeAngle=h,e.toDegrees=a,e.toRadians=c,e.getPosition=u,e.addItemToArray=l,e.removeItemToArray=p,e.contains=d,e.getOppositeSide=f;var g=function(){function t(e){void 0===e&&(e=t.DefaultSize),this._internalArray=null,this._endPointer=0,this._internalArray=Array(e)}return t.prototype._resize=function(){for(var t=2*this._internalArray.length,e=Array(t),i=this.count(),n=0;i>n;n++)e[n]=this._internalArray[n];delete this._internalArray,this._internalArray=e},t.prototype.push=function(t){return this._endPointer===this._internalArray.length&&this._resize(),this._internalArray[this._endPointer++]=t},t.prototype.pop=function(){return this._endPointer=0>this._endPointer-1?0:this._endPointer-1,this._internalArray[this._endPointer]},t.prototype.count=function(){return this._endPointer},t.prototype.clear=function(){this._endPointer=0},t.prototype.internalSize=function(){return this._internalArray.length},t.prototype.elementAt=function(t){return t>=this.count()?void 0:this._internalArray[t]},t.prototype.insert=function(t,e){return t>=this.count()&&this._resize(),this._internalArray[t]=e},t.prototype.remove=function(t){var e=this.count();if(0!==e){for(var i=this._internalArray[t],n=t;e>n;n++)this._internalArray[n]=this._internalArray[n+1];return this._endPointer--,i}},t.prototype.removeElement=function(t){var e=this._internalArray.indexOf(t);this.remove(e)},t.prototype.toArray=function(){return this._internalArray.slice(0,this._endPointer)},t.prototype.forEach=function(t){var e=0,i=this.count();for(e;i>e;e++)t.call(this,this._internalArray[e],e)},t.prototype.map=function(t){for(var e=this.count(),i=0;e>i;i++)this._internalArray[i]=t.call(this,this._internalArray[i],i)},t.DefaultSize=200,t}();e.Collection=g})(e=t.Util||(t.Util={}))})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s,o){var r=this;this.sx=i,this.sy=n,this.swidth=s,this.sheight=o,this.rotation=0,this.anchor=new t.Point(0,0),this.scale=new t.Point(1,1),this.logger=t.Logger.getInstance(),this.flipVertical=!1,this.flipHorizontal=!1,this.width=0,this.height=0,this.effects=[],this.internalImage=new Image,this.naturalWidth=0,this.naturalHeight=0,this._spriteCanvas=null,this._spriteCtx=null,this._pixelData=null,this._pixelsLoaded=!1,this._dirtyEffect=!1,(0>i||0>n||0>s||0>o)&&this.logger.error("Sprite cannot have any negative dimensions x:",i,"y:",n,"width:",s,"height:",o),this._texture=e,this._spriteCanvas=document.createElement("canvas"),this._spriteCanvas.width=s,this._spriteCanvas.height=o,this._spriteCtx=this._spriteCanvas.getContext("2d"),this._texture.loaded.then(function(){r._spriteCanvas.width=r._spriteCanvas.width||r._texture.image.naturalWidth,r._spriteCanvas.height=r._spriteCanvas.height||r._texture.image.naturalHeight,r._loadPixels(),r._dirtyEffect=!0}).error(function(t){r.logger.error("Error loading texture ",r._texture.path,t)}),this.width=s,this.height=o,this.naturalWidth=s,this.naturalHeight=o}return e.prototype._loadPixels=function(){if(this._texture.isLoaded()&&!this._pixelsLoaded){var e=t.Util.clamp,i=this._texture.image.naturalWidth||0,n=this._texture.image.naturalHeight||0;this.swidth>i&&this.logger.warn("The sprite width",this.swidth,"exceeds the width",i,"of the backing texture",this._texture.path),this.sheight>n&&this.logger.warn("The sprite height",this.sheight,"exceeds the height",n,"of the backing texture",this._texture.path),this._spriteCtx.drawImage(this._texture.image,e(this.sx,0,i),e(this.sy,0,n),e(this.swidth,0,i),e(this.sheight,0,n),0,0,this.swidth,this.sheight),this.internalImage.src=this._spriteCanvas.toDataURL("image/png"),this._pixelsLoaded=!0}},e.prototype.opacity=function(e){this.addEffect(new t.Effects.Opacity(e))},e.prototype.grayscale=function(){this.addEffect(new t.Effects.Grayscale)},e.prototype.invert=function(){this.addEffect(new t.Effects.Invert)},e.prototype.fill=function(e){this.addEffect(new t.Effects.Fill(e))},e.prototype.colorize=function(e){this.addEffect(new t.Effects.Colorize(e))},e.prototype.lighten=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Lighten(e))},e.prototype.darken=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Darken(e))},e.prototype.saturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Saturate(e))},e.prototype.desaturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Desaturate(e))},e.prototype.addEffect=function(t){this.effects.push(t),this._texture.isLoaded()&&this._pixelsLoaded?this._applyEffects():this._dirtyEffect=!0},e.prototype.removeEffect=function(t){var e=null;e="number"==typeof t?t:this.effects.indexOf(t),this.effects.splice(e,1),this._texture.isLoaded()&&this._pixelsLoaded?this._applyEffects():this._dirtyEffect=!0},e.prototype._applyEffects=function(){var e=t.Util.clamp,i=this._texture.image.naturalWidth||0,n=this._texture.image.naturalHeight||0;this._spriteCtx.clearRect(0,0,this.swidth,this.sheight),this._spriteCtx.drawImage(this._texture.image,e(this.sx,0,i),e(this.sy,0,n),e(this.swidth,0,i),e(this.sheight,0,n),0,0,this.swidth,this.sheight),this._pixelData=this._spriteCtx.getImageData(0,0,this.swidth,this.sheight);var s=0,o=0,r=0,h=this.effects.length;for(s;h>s;s++)for(r=0;this.sheight>r;r++)for(o=0;this.swidth>o;o++)this.effects[s].updatePixel(o,r,this._pixelData);this._spriteCtx.clearRect(0,0,this.swidth,this.sheight),this._spriteCtx.putImageData(this._pixelData,0,0),this.internalImage.src=this._spriteCanvas.toDataURL("image/png")},e.prototype.clearEffects=function(){this.effects.length=0,this._applyEffects()},e.prototype.reset=function(){},e.prototype.debugDraw=function(e,i,n){e.save(),e.translate(i,n),e.rotate(this.rotation);var s=this.width*this.scale.x*this.anchor.x,o=this.height*this.scale.y*this.anchor.y;e.strokeStyle=t.Color.Black,e.strokeRect(-s,-o,this.width*this.scale.x,this.height*this.scale.y),e.restore()},e.prototype.draw=function(t,e,i){this._dirtyEffect&&(this._applyEffects(),this._dirtyEffect=!1),this.width=this.naturalWidth*this.scale.x,this.height=this.naturalHeight*this.scale.y,t.save();var n=this.width*this.anchor.x,s=this.height*this.anchor.y;t.translate(e,i),t.rotate(this.rotation),this.flipHorizontal&&(t.translate(this.swidth*this.scale.x,0),t.scale(-1,1)),this.flipVertical&&(t.translate(0,this.sheight*this.scale.y),t.scale(1,-1)),this.internalImage&&t.drawImage(this.internalImage,0,0,this.swidth,this.sheight,-n,-s,this.swidth*this.scale.x,this.sheight*this.scale.y),t.restore()},e.prototype.clone=function(){var t=new e(this._texture,this.sx,this.sy,this.swidth,this.sheight);t.scale=this.scale.clone(),t.rotation=this.rotation,t.flipHorizontal=this.flipHorizontal,t.flipVertical=this.flipVertical;var i=0,n=this.effects.length;for(i;n>i;i++)t.addEffect(this.effects[i]);return t},e}();t.Sprite=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s,o){this.image=e,this.columns=i,this.rows=n,this.sprites=[],this._internalImage=e.image,this.sprites=Array(i*n);var r=0,h=0;for(r=0;n>r;r++)for(h=0;i>h;h++)this.sprites[h+r*i]=new t.Sprite(this.image,h*s,r*o,s,o)}return e.prototype.getAnimationByIndices=function(e,i,n){var s=this,o=i.map(function(t){return s.sprites[t]});return o=o.map(function(t){return t.clone()}),new t.Animation(e,o,n)},e.prototype.getAnimationBetween=function(e,i,n,s){var o=this.sprites.slice(i,n);return o=o.map(function(t){return t.clone()}),new t.Animation(e,o,s)},e.prototype.getAnimationForAll=function(e,i){var n=this.sprites.map(function(t){return t.clone()});return new t.Animation(e,n,i)},e.prototype.getSprite=function(t){return t>=0&&this.sprites.length>t?this.sprites[t]:void 0},e}();t.SpriteSheet=e;var i=function(e){function i(i,n,s,o,r,h,a){e.call(this,i,o,r,h,a),this.image=i,this.alphabet=n,this.caseInsensitive=s,this.spWidth=h,this.spHeight=a,this._spriteLookup={},this._colorLookup={},this._currentColor=t.Color.Black.clone(),this._currentOpacity=1,this._sprites={},this._textShadowOn=!1,this._textShadowDirty=!0,this._textShadowColor=t.Color.Black.clone(),this._textShadowSprites={},this._shadowOffsetX=5,this._shadowOffsetY=5,this._sprites=this.getTextSprites()}return __extends(i,e),i.prototype.getTextSprites=function(){for(var t={},e=0;this.alphabet.length>e;e++){var i=this.alphabet[e];this.caseInsensitive&&(i=i.toLowerCase()),t[i]=this.sprites[e].clone()}return t},i.prototype.setTextShadow=function(t,e,i){this._textShadowOn=!0,this._shadowOffsetX=t,this._shadowOffsetY=e,this._textShadowColor=i.clone(),this._textShadowDirty=!0;for(var n in this._sprites)this._textShadowSprites[n]=this._sprites[n].clone()},i.prototype.useTextShadow=function(t){this._textShadowOn=t,t&&this.setTextShadow(5,5,this._textShadowColor)},i.prototype.draw=function(e,i,n,s,o){if(o=this._parseOptions(o),""+this._currentColor!=""+o.color||this._currentOpacity!==o.opacity){this._currentOpacity=o.opacity,this._currentColor=o.color;for(var r in this._sprites)this._sprites[r].clearEffects(),this._sprites[r].fill(o.color),this._sprites[r].opacity(o.opacity)}if(this._textShadowOn&&this._textShadowDirty&&this._textShadowColor){for(var h in this._textShadowSprites)this._textShadowSprites[h].clearEffects(),this._textShadowSprites[h].addEffect(new t.Effects.Fill(this._textShadowColor.clone()));this._textShadowDirty=!1}var a=this.sprites[0],c=a.sheight,u=o.fontSize/c,l=i.length*a.swidth*u+i.length*o.letterSpacing,p=n;o.textAlign===t.TextAlign.Left||o.textAlign===t.TextAlign.Start?p=n:o.textAlign===t.TextAlign.Right||o.textAlign===t.TextAlign.End?p=n-l:o.textAlign===t.TextAlign.Center&&(p=n-l/2);var d=s-c*u;o.baseAlign===t.BaseAlign.Top||o.baseAlign===t.BaseAlign.Hanging?d=s:o.baseAlign===t.BaseAlign.Ideographic||o.baseAlign===t.BaseAlign.Bottom||o.baseAlign===t.BaseAlign.Alphabetic?d=s-c*u:o.baseAlign===t.BaseAlign.Middle&&(d=s-c*u/2);for(var f=0;i.length>f;f++){var g=i[f];this.caseInsensitive&&(g=g.toLowerCase());try{this._textShadowOn&&(this._textShadowSprites[g].scale.x=u,this._textShadowSprites[g].scale.y=u,this._textShadowSprites[g].draw(e,p+this._shadowOffsetX,d+this._shadowOffsetY));var _=this._sprites[g];_.scale.x=u,_.scale.y=u,_.draw(e,p,d),p+=_.width+o.letterSpacing}catch(y){t.Logger.getInstance().error("SpriteFont Error drawing char "+g)}}},i.prototype._parseOptions=function(e){return{fontSize:e.fontSize||10,letterSpacing:e.letterSpacing||0,color:e.color||t.Color.Black.clone(),textAlign:void 0===typeof e.textAlign?t.TextAlign.Left:e.textAlign,baseAlign:void 0===typeof e.baseAlign?t.BaseAlign.Bottom:e.baseAlign,maxWidth:e.maxWidth||-1,opacity:e.opacity||0}},i}(e);t.SpriteFont=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,s,o,r,h){var a=this;this.x=e,this.y=i,this.cellWidth=s,this.cellHeight=o,this.rows=r,this.cols=h,this._collidingX=-1,this._collidingY=-1,this._onScreenXStart=0,this._onScreenXEnd=9999,this._onScreenYStart=0,this._onScreenYEnd=9999,this._spriteSheets={},this.logger=t.Logger.getInstance(),this.data=[],this.data=Array(r*h);for(var c=0;h>c;c++)for(var u=0;r>u;u++)(function(){var t=new n(c*s+e,u*o+i,s,o,c+u*h);a.data[c+u*h]=t})()}return e.prototype.registerSpriteSheet=function(t,e){this._spriteSheets[t]=e},e.prototype.collides=function(e){for(var i=e.x+e.getWidth(),n=e.y+e.getHeight(),s=e.getBounds(),o=[],r=s.left;i>=r;r+=Math.min(e.getWidth()/2,this.cellWidth/2))for(var h=s.top;n>=h;h+=Math.min(e.getHeight()/2,this.cellHeight/2)){var a=this.getCellByPoint(r,h);if(a&&a.solid){var c=s.collides(a.getBounds()),u=e.getCenter().minus(a.getCenter());c&&c.dot(u)>0&&o.push(c)}}if(0===o.length)return null;var l=o.reduce(function(e,i){var n=e.x,s=e.y;return Math.abs(e.x)t||0>e||t>=this.cols||e>=this.rows?null:this.data[t+e*this.cols]},e.prototype.getCellByPoint=function(t,e){t=Math.floor((t-this.x)/this.cellWidth),e=Math.floor((e-this.y)/this.cellHeight);var i=this.getCell(t,e);return t>=0&&e>=0&&this.cols>t&&this.rows>e&&i?i:null},e.prototype.update=function(e){var i=e.screenToWorldCoordinates(new t.Point(0,0)),n=e.screenToWorldCoordinates(new t.Point(e.canvas.clientWidth,e.canvas.clientHeight));this._onScreenXStart=Math.max(Math.floor(i.x/this.cellWidth)-2,0),this._onScreenYStart=Math.max(Math.floor((i.y-this.y)/this.cellHeight)-2,0),this._onScreenXEnd=Math.max(Math.floor(n.x/this.cellWidth)+2,0),this._onScreenYEnd=Math.max(Math.floor((n.y-this.y)/this.cellHeight)+2,0)},e.prototype.draw=function(t){t.save(),t.translate(this.x,this.y);var e,i,n,s=this._onScreenXStart,o=Math.min(this._onScreenXEnd,this.cols),r=this._onScreenYStart,h=Math.min(this._onScreenYEnd,this.rows);for(s;o>s;s++){for(r;h>r;r++)for(e=this.getCell(s,r).sprites.filter(function(t){return t.spriteId>-1}),i=0,n=e.length;n>i;i++){var a=this._spriteSheets[e[i].spriteSheetKey];if(a){var c=a.getSprite(e[i].spriteId);c?c.draw(t,s*this.cellWidth,r*this.cellHeight):this.logger.warn("Sprite does not exist for id",e[i].spriteId,"in sprite sheet",e[i].spriteSheetKey,c,a)}else this.logger.warn("Sprite sheet",e[i].spriteSheetKey,"does not exist",a)}r=this._onScreenYStart}t.restore()},e.prototype.debugDraw=function(e){var i=this.cols*this.cellWidth,n=this.rows*this.cellHeight;e.save(),e.strokeStyle=""+t.Color.Red;for(var s=0;this.cols+1>s;s++)e.beginPath(),e.moveTo(this.x+s*this.cellWidth,this.y),e.lineTo(this.x+s*this.cellWidth,this.y+n),e.stroke();for(var o=0;this.rows+1>o;o++)e.beginPath(),e.moveTo(this.x,this.y+o*this.cellHeight),e.lineTo(this.x+i,this.y+o*this.cellHeight),e.stroke();var r=t.Color.Red.clone();r.a=.3,this.data.filter(function(t){return t.solid}).forEach(function(t){e.fillStyle=""+r,e.fillRect(t.x,t.y,t.width,t.height)}),this._collidingY>-1&&this._collidingX>-1&&(e.fillStyle=""+t.Color.Cyan,e.fillRect(this.x+this._collidingX*this.cellWidth,this.y+this._collidingY*this.cellHeight,this.cellWidth,this.cellHeight)),e.restore()},e}();t.TileMap=e;var i=function(){function t(t,e){this.spriteSheetKey=t,this.spriteId=e}return t}();t.TileSprite=i;var n=function(){function e(e,i,n,s,o,r,h){void 0===r&&(r=!1),void 0===h&&(h=[]),this.x=e,this.y=i,this.width=n,this.height=s,this.index=o,this.solid=r,this.sprites=h,this._bounds=new t.BoundingBox(this.x,this.y,this.x+this.width,this.y+this.height)}return e.prototype.getBounds=function(){return this._bounds},e.prototype.getCenter=function(){return new t.Vector(this.x+this.width/2,this.y+this.height/2)},e.prototype.pushSprite=function(t){this.sprites.push(t)},e.prototype.removeSprite=function(t){var e=-1;(e=this.sprites.indexOf(t))>-1&&this.sprites.splice(e,1)},e.prototype.clearSprites=function(){this.sprites.length=0},e}();t.Cell=n})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Naive=0]="Naive",t[t.DynamicAABBTree=1]="DynamicAABBTree",t[t.SeparatingAxis=2]="SeparatingAxis"})(t.CollisionStrategy||(t.CollisionStrategy={})),t.CollisionStrategy;var e=function(){function e(t,e,i,n){void 0===t&&(t=0),void 0===e&&(e=0),void 0===i&&(i=0),void 0===n&&(n=0),this.left=t,this.top=e,this.right=i,this.bottom=n}return e.prototype.getWidth=function(){return this.right-this.left},e.prototype.getHeight=function(){return this.bottom-this.top},e.prototype.getPerimeter=function(){var t=this.getWidth(),e=this.getHeight();return 2*(t+e)},e.prototype.contains=function(i){return i instanceof t.Point?this.left<=i.x&&this.top<=i.y&&this.bottom>=i.y&&this.right>=i.x:i instanceof e?this.left=n.left&&this.right<=n.right?n.left-this.right:n.right-this.left;var r=0;return r=this.top<=n.bottom&&this.top>=n.top?n.bottom-this.top:n.top-this.bottom,Math.abs(o)n;n++)e.push(new t.Line(this._points[n],this._points[(n+1)%i]));return e},e.prototype.getAxes=function(){for(var t=[],e=this._points.length,i=0;e>i;i++)t.push(this._points[i].minus(this._points[(i+1)%e]).normal());return t},e.prototype.project=function(e){for(var i=[],n=this._points.length,s=0;n>s;s++)i.push(this._points[s].dot(e));return new t.Projection(Math.min.apply(Math,i),Math.max.apply(Math,i))},e.prototype.getWidth=function(){var t=this._points.reduce(function(t,e){return Math.min(t,e.x)},1/0),e=this._points.reduce(function(t,e){return Math.max(t,e.x)},-1/0);return e-t},e.prototype.getHeight=function(){var t=this._points.reduce(function(t,e){return Math.min(t,e.y)},1/0),e=this._points.reduce(function(t,e){return Math.max(t,e.y)},-1/0);return t-e},e.prototype.contains=function(e){var i=new t.Ray(e,new t.Vector(1,0)),n=this.getSides().reduce(function(t,e){return i.intersect(e)>=0?t+1:t},0);return 0===n%2?!1:!0},e.prototype.collides=function(t){if(t instanceof e){var i=t,n=this.getAxes();n=i.getAxes().concat(n);for(var s=99999,o=null,r=0;n.length>r;r++){var h=this.project(n[r]),a=i.project(n[r]),c=h.getOverlap(a);if(0===c)return null;s>=c&&(s=c,o=n[r])}return o?o.normalize().scale(s):null}return null},e.prototype.debugDraw=function(e){e.beginPath(),e.lineWidth=2;var i=this._points[0];e.moveTo(i.x,i.y);var n=0,s=this._points.length;for(n;s>n;n++)e.lineTo(this._points[n].x,this._points[n].y);e.lineTo(i.x,i.y),e.closePath(),e.strokeStyle=""+t.Color.Blue,e.stroke()},e}();t.SATBoundingBox=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.eventDispatcher=new t.EventDispatcher(this)}return e.prototype.addEventListener=function(t,e){this.eventDispatcher.subscribe(t,e)},e.prototype.removeEventListener=function(t,e){this.eventDispatcher.unsubscribe(t,e)},e.prototype.on=function(t,e){this.eventDispatcher.subscribe(t,e)},e.prototype.off=function(t,e){this.eventDispatcher.unsubscribe(t,e)},e.prototype.emit=function(t,e){this.eventDispatcher.emit(t,e)},e.extend=function(t){var i,n=this;i=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return n.apply(this,arguments)};var s=function(){this.constructor=i};if(s.prototype=n.prototype,i.prototype=new s,t)for(var o in t)t.hasOwnProperty(o)&&(i.prototype[o]=t[o]);return i.extend=e.extend,i},e}();t.Class=e})(ex||(ex={})); var ex;(function(t){var e=function(){function t(e,i,n){this.id=0,this.interval=10,this.fcn=function(){},this.repeats=!1,this._elapsedTime=0,this._totalTimeAlive=0,this.complete=!1,this.scene=null,this.id=t.id++,this.interval=i||this.interval,this.fcn=e||this.fcn,this.repeats=n||this.repeats}return t.prototype.update=function(t){this._totalTimeAlive+=t,this._elapsedTime+=t,this._elapsedTime>this.interval&&(this.fcn.call(this),this.repeats?this._elapsedTime=0:this.complete=!0)},t.prototype.getTimeRunning=function(){return this._totalTimeAlive},t.prototype.cancel=function(){this.scene&&this.scene.cancelTimer(this)},t.id=0,t}();t.Timer=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){}return e.prototype.register=function(){},e.prototype.remove=function(){},e.prototype.evaluate=function(e){for(var i,n,s=e.filter(function(e){return!e.isKilled()&&e.collisionType!==t.CollisionType.PreventCollision}),o=[],r=0,h=s.length;h>r;r++){i=s[r];for(var a=r+1;h>a;a++){n=s[a];var c;if(c=i.collides(n)){var u=i.getSideFromIntersect(c),l=new t.CollisionPair(i,n,c,u);o.some(function(t){return t.equals(l)})||o.push(l)}}}var p=0,d=o.length;for(p;d>p;p++)o[p].evaluate();return o},e.prototype.update=function(){return 0},e.prototype.debugDraw=function(){},e}();t.NaiveCollisionResolver=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this.parent=e,this.parent=e||null,this.actor=null,this.bounds=new t.BoundingBox,this.left=null,this.right=null,this.height=0}return e.prototype.isLeaf=function(){return!this.left&&!this.right},e}();t.TreeNode=e;var i=function(){function t(){this.root=null,this.nodes={}}return t.prototype.insert=function(t){if(null===this.root)return this.root=t,this.root.parent=null,void 0;for(var i=t.bounds,n=this.root;!n.isLeaf();){var s,o,r=n.left,h=n.right,a=n.bounds.getPerimeter(),c=n.bounds.combine(i),u=c.getPerimeter(),l=2*u,p=2*(u-a),d=0,f=i.combine(r.bounds);r.isLeaf()?d=f.getPerimeter()+p:(o=r.bounds.getPerimeter(),s=f.getPerimeter(),d=s-o+p);var g=0,_=i.combine(h.bounds);if(h.isLeaf()?g=_.getPerimeter()+p:(o=h.bounds.getPerimeter(),s=_.getPerimeter(),g=s-o+p),d>l&&g>l)break;n=g>d?r:h}var y=n.parent,A=new e(y);A.bounds=i.combine(n.bounds),A.height=n.height+1,null!==y?(y.left===n?y.left=A:y.right=A,A.left=n,A.right=t,n.parent=A,t.parent=A):(A.left=n,A.right=t,n.parent=A,t.parent=A,this.root=A);for(var v=t.parent;v;){if(v=this.balance(v),!v.left)throw Error("Parent of current leaf cannot have a null left child"+v);if(!v.right)throw Error("Parent of current leaf cannot have a null right child"+v);v.height=1+Math.max(v.left.height,v.right.height),v.bounds=v.left.bounds.combine(v.right.bounds),v=v.parent}},t.prototype.remove=function(t){if(t===this.root)return this.root=null,void 0;var e,i=t.parent,n=i.parent;if(e=i.left===t?i.right:i.left,n){n.left===i?n.left=e:n.right=e,e.parent=n;for(var s=n;s;)s=this.balance(s),s.bounds=s.left.bounds.combine(s.right.bounds),s.height=1+Math.max(s.left.height,s.right.height),s=s.parent}else this.root=e,e.parent=null},t.prototype.registerActor=function(t){var i=new e;i.actor=t,i.bounds=t.getBounds(),i.bounds.left-=2,i.bounds.top-=2,i.bounds.right+=2,i.bounds.bottom+=2,this.nodes[t.id]=i,this.insert(i)},t.prototype.updateActor=function(t){var e=this.nodes[t.id];if(e){var i=t.getBounds();if(e.bounds.contains(i))return!1;this.remove(e),i.left-=5,i.top-=5,i.right+=5,i.bottom+=5;var n=2*t.dx,s=2*t.dy;return 0>n?i.left+=n:i.right+=n,0>s?i.top+=s:i.bottom+=s,e.bounds=i,this.insert(e),!0}},t.prototype.removeActor=function(t){var e=this.nodes[t.id];e&&(this.remove(e),this.nodes[t.id]=null,delete this.nodes[t.id])},t.prototype.balance=function(t){if(null===t)throw Error("Cannot balance at null node");if(t.isLeaf()||2>t.height)return t;var e=t.left,i=t.right,n=t,s=e,o=i,r=e.left,h=e.right,a=i.left,c=i.right,u=o.height-s.height;if(u>1)return o.left=n,o.parent=n.parent,n.parent=o,o.parent?o.parent.left===n?o.parent.left=o:o.parent.right=o:this.root=o,a.height>c.height?(o.right=a,n.right=c,c.parent=n,n.bounds=s.bounds.combine(c.bounds),o.bounds=n.bounds.combine(a.bounds),n.height=1+Math.max(s.height,c.height),o.height=1+Math.max(n.height,a.height)):(o.right=c,n.right=a,a.parent=n,n.bounds=s.bounds.combine(a.bounds),o.bounds=n.bounds.combine(c.bounds),n.height=1+Math.max(s.height,a.height),o.height=1+Math.max(n.height,c.height)),o;if(-1>u){if(s.left=n,s.parent=n.parent,n.parent=s,s.parent)if(s.parent.left===n)s.parent.left=s;else{if(s.parent.right!==n)throw"Error rotating Dynamic Tree";s.parent.right=s}else this.root=s;return r.height>h.height?(s.right=r,n.left=h,h.parent=n,n.bounds=o.bounds.combine(h.bounds),s.bounds=n.bounds.combine(r.bounds),n.height=1+Math.max(o.height,h.height),s.height=1+Math.max(n.height,r.height)):(s.right=h,n.left=r,r.parent=n,n.bounds=o.bounds.combine(r.bounds),s.bounds=n.bounds.combine(h.bounds),n.height=1+Math.max(o.height,r.height),s.height=1+Math.max(n.height,h.height)),s}return t},t.prototype.getHeight=function(){return null===this.root?0:this.root.height},t.prototype.query=function(t,e){var i=t.getBounds(),n=function(s){return s&&s.bounds.collides(i)?s.isLeaf()&&s.actor!==t?e.call(t,s.actor)?!0:void 0:n(s.left)||n(s.right):null};return n(this.root)},t.prototype.rayCast=function(){return null},t.prototype.getNodes=function(){var t=function(e){return e?[e].concat(t(e.left),t(e.right)):[]};return t(this.root)},t.prototype.debugDraw=function(t){var e=function(i){i&&(t.strokeStyle=i.isLeaf()?"green":"white",i.bounds.debugDraw(t),i.left&&e(i.left),i.right&&e(i.right))};e(this.root)},t}();t.DynamicTree=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this._dynamicCollisionTree=new t.DynamicTree}return e.prototype.register=function(t){this._dynamicCollisionTree.registerActor(t)},e.prototype.remove=function(t){this._dynamicCollisionTree.removeActor(t)},e.prototype.evaluate=function(e){for(var i,n=e.filter(function(e){return!e.isKilled()&&e.collisionType!==t.CollisionType.PreventCollision}),s=[],o=0,r=n.length;r>o;o++)i=n[o],this._dynamicCollisionTree.query(i,function(e){if(e.collisionType===t.CollisionType.PreventCollision||e.isKilled())return!1;var n;if(n=i.collides(e)){var o=i.getSideFromIntersect(n),r=new t.CollisionPair(i,e,n,o);return s.some(function(t){return t.equals(r)})||s.push(r),!0}return!1});var h=0,a=s.length;for(h;a>h;h++)s[h].evaluate();return s},e.prototype.update=function(t){var e=0,i=0,n=t.length;for(i;n>i;i++)this._dynamicCollisionTree.updateActor(t[i])&&e++;return e},e.prototype.debugDraw=function(t,e){this._dynamicCollisionTree.debugDraw(t,e)},e}();t.DynamicTreeCollisionResolver=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(t,e,i,n){this.left=t,this.right=e,this.intersect=i,this.side=n}return e.prototype.equals=function(t){return t.left===this.left&&t.right===this.right||t.right===this.left&&t.left===this.right},e.prototype.evaluate=function(){this.left.eventDispatcher.emit("collision",new t.CollisionEvent(this.left,this.right,this.side,this.intersect)),this.right.eventDispatcher.emit("collision",new t.CollisionEvent(this.right,this.left,t.Util.getOppositeSide(this.side),this.intersect.scale(-1)));var e=this.side;this.left.collisionType!==t.CollisionType.Active&&this.left.collisionType!==t.CollisionType.Elastic||this.right.collisionType===t.CollisionType.Passive||(this.left.y+=this.intersect.y,this.left.x+=this.intersect.x,this.left.collisionType===t.CollisionType.Elastic?e===t.Side.Left?this.left.dx=Math.abs(this.left.dx):e===t.Side.Right?this.left.dx=-Math.abs(this.left.dx):e===t.Side.Top?this.left.dy=Math.abs(this.left.dy):e===t.Side.Bottom&&(this.left.dy=-Math.abs(this.left.dy)):(0!==this.intersect.x&&(this.left.dx=0>=this.left.dx&&0>=this.right.dx?Math.max(this.left.dx,this.right.dx):this.left.dx>=0&&this.right.dx>=0?Math.min(this.left.dx,this.right.dx):0),0!==this.intersect.y&&(this.left.dy=0>=this.left.dy&&0>=this.right.dy?Math.max(this.left.dy,this.right.dy):this.left.dy>=0&&this.right.dy>=0?Math.min(this.left.dy,this.right.dy):0)));var i=t.Util.getOppositeSide(this.side),n=this.intersect.scale(-1);this.right.collisionType!==t.CollisionType.Active&&this.right.collisionType!==t.CollisionType.Elastic||this.left.collisionType===t.CollisionType.Passive||(this.right.y+=n.y,this.right.x+=n.x,this.right.collisionType===t.CollisionType.Elastic?i===t.Side.Left?this.right.dx=Math.abs(this.right.dx):i===t.Side.Right?this.right.dx=-Math.abs(this.right.dx):i===t.Side.Top?this.right.dy=Math.abs(this.right.dy):i===t.Side.Bottom&&(this.right.dy=-Math.abs(this.right.dy)):(0!==n.x&&(this.right.dx=0>=this.right.dx&&0>=this.left.dx?Math.max(this.left.dx,this.right.dx):this.left.dx>=0&&this.right.dx>=0?Math.min(this.left.dx,this.right.dx):0),0!==n.y&&(this.right.dy=0>=this.right.dy&&0>=this.left.dy?Math.max(this.left.dy,this.right.dy):this.left.dy>=0&&this.right.dy>=0?Math.min(this.left.dy,this.right.dy):0)))},e}();t.CollisionPair=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.focus=new t.Point(0,0),this.lerp=!1,this.x=0,this.y=0,this.z=1,this.dx=0,this.dy=0,this.dz=0,this.ax=0,this.ay=0,this.az=0,this.rotation=0,this.rx=0,this._cameraMoving=!1,this._currentLerpTime=0,this._lerpDuration=1e3,this._totalLerpTime=0,this._lerpStart=null,this._lerpEnd=null,this._isShaking=!1,this._shakeMagnitudeX=0,this._shakeMagnitudeY=0,this._shakeDuration=0,this._elapsedShakeTime=0,this._isZooming=!1,this._currentZoomScale=1,this._maxZoomScale=1,this._zoomDuration=0,this._elapsedZoomTime=0,this._zoomIncrement=.01}return e.prototype._easeInOutCubic=function(t,e,i,n){return i-=e,t/=n/2,1>t?i/2*t*t*t+e:(t-=2,i/2*(t*t*t+2)+e)},e.prototype.setActorToFollow=function(t){this._follow=t},e.prototype.getFocus=function(){return new t.Point(this.x,this.y)},e.prototype.setFocus=function(e,i){this._follow||this.lerp||(this.x=e,this.y=i),this.lerp&&(this._lerpStart=this.getFocus().clone(),this._lerpEnd=new t.Point(e,i),this._currentLerpTime=0,this._cameraMoving=!0)},e.prototype.shake=function(t,e,i){this._isShaking=!0,this._shakeMagnitudeX=t,this._shakeMagnitudeY=e,this._shakeDuration=i},e.prototype.zoom=function(t,e){void 0===e&&(e=0),this._isZooming=!0,this._maxZoomScale=t,this._zoomDuration=e,e&&(this._zoomIncrement=1e3*(Math.abs(this._maxZoomScale-this._currentZoomScale)/e)),1>this._maxZoomScale?e?this._zoomIncrement=-1*this._zoomIncrement:(this._isZooming=!1,this._setCurrentZoomScale(this._maxZoomScale)):e||(this._isZooming=!1,this._setCurrentZoomScale(this._maxZoomScale))},e.prototype.getZoom=function(){return this.z},e.prototype._setCurrentZoomScale=function(t){this.z=t},e.prototype.update=function(t,e){this.x+=this.dx*e/1e3,this.y+=this.dy*e/1e3,this.z+=this.dz*e/1e3,this.dx+=this.ax*e/1e3,this.dy+=this.ay*e/1e3,this.dz+=this.az*e/1e3,this.rotation+=this.rx*e/1e3;var i=this.getFocus(),n=0,s=0,o=t.canvas.width,r=t.canvas.height,h=o/this.getZoom(),a=r/this.getZoom();this.lerp&&(this._currentLerpTime=this._shakeDuration},e.prototype._isDoneZooming=function(){return 0!==this._zoomDuration?this._elapsedZoomTime>=this._zoomDuration:1>this._maxZoomScale?this._currentZoomScale<=this._maxZoomScale:this._currentZoomScale>=this._maxZoomScale},e}();t.BaseCamera=e;var i=function(e){function i(){e.apply(this,arguments)}return __extends(i,e),i.prototype.getFocus=function(){return this._follow?new t.Point(this._follow.x+this._follow.getWidth()/2,this.focus.y):this.focus},i}(e);t.SideCamera=i;var n=function(e){function i(){e.apply(this,arguments)}return __extends(i,e),i.prototype.getFocus=function(){return this._follow?new t.Point(this._follow.x+this._follow.getWidth()/2,this._follow.y+this._follow.getHeight()/2):this.focus},i}(e);t.LockedCamera=n})(ex||(ex={}));var ex;(function(t){(function(t){t[t.ShortestPath=0]="ShortestPath",t[t.LongestPath=1]="LongestPath",t[t.Clockwise=2]="Clockwise",t[t.CounterClockwise=3]="CounterClockwise"})(t.RotationType||(t.RotationType={})),t.RotationType})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i;(function(e){var i=function(){function e(e,i,n,s,o){this.actor=e,this.easingFcn=o,this._currentLerpTime=0,this._lerpDuration=1e3,this._lerpStart=new t.Point(0,0),this._lerpEnd=new t.Point(0,0),this._initialized=!1,this._stopped=!1,this._distance=0,this._lerpDuration=s,this._lerpEnd=new t.Point(i,n)}return e.prototype._initialize=function(){this._lerpStart=new t.Point(this.actor.x,this.actor.y),this._currentLerpTime=0,this._distance=this._lerpStart.toVector().distance(this._lerpEnd.toVector())},e.prototype.update=function(t){this._initialized||(this._initialize(),this._initialized=!0);var e=this.actor.x,i=this.actor.y;this._currentLerpTime=this._distance},e.prototype.reset=function(){this._initialized=!1},e.prototype.stop=function(){this._stopped=!0},e}();e.EaseTo=i;var n=function(){function e(e,i,n,s){this._started=!1,this._stopped=!1,this._actor=e,this._end=new t.Vector(i,n),this._speed=s}return e.prototype.update=function(){this._started||(this._started=!0,this._start=new t.Vector(this._actor.x,this._actor.y),this._distance=this._start.distance(this._end),this._dir=this._end.minus(this._start).normalize());var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y,this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.isComplete=function(e){return this._stopped||new t.Vector(e.x,e.y).distance(this._start)>=this._distance},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.MoveTo=n;var s=function(){function e(e,i,n,s){if(this._started=!1,this._stopped=!1,this._actor=e,this._end=new t.Vector(i,n),0>=s)throw t.Logger.getInstance().error("Attempted to moveBy time less than or equal to zero : "+s),Error("Cannot move in time <= 0");this._time=s}return e.prototype.update=function(){this._started||(this._started=!0,this._start=new t.Vector(this._actor.x,this._actor.y),this._distance=this._start.distance(this._end),this._dir=this._end.minus(this._start).normalize(),this._speed=this._distance/(this._time/1e3));var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y,this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.isComplete=function(e){return this._stopped||new t.Vector(e.x,e.y).distance(this._start)>=this._distance},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.MoveBy=s;var o=function(){function e(e,i,n){this._started=!1,this._stopped=!1,this._actor=e,this._actorToFollow=i,this._current=new t.Vector(this._actor.x,this._actor.y),this._end=new t.Vector(i.x,i.y),this._maximumDistance=void 0!==n?n:this._current.distance(this._end),this._speed=0}return e.prototype.update=function(){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize());var t=Math.sqrt(Math.pow(this._actorToFollow.dx,2)+Math.pow(this._actorToFollow.dy,2));if(0!==t&&(this._speed=t),this._current.x=this._actor.x,this._current.y=this._actor.y,this._end.x=this._actorToFollow.x,this._end.y=this._actorToFollow.y,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize(),this._distanceBetween>=this._maximumDistance){var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y}else this._actor.dx=0,this._actor.dy=0;this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.isComplete=function(){return this._stopped},e.prototype.reset=function(){this._started=!1},e}();e.Follow=o;var r=function(){function e(e,i,n){this._started=!1,this._stopped=!1,this._speedWasSpecified=!1,this._actor=e,this._actorToMeet=i,this._current=new t.Vector(this._actor.x,this._actor.y),this._end=new t.Vector(i.x,i.y),this._speed=n||0,void 0!==n&&(this._speedWasSpecified=!0)}return e.prototype.update=function(){this._started||(this._started=!0,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize());var t=Math.sqrt(Math.pow(this._actorToMeet.dx,2)+Math.pow(this._actorToMeet.dy,2));0===t||this._speedWasSpecified||(this._speed=t),this._current.x=this._actor.x,this._current.y=this._actor.y,this._end.x=this._actorToMeet.x,this._end.y=this._actorToMeet.y,this._distanceBetween=this._current.distance(this._end),this._dir=this._end.minus(this._current).normalize();var e=this._dir.scale(this._speed);this._actor.dx=e.x,this._actor.dy=e.y,this.isComplete(this._actor)&&(this._actor.x=this._end.x,this._actor.y=this._end.y,this._actor.dy=0,this._actor.dx=0)},e.prototype.isComplete=function(){return this._stopped||1>=this._distanceBetween},e.prototype.stop=function(){this._actor.dy=0,this._actor.dx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.Meet=r;var h=function(){function e(e,i,n,s){this._started=!1,this._stopped=!1,this._actor=e,this._end=i,this._speed=n,this._rotationType=s||t.RotationType.ShortestPath}return e.prototype.update=function(){if(!this._started){this._started=!0,this._start=this._actor.rotation;var e=Math.abs(this._end-this._start),i=t.Util.TwoPI-e;switch(e>i?(this._shortDistance=i,this._longDistance=e):(this._shortDistance=e,this._longDistance=i),this._shortestPathIsPositive=(this._start-this._end+t.Util.TwoPI)%t.Util.TwoPI>=Math.PI,this._rotationType){case t.RotationType.ShortestPath:this._distance=this._shortDistance,this._direction=this._shortestPathIsPositive?1:-1;break;case t.RotationType.LongestPath:this._distance=this._longDistance,this._direction=this._shortestPathIsPositive?-1:1;break;case t.RotationType.Clockwise:this._direction=1,this._distance=this._shortestPathIsPositive?this._shortDistance:this._longDistance;break;case t.RotationType.CounterClockwise:this._direction=-1,this._distance=this._shortestPathIsPositive?this._longDistance:this._shortDistance}}this._actor.rx=this._direction*this._speed,this.isComplete(this._actor)&&(this._actor.rotation=this._end,this._actor.rx=0,this._stopped=!0)},e.prototype.isComplete=function(){var t=Math.abs(this._actor.rotation-this._start);return this._stopped||t>=Math.abs(this._distance)},e.prototype.stop=function(){this._actor.rx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.RotateTo=h;var a=function(){function e(e,i,n,s){this._started=!1,this._stopped=!1,this._actor=e,this._end=i,this._time=n,this._rotationType=s||t.RotationType.ShortestPath}return e.prototype.update=function(){if(!this._started){this._started=!0,this._start=this._actor.rotation;var e=Math.abs(this._end-this._start),i=t.Util.TwoPI-e;switch(e>i?(this._shortDistance=i,this._longDistance=e):(this._shortDistance=e,this._longDistance=i),this._shortestPathIsPositive=(this._start-this._end+t.Util.TwoPI)%t.Util.TwoPI>=Math.PI,this._rotationType){case t.RotationType.ShortestPath:this._distance=this._shortDistance,this._direction=this._shortestPathIsPositive?1:-1;break;case t.RotationType.LongestPath:this._distance=this._longDistance,this._direction=this._shortestPathIsPositive?-1:1;break;case t.RotationType.Clockwise:this._direction=1,this._distance=this._shortDistance>=0?this._shortDistance:this._longDistance;break;case t.RotationType.CounterClockwise:this._direction=-1,this._distance=0>=this._shortDistance?this._shortDistance:this._longDistance}this._speed=Math.abs(1e3*(this._distance/this._time))}this._actor.rx=this._direction*this._speed,this.isComplete(this._actor)&&(this._actor.rotation=this._end,this._actor.rx=0,this._stopped=!0)},e.prototype.isComplete=function(){var t=Math.abs(this._actor.rotation-this._start);return this._stopped||t>=Math.abs(this._distance)},e.prototype.stop=function(){this._actor.rx=0,this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.RotateBy=a;var c=function(){function t(t,e,i,n,s){this._started=!1,this._stopped=!1,this._actor=t,this._endX=e,this._endY=i,this._speedX=n,this._speedY=s}return t.prototype.update=function(){if(this._started||(this._started=!0,this._startX=this._actor.scale.x,this._startY=this._actor.scale.y,this._distanceX=Math.abs(this._endX-this._startX),this._distanceY=Math.abs(this._endY-this._startY)),Math.abs(this._actor.scale.x-this._startX)>=this._distanceX)this._actor.sx=0;else{var t=this._endY=this._distanceY)this._actor.sy=0;else{var e=this._endY=this._distanceX&&Math.abs(this._actor.scale.y-this._startY)>=this._distanceY},t.prototype.stop=function(){this._actor.sx=0,this._actor.sy=0,this._stopped=!0},t.prototype.reset=function(){this._started=!1},t}();e.ScaleTo=c;var u=function(){function t(t,e,i,n){this._started=!1,this._stopped=!1,this._actor=t,this._endX=e,this._endY=i,this._time=n,this._speedX=1e3*((this._endX-this._actor.scale.x)/n),this._speedY=1e3*((this._endY-this._actor.scale.y)/n)}return t.prototype.update=function(){this._started||(this._started=!0,this._startX=this._actor.scale.x,this._startY=this._actor.scale.y,this._distanceX=Math.abs(this._endX-this._startX),this._distanceY=Math.abs(this._endY-this._startY));var t=this._endX=this._distanceX&&Math.abs(this._actor.scale.y-this._startY)>=this._distanceY},t.prototype.stop=function(){this._actor.sx=0,this._actor.sy=0,this._stopped=!0},t.prototype.reset=function(){this._started=!1},t}();e.ScaleBy=u;var l=function(){function t(t,e){this._elapsedTime=0,this._started=!1,this._stopped=!1,this._actor=t,this._delay=e}return t.prototype.update=function(t){this._started||(this._started=!0),this.x=this._actor.x,this.y=this._actor.y,this._elapsedTime+=t},t.prototype.isComplete=function(){return this._stopped||this._elapsedTime>=this._delay},t.prototype.stop=function(){this._stopped=!0},t.prototype.reset=function(){this._elapsedTime=0,this._started=!1},t}();e.Delay=l;var p=function(){function t(t,e,i,n){void 0===n&&(n=1),this._timeVisible=0,this._timeNotVisible=0,this._elapsedTime=0,this._totalTime=0,this._stopped=!1,this._started=!1,this._actor=t,this._timeVisible=e,this._timeNotVisible=i,this._duration=(e+i)*n}return t.prototype.update=function(t){this._started||(this._started=!0),this._elapsedTime+=t,this._totalTime+=t,this._actor.visible&&this._elapsedTime>=this._timeVisible&&(this._actor.visible=!1,this._elapsedTime=0),!this._actor.visible&&this._elapsedTime>=this._timeNotVisible&&(this._actor.visible=!0,this._elapsedTime=0),this.isComplete(this._actor)&&(this._actor.visible=!0)},t.prototype.isComplete=function(){return this._stopped||this._totalTime>=this._duration},t.prototype.stop=function(){this._actor.visible=!0,this._stopped=!0},t.prototype.reset=function(){this._started=!1,this._elapsedTime=0,this._totalTime=0},t}();e.Blink=p;var d=function(){function e(t,e,i){this._multiplyer=1,this._started=!1,this._stopped=!1,this._actor=t,this._endOpacity=e,this._speed=i,t.opacity>e&&(this._multiplyer=-1)}return e.prototype.update=function(e){this._started||(this._started=!0),this._speed>0&&(this._actor.opacity+=this._multiplyer*Math.abs(this._actor.opacity-this._endOpacity)*e/this._speed),this._speed-=e,t.Logger.getInstance().debug("actor opacity: "+this._actor.opacity),this.isComplete(this._actor)&&(this._actor.opacity=this._endOpacity)},e.prototype.isComplete=function(){return this._stopped||.05>Math.abs(this._actor.opacity-this._endOpacity)},e.prototype.stop=function(){this._stopped=!0},e.prototype.reset=function(){this._started=!1},e}();e.Fade=d;var f=function(){function t(t){this._started=!1,this._stopped=!1,this._actor=t}return t.prototype.update=function(){this._actor.actionQueue.clearActions(),this._actor.kill(),this._stopped=!0},t.prototype.isComplete=function(){return this._stopped},t.prototype.stop=function(){},t.prototype.reset=function(){},t}();e.Die=f;var g=function(){function t(t,e){this._method=null,this._actor=null,this._hasBeenCalled=!1,this._actor=t,this._method=e}return t.prototype.update=function(){this._method.call(this._actor),this._hasBeenCalled=!0},t.prototype.isComplete=function(){return this._hasBeenCalled},t.prototype.reset=function(){this._hasBeenCalled=!1},t.prototype.stop=function(){this._hasBeenCalled=!0},t}();e.CallMethod=g;var _=function(){function t(t,e,i){this._stopped=!1,this._actor=t,this._actionQueue=new A(t),this._repeat=e,this._originalRepeat=e;var n=0,s=i.length;for(n;s>n;n++)i[n].reset(),this._actionQueue.add(i[n])}return t.prototype.update=function(t){this.x=this._actor.x,this.y=this._actor.y,this._actionQueue.hasNext()||(this._actionQueue.reset(),this._repeat--),this._actionQueue.update(t)},t.prototype.isComplete=function(){return this._stopped||0>=this._repeat},t.prototype.stop=function(){this._stopped=!0},t.prototype.reset=function(){this._repeat=this._originalRepeat},t}();e.Repeat=_;var y=function(){function t(t,e){this._stopped=!1,this._actor=t,this._actionQueue=new A(t);var i=0,n=e.length;for(i;n>i;i++)e[i].reset(),this._actionQueue.add(e[i])}return t.prototype.update=function(t){this.x=this._actor.x,this.y=this._actor.y,this._stopped||(this._actionQueue.hasNext()||this._actionQueue.reset(),this._actionQueue.update(t))},t.prototype.isComplete=function(){return this._stopped},t.prototype.stop=function(){this._stopped=!0,this._actionQueue.clearActions()},t.prototype.reset=function(){},t}();e.RepeatForever=y;var A=function(){function t(t){this._actions=[],this._completedActions=[],this._actor=t}return t.prototype.add=function(t){this._actions.push(t)},t.prototype.remove=function(t){var e=this._actions.indexOf(t);this._actions.splice(e,1)},t.prototype.clearActions=function(){this._actions.length=0,this._completedActions.length=0,this._currentAction&&this._currentAction.stop()},t.prototype.getActions=function(){return this._actions.concat(this._completedActions)},t.prototype.hasNext=function(){return this._actions.length>0},t.prototype.reset=function(){this._actions=this.getActions();var t=0,e=this._actions.length;for(t;e>t;t++)this._actions[t].reset();this._completedActions=[]},t.prototype.update=function(t){this._actions.length>0&&(this._currentAction=this._actions[0],this._currentAction.update(t),this._currentAction.isComplete(this._actor)&&this._completedActions.push(this._actions.shift()))},t}();e.ActionQueue=A})(i=e.Actions||(e.Actions={}))})(e=t.Internal||(t.Internal={}))})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this._actors=[],this._queues=[],null!==arguments&&(this._actors=Array.prototype.slice.call(arguments,0),this._queues=this._actors.map(function(t){return t.actionQueue}))}return e.prototype.clearActions=function(){var t=0,e=this._queues.length;for(t;e>t;t++)this._queues[t].clearActions()},e.prototype.addActorToContext=function(t){this._actors.push(t),this._queues.push(t.actionQueue)},e.prototype.removeActorFromContext=function(t){var e=this._actors.indexOf(t);e>-1&&(this._actors.splice(e,1),this._queues.splice(e,1))},e.prototype.easeTo=function(e,i,n,s){void 0===s&&(s=t.EasingFunctions.Linear);var o=0,r=this._queues.length;for(o;r>o;o++)this._queues[o].add(new t.Internal.Actions.EaseTo(this._actors[o],e,i,n,s));return this},e.prototype.moveTo=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.MoveTo(this._actors[s],e,i,n));return this},e.prototype.moveBy=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.MoveBy(this._actors[s],e,i,n));return this},e.prototype.rotateTo=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.RotateTo(this._actors[s],e,i,n));return this},e.prototype.rotateBy=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.RotateBy(this._actors[s],e,i,n));return this},e.prototype.scaleTo=function(e,i,n,s){var o=0,r=this._queues.length;for(o;r>o;o++)this._queues[o].add(new t.Internal.Actions.ScaleTo(this._actors[o],e,i,n,s));return this},e.prototype.scaleBy=function(e,i,n){var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.ScaleBy(this._actors[s],e,i,n));return this},e.prototype.blink=function(e,i,n){void 0===n&&(n=1);var s=0,o=this._queues.length;for(s;o>s;s++)this._queues[s].add(new t.Internal.Actions.Blink(this._actors[s],e,i,n));return this},e.prototype.fade=function(e,i){var n=0,s=this._queues.length;for(n;s>n;n++)this._queues[n].add(new t.Internal.Actions.Fade(this._actors[n],e,i));return this},e.prototype.delay=function(e){var i=0,n=this._queues.length;for(i;n>i;i++)this._queues[i].add(new t.Internal.Actions.Delay(this._actors[i],e));return this},e.prototype.die=function(){var e=0,i=this._queues.length;for(e;i>e;e++)this._queues[e].add(new t.Internal.Actions.Die(this._actors[e]));return this},e.prototype.callMethod=function(e){var i=0,n=this._queues.length;for(i;n>i;i++)this._queues[i].add(new t.Internal.Actions.CallMethod(this._actors[i],e));return this},e.prototype.repeat=function(e){if(!e)return this.repeatForever(),this;var i=0,n=this._queues.length;for(i;n>i;i++)this._queues[i].add(new t.Internal.Actions.Repeat(this._actors[i],e,this._actors[i].actionQueue.getActions())); return this},e.prototype.repeatForever=function(){var e=0,i=this._queues.length;for(e;i>e;e++)this._queues[e].add(new t.Internal.Actions.RepeatForever(this._actors[e],this._actors[e].actionQueue.getActions()));return this},e.prototype.follow=function(e,i){var n=0,s=this._queues.length;for(n;s>n;n++)void 0===i?this._queues[n].add(new t.Internal.Actions.Follow(this._actors[n],e)):this._queues[n].add(new t.Internal.Actions.Follow(this._actors[n],e,i));return this},e.prototype.meet=function(e,i){var n=0,s=this._queues.length;for(n;s>n;n++)void 0===i?this._queues[n].add(new t.Internal.Actions.Meet(this._actors[n],e)):this._queues[n].add(new t.Internal.Actions.Meet(this._actors[n],e,i));return this},e.prototype.asPromise=function(){var e=this,i=this._queues.map(function(i,n){var s=new t.Promise;return i.add(new t.Internal.Actions.CallMethod(e._actors[n],function(){s.resolve()})),s});return t.Promise.join.apply(this,i)},e}();t.ActionContext=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n){if(e.call(this),this.name=i,this.scene=n,this._logger=t.Logger.getInstance(),this._members=[],this.actions=new t.ActionContext,null==n)this._logger.error("Invalid constructor arguments passed to Group: ",i,", scene must not be null!");else{var s=n.groups[i];s&&this._logger.warn("Group with name",i,"already exists. This new group will replace it."),n.groups[i]=this}}return __extends(i,e),i.prototype.add=function(e){e instanceof t.Actor&&(e=[].concat(e));var i,n=0,s=e.length;for(n;s>n;n++)i=this.getMembers().indexOf(e[n]),-1===i&&(this._members.push(e[n]),this.scene.add(e[n]),this.actions.addActorToContext(e[n]),this.eventDispatcher.wire(e[n].eventDispatcher))},i.prototype.remove=function(t){var e=this._members.indexOf(t);e>-1&&(this._members.splice(e,1),this.actions.removeActorFromContext(t),this.eventDispatcher.unwire(t.eventDispatcher))},i.prototype.move=function(e){var i=0,n=this.getMembers(),s=n.length;if(1===arguments.length&&e instanceof t.Vector)for(i;s>i;i++)n[i].x+=e.x,n[i].y+=e.y;else if("number"==typeof arguments[0]&&"number"==typeof arguments[1]){var o=arguments[0],r=arguments[1];for(i;s>i;i++)n[i].x+=o,n[i].y+=r}else this._logger.error("Invalid arguments passed to group move",this.name,"args:",arguments)},i.prototype.rotate=function(){if("number"==typeof arguments[0]){var t=arguments[0],e=0,i=this.getMembers(),n=i.length;for(e;n>e;e++)i[e].rotation+=t}else this._logger.error("Invalid arguments passed to group rotate",this.name,"args:",arguments)},i.prototype.on=function(t,e){this.eventDispatcher.subscribe(t,e)},i.prototype.off=function(t,e){this.eventDispatcher.unsubscribe(t,e)},i.prototype.emit=function(t,e){this.eventDispatcher.emit(t,e)},i.prototype.contains=function(t){return this.getMembers().indexOf(t)>-1},i.prototype.getMembers=function(){return this._members},i.prototype.getRandomMember=function(){return this._members[Math.floor(Math.random()*this._members.length)]},i.prototype.getBounds=function(){return this.getMembers().map(function(t){return t.getBounds()}).reduce(function(t,e){return t.combine(e)})},i}(t.Class);t.Group=e})(ex||(ex={}));var ex;(function(t){var e=function(){function t(t){this._getComparable=t}return t.prototype.find=function(t){return this._find(this._root,t)},t.prototype._find=function(t,e){return null==t?!1:this._getComparable.call(e)===t.getKey()?t.getData().indexOf(e)>-1?!0:!1:this._getComparable.call(e)e?this._get(t.getLeft(),e):this._get(t.getRight(),e)},t.prototype.add=function(t){return null==this._root?(this._root=new i(this._getComparable.call(t),[t],null,null),!0):this._insert(this._root,t)},t.prototype._insert=function(t,e){return null!=t?this._getComparable.call(e)===t.getKey()?t.getData().indexOf(e)>-1?!1:(t.getData().push(e),!0):this._getComparable.call(e)-1){if(t.getData().splice(i,1),0===t.getData().length){if(null==t.getLeft()&&null==t.getRight())return null;if(null==t.getLeft())return t.getRight();if(null==t.getRight())return t.getLeft();var n=this._findMinNode(t.getRight());return t.setKey(n.getKey()),t.setData(n.getData()),t.setRight(this._cleanup(t.getRight(),n)),t}return t}},t.prototype._cleanup=function(t,e){var i=e.getKey();if(null==t)return null;if(i===t.getKey()){if(null==t.getLeft()&&null==t.getRight())return null;if(null==t.getLeft())return t.getRight();if(null==t.getRight())return t.getLeft();var n=this._findMinNode(t.getRight());return t.setKey(n.getKey()),t.setData(n.getData()),t.setRight(this._cleanup(t.getRight(),n)),t}return this._getComparable.call(e)n;n++)this.uiActors[n].update(e,i);for(n=0,s=this.tileMaps.length;s>n;n++)this.tileMaps[n].update(e,i);for(n=0,s=this.children.length;s>n;n++)this.children[n].update(e,i);this._collisionResolver&&(this._collisionResolver.update(this.children),this._collisionResolver.evaluate(this.children));var o;for(n=0,s=this._killQueue.length;s>n;n++)o=this.children.indexOf(this._killQueue[n]),o>-1&&(this._sortedDrawingTree.removeByComparable(this._killQueue[n]),this.children.splice(o,1));for(this._killQueue.length=0,n=0,s=this._cancelQueue.length;s>n;n++)this.removeTimer(this._cancelQueue[n]);this._cancelQueue.length=0,this._timers=this._timers.filter(function(t){return t.update(i),!t.complete}),this.emit("postupdate",new t.PostUpdateEvent(e,i,this))},i.prototype.draw=function(e,i){this.emit("predraw",new t.PreDrawEvent(e,i,this)),e.save(),this.camera&&this.camera.update(e,i);var n,s;for(n=0,s=this.tileMaps.length;s>n;n++)this.tileMaps[n].draw(e,i);var o=this._sortedDrawingTree.list();for(n=0,s=o.length;s>n;n++)o[n].visible&&!o[n].isOffScreen&&o[n].draw(e,i);for(this.engine&&this.engine.isDebug&&(e.strokeStyle="yellow",this.debugDraw(e)),e.restore(),n=0,s=this.uiActors.length;s>n;n++)this.uiActors[n].visible&&this.uiActors[n].draw(e,i);if(this.engine&&this.engine.isDebug)for(n=0,s=this.uiActors.length;s>n;n++)this.uiActors[n].debugDraw(e);this.emit("postdraw",new t.PreDrawEvent(e,i,this))},i.prototype.debugDraw=function(e){this.emit("predebugdraw",new t.PreDebugDrawEvent(e,this));var i,n;for(i=0,n=this.tileMaps.length;n>i;i++)this.tileMaps[i].debugDraw(e);for(i=0,n=this.children.length;n>i;i++)this.children[i].debugDraw(e);this.camera.debugDraw(e),this.emit("postdebugdraw",new t.PostDebugDrawEvent(e,this))},i.prototype.contains=function(t){return this.children.indexOf(t)>-1},i.prototype.add=function(e){return e instanceof t.Actor&&e.unkill(),e instanceof t.UIActor?(t.Util.contains(this.uiActors,e)||this.addUIActor(e),void 0):e instanceof t.Actor?(t.Util.contains(this.children,e)||(this.addChild(e),this._sortedDrawingTree.add(e)),void 0):e instanceof t.Timer?(t.Util.contains(this._timers,e)||this.addTimer(e),void 0):(e instanceof t.TileMap&&(t.Util.contains(this.tileMaps,e)||this.addTileMap(e)),void 0)},i.prototype.remove=function(e){return e instanceof t.UIActor?(this.removeUIActor(e),void 0):(e instanceof t.Actor&&(this._collisionResolver.remove(e),this.removeChild(e)),e instanceof t.Timer&&this.removeTimer(e),e instanceof t.TileMap&&this.removeTileMap(e),void 0)},i.prototype.addUIActor=function(t){this.uiActors.push(t),t.scene=this},i.prototype.removeUIActor=function(t){var e=this.uiActors.indexOf(t);e>-1&&this.uiActors.splice(e,1)},i.prototype.addChild=function(t){this._collisionResolver.register(t),t.scene=this,this.children.push(t),this._sortedDrawingTree.add(t),t.parent=this.actor},i.prototype.addTileMap=function(t){this.tileMaps.push(t)},i.prototype.removeTileMap=function(t){var e=this.tileMaps.indexOf(t);e>-1&&this.tileMaps.splice(e,1)},i.prototype.removeChild=function(t){this._collisionResolver.remove(t),this._killQueue.push(t),t.parent=null},i.prototype.addTimer=function(t){return this._timers.push(t),t.scene=this,t},i.prototype.removeTimer=function(t){var e=this._timers.indexOf(t);return-1!==e&&this._timers.splice(e,1),t},i.prototype.cancelTimer=function(t){return this._cancelQueue.push(t),t},i.prototype.isTimerActive=function(t){return this._timers.indexOf(t)>-1},i.prototype.createGroup=function(e){return new t.Group(e,this)},i.prototype.getGroup=function(t){return this.groups[t]},i.prototype.removeGroup=function(e){"string"==typeof e?delete this.groups[e]:e instanceof t.Group?delete this.groups[e.name]:this._logger.error("Invalid arguments to removeGroup",e)},i.prototype.cleanupDrawTree=function(t){this._sortedDrawingTree.removeByComparable(t)},i.prototype.updateDrawTree=function(t){this._sortedDrawingTree.add(t)},i}(t.Class);t.Scene=e})(ex||(ex={}));var ex;(function(t){var e=function(){function t(){}return t.Linear=function(t,e,i,n){return i-=e,i*t/n+e},t.EaseInQuad=function(t,e,i,n){t/=n},t.EaseOutQuad=function(t,e,i,n){return t/=n,-i*t*(t-2)+e},t.EaseInOutQuad=function(t,e,i,n){return i-=e,t/=n/2,1>t?i/2*t*t+e:(t--,-i/2*(t*(t-2)-1)+e)},t.EaseInCubic=function(t,e,i,n){return i-=e,t/=n,i*t*t*t+e},t.EaseOutCubic=function(t,e,i,n){return i-=e,t/=n,i*(t*t*t+1)+e},t.EaseInOutCubic=function(t,e,i,n){return i-=e,t/=n/2,1>t?i/2*t*t*t+e:(t-=2,i/2*(t*t*t+2)+e)},t}();t.EasingFunctions=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function n(s,o,r,h,a){e.call(this),this.id=n.maxId++,this.x=0,this.y=0,this._height=0,this._width=0,this.rotation=0,this.rx=0,this.scale=new t.Vector(1,1),this.sx=0,this.sy=0,this.dx=0,this.dy=0,this.ax=0,this.ay=0,this.isOffScreen=!1,this.visible=!0,this.opacity=1,this.previousOpacity=1,this.logger=t.Logger.getInstance(),this.scene=null,this.parent=null,this.children=[],this.collisionType=i.PreventCollision,this.collisionGroups=[],this._collisionHandlers={},this._isInitialized=!1,this.frames={},this.currentDrawing=null,this.centerDrawingX=!0,this.centerDrawingY=!0,this.traits=[],this.enableCapturePointer=!1,this.capturePointer={captureMoveEvents:!1},this._zIndex=0,this._isKilled=!1,this.x=s||0,this.y=o||0,this._width=r||0,this._height=h||0,a&&(this.color=a.clone(),this.opacity=a.a),this.traits.push(new t.Traits.Movement),this.traits.push(new t.Traits.CollisionDetection),this.traits.push(new t.Traits.OffscreenCulling),this.traits.push(new t.Traits.CapturePointer),this.actionQueue=new t.Internal.Actions.ActionQueue(this),this.actions=new t.ActionContext(this),this.anchor=new t.Point(.5,.5)}return __extends(n,e),n.prototype.onInitialize=function(){},n.prototype._checkForPointerOptIn=function(t){!t||"pointerdown"!==t.toLowerCase()&&"pointerdown"!==t.toLowerCase()&&"pointermove"!==t.toLowerCase()||(this.enableCapturePointer=!0,"pointermove"===t.toLowerCase()&&(this.capturePointer.captureMoveEvents=!0))},n.prototype.addEventListener=function(t,i){this._checkForPointerOptIn(t),e.prototype.addEventListener.call(this,t,i)},n.prototype.on=function(t,e){this._checkForPointerOptIn(t),this.eventDispatcher.subscribe(t,e)},n.prototype.kill=function(){this.scene?(this.emit("kill",new t.KillEvent(this)),this.scene.remove(this),this._isKilled=!0):this.logger.warn("Cannot kill actor, it was never added to the Scene")},n.prototype.unkill=function(){this._isKilled=!1},n.prototype.isKilled=function(){return this._isKilled},n.prototype.add=function(e){e.collisionType=i.PreventCollision,t.Util.addItemToArray(e,this.children)&&(e.parent=this)},n.prototype.remove=function(e){t.Util.removeItemToArray(e,this.children)&&(e.parent=null)},n.prototype.setDrawing=function(e){e=""+e,this.currentDrawing!==this.frames[e]&&(null!=this.frames[e]?(this.frames[e].reset(),this.currentDrawing=this.frames[e]):t.Logger.getInstance().error("the specified drawing key '"+e+"' does not exist"))},n.prototype.addDrawing=function(){2===arguments.length?(this.frames[arguments[0]]=arguments[1],this.currentDrawing||(this.currentDrawing=arguments[1])):(arguments[0]instanceof t.Sprite&&this.addDrawing("default",arguments[0]),arguments[0]instanceof t.Texture&&this.addDrawing("default",arguments[0].asSprite()))},n.prototype.getZIndex=function(){return this._zIndex},n.prototype.setZIndex=function(t){this.scene.cleanupDrawTree(this),this._zIndex=t,this.scene.updateDrawTree(this)},n.prototype.addCollisionGroup=function(t){this.collisionGroups.push(t)},n.prototype.removeCollisionGroup=function(t){var e=this.collisionGroups.indexOf(t);-1!==e&&this.collisionGroups.splice(e,1)},n.prototype.getCenter=function(){return new t.Vector(this.x+this.getWidth()/2-this.anchor.x*this.getWidth(),this.y+this.getHeight()/2-this.anchor.y*this.getHeight())},n.prototype.getWidth=function(){return this._width*this.scale.x},n.prototype.setWidth=function(t){this._width=t/this.scale.x},n.prototype.getHeight=function(){return this._height*this.scale.y},n.prototype.setHeight=function(t){this._height=t/this.scale.y},n.prototype.setCenterDrawing=function(t){this.centerDrawingY=t,this.centerDrawingX=t},n.prototype.getLeft=function(){return this.getBounds().left},n.prototype.getRight=function(){return this.getBounds().right},n.prototype.getTop=function(){return this.getBounds().top},n.prototype.getBottom=function(){return this.getBounds().bottom},n.prototype.getWorldX=function(){return this.parent?this.x*this.parent.scale.x+this.parent.getWorldX():this.x},n.prototype.getWorldY=function(){return this.parent?this.y*this.parent.scale.y+this.parent.getWorldY():this.y},n.prototype.getGlobalScale=function(){if(!this.parent)return new t.Point(this.scale.x,this.scale.y);var e=this.parent.getGlobalScale();return new t.Point(this.scale.x*e.x,this.scale.y*e.y)},n.prototype.getBounds=function(){var e=this._getCalculatedAnchor();return new t.BoundingBox(this.getWorldX()-e.x,this.getWorldY()-e.y,this.getWorldX()+this.getWidth()-e.x,this.getWorldY()+this.getHeight()-e.y)},n.prototype.contains=function(e,i,n){void 0===n&&(n=!1);var s=this.getBounds().contains(new t.Point(e,i));return n?s||this.children.some(function(t){return t.contains(e,i,!0)}):s},n.prototype.getSideFromIntersect=function(e){return e?Math.abs(e.x)>Math.abs(e.y)?0>e.x?t.Side.Right:t.Side.Left:0>e.y?t.Side.Bottom:t.Side.Top:t.Side.None},n.prototype.collidesWithSide=function(e){var i=this.collides(e);return i?Math.abs(i.x)>Math.abs(i.y)?this.x=Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},n.prototype.clearActions=function(){this.actionQueue.clearActions()},n.prototype.easeTo=function(e,i,n,s){return void 0===s&&(s=t.EasingFunctions.Linear),this.actionQueue.add(new t.Internal.Actions.EaseTo(this,e,i,n,s)),this},n.prototype.moveTo=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.MoveTo(this,e,i,n)),this},n.prototype.moveBy=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.MoveBy(this,e,i,n)),this},n.prototype.rotateTo=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.RotateTo(this,e,i,n)),this},n.prototype.rotateBy=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.RotateBy(this,e,i,n)),this},n.prototype.scaleTo=function(e,i,n,s){return this.actionQueue.add(new t.Internal.Actions.ScaleTo(this,e,i,n,s)),this},n.prototype.scaleBy=function(e,i,n){return this.actionQueue.add(new t.Internal.Actions.ScaleBy(this,e,i,n)),this},n.prototype.blink=function(e,i,n){return void 0===n&&(n=1),this.actionQueue.add(new t.Internal.Actions.Blink(this,e,i,n)),this},n.prototype.fade=function(e,i){return this.actionQueue.add(new t.Internal.Actions.Fade(this,e,i)),this},n.prototype.delay=function(e){return this.actionQueue.add(new t.Internal.Actions.Delay(this,e)),this},n.prototype.die=function(){return this.actionQueue.add(new t.Internal.Actions.Die(this)),this},n.prototype.callMethod=function(e){return this.actionQueue.add(new t.Internal.Actions.CallMethod(this,e)),this},n.prototype.repeat=function(e){return e?(this.actionQueue.add(new t.Internal.Actions.Repeat(this,e,this.actionQueue.getActions())),this):(this.repeatForever(),this)},n.prototype.repeatForever=function(){return this.actionQueue.add(new t.Internal.Actions.RepeatForever(this,this.actionQueue.getActions())),this},n.prototype.follow=function(e,i){return i===void 0?this.actionQueue.add(new t.Internal.Actions.Follow(this,e)):this.actionQueue.add(new t.Internal.Actions.Follow(this,e,i)),this},n.prototype.meet=function(e,i){return i===void 0?this.actionQueue.add(new t.Internal.Actions.Meet(this,e)):this.actionQueue.add(new t.Internal.Actions.Meet(this,e,i)),this},n.prototype.asPromise=function(){var e=new t.Promise;return this.callMethod(function(){e.resolve()}),e},n.prototype._getCalculatedAnchor=function(){return new t.Point(this.getWidth()*this.anchor.x,this.getHeight()*this.anchor.y)},n.prototype.update=function(e,i){this._isInitialized||(this.onInitialize(e),this.eventDispatcher.emit("initialize",new t.InitializeEvent(e)),this._isInitialized=!0),this.emit("preupdate",new t.PreUpdateEvent(e,i,this));var n=this.eventDispatcher;this.actionQueue.update(i),this.color&&(this.color.a=this.opacity);for(var s=0;this.traits.length>s;s++)this.traits[s].update(this,e,i);n.emit("update",new t.UpdateEvent(i)),this.emit("postupdate",new t.PostUpdateEvent(e,i,this))},n.prototype.draw=function(e,i){var n=this._getCalculatedAnchor();if(e.save(),e.translate(this.x,this.y),e.scale(this.scale.x,this.scale.y),e.rotate(this.rotation),this.emit("predraw",new t.PreDrawEvent(e,i,this)),this.previousOpacity!==this.opacity){for(var s in this.frames)this.frames[s].addEffect(new t.Effects.Opacity(this.opacity));this.previousOpacity=this.opacity}if(this.currentDrawing){var o=0,r=0;this.centerDrawingX&&(o=(this.currentDrawing.naturalWidth*this.currentDrawing.scale.x-this.getWidth())/2-this.currentDrawing.naturalWidth*this.currentDrawing.scale.x*this.currentDrawing.anchor.x),this.centerDrawingY&&(r=(this.currentDrawing.naturalHeight*this.currentDrawing.scale.y-this.getHeight())/2-this.currentDrawing.naturalHeight*this.currentDrawing.scale.y*this.currentDrawing.anchor.y),this.currentDrawing.draw(e,-n.x-o,-n.y-r)}else this.color&&(e.fillStyle=""+this.color,e.fillRect(-n.x,-n.y,this._width,this._height));for(var h=0;this.children.length>h;h++)this.children[h].visible&&this.children[h].draw(e,i);this.emit("postdraw",new t.PostDrawEvent(e,i,this)),e.restore()},n.prototype.debugDraw=function(e){this.emit("predebugdraw",new t.PreDebugDrawEvent(e,this));var i=this.getBounds();i.debugDraw(e),e.fillText("id: "+this.id,i.left+3,i.top+10),e.fillStyle=""+t.Color.Yellow,e.beginPath(),e.arc(this.getWorldX(),this.getWorldY(),3,0,2*Math.PI),e.closePath(),e.fill();for(var n=0;this.traits.length>n;n++)this.traits[n]instanceof t.Traits.OffscreenCulling&&this.traits[n].cullingBox.debugDraw(e);e.strokeStyle=""+t.Color.Yellow,e.beginPath();var s=Math.min(this.getWidth(),this.getHeight());e.arc(this.getWorldX(),this.getWorldY(),s,0,2*Math.PI),e.closePath(),e.stroke();var o={"0 Pi":0,"Pi/2":Math.PI/2,Pi:Math.PI,"3/2 Pi":3*Math.PI/2},r=e.font;for(var h in o)e.fillStyle=""+t.Color.Yellow,e.font="14px",e.textAlign="center",e.fillText(h,this.getWorldX()+Math.cos(o[h])*(s+10),this.getWorldY()+Math.sin(o[h])*(s+10));e.font=r,e.save(),e.translate(this.x,this.y),e.rotate(this.rotation);for(var a=0;this.children.length>a;a++)this.children[a].debugDraw(e);e.restore(),this.emit("postdebugdraw",new t.PostDebugDrawEvent(e,this))},n.maxId=0,n}(t.Class);t.Actor=e,function(t){t[t.PreventCollision=0]="PreventCollision",t[t.Passive=1]="Passive",t[t.Active=2]="Active",t[t.Elastic=3]="Elastic",t[t.Fixed=4]="Fixed"}(t.CollisionType||(t.CollisionType={}));var i=t.CollisionType})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Debug=0]="Debug",t[t.Info=1]="Info",t[t.Warn=2]="Warn",t[t.Error=3]="Error",t[t.Fatal=4]="Fatal"})(t.LogLevel||(t.LogLevel={}));var e=t.LogLevel,i=function(){function t(){if(this._appenders=[],this.defaultLevel=e.Info,t._instance)throw Error("Logger is a singleton");return t._instance=this,t._instance.addAppender(new n),t._instance}return t.getInstance=function(){return null==t._instance&&(t._instance=new t),t._instance},t.prototype.addAppender=function(t){this._appenders.push(t)},t.prototype.clearAppenders=function(){this._appenders.length=0},t.prototype._log=function(t,e){null==t&&(t=this.defaultLevel);var i=0,n=this._appenders.length;for(i;n>i;i++)t>=this.defaultLevel&&this._appenders[i].log(t,e)},t.prototype.debug=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Debug,t)},t.prototype.info=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Info,t)},t.prototype.warn=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Warn,t)},t.prototype.error=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Error,t)},t.prototype.fatal=function(){for(var t=[],i=0;arguments.length>i;i++)t[i-0]=arguments[i];this._log(e.Fatal,t)},t._instance=null,t}();t.Logger=i;var n=function(){function t(){}return t.prototype.log=function(t,i){if(console||console.log||!console.warn||!console.error){var n=[];n.unshift.apply(n,i),n.unshift("["+e[t]+"] : "),e.Warn>t?console.log.apply?console.log.apply(console,n):console.log(n.join(" ")):e.Error>t?console.warn.apply?console.warn.apply(console,n):console.warn(n.join(" ")):console.error.apply?console.error.apply(console,n):console.error(n.join(" "))}},t}();t.ConsoleAppender=n;var s=function(){function t(t,e){this._messages=[],this._canvas=document.createElement("canvas"),this._canvas.width=t||window.innerWidth,this._canvas.height=e||window.innerHeight,this._canvas.style.position="absolute",this._ctx=this._canvas.getContext("2d"),document.body.appendChild(this._canvas)}return t.prototype.log=function(t,i){var n=i.join(",");this._ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this._messages.unshift("["+e[t]+"] : "+n);for(var s=10,o=1,r=0;this._messages.length>r;r++)this._ctx.fillStyle="rgba(255,255,255,"+o.toFixed(2)+")",this._ctx.fillText(this._messages[r],200,s),s+=10,o=o>0?o-.05:0},t}();t.ScreenAppender=s})(ex||(ex={}));var ex;(function(t){var e=function(){function t(){}return t}();t.GameEvent=e;var i=function(t){function e(e){t.call(this),this.target=e}return __extends(e,t),e}(e);t.KillEvent=i;var n=function(t){function e(e,i,n){t.call(this),this.ctx=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PreDrawEvent=n;var s=function(t){function e(e,i,n){t.call(this),this.ctx=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PostDrawEvent=s;var o=function(t){function e(e,i){t.call(this),this.ctx=e,this.target=i}return __extends(e,t),e}(e);t.PreDebugDrawEvent=o;var r=function(t){function e(e,i){t.call(this),this.ctx=e,this.target=i}return __extends(e,t),e}(e);t.PostDebugDrawEvent=r;var h=function(t){function e(e,i,n){t.call(this),this.engine=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PreUpdateEvent=h;var a=function(t){function e(e,i,n){t.call(this),this.engine=e,this.delta=i,this.target=n}return __extends(e,t),e}(e);t.PostUpdateEvent=a;var c=function(t){function e(e,i){t.call(this),this.index=e,this.gamepad=i}return __extends(e,t),e}(e);t.GamepadConnectEvent=c;var u=function(t){function e(e){t.call(this),this.index=e}return __extends(e,t),e}(e);t.GamepadDisconnectEvent=u;var l=function(t){function e(e,i){t.call(this),this.button=e,this.value=i}return __extends(e,t),e}(t.GameEvent);t.GamepadButtonEvent=l;var p=function(t){function e(e,i){t.call(this),this.axis=e,this.value=i}return __extends(e,t),e}(t.GameEvent);t.GamepadAxisEvent=p;var d=function(t){function e(e,i){t.call(this),this.topic=e,this.handler=i}return __extends(e,t),e}(e);t.SubscribeEvent=d;var f=function(t){function e(e,i){t.call(this),this.topic=e,this.handler=i}return __extends(e,t),e}(e);t.UnsubscribeEvent=f;var g=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.VisibleEvent=g;var _=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.HiddenEvent=_;var y=function(t){function e(e,i,n,s){t.call(this),this.actor=e,this.other=i,this.side=n,this.intersection=s}return __extends(e,t),e}(e);t.CollisionEvent=y;var A=function(t){function e(e){t.call(this),this.delta=e}return __extends(e,t),e}(e);t.UpdateEvent=A;var v=function(t){function e(e){t.call(this),this.engine=e}return __extends(e,t),e}(e);t.InitializeEvent=v;var m=function(t){function e(e){t.call(this),this.oldScene=e}return __extends(e,t),e}(e);t.ActivateEvent=m;var x=function(t){function e(e){t.call(this),this.newScene=e}return __extends(e,t),e}(e);t.DeactivateEvent=x;var w=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.ExitViewPortEvent=w;var b=function(t){function e(){t.call(this)}return __extends(e,t),e}(e);t.EnterViewPortEvent=b})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this._handlers={},this._wiredEventDispatchers=[],this._log=t.Logger.getInstance(),this._target=e}return e.prototype.publish=function(e,i){if(e){e=e.toLowerCase();var n=this._target;i||(i=new t.GameEvent),i.target=n;var s,o;if(this._handlers[e])for(s=0,o=this._handlers[e].length,s;o>s;s++)this._handlers[e][s].call(n,i);for(s=0,o=this._wiredEventDispatchers.length,s;o>s;s++)this._wiredEventDispatchers[s].emit(e,i)}},e.prototype.emit=function(t,e){this.publish(t,e)},e.prototype.subscribe=function(e,i){e=e.toLowerCase(),this._handlers[e]||(this._handlers[e]=[]),this._handlers[e].push(i),"unsubscribe"!==e&&"subscribe"!==e&&this.emit("subscribe",new t.SubscribeEvent(e,i))},e.prototype.unsubscribe=function(e,i){e=e.toLowerCase();var n=this._handlers[e];if(n)if(i){var s=n.indexOf(i);this._handlers[e].splice(s,1)}else this._handlers[e].length=0;"unsubscribe"!==e&&"subscribe"!==e&&this.emit("unsubscribe",new t.UnsubscribeEvent(e,i))},e.prototype.wire=function(t){t._wiredEventDispatchers.push(this)},e.prototype.unwire=function(t){var e=t._wiredEventDispatchers.indexOf(this);e>-1&&t._wiredEventDispatchers.splice(e,1)},e}();t.EventDispatcher=e})(ex||(ex={}));var ex;(function(t){var e=function(){function t(t,e,i,n){this.r=t,this.g=e,this.b=i,this.a=null!=n?n:1}return t.fromRGB=function(e,i,n,s){return new t(e,i,n,s)},t.fromHex=function(e){var i=/^#?([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})?$/i,n=null;if(n=e.match(i)){var s=parseInt(n[1],16),o=parseInt(n[2],16),r=parseInt(n[3],16),h=1;return n[4]&&(h=parseInt(n[4],16)/255),new t(s,o,r,h)}throw Error("Invalid hex string: "+e)},t.fromHSL=function(t,e,n,s){void 0===s&&(s=1);var o=new i(t,e,n,s);return o.toRGBA()},t.prototype.lighten=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.l+=e.l*t,e.toRGBA()},t.prototype.darken=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.l-=e.l*t,e.toRGBA()},t.prototype.saturate=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.s+=e.s*t,e.toRGBA()},t.prototype.desaturate=function(t){void 0===t&&(t=.1);var e=i.fromRGBA(this.r,this.g,this.b,this.a);return e.s-=e.s*t,e.toRGBA()},t.prototype.mulitiply=function(e){var i=255*(e.r/255*this.r/255),n=255*(e.g/255*this.g/255),s=255*(e.b/255*this.b/255),o=e.a*this.a;return new t(i,n,s,o)},t.prototype.screen=function(t){var e=t.invert(),i=t.invert();return e.mulitiply(i).invert()},t.prototype.invert=function(){return new t(255-this.r,255-this.g,255-this.b,1-this.a)},t.prototype.average=function(e){var i=(e.r+this.r)/2,n=(e.g+this.g)/2,s=(e.b+this.b)/2,o=(e.a+this.a)/2;return new t(i,n,s,o)},t.prototype.toString=function(){var t=this.r.toFixed(0)+""+", "+(this.g.toFixed(0)+"")+", "+(this.b.toFixed(0)+"");return void 0!==this.a||null!==this.a?"rgba("+t+", "+(this.a+"")+")":"rgb("+t+")"},t.prototype.fillStyle=function(){return""+this},t.prototype.clone=function(){return new t(this.r,this.g,this.b,this.a)},t.Black=t.fromHex("#000000"),t.White=t.fromHex("#FFFFFF"),t.Gray=t.fromHex("#808080"),t.LightGray=t.fromHex("#D3D3D3"),t.DarkGray=t.fromHex("#A9A9A9"),t.Yellow=t.fromHex("#FFFF00"),t.Orange=t.fromHex("#FFA500"),t.Red=t.fromHex("#FF0000"),t.Vermillion=t.fromHex("#FF5B31"),t.Rose=t.fromHex("#FF007F"),t.Magenta=t.fromHex("#FF00FF"),t.Violet=t.fromHex("#7F00FF"),t.Blue=t.fromHex("#0000FF"),t.Azure=t.fromHex("#007FFF"),t.Cyan=t.fromHex("#00FFFF"),t.Viridian=t.fromHex("#59978F"),t.Green=t.fromHex("#00FF00"),t.Chartreuse=t.fromHex("#7FFF00"),t.Transparent=t.fromHex("#FFFFFF00"),t}();t.Color=e;var i=function(){function t(t,e,i,n){this.h=t,this.s=e,this.l=i,this.a=n}return t.fromRGBA=function(e,i,n,s){e/=255,i/=255,n/=255;var o,r,h=Math.max(e,i,n),a=Math.min(e,i,n),c=(h+a)/2;if(h===a)o=r=0;else{var u=h-a;switch(r=c>.5?u/(2-h-a):u/(h+a),h){case e:o=(i-n)/u+(n>i?6:0);break;case i:o=(n-e)/u+2;break;case n:o=(e-i)/u+4}o/=6}return new t(o,r,c,s)},t.prototype.toRGBA=function(){function t(t,e,i){return 0>i&&(i+=1),i>1&&(i-=1),1/6>i?t+6*(e-t)*i:.5>i?e:2/3>i?t+6*(e-t)*(2/3-i):t}var i,n,s;if(0===this.s)i=n=s=this.l;else{var o=.5>this.l?this.l*(1+this.s):this.l+this.s-this.l*this.s,r=2*this.l-o;i=t(r,o,this.h+1/3),n=t(r,o,this.h),s=t(r,o,this.h-1/3)}return new e(255*i,255*n,255*s,this.a)},t}() -})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o){e.call(this,i,n,s,o),this.traits=[],this.traits.push(new t.Traits.Movement),this.traits.push(new t.Traits.CapturePointer),this.anchor.setTo(0,0),this.collisionType=t.CollisionType.PreventCollision,this.enableCapturePointer=!0}return __extends(i,e),i.prototype.onInitialize=function(t){this._engine=t},i.prototype.contains=function(i,n,s){if(void 0===s&&(s=!0),s)return e.prototype.contains.call(this,i,n);var o=this._engine.worldToScreenCoordinates(new t.Point(i,n));return e.prototype.contains.call(this,o.x,o.y)},i}(t.Actor);t.UIActor=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o,r,h){e.call(this,i,n,s,o),this._action=function(){},this.repeats=1,this.target=null,this.repeats=h||this.repeats,this._action=r||this._action,this.collisionType=t.CollisionType.PreventCollision,this.eventDispatcher=new t.EventDispatcher(this),this.actionQueue=new t.Internal.Actions.ActionQueue(this)}return __extends(i,e),i.prototype.update=function(e,i){if(this.actionQueue.update(i),this.x+=this.dx*i/1e3,this.y+=this.dy*i/1e3,this.rotation+=this.rx*i/1e3,this.scale.x+=this.sx*i/1e3,this.scale.y+=this.sy*i/1e3,this.target)this.collides(this.target)&&this._dispatchAction();else for(var n=0;e.currentScene.children.length>n;n++){var s=e.currentScene.children[n];s!==this&&s.collisionType!==t.CollisionType.PreventCollision&&this.collides(s)&&this._dispatchAction()}0===this.repeats&&this.kill()},i.prototype._dispatchAction=function(){this._action.call(this),this.repeats--},i.prototype.draw=function(){},i.prototype.debugDraw=function(i){e.prototype.debugDraw.call(this,i),i.save(),i.translate(this.x,this.y);var n=this.getBounds();n.left=n.left-this.getWorldX(),n.right=n.right-this.getWorldX(),n.top=n.top-this.getWorldY(),n.bottom=n.bottom-this.getWorldY(),i.fillStyle=""+t.Color.Violet,i.strokeStyle=""+t.Color.Violet,i.fillText("Trigger",10,10),n.debugDraw(i),i.restore()},i}(t.Actor);t.Trigger=e})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Circle=0]="Circle",t[t.Rectangle=1]="Rectangle"})(t.EmitterType||(t.EmitterType={}));var e=t.EmitterType,i=function(){function e(e,i,n,s,o,r,h,a,c,u){this.position=new t.Vector(0,0),this.velocity=new t.Vector(0,0),this.acceleration=new t.Vector(0,0),this.particleRotationalVelocity=0,this.currentRotation=0,this.focus=null,this.focusAccel=0,this.opacity=1,this.beginColor=t.Color.White.clone(),this.endColor=t.Color.White.clone(),this.life=300,this.fadeFlag=!1,this._rRate=1,this._gRate=1,this._bRate=1,this._aRate=0,this._currentColor=t.Color.White.clone(),this.emitter=null,this.particleSize=5,this.particleSprite=null,this.sizeRate=0,this.elapsedMultiplier=0,this.emitter=e,this.life=i||this.life,this.opacity=n||this.opacity,this.endColor=o||this.endColor.clone(),this.beginColor=s||this.beginColor.clone(),this._currentColor=this.beginColor.clone(),this.position=r||this.position,this.velocity=h||this.velocity,this.acceleration=a||this.acceleration,this._rRate=(this.endColor.r-this.beginColor.r)/this.life,this._gRate=(this.endColor.g-this.beginColor.g)/this.life,this._bRate=(this.endColor.b-this.beginColor.b)/this.life,this._aRate=this.opacity/this.life,this.startSize=c||0,this.endSize=u||0,this.endSize>0&&this.startSize>0&&(this.sizeRate=(this.endSize-this.startSize)/this.life,this.particleSize=this.startSize)}return e.prototype.kill=function(){this.emitter.removeParticle(this)},e.prototype.update=function(e){if(this.life=this.life-e,this.elapsedMultiplier=this.elapsedMultiplier+e,0>this.life&&this.kill(),this.fadeFlag&&(this.opacity=t.Util.clamp(this._aRate*this.life,1e-4,1)),this.startSize>0&&this.endSize>0&&(this.particleSize=t.Util.clamp(this.sizeRate*e+this.particleSize,Math.min(this.startSize,this.endSize),Math.max(this.startSize,this.endSize))),this._currentColor.r=t.Util.clamp(this._currentColor.r+this._rRate*e,0,255),this._currentColor.g=t.Util.clamp(this._currentColor.g+this._gRate*e,0,255),this._currentColor.b=t.Util.clamp(this._currentColor.b+this._bRate*e,0,255),this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),this.focus){var i=this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(e/1e3);this.velocity=this.velocity.add(i)}else this.velocity=this.velocity.add(this.acceleration.scale(e/1e3));this.position=this.position.add(this.velocity.scale(e/1e3)),this.particleRotationalVelocity&&(this.currentRotation=(this.currentRotation+this.particleRotationalVelocity*e/1e3)%(2*Math.PI))},e.prototype.draw=function(e){return this.particleSprite?(this.particleSprite.rotation=this.currentRotation,this.particleSprite.scale.setTo(this.particleSize,this.particleSize),this.particleSprite.draw(e,this.position.x,this.position.y),void 0):(this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),e.fillStyle=""+this._currentColor,e.beginPath(),e.arc(this.position.x,this.position.y,this.particleSize,0,2*Math.PI),e.fill(),e.closePath(),void 0)},e}();t.Particle=i;var n=function(n){function s(i,s,o,r){n.call(this,i,s,o,r,t.Color.White),this._particlesToEmit=0,this.numParticles=0,this.isEmitting=!0,this.particles=null,this.deadParticles=null,this.minVel=0,this.maxVel=0,this.acceleration=new t.Vector(0,0),this.minAngle=0,this.maxAngle=0,this.emitRate=1,this.particleLife=2e3,this.opacity=1,this.fadeFlag=!1,this.focus=null,this.focusAccel=1,this.startSize=null,this.endSize=null,this.minSize=5,this.maxSize=5,this.beginColor=t.Color.White,this.endColor=t.Color.White,this.particleSprite=null,this.emitterType=e.Rectangle,this.radius=0,this.particleRotationalVelocity=0,this.randomRotation=!1,this.collisionType=t.CollisionType.PreventCollision,this.particles=new t.Util.Collection,this.deadParticles=new t.Util.Collection;for(var h in this.traits)this.traits[h]instanceof t.Traits.OffscreenCulling&&this.traits.splice(h,1)}return __extends(s,n),s.prototype.removeParticle=function(t){this.deadParticles.push(t)},s.prototype.emitParticles=function(t){for(var e=0;t>e;e++)this.particles.push(this._createParticle())},s.prototype.clearParticles=function(){this.particles.clear()},s.prototype._createParticle=function(){var n=0,s=0,o=t.Util.randomInRange(this.minAngle,this.maxAngle),r=t.Util.randomInRange(this.minVel,this.maxVel),h=this.startSize||t.Util.randomInRange(this.minSize,this.maxSize),a=r*Math.cos(o),c=r*Math.sin(o);if(this.emitterType===e.Rectangle)n=t.Util.randomInRange(this.x,this.x+this.getWidth()),s=t.Util.randomInRange(this.y,this.y+this.getHeight());else if(this.emitterType===e.Circle){var u=t.Util.randomInRange(0,this.radius);n=u*Math.cos(o)+this.x,s=u*Math.sin(o)+this.y}var l=new i(this,this.particleLife,this.opacity,this.beginColor,this.endColor,new t.Vector(n,s),new t.Vector(a,c),this.acceleration,this.startSize,this.endSize);return l.fadeFlag=this.fadeFlag,l.particleSize=h,this.particleSprite&&(l.particleSprite=this.particleSprite),l.particleRotationalVelocity=this.particleRotationalVelocity,this.randomRotation&&(l.currentRotation=t.Util.randomInRange(0,2*Math.PI)),this.focus&&(l.focus=this.focus.add(new t.Vector(this.x,this.y)),l.focusAccel=this.focusAccel),l},s.prototype.update=function(t,e){var i=this;n.prototype.update.call(this,t,e),this.isEmitting&&(this._particlesToEmit+=this.emitRate*(e/1e3),this._particlesToEmit>1&&(this.emitParticles(Math.floor(this._particlesToEmit)),this._particlesToEmit=this._particlesToEmit-Math.floor(this._particlesToEmit))),this.particles.forEach(function(t){return t.update(e)}),this.deadParticles.forEach(function(t){return i.particles.removeElement(t)}),this.deadParticles.clear()},s.prototype.draw=function(t){this.particles.forEach(function(e){return e.draw(t)})},s.prototype.debugDraw=function(e){n.prototype.debugDraw.call(this,e),e.fillStyle=""+t.Color.Black,e.fillText("Particles: "+this.particles.count(),this.x,this.y+20),this.focus&&(e.fillRect(this.focus.x+this.x,this.focus.y+this.y,3,3),t.Util.drawLine(e,"yellow",this.focus.x+this.x,this.focus.y+this.y,n.prototype.getCenter.call(this).x,n.prototype.getCenter.call(this).y),e.fillText("Focus",this.focus.x+this.x,this.focus.y+this.y))},s}(t.Actor);t.ParticleEmitter=n})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s){this.currentFrame=0,this._oldTime=Date.now(),this.anchor=new t.Point(0,0),this.rotation=0,this.scale=new t.Point(1,1),this.loop=!1,this.freezeFrame=-1,this.flipVertical=!1,this.flipHorizontal=!1,this.width=0,this.height=0,this.naturalWidth=0,this.naturalHeight=0,this.sprites=i,this.speed=n,this._engine=e,null!=s&&(this.loop=s),i&&i[0]&&(this.height=i[0]?i[0].height:0,this.width=i[0]?i[0].width:0,this.naturalWidth=i[0]?i[0].naturalWidth:0,this.naturalHeight=i[0]?i[0].naturalHeight:0,this.freezeFrame=i.length-1)}return e.prototype.opacity=function(e){this.addEffect(new t.Effects.Opacity(e))},e.prototype.grayscale=function(){this.addEffect(new t.Effects.Grayscale)},e.prototype.invert=function(){this.addEffect(new t.Effects.Invert)},e.prototype.fill=function(e){this.addEffect(new t.Effects.Fill(e))},e.prototype.colorize=function(e){this.addEffect(new t.Effects.Colorize(e))},e.prototype.lighten=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Lighten(e))},e.prototype.darken=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Darken(e))},e.prototype.saturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Saturate(e))},e.prototype.desaturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Desaturate(e))},e.prototype.addEffect=function(t){for(var e in this.sprites)this.sprites[e].addEffect(t)},e.prototype.removeEffect=function(t){for(var e in this.sprites)this.sprites[e].removeEffect(t)},e.prototype.clearEffects=function(){for(var t in this.sprites)this.sprites[t].clearEffects()},e.prototype._setAnchor=function(t){for(var e in this.sprites)this.sprites[e].anchor.setTo(t.x,t.y)},e.prototype._setRotation=function(t){for(var e in this.sprites)this.sprites[e].rotation=t},e.prototype._setScale=function(t){for(var e in this.sprites)this.sprites[e].scale=t},e.prototype.reset=function(){this.currentFrame=0},e.prototype.isDone=function(){return!this.loop&&this.currentFrame>=this.sprites.length},e.prototype.tick=function(){var t=Date.now();t-this._oldTime>this.speed&&(this.currentFrame=this.loop?(this.currentFrame+1)%this.sprites.length:this.currentFrame+1,this._oldTime=t)},e.prototype._updateValues=function(){this._setAnchor(this.anchor),this._setRotation(this.rotation),this._setScale(this.scale)},e.prototype.skip=function(t){this.currentFrame=(this.currentFrame+t)%this.sprites.length},e.prototype.draw=function(e,i,n){this.tick(),this._updateValues();var s;this.currentFrame=this.sprites.length&&(s=this.sprites[t.Util.clamp(this.freezeFrame,0,this.sprites.length-1)],s.draw(e,i,n)),s&&(this.width=s.width,this.height=s.height)},e.prototype.play=function(t,e){this.reset(),this._engine.playAnimation(this,t,e)},e}();t.Animation=e})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(){function e(e,i){this.path=e,this._log=t.Logger.getInstance(),this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},window.AudioContext?(this._log.debug("Using new Web Audio Api for "+e),this._soundImpl=new o(e,i)):(this._log.debug("Falling back to Audio Element for "+e),this._soundImpl=new n(e,i))}return e.prototype.setVolume=function(t){this._soundImpl.setVolume(t)},e.prototype.setLoop=function(t){this._soundImpl.setLoop(t)},e.prototype.load=function(){this._soundImpl.onload=this.onload,this._soundImpl.onprogress=this.onprogress,this._soundImpl.onerror=this.onerror,this._soundImpl.load()},e.prototype.processData=function(t){return this._soundImpl.processData(t)},e.prototype.getData=function(){return this._soundImpl.getData()},e.prototype.setData=function(t){this._soundImpl.setData(t)},e.prototype.isPlaying=function(){return this._soundImpl.isPlaying()},e.prototype.play=function(){return this._soundImpl.play()},e.prototype.pause=function(){this._soundImpl.pause()},e.prototype.stop=function(){this._soundImpl.stop()},e}();e.FallbackAudio=i;var n=function(){function e(e,i){var n=this;this.path=e,this._audioElements=Array(5),this._loadedAudio=null,this._isLoaded=!1,this._index=0,this._log=t.Logger.getInstance(),this._isPlaying=!1,this._currentOffset=0,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){};for(var s=0;this._audioElements.length>s;s++)(function(t){n._audioElements[t]=new Audio})(s);i?this.setVolume(t.Util.clamp(i,0,1)):this.setVolume(1)}return e.prototype.isPlaying=function(){return this._isPlaying},e.prototype._audioLoaded=function(){this._isLoaded=!0},e.prototype.setVolume=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].volume=t},e.prototype.setLoop=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].loop=t},e.prototype.getLoop=function(){this._audioElements.some(function(t){return t.loop})},e.prototype.load=function(){var t=this;if(!this._loadedAudio){var e=new XMLHttpRequest;e.open("GET",this.path,!0),e.responseType="blob",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(i){return 200!==e.status?(t._log.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t._isLoaded=!0,t.setData(e.response),t.onload(i),void 0)},e.send()}},e.prototype.getData=function(){return this._loadedAudio},e.prototype.setData=function(t){this._isLoaded=!0,this._loadedAudio=this.processData(t)},e.prototype.processData=function(t){var e=URL.createObjectURL(t);return this._audioElements.forEach(function(t){t.src=e}),this._audioLoaded(),e},e.prototype.play=function(){var e=this;this._audioElements[this._index].load(),this._audioElements[this._index].play(),this._currentOffset=0;var i=new t.Promise;return this._isPlaying=!0,this.getLoop()||this._audioElements[this._index].addEventListener("ended",function(){e._isPlaying=!1,i.resolve(!0)}),this._index=(this._index+1)%this._audioElements.length,i},e.prototype.pause=function(){this._index=(this._index-1+this._audioElements.length)%this._audioElements.length,this._currentOffset=this._audioElements[this._index].currentTime,this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e.prototype.stop=function(){this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e}();if(e.AudioTag=n,window.AudioContext)var s=new window.AudioContext;var o=function(){function e(e,i){this.path=e,this._context=s,this._volume=this._context.createGain(),this._buffer=null,this._sound=null,this._isLoaded=!1,this._loop=!1,this._isPlaying=!1,this._isPaused=!1,this._currentOffset=0,this._logger=t.Logger.getInstance(),this._data=null,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},this._volume.gain.value=i?t.Util.clamp(i,0,1):1}return e.prototype.setVolume=function(t){this._volume.gain.value=t},e.prototype.load=function(){var t=this;if(null===this._data){var e=new XMLHttpRequest;e.open("GET",this.path),e.responseType="arraybuffer",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(){return 200!==e.status?(t._logger.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t.setData(e.response),void 0)};try{e.send()}catch(i){console.error("Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.")}}},e.prototype.getData=function(){return this._data},e.prototype.setData=function(t){this._data=this.processData(t)},e.prototype.processData=function(t){var e=this;return this._context.decodeAudioData(t,function(t){e._buffer=t,e._isLoaded=!0,e.onload(e)},function(){e._logger.error("Unable to decode "+e.path+" this browser may not fully support this format, or the file may be corrupt, "+"if this is an mp3 try removing id3 tags and album art from the file."),e._isLoaded=!1,e.onload(e)}),t},e.prototype.setLoop=function(t){this._loop=t},e.prototype.isPlaying=function(){return this._isPlaying},e.prototype.play=function(){var e=this;if(this._isLoaded){this._sound=this._context.createBufferSource(),this._sound.buffer=this._buffer,this._sound.loop=this._loop,this._sound.connect(this._volume),this._volume.connect(this._context.destination),this._sound.start(0,this._currentOffset%this._buffer.duration),this._currentOffset=0;var i;return i=this._isPaused&&this._playPromise?this._playPromise:new t.Promise,this._isPaused=!1,this._isPlaying=!0,this._loop||(this._sound.onended=function(){e._isPlaying=!1,e._isPaused||i.resolve(!0)}.bind(this)),this._playPromise=i,i}return t.Promise.wrap(!0)},e.prototype.pause=function(){if(this._isPlaying)try{window.clearTimeout(this._playingTimer),this._sound.stop(0),this._currentOffset=this._context.currentTime,this._isPlaying=!1,this._isPaused=!0}catch(t){this._logger.warn("The sound clip",this.path,"has already been paused!")}},e.prototype.stop=function(){if(this._sound)try{window.clearTimeout(this._playingTimer),this._currentOffset=0,this._sound.stop(0),this._isPlaying=!1,this._isPaused=!1}catch(t){this._logger.warn("The sound clip",this.path,"has already been stopped!")}},e}();e.WebAudio=o})(e=t.Internal||(t.Internal={}))})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Resolved=0]="Resolved",t[t.Rejected=1]="Rejected",t[t.Pending=2]="Pending"})(t.PromiseState||(t.PromiseState={}));var e=t.PromiseState,i=function(){function i(){this._state=e.Pending,this._successCallbacks=[],this._rejectCallback=function(){},this._logger=t.Logger.getInstance()}return i.wrap=function(t){var e=(new i).resolve(t);return e},i.join=function(){for(var t=[],e=0;arguments.length>e;e++)t[e-0]=arguments[e];var n=new i;if(!t||!t.length)return n.resolve();var s=t.length,o=0,r=0,h=[];return t.forEach(function(t){t.then(function(){o+=1,o===s?n.resolve():o+r+h.length===s&&n.reject(h)},function(){r+=1,o+r+h.length===s&&n.reject(h)}).error(function(t){h.push(t),h.length+o+r===s&&n.reject(h)})}),n},i.prototype.then=function(t,i){if(t&&(this._successCallbacks.push(t),this.state()===e.Resolved))try{t.call(this,this._value)}catch(n){this._handleError(n)}if(i&&(this._rejectCallback=i,this.state()===e.Rejected))try{i.call(this,this._value)}catch(n){this._handleError(n)}return this},i.prototype.error=function(t){return t&&(this._errorCallback=t),this},i.prototype.resolve=function(t){var i=this;if(this._state!==e.Pending)throw Error("Cannot resolve a promise that is not in a pending state!");this._value=t;try{this._state=e.Resolved,this._successCallbacks.forEach(function(t){t.call(i,i._value)})}catch(n){this._handleError(n)}return this},i.prototype.reject=function(t){if(this._state!==e.Pending)throw Error("Cannot reject a promise that is not in a pending state!");this._value=t;try{this._state=e.Rejected,this._rejectCallback.call(this,this._value)}catch(i){this._handleError(i)}return this},i.prototype.state=function(){return this._state},i.prototype._handleError=function(t){if(!this._errorCallback)throw t;this._errorCallback.call(this,t)},i}();t.Promise=i})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s){void 0===s&&(s=!0),e.call(this),this.path=i,this.responseType=n,this.bustCache=s,this.data=null,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){}}return __extends(i,e),i.prototype.isLoaded=function(){return null!==this.data},i.prototype.wireEngine=function(t){this._engine=t},i.prototype._cacheBust=function(t){var e=/\?\w*=\w*/;return t+=e.test(t)?"&__="+Date.now():"?__="+Date.now()},i.prototype._start=function(){this.logger.debug("Started loading resource "+this.path)},i.prototype.load=function(){var e=this,i=new t.Promise;if(null!==this.data)return this.logger.debug("Already have data for resource",this.path),i.resolve(this.data),this.oncomplete(),i;var n=new XMLHttpRequest;return n.open("GET",this.bustCache?this._cacheBust(this.path):this.path,!0),n.responseType=this.responseType,n.onloadstart=function(t){e._start(t)},n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load resource ",e.path," server responded with error code",n.status),e.onerror(n.response),i.resolve(n.response),void 0):(e.data=e.processData(n.response),e.oncomplete(),e.logger.debug("Completed loading resource",e.path),i.resolve(e.data),void 0)},n.send(),i},i.prototype.getData=function(){return this.data},i.prototype.setData=function(t){this.data=this.processData(t)},i.prototype.processData=function(t){return URL.createObjectURL(t)},i}(t.Class);t.Resource=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n){void 0===n&&(n=!0),e.call(this,i,"blob",n),this.path=i,this.bustCache=n,this.loaded=new t.Promise,this._isLoaded=!1,this._sprite=null,this._sprite=new t.Sprite(this,0,0,0,0)}return __extends(i,e),i.prototype.isLoaded=function(){return this._isLoaded},i.prototype.load=function(){var i=this,n=new t.Promise,s=e.prototype.load.call(this);return s.then(function(){i.image=new Image,i.image.addEventListener("load",function(){i._isLoaded=!0,i.width=i._sprite.swidth=i._sprite.naturalWidth=i._sprite.width=i.image.naturalWidth,i.height=i._sprite.sheight=i._sprite.naturalHeight=i._sprite.height=i.image.naturalHeight,i.loaded.resolve(i.image),n.resolve(i.image)}),i.image.src=e.prototype.getData.call(i)},function(){n.reject("Error loading texture.")}),n},i.prototype.asSprite=function(){return this._sprite},i}(t.Resource);t.Texture=e;var i=function(){function e(){for(var i=[],n=0;arguments.length>n;n++)i[n-0]=arguments[n];this._logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this.onload=function(){},this._isLoaded=!1,this._wasPlayingOnHidden=!1,this.path="";for(var s=0;i.length>s;s++)if(e.canPlayFile(i[s])){this.path=i[s];break}this.path||(this._logger.warn("This browser does not support any of the audio files specified:",i.join(", ")),this._logger.warn("Attempting to use",i[0]),this.path=i[0]),this.sound=new t.Internal.FallbackAudio(this.path,1)}return e.canPlayFile=function(e){try{var i=new Audio,n=/.*\.([A-Za-z0-9]+)$/,s=e.match(n)[1];return i.canPlayType("audio/"+s)?!0:!1}catch(o){return t.Logger.getInstance().warn("Cannot determine audio support, assuming no support for the Audio Tag",o),!1}},e.prototype.wireEngine=function(t){var e=this;t&&(this._engine=t,this._engine.on("hidden",function(){t.pauseAudioWhenHidden&&e.isPlaying()&&(e._wasPlayingOnHidden=!0,e.pause())}),this._engine.on("visible",function(){t.pauseAudioWhenHidden&&e._wasPlayingOnHidden&&(e.play(),e._wasPlayingOnHidden=!1)}))},e.prototype.setVolume=function(t){this.sound&&this.sound.setVolume(t)},e.prototype.setLoop=function(t){this.sound&&this.sound.setLoop(t)},e.prototype.isPlaying=function(){return this.sound?this.sound.isPlaying():void 0},e.prototype.play=function(){return this.sound?this.sound.play():void 0},e.prototype.pause=function(){this.sound&&this.sound.pause()},e.prototype.stop=function(){this.sound&&this.sound.stop()},e.prototype.isLoaded=function(){return this._isLoaded},e.prototype.load=function(){var e=this,i=new t.Promise;return null!==this.sound.getData()?(this._logger.debug("Already have data for resource",this.path),i.resolve(this.sound),i):(this._logger.debug("Started loading sound",this.path),this.sound.onprogress=this.onprogress,this.sound.onload=function(){e.oncomplete(),e._isLoaded=!0,e._logger.debug("Completed loading sound",e.path),i.resolve(e.sound)},this.sound.onerror=function(t){e.onerror(t),i.resolve(t)},this.sound.load(),i)},e.prototype.getData=function(){return this.sound.getData()},e.prototype.setData=function(t){this.sound.setData(t)},e.prototype.processData=function(t){return this.sound.processData(t)},e}();t.Sound=i;var n=function(){function e(t){this._resourceList=[],this._index=0,this._resourceCount=0,this._numLoaded=0,this._progressCounts={},this._totalCounts={},this.getData=function(){},this.setData=function(){},this.processData=function(){},this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},t&&this.addResources(t)}return e.prototype.wireEngine=function(t){this._engine=t},e.prototype.addResource=function(t){var e=this._index++;this._resourceList.push(t),this._progressCounts[e]=0,this._totalCounts[e]=1,this._resourceCount++},e.prototype.addResources=function(t){var e=0,i=t.length;for(e;i>e;e++)this.addResource(t[e])},e.prototype._sumCounts=function(t){var e=0;for(var i in t)e+=0|t[i];return e},e.prototype.isLoaded=function(){return this._numLoaded===this._resourceCount},e.prototype.load=function(){function e(t,i){t[i]&&t[i].load().then(function(){e(t,i+1)})}var i=this,n=new t.Promise,s=this;if(0===this._resourceList.length)return s.oncomplete.call(s),n;var o=Array(this._resourceList.length),r=this._resourceList.length;return this._resourceList.forEach(function(t,e){i._engine&&t.wireEngine(i._engine),t.onprogress=function(t){var i=t.total,n=t.loaded;o[e]={loaded:n/i*(100/r),total:100};var h=o.reduce(function(t,e){return{loaded:t.loaded+e.loaded,total:100}},{loaded:0,total:100});s.onprogress.call(s,h)},t.oncomplete=t.onerror=function(){s._numLoaded++,s._numLoaded===s._resourceCount&&(s.onprogress.call(s,{loaded:100,total:100}),s.oncomplete.call(s),n.resolve())}}),e(this._resourceList,0),n},e}();t.Loader=n})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.failedTests=[],this._criticalTests={canvasSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("2d"))},arrayBufferSupport:function(){var t=new XMLHttpRequest;t.open("GET","/");try{t.responseType="arraybuffer"}catch(e){return!1}return"arraybuffer"===t.responseType},dataUrlSupport:function(){var t=document.createElement("canvas");return 0===t.toDataURL("image/png").indexOf("data:image/png")},objectUrlSupport:function(){return"URL"in window&&"revokeObjectURL"in URL&&"createObjectURL"in URL},rgbaSupport:function(){var t=document.createElement("a").style;return t.cssText="background-color:rgba(150,255,150,.5)",(""+t.backgroundColor).indexOf("rgba")>-1}},this._warningTest={webAudioSupport:function(){return!!(window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext)},webglSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("webgl"))}}}return e.prototype.test=function(){var e=!1;for(var i in this._criticalTests)this._criticalTests[i]()||(this.failedTests.push(i),t.Logger.getInstance().error("Critical browser feature missing, Excalibur requires:",i),e=!0);if(e)return!1;for(var n in this._warningTest)this._warningTest[n]()||t.Logger.getInstance().warn("Warning browser feature missing, Excalibur will have reduced performance:",n);return!0},e}();t.Detector=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this.path=e,this._isLoaded=!1,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this._innerElement=document.createElement("div"),this._innerElement.className="excalibur-template"}return e.prototype.wireEngine=function(t){this._engine=t},e.prototype.getTemplateString=function(){return this._isLoaded?this._htmlString:""},e.prototype._compile=function(){this._innerElement.innerHTML=this._htmlString,this._styleElements=this._innerElement.querySelectorAll("[data-style]"),this._textElements=this._innerElement.querySelectorAll("[data-text]")},e.prototype._evaluateExpresion=function(t,e){var i=Function("return "+t+";"),n=i.call(e);return n},e.prototype.apply=function(t){for(var e=this,i=0;this._styleElements.length>i;i++)(function(){var n={};e._styleElements[i].dataset.style.split(";").forEach(function(t){if(t){var e=t.split(":");n[e[0].trim()]=e[1].trim()}});for(var s in n)(function(){var o=n[s];e._styleElements[i].style[s]=e._evaluateExpresion(o,t)})()})();for(var n=0;this._textElements.length>n;n++)(function(){var i=e._textElements[n].dataset.text;e._textElements[n].innerText=e._evaluateExpresion(i,t)})();return 1===this._innerElement.children.length&&(this._innerElement=this._innerElement.firstChild),this._innerElement},e.prototype.load=function(){var e=this,i=new t.Promise,n=new XMLHttpRequest;return n.open("GET",this.path,!0),n.responseType="text",n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load html template resource ",e.path," server responded with error code",n.status),e.onerror(n.response),e._isLoaded=!1,i.resolve("error"),void 0):(e.setData(n.response),e.oncomplete(),e.logger.debug("Completed loading template",e.path),i.resolve(e._htmlString),void 0)},n.overrideMimeType&&n.overrideMimeType("text/plain; charset=x-user-defined"),n.send(),i},e.prototype.getData=function(){return this._htmlString},e.prototype.setData=function(t){this._htmlString=this.processData(t),this._compile(),this._isLoaded=!0},e.prototype.processData=function(t){return t},e.prototype.isLoaded=function(){return this._isLoaded},e}();t.Template=e;var i=function(){function t(t,e,i){this.parent=document.getElementById(t),this.template=e,this._ctx=i,this.update()}return t.prototype.listen=function(t,e,i){var n=this;i||(i=function(){n.update()}),t.addEventListener&&e.forEach(function(e){t.addEventListener(e,i)})},t.prototype.update=function(){var t=this._applyTemplate(this.template,this._ctx);t instanceof String&&(this.parent.innerHTML=t),t instanceof Node&&this.parent.lastChild!==t&&this.parent.appendChild(t)},t.prototype._applyTemplate=function(t,e){return t.isLoaded()?t.apply(e):void 0},t}();t.Binding=i})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Em=0]="Em",t[t.Rem=1]="Rem",t[t.Px=2]="Px",t[t.Pt=3]="Pt",t[t.Percent=4]="Percent"})(t.FontUnit||(t.FontUnit={}));var e=t.FontUnit;(function(t){t[t.Left=0]="Left",t[t.Right=1]="Right",t[t.Center=2]="Center",t[t.Start=3]="Start",t[t.End=4]="End"})(t.TextAlign||(t.TextAlign={}));var i=t.TextAlign;(function(t){t[t.Top=0]="Top",t[t.Hanging=1]="Hanging",t[t.Middle=2]="Middle",t[t.Alphabetic=3]="Alphabetic",t[t.Ideographic=4]="Ideographic",t[t.Bottom=5]="Bottom"})(t.BaseAlign||(t.BaseAlign={}));var n=t.BaseAlign,s=function(s){function o(o,r,h,a,c){s.call(this,r,h),this.fontSize=10,this.fontUnit=e.Px,this.textAlign=i.Left,this.baseAlign=n.Bottom,this.letterSpacing=0,this.caseInsensitive=!0,this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone(),this._shadowColorDirty=!1,this._textSprites={},this._shadowSprites={},this._color=t.Color.Black.clone(),this.text=o||"",this.color=t.Color.Black.clone(),this.spriteFont=c,this.collisionType=t.CollisionType.PreventCollision,this.fontFamily=a||"10px sans-serif"}return __extends(o,s),o.prototype.getTextWidth=function(t){var e=t.font;t.font=this.fontFamily;var i=t.measureText(this.text).width;return t.font=e,i},o.prototype._lookupFontUnit=function(t){switch(t){case e.Em:return"em";case e.Rem:return"rem";case e.Pt:return"pt";case e.Px:return"px";case e.Percent:return"%";default:return"px"}},o.prototype._lookupTextAlign=function(t){switch(t){case i.Left:return"left";case i.Right:return"right";case i.Center:return"center";case i.End:return"end";case i.Start:return"start";default:return"start"}},o.prototype._lookupBaseAlign=function(t){switch(t){case n.Alphabetic:return"alphabetic";case n.Bottom:return"bottom";case n.Hanging:return"hangin";case n.Ideographic:return"ideographic";case n.Middle:return"middle";case n.Top:return"top";default:return"alphabetic"}},o.prototype.setTextShadow=function(t,e,i){this.spriteFont.setTextShadow(t,e,i)},o.prototype.useTextShadow=function(t){this.spriteFont.useTextShadow(t)},o.prototype.clearTextShadow=function(){this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone() -},o.prototype.update=function(t,e){s.prototype.update.call(this,t,e)},o.prototype.draw=function(t,e){t.save(),t.translate(this.x,this.y),t.scale(this.scale.x,this.scale.y),t.rotate(this.rotation),this._textShadowOn&&(t.save(),t.translate(this._shadowOffsetX,this._shadowOffsetY),this._fontDraw(t,e,this._shadowSprites),t.restore()),this._fontDraw(t,e,this._textSprites),s.prototype.draw.call(this,t,e),t.restore()},o.prototype._fontDraw=function(t){if(this.spriteFont)this.spriteFont.draw(t,this.text,0,0,{color:this.color.clone(),baseAlign:this.baseAlign,textAlign:this.textAlign,fontSize:this.fontSize,letterSpacing:this.letterSpacing,opacity:this.opacity});else{var e=t.textAlign,i=t.textBaseline;t.textAlign=this._lookupTextAlign(this.textAlign),t.textBaseline=this._lookupBaseAlign(this.baseAlign),this.color&&(this.color.a=this.opacity),t.fillStyle=""+this.color,t.font=""+this.fontSize+this._lookupFontUnit(this.fontUnit)+" "+this.fontFamily,this.maxWidth?t.fillText(this.text,0,0,this.maxWidth):t.fillText(this.text,0,0),t.textAlign=e,t.textBaseline=i}},o.prototype.debugDraw=function(t){s.prototype.debugDraw.call(this,t)},o}(t.Actor);t.Label=s})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Touch=0]="Touch",t[t.Mouse=1]="Mouse",t[t.Pen=2]="Pen",t[t.Unknown=3]="Unknown"})(e.PointerType||(e.PointerType={}));var i=e.PointerType;(function(t){t[t.Left=0]="Left",t[t.Middle=1]="Middle",t[t.Right=2]="Right",t[t.Unknown=3]="Unknown"})(e.PointerButton||(e.PointerButton={}));var n=e.PointerButton;(function(t){t[t.Canvas=0]="Canvas",t[t.Document=1]="Document"})(e.PointerScope||(e.PointerScope={}));var s=e.PointerScope,o=function(t){function e(e,i,n,s,o,r){t.call(this),this.x=e,this.y=i,this.index=n,this.pointerType=s,this.button=o,this.ev=r}return __extends(e,t),e}(t.GameEvent);e.PointerEvent=o;var r=function(e){function r(t){e.call(this),this._pointerDown=[],this._pointerUp=[],this._pointerMove=[],this._pointerCancel=[],this._pointers=[],this._activePointers=[],this._engine=t,this._pointers.push(new h),this._activePointers=[-1],this.primary=this._pointers[0]}return __extends(r,e),r.prototype.init=function(t){void 0===t&&(t=s.Document);var e=document;e=t===s.Document?document:this._engine.canvas,e.addEventListener("touchstart",this._handleTouchEvent("down",this._pointerDown)),e.addEventListener("touchend",this._handleTouchEvent("up",this._pointerUp)),e.addEventListener("touchmove",this._handleTouchEvent("move",this._pointerMove)),e.addEventListener("touchcancel",this._handleTouchEvent("cancel",this._pointerCancel)),window.PointerEvent?(this._engine.canvas.style.touchAction="none",e.addEventListener("pointerdown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("pointerup",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("pointermove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("pointercancel",this._handlePointerEvent("cancel",this._pointerMove))):window.MSPointerEvent?(this._engine.canvas.style.msTouchAction="none",e.addEventListener("MSPointerDown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("MSPointerUp",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("MSPointerMove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("MSPointerCancel",this._handlePointerEvent("cancel",this._pointerMove))):(e.addEventListener("mousedown",this._handleMouseEvent("down",this._pointerDown)),e.addEventListener("mouseup",this._handleMouseEvent("up",this._pointerUp)),e.addEventListener("mousemove",this._handleMouseEvent("move",this._pointerMove)))},r.prototype.update=function(){this._pointerUp.length=0,this._pointerDown.length=0,this._pointerMove.length=0,this._pointerCancel.length=0},r.prototype.at=function(t){if(t>=this._pointers.length)for(var e=this._pointers.length-1,i=t;i>e;e++)this._pointers.push(new h),this._activePointers.push(-1);return this._pointers[t]},r.prototype.count=function(){return this._pointers.length},r.prototype.propogate=function(e){var i=e instanceof t.UIActor,n=0,s=this._pointerUp.length;for(n;s>n;n++)e.contains(this._pointerUp[n].x,this._pointerUp[n].y,!i)&&e.eventDispatcher.emit("pointerup",this._pointerUp[n]);for(n=0,s=this._pointerDown.length,n;s>n;n++)e.contains(this._pointerDown[n].x,this._pointerDown[n].y,!i)&&e.eventDispatcher.emit("pointerdown",this._pointerDown[n]);if(e.capturePointer.captureMoveEvents)for(n=0,s=this._pointerMove.length,n;s>n;n++)e.contains(this._pointerMove[n].x,this._pointerMove[n].y,!i)&&e.eventDispatcher.emit("pointermove",this._pointerMove[n]);for(n=0,s=this._pointerCancel.length,n;s>n;n++)e.contains(this._pointerCancel[n].x,this._pointerCancel[n].y,!i)&&e.eventDispatcher.emit("pointercancel",this._pointerCancel[n])},r.prototype._handleMouseEvent=function(e,n){var s=this;return function(r){r.preventDefault();var h=r.pageX-t.Util.getPosition(s._engine.canvas).x,a=r.pageY-t.Util.getPosition(s._engine.canvas).y,c=s._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,0,i.Mouse,r.button,r);n.push(u),s.at(0).eventDispatcher.emit(e,u)}},r.prototype._handleTouchEvent=function(e,s){var r=this;return function(h){h.preventDefault();for(var a=0,c=h.changedTouches.length;c>a;a++){var u=r._pointers.length>1?r._getPointerIndex(h.changedTouches[a].identifier):0;if(-1!==u){var l=h.changedTouches[a].pageX-t.Util.getPosition(r._engine.canvas).x,p=h.changedTouches[a].pageY-t.Util.getPosition(r._engine.canvas).y,d=r._engine.screenToWorldCoordinates(new t.Point(l,p)),f=new o(d.x,d.y,u,i.Touch,n.Unknown,h);s.push(f),r.at(u).eventDispatcher.emit(e,f),r._pointers.length>1&&("up"===e?r._activePointers[u]=-1:"down"===e&&(r._activePointers[u]=h.changedTouches[a].identifier))}}}},r.prototype._handlePointerEvent=function(e,i){var n=this;return function(s){s.preventDefault();var r=n._pointers.length>1?n._getPointerIndex(s.pointerId):0;if(-1!==r){var h=s.pageX-t.Util.getPosition(n._engine.canvas).x,a=s.pageY-t.Util.getPosition(n._engine.canvas).y,c=n._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,r,n._stringToPointerType(s.pointerType),s.button,s);i.push(u),n.at(r).eventDispatcher.emit(e,u),n._pointers.length>1&&("up"===e?n._activePointers[r]=-1:"down"===e&&(n._activePointers[r]=s.pointerId))}}},r.prototype._getPointerIndex=function(t){var e;if((e=this._activePointers.indexOf(t))>-1)return e;for(var i=0;this._activePointers.length>i;i++)if(-1===this._activePointers[i])return i;return-1},r.prototype._stringToPointerType=function(t){switch(t){case"touch":return i.Touch;case"mouse":return i.Mouse;case"pen":return i.Pen;default:return i.Unknown}},r}(t.Class);e.Pointers=r;var h=function(t){function e(){t.apply(this,arguments)}return __extends(e,t),e}(t.Class);e.Pointer=h})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Num1=97]="Num1",t[t.Num2=98]="Num2",t[t.Num3=99]="Num3",t[t.Num4=100]="Num4",t[t.Num5=101]="Num5",t[t.Num6=102]="Num6",t[t.Num7=103]="Num7",t[t.Num8=104]="Num8",t[t.Num9=105]="Num9",t[t.Num0=96]="Num0",t[t.Numlock=144]="Numlock",t[t.Semicolon=186]="Semicolon",t[t.A=65]="A",t[t.B=66]="B",t[t.C=67]="C",t[t.D=68]="D",t[t.E=69]="E",t[t.F=70]="F",t[t.G=71]="G",t[t.H=72]="H",t[t.I=73]="I",t[t.J=74]="J",t[t.K=75]="K",t[t.L=76]="L",t[t.M=77]="M",t[t.N=78]="N",t[t.O=79]="O",t[t.P=80]="P",t[t.Q=81]="Q",t[t.R=82]="R",t[t.S=83]="S",t[t.T=84]="T",t[t.U=85]="U",t[t.V=86]="V",t[t.W=87]="W",t[t.X=88]="X",t[t.Y=89]="Y",t[t.Z=90]="Z",t[t.Shift=16]="Shift",t[t.Alt=18]="Alt",t[t.Up=38]="Up",t[t.Down=40]="Down",t[t.Left=37]="Left",t[t.Right=39]="Right",t[t.Space=32]="Space",t[t.Esc=27]="Esc"})(e.Keys||(e.Keys={})),e.Keys;var i=function(t){function e(e){t.call(this),this.key=e}return __extends(e,t),e}(t.GameEvent);e.KeyEvent=i;var n=function(t){function e(e){t.call(this),this._keys=[],this._keysUp=[],this._keysDown=[],this._engine=e}return __extends(e,t),e.prototype.init=function(){var t=this;window.addEventListener("blur",function(){t._keys.length=0}),window.addEventListener("keyup",function(e){var n=t._keys.indexOf(e.keyCode);t._keys.splice(n,1),t._keysUp.push(e.keyCode);var s=new i(e.keyCode);t.eventDispatcher.emit("up",s),t.eventDispatcher.emit("release",s)}),window.addEventListener("keydown",function(e){if(-1===t._keys.indexOf(e.keyCode)){t._keys.push(e.keyCode),t._keysDown.push(e.keyCode);var n=new i(e.keyCode);t.eventDispatcher.emit("down",n),t.eventDispatcher.emit("press",n)}})},e.prototype.update=function(){this._keysDown.length=0,this._keysUp.length=0;for(var t=0;this._keys.length>t;t++)this.eventDispatcher.emit("hold",new i(this._keys[t]))},e.prototype.getKeys=function(){return this._keys},e.prototype.wasPressed=function(t){return this._keysDown.indexOf(t)>-1},e.prototype.isHeld=function(t){return this._keys.indexOf(t)>-1},e.prototype.wasReleased=function(t){return this._keysUp.indexOf(t)>-1},e}(t.Class);e.Keyboard=n})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(e){function i(t){e.call(this),this.enabled=!1,this.supported=!!navigator.getGamepads,this._gamePadTimeStamps=[0,0,0,0],this._oldPads=[],this._pads=[],this._initSuccess=!1,this._navigator=navigator,this._minimumConfiguration=null,this._engine=t}return __extends(i,e),i.prototype.init=function(){this.supported&&(this._initSuccess||(this._oldPads=this._clonePads(this._navigator.getGamepads()),this._oldPads.length&&this._oldPads[0]&&(this._initSuccess=!0)))},i.prototype.setMinimumGamepadConfiguration=function(t){this._enableAndUpdate(),this._minimumConfiguration=t},i.prototype._enableAndUpdate=function(){this.enabled||(this.enabled=!0,this.update(100))},i.prototype._isGamepadValid=function(t){if(!this._minimumConfiguration)return!0;if(!t)return!1;var e=t.axes.filter(function(t){return void 0!==typeof t}).length,i=t.buttons.filter(function(t){return void 0!==typeof t}).length;return e>=this._minimumConfiguration.axis&&i>=this._minimumConfiguration.buttons&&t.connected},i.prototype.on=function(t,i){this._enableAndUpdate(),e.prototype.on.call(this,t,i)},i.prototype.off=function(t,i){this._enableAndUpdate(),e.prototype.off.call(this,t,i)},i.prototype.update=function(){if(this.enabled&&this.supported){this.init();for(var e=this._navigator.getGamepads(),i=0;e.length>i;i++)if(e[i]){if(!this.at(i).connected&&this._isGamepadValid(e[i])&&this.eventDispatcher.emit("connect",new t.GamepadConnectEvent(i,this.at(i))),this.at(i).connected=!0,!e[i].timestamp||e[i].timestamp!==this._gamePadTimeStamps[i]){this._gamePadTimeStamps[i]=e[i].timestamp,this.at(i).navigatorGamepad=e[i];var n,r,h,a,c;for(n in s)"number"==typeof s[n]&&(a=s[n],e[i].buttons[a]&&(h=e[i].buttons[a].value,h!==this._oldPads[i].getButton(a)&&(e[i].buttons[a].pressed?(this.at(i).updateButton(a,h),this.at(i).eventDispatcher.publish("button",new t.GamepadButtonEvent(a,h))):this.at(i).updateButton(a,0))));for(r in o)"number"==typeof o[r]&&(c=o[r],h=e[i].axes[c],h!==this._oldPads[i].getAxes(c)&&(this.at(i).updateAxes(c,h),this.at(i).eventDispatcher.emit("axis",new t.GamepadAxisEvent(c,h))));this._oldPads[i]=this._clonePad(e[i])}}else this.at(i).connected&&this.eventDispatcher.emit("disconnect",new t.GamepadDisconnectEvent(i)),this.at(i).connected=!1}},i.prototype.at=function(t){if(this._enableAndUpdate(),t>=this._pads.length)for(var e=this._pads.length-1,i=t;i>e;e++)this._pads.push(new n),this._oldPads.push(new n);return this._pads[t]},i.prototype.getValidGamepads=function(){this._enableAndUpdate();for(var t=[],e=0;this._pads.length>e;e++)this._isGamepadValid(this.at(e).navigatorGamepad)&&this.at(e).connected&&t.push(this.at(e));return t},i.prototype.count=function(){return this._pads.filter(function(t){return t.connected}).length},i.prototype._clonePads=function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(this._clonePad(t[i]));return e},i.prototype._clonePad=function(t){var e,i,s=new n;if(!t)return s;for(e=0,i=t.buttons.length;i>e;e++)t.buttons[e]&&s.updateButton(e,t.buttons[e].value);for(e=0,i=t.axes.length;i>e;e++)s.updateAxes(e,t.axes[e]);return s},i.MinAxisMoveThreshold=.05,i}(t.Class);e.Gamepads=i;var n=function(t){function e(){t.call(this),this.connected=!1,this._buttons=Array(16),this._axes=Array(4);var e;for(e=0;this._buttons.length>e;e++)this._buttons[e]=0;for(e=0;this._axes.length>e;e++)this._axes[e]=0}return __extends(e,t),e.prototype.isButtonPressed=function(t,e){return void 0===e&&(e=1),this._buttons[t]>=e},e.prototype.getButton=function(t){return this._buttons[t]},e.prototype.getAxes=function(t){var e=this._axes[t];return Math.abs(e)n;n++)this._animations[n].animation.draw(i,this._animations[n].x,this._animations[n].y);if(this.fps=1/(e/1e3),this.isDebug){this.ctx.font="Consolas",this.ctx.fillStyle=""+this.debugColor;for(var o=this.input.keyboard.getKeys(),r=0;o.length>r;r++)this.ctx.fillText(""+o[r]+" : "+(t.Input.Keys[o[r]]?t.Input.Keys[o[r]]:"Not Mapped"),100,10*r+10);this.ctx.fillText("FPS:"+(""+this.fps.toFixed(2)),10,10)}for(var h=0;this.postProcessors.length>h;h++)this.postProcessors[h].process(this.ctx.getImageData(0,0,this.width,this.height),this.ctx);this.emit("postdraw",new t.PreDrawEvent(i,e,this))},s.prototype.start=function(e){if(!this._compatible){var i=new t.Promise;return i.reject("Excalibur is incompatible with your browser")}var n;if(e?(e.wireEngine(this),n=this.load(e)):n=t.Promise.wrap(),!this._hasStarted){this._hasStarted=!0,this._logger.debug("Starting game...");var s=Date.now(),o=this;(function r(){if(o._hasStarted)try{o._requestId=window.requestAnimationFrame(r);var t=Date.now(),e=Math.floor(t-s)||1;e>200&&(e=1),o._update(e),o._draw(e),s=t}catch(i){window.cancelAnimationFrame(o._requestId),o.stop(),o.onFatalException(i)}})(),this._logger.debug("Game started")}return n},s.prototype.stop=function(){this._hasStarted&&(this._hasStarted=!1,this._logger.debug("Game stopped"))},s.prototype.screenshot=function(){var t=new Image,e=this.canvas.toDataURL("image/png");return t.src=e,t},s.prototype._drawLoadingBar=function(t,e,i){if(this._loadingDraw)return this._loadingDraw(t,e,i),void 0;var n=this.canvas.height/2,s=this.canvas.width/3,o=s,r=new Image;r.src="data:image/png;base64,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"; -var h=3*s/8,a=this.getAntialiasing();this.setAntialiasing(!0),t.drawImage(r,0,0,800,300,o,n-h-20,s,h),t.strokeStyle="white",t.lineWidth=2,t.strokeRect(o,n,s,20);var c=s*(e/i);t.fillStyle="white";var u=5,l=c-2*u,p=20-2*u;t.fillRect(o+u,n+u,l>0?l:0,p),this.setAntialiasing(a)},s.prototype.setLoadingDrawFunction=function(t){this._loadingDraw=t},s.prototype.load=function(e){var i=this,n=new t.Promise;return this._isLoading=!0,e.onprogress=function(t){i._progress=t.loaded,i._total=t.total,i._logger.debug("Loading "+(100*i._progress/i._total).toFixed(0))},e.oncomplete=function(){setTimeout(function(){i._isLoading=!1,n.resolve()},500)},e.load(),n},s}(t.Class);t.Engine=e,function(t){t[t.FullScreen=0]="FullScreen",t[t.Container=1]="Container",t[t.Fixed=2]="Fixed"}(t.DisplayMode||(t.DisplayMode={}));var i=t.DisplayMode,n=function(){function t(t,e,i){this.animation=t,this.x=e,this.y=i}return t}()})(ex||(ex={})); +})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s){void 0===s&&(s=!0),e.call(this),this.path=i,this.responseType=n,this.bustCache=s,this.data=null,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){}}return __extends(i,e),i.prototype.isLoaded=function(){return null!==this.data},i.prototype.wireEngine=function(t){this._engine=t},i.prototype._cacheBust=function(t){var e=/\?\w*=\w*/;return t+=e.test(t)?"&__="+Date.now():"?__="+Date.now()},i.prototype._start=function(){this.logger.debug("Started loading resource "+this.path)},i.prototype.load=function(){var e=this,i=new t.Promise;if(null!==this.data)return this.logger.debug("Already have data for resource",this.path),i.resolve(this.data),this.oncomplete(),i;var n=new XMLHttpRequest;return n.open("GET",this.bustCache?this._cacheBust(this.path):this.path,!0),n.responseType=this.responseType,n.onloadstart=function(t){e._start(t)},n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load resource ",e.path," server responded with error code",n.status),e.onerror(n.response),i.resolve(n.response),void 0):(e.data=e.processData(n.response),e.oncomplete(),e.logger.debug("Completed loading resource",e.path),i.resolve(e.data),void 0)},n.send(),i},i.prototype.getData=function(){return this.data},i.prototype.setData=function(t){this.data=this.processData(t)},i.prototype.processData=function(t){return URL.createObjectURL(t)},i}(t.Class);t.Resource=e})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Resolved=0]="Resolved",t[t.Rejected=1]="Rejected",t[t.Pending=2]="Pending"})(t.PromiseState||(t.PromiseState={}));var e=t.PromiseState,i=function(){function i(){this._state=e.Pending,this._successCallbacks=[],this._rejectCallback=function(){},this._logger=t.Logger.getInstance()}return i.wrap=function(t){var e=(new i).resolve(t);return e},i.join=function(){for(var t=[],e=0;arguments.length>e;e++)t[e-0]=arguments[e];var n=new i;if(!t||!t.length)return n.resolve();var s=t.length,o=0,r=0,h=[];return t.forEach(function(t){t.then(function(){o+=1,o===s?n.resolve():o+r+h.length===s&&n.reject(h)},function(){r+=1,o+r+h.length===s&&n.reject(h)}).error(function(t){h.push(t),h.length+o+r===s&&n.reject(h)})}),n},i.prototype.then=function(t,i){if(t&&(this._successCallbacks.push(t),this.state()===e.Resolved))try{t.call(this,this._value)}catch(n){this._handleError(n)}if(i&&(this._rejectCallback=i,this.state()===e.Rejected))try{i.call(this,this._value)}catch(n){this._handleError(n)}return this},i.prototype.error=function(t){return t&&(this._errorCallback=t),this},i.prototype.resolve=function(t){var i=this;if(this._state!==e.Pending)throw Error("Cannot resolve a promise that is not in a pending state!");this._value=t;try{this._state=e.Resolved,this._successCallbacks.forEach(function(t){t.call(i,i._value)})}catch(n){this._handleError(n)}return this},i.prototype.reject=function(t){if(this._state!==e.Pending)throw Error("Cannot reject a promise that is not in a pending state!");this._value=t;try{this._state=e.Rejected,this._rejectCallback.call(this,this._value)}catch(i){this._handleError(i)}return this},i.prototype.state=function(){return this._state},i.prototype._handleError=function(t){if(!this._errorCallback)throw t;this._errorCallback.call(this,t)},i}();t.Promise=i})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n){void 0===n&&(n=!0),e.call(this,i,"blob",n),this.path=i,this.bustCache=n,this.loaded=new t.Promise,this._isLoaded=!1,this._sprite=null,this._sprite=new t.Sprite(this,0,0,0,0)}return __extends(i,e),i.prototype.isLoaded=function(){return this._isLoaded},i.prototype.load=function(){var i=this,n=new t.Promise,s=e.prototype.load.call(this);return s.then(function(){i.image=new Image,i.image.addEventListener("load",function(){i._isLoaded=!0,i.width=i._sprite.swidth=i._sprite.naturalWidth=i._sprite.width=i.image.naturalWidth,i.height=i._sprite.sheight=i._sprite.naturalHeight=i._sprite.height=i.image.naturalHeight,i.loaded.resolve(i.image),n.resolve(i.image)}),i.image.src=e.prototype.getData.call(i)},function(){n.reject("Error loading texture.")}),n},i.prototype.asSprite=function(){return this._sprite},i}(t.Resource);t.Texture=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){for(var i=[],n=0;arguments.length>n;n++)i[n-0]=arguments[n];this._logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this.onload=function(){},this._isLoaded=!1,this._wasPlayingOnHidden=!1,this.path="";for(var s=0;i.length>s;s++)if(e.canPlayFile(i[s])){this.path=i[s];break}this.path||(this._logger.warn("This browser does not support any of the audio files specified:",i.join(", ")),this._logger.warn("Attempting to use",i[0]),this.path=i[0]),this.sound=new t.Internal.FallbackAudio(this.path,1)}return e.canPlayFile=function(e){try{var i=new Audio,n=/.*\.([A-Za-z0-9]+)$/,s=e.match(n)[1];return i.canPlayType("audio/"+s)?!0:!1}catch(o){return t.Logger.getInstance().warn("Cannot determine audio support, assuming no support for the Audio Tag",o),!1}},e.prototype.wireEngine=function(t){var e=this;t&&(this._engine=t,this._engine.on("hidden",function(){t.pauseAudioWhenHidden&&e.isPlaying()&&(e._wasPlayingOnHidden=!0,e.pause())}),this._engine.on("visible",function(){t.pauseAudioWhenHidden&&e._wasPlayingOnHidden&&(e.play(),e._wasPlayingOnHidden=!1)}))},e.prototype.setVolume=function(t){this.sound&&this.sound.setVolume(t)},e.prototype.setLoop=function(t){this.sound&&this.sound.setLoop(t)},e.prototype.isPlaying=function(){return this.sound?this.sound.isPlaying():void 0},e.prototype.play=function(){return this.sound?this.sound.play():void 0},e.prototype.pause=function(){this.sound&&this.sound.pause()},e.prototype.stop=function(){this.sound&&this.sound.stop()},e.prototype.isLoaded=function(){return this._isLoaded},e.prototype.load=function(){var e=this,i=new t.Promise;return null!==this.sound.getData()?(this._logger.debug("Already have data for resource",this.path),i.resolve(this.sound),i):(this._logger.debug("Started loading sound",this.path),this.sound.onprogress=this.onprogress,this.sound.onload=function(){e.oncomplete(),e._isLoaded=!0,e._logger.debug("Completed loading sound",e.path),i.resolve(e.sound)},this.sound.onerror=function(t){e.onerror(t),i.resolve(t)},this.sound.load(),i)},e.prototype.getData=function(){return this.sound.getData()},e.prototype.setData=function(t){this.sound.setData(t)},e.prototype.processData=function(t){return this.sound.processData(t)},e}();t.Sound=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o){e.call(this,i,n,s,o),this.traits=[],this.traits.push(new t.Traits.Movement),this.traits.push(new t.Traits.CapturePointer),this.anchor.setTo(0,0),this.collisionType=t.CollisionType.PreventCollision,this.enableCapturePointer=!0}return __extends(i,e),i.prototype.onInitialize=function(t){this._engine=t},i.prototype.contains=function(i,n,s){if(void 0===s&&(s=!0),s)return e.prototype.contains.call(this,i,n);var o=this._engine.worldToScreenCoordinates(new t.Point(i,n));return e.prototype.contains.call(this,o.x,o.y)},i}(t.Actor);t.UIActor=e})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i,n,s,o,r,h){e.call(this,i,n,s,o),this._action=function(){},this.repeats=1,this.target=null,this.repeats=h||this.repeats,this._action=r||this._action,this.collisionType=t.CollisionType.PreventCollision,this.eventDispatcher=new t.EventDispatcher(this),this.actionQueue=new t.Internal.Actions.ActionQueue(this)}return __extends(i,e),i.prototype.update=function(e,i){if(this.actionQueue.update(i),this.x+=this.dx*i/1e3,this.y+=this.dy*i/1e3,this.rotation+=this.rx*i/1e3,this.scale.x+=this.sx*i/1e3,this.scale.y+=this.sy*i/1e3,this.target)this.collides(this.target)&&this._dispatchAction();else for(var n=0;e.currentScene.children.length>n;n++){var s=e.currentScene.children[n];s!==this&&s.collisionType!==t.CollisionType.PreventCollision&&this.collides(s)&&this._dispatchAction()}0===this.repeats&&this.kill()},i.prototype._dispatchAction=function(){this._action.call(this),this.repeats--},i.prototype.draw=function(){},i.prototype.debugDraw=function(i){e.prototype.debugDraw.call(this,i),i.save(),i.translate(this.x,this.y);var n=this.getBounds();n.left=n.left-this.getWorldX(),n.right=n.right-this.getWorldX(),n.top=n.top-this.getWorldY(),n.bottom=n.bottom-this.getWorldY(),i.fillStyle=""+t.Color.Violet,i.strokeStyle=""+t.Color.Violet,i.fillText("Trigger",10,10),n.debugDraw(i),i.restore()},i}(t.Actor);t.Trigger=e})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Circle=0]="Circle",t[t.Rectangle=1]="Rectangle"})(t.EmitterType||(t.EmitterType={}));var e=t.EmitterType,i=function(){function e(e,i,n,s,o,r,h,a,c,u){this.position=new t.Vector(0,0),this.velocity=new t.Vector(0,0),this.acceleration=new t.Vector(0,0),this.particleRotationalVelocity=0,this.currentRotation=0,this.focus=null,this.focusAccel=0,this.opacity=1,this.beginColor=t.Color.White.clone(),this.endColor=t.Color.White.clone(),this.life=300,this.fadeFlag=!1,this._rRate=1,this._gRate=1,this._bRate=1,this._aRate=0,this._currentColor=t.Color.White.clone(),this.emitter=null,this.particleSize=5,this.particleSprite=null,this.sizeRate=0,this.elapsedMultiplier=0,this.emitter=e,this.life=i||this.life,this.opacity=n||this.opacity,this.endColor=o||this.endColor.clone(),this.beginColor=s||this.beginColor.clone(),this._currentColor=this.beginColor.clone(),this.position=r||this.position,this.velocity=h||this.velocity,this.acceleration=a||this.acceleration,this._rRate=(this.endColor.r-this.beginColor.r)/this.life,this._gRate=(this.endColor.g-this.beginColor.g)/this.life,this._bRate=(this.endColor.b-this.beginColor.b)/this.life,this._aRate=this.opacity/this.life,this.startSize=c||0,this.endSize=u||0,this.endSize>0&&this.startSize>0&&(this.sizeRate=(this.endSize-this.startSize)/this.life,this.particleSize=this.startSize)}return e.prototype.kill=function(){this.emitter.removeParticle(this)},e.prototype.update=function(e){if(this.life=this.life-e,this.elapsedMultiplier=this.elapsedMultiplier+e,0>this.life&&this.kill(),this.fadeFlag&&(this.opacity=t.Util.clamp(this._aRate*this.life,1e-4,1)),this.startSize>0&&this.endSize>0&&(this.particleSize=t.Util.clamp(this.sizeRate*e+this.particleSize,Math.min(this.startSize,this.endSize),Math.max(this.startSize,this.endSize))),this._currentColor.r=t.Util.clamp(this._currentColor.r+this._rRate*e,0,255),this._currentColor.g=t.Util.clamp(this._currentColor.g+this._gRate*e,0,255),this._currentColor.b=t.Util.clamp(this._currentColor.b+this._bRate*e,0,255),this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),this.focus){var i=this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(e/1e3);this.velocity=this.velocity.add(i)}else this.velocity=this.velocity.add(this.acceleration.scale(e/1e3));this.position=this.position.add(this.velocity.scale(e/1e3)),this.particleRotationalVelocity&&(this.currentRotation=(this.currentRotation+this.particleRotationalVelocity*e/1e3)%(2*Math.PI))},e.prototype.draw=function(e){return this.particleSprite?(this.particleSprite.rotation=this.currentRotation,this.particleSprite.scale.setTo(this.particleSize,this.particleSize),this.particleSprite.draw(e,this.position.x,this.position.y),void 0):(this._currentColor.a=t.Util.clamp(this.opacity,1e-4,1),e.fillStyle=""+this._currentColor,e.beginPath(),e.arc(this.position.x,this.position.y,this.particleSize,0,2*Math.PI),e.fill(),e.closePath(),void 0)},e}();t.Particle=i;var n=function(n){function s(i,s,o,r){n.call(this,i,s,o,r,t.Color.White),this._particlesToEmit=0,this.numParticles=0,this.isEmitting=!0,this.particles=null,this.deadParticles=null,this.minVel=0,this.maxVel=0,this.acceleration=new t.Vector(0,0),this.minAngle=0,this.maxAngle=0,this.emitRate=1,this.particleLife=2e3,this.opacity=1,this.fadeFlag=!1,this.focus=null,this.focusAccel=1,this.startSize=null,this.endSize=null,this.minSize=5,this.maxSize=5,this.beginColor=t.Color.White,this.endColor=t.Color.White,this.particleSprite=null,this.emitterType=e.Rectangle,this.radius=0,this.particleRotationalVelocity=0,this.randomRotation=!1,this.collisionType=t.CollisionType.PreventCollision,this.particles=new t.Util.Collection,this.deadParticles=new t.Util.Collection;for(var h in this.traits)this.traits[h]instanceof t.Traits.OffscreenCulling&&this.traits.splice(h,1)}return __extends(s,n),s.prototype.removeParticle=function(t){this.deadParticles.push(t)},s.prototype.emitParticles=function(t){for(var e=0;t>e;e++)this.particles.push(this._createParticle())},s.prototype.clearParticles=function(){this.particles.clear()},s.prototype._createParticle=function(){var n=0,s=0,o=t.Util.randomInRange(this.minAngle,this.maxAngle),r=t.Util.randomInRange(this.minVel,this.maxVel),h=this.startSize||t.Util.randomInRange(this.minSize,this.maxSize),a=r*Math.cos(o),c=r*Math.sin(o);if(this.emitterType===e.Rectangle)n=t.Util.randomInRange(this.x,this.x+this.getWidth()),s=t.Util.randomInRange(this.y,this.y+this.getHeight());else if(this.emitterType===e.Circle){var u=t.Util.randomInRange(0,this.radius);n=u*Math.cos(o)+this.x,s=u*Math.sin(o)+this.y}var l=new i(this,this.particleLife,this.opacity,this.beginColor,this.endColor,new t.Vector(n,s),new t.Vector(a,c),this.acceleration,this.startSize,this.endSize);return l.fadeFlag=this.fadeFlag,l.particleSize=h,this.particleSprite&&(l.particleSprite=this.particleSprite),l.particleRotationalVelocity=this.particleRotationalVelocity,this.randomRotation&&(l.currentRotation=t.Util.randomInRange(0,2*Math.PI)),this.focus&&(l.focus=this.focus.add(new t.Vector(this.x,this.y)),l.focusAccel=this.focusAccel),l},s.prototype.update=function(t,e){var i=this;n.prototype.update.call(this,t,e),this.isEmitting&&(this._particlesToEmit+=this.emitRate*(e/1e3),this._particlesToEmit>1&&(this.emitParticles(Math.floor(this._particlesToEmit)),this._particlesToEmit=this._particlesToEmit-Math.floor(this._particlesToEmit))),this.particles.forEach(function(t){return t.update(e)}),this.deadParticles.forEach(function(t){return i.particles.removeElement(t)}),this.deadParticles.clear()},s.prototype.draw=function(t){this.particles.forEach(function(e){return e.draw(t)})},s.prototype.debugDraw=function(e){n.prototype.debugDraw.call(this,e),e.fillStyle=""+t.Color.Black,e.fillText("Particles: "+this.particles.count(),this.x,this.y+20),this.focus&&(e.fillRect(this.focus.x+this.x,this.focus.y+this.y,3,3),t.Util.drawLine(e,"yellow",this.focus.x+this.x,this.focus.y+this.y,n.prototype.getCenter.call(this).x,n.prototype.getCenter.call(this).y),e.fillText("Focus",this.focus.x+this.x,this.focus.y+this.y))},s}(t.Actor);t.ParticleEmitter=n})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e,i,n,s){this.currentFrame=0,this._oldTime=Date.now(),this.anchor=new t.Point(0,0),this.rotation=0,this.scale=new t.Point(1,1),this.loop=!1,this.freezeFrame=-1,this.flipVertical=!1,this.flipHorizontal=!1,this.width=0,this.height=0,this.naturalWidth=0,this.naturalHeight=0,this.sprites=i,this.speed=n,this._engine=e,null!=s&&(this.loop=s),i&&i[0]&&(this.height=i[0]?i[0].height:0,this.width=i[0]?i[0].width:0,this.naturalWidth=i[0]?i[0].naturalWidth:0,this.naturalHeight=i[0]?i[0].naturalHeight:0,this.freezeFrame=i.length-1)}return e.prototype.opacity=function(e){this.addEffect(new t.Effects.Opacity(e))},e.prototype.grayscale=function(){this.addEffect(new t.Effects.Grayscale)},e.prototype.invert=function(){this.addEffect(new t.Effects.Invert)},e.prototype.fill=function(e){this.addEffect(new t.Effects.Fill(e))},e.prototype.colorize=function(e){this.addEffect(new t.Effects.Colorize(e))},e.prototype.lighten=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Lighten(e))},e.prototype.darken=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Darken(e))},e.prototype.saturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Saturate(e))},e.prototype.desaturate=function(e){void 0===e&&(e=.1),this.addEffect(new t.Effects.Desaturate(e))},e.prototype.addEffect=function(t){for(var e in this.sprites)this.sprites[e].addEffect(t)},e.prototype.removeEffect=function(t){for(var e in this.sprites)this.sprites[e].removeEffect(t)},e.prototype.clearEffects=function(){for(var t in this.sprites)this.sprites[t].clearEffects()},e.prototype._setAnchor=function(t){for(var e in this.sprites)this.sprites[e].anchor.setTo(t.x,t.y)},e.prototype._setRotation=function(t){for(var e in this.sprites)this.sprites[e].rotation=t},e.prototype._setScale=function(t){for(var e in this.sprites)this.sprites[e].scale=t},e.prototype.reset=function(){this.currentFrame=0},e.prototype.isDone=function(){return!this.loop&&this.currentFrame>=this.sprites.length},e.prototype.tick=function(){var t=Date.now();t-this._oldTime>this.speed&&(this.currentFrame=this.loop?(this.currentFrame+1)%this.sprites.length:this.currentFrame+1,this._oldTime=t)},e.prototype._updateValues=function(){this._setAnchor(this.anchor),this._setRotation(this.rotation),this._setScale(this.scale)},e.prototype.skip=function(t){this.currentFrame=(this.currentFrame+t)%this.sprites.length},e.prototype.draw=function(e,i,n){this.tick(),this._updateValues();var s;this.currentFrame=this.sprites.length&&(s=this.sprites[t.Util.clamp(this.freezeFrame,0,this.sprites.length-1)],s.draw(e,i,n)),s&&(this.width=s.width,this.height=s.height)},e.prototype.play=function(t,e){this.reset(),this._engine.playAnimation(this,t,e)},e}();t.Animation=e})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(){function e(e,i){this.path=e,this._log=t.Logger.getInstance(),this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},window.AudioContext?(this._log.debug("Using new Web Audio Api for "+e),this._soundImpl=new o(e,i)):(this._log.debug("Falling back to Audio Element for "+e),this._soundImpl=new n(e,i))}return e.prototype.setVolume=function(t){this._soundImpl.setVolume(t)},e.prototype.setLoop=function(t){this._soundImpl.setLoop(t)},e.prototype.load=function(){this._soundImpl.onload=this.onload,this._soundImpl.onprogress=this.onprogress,this._soundImpl.onerror=this.onerror,this._soundImpl.load()},e.prototype.processData=function(t){return this._soundImpl.processData(t)},e.prototype.getData=function(){return this._soundImpl.getData()},e.prototype.setData=function(t){this._soundImpl.setData(t)},e.prototype.isPlaying=function(){return this._soundImpl.isPlaying()},e.prototype.play=function(){return this._soundImpl.play()},e.prototype.pause=function(){this._soundImpl.pause()},e.prototype.stop=function(){this._soundImpl.stop()},e}();e.FallbackAudio=i;var n=function(){function e(e,i){var n=this;this.path=e,this._audioElements=Array(5),this._loadedAudio=null,this._isLoaded=!1,this._index=0,this._log=t.Logger.getInstance(),this._isPlaying=!1,this._currentOffset=0,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){};for(var s=0;this._audioElements.length>s;s++)(function(t){n._audioElements[t]=new Audio})(s);i?this.setVolume(t.Util.clamp(i,0,1)):this.setVolume(1)}return e.prototype.isPlaying=function(){return this._isPlaying},e.prototype._audioLoaded=function(){this._isLoaded=!0},e.prototype.setVolume=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].volume=t},e.prototype.setLoop=function(t){var e=0,i=this._audioElements.length;for(e;i>e;e++)this._audioElements[e].loop=t},e.prototype.getLoop=function(){this._audioElements.some(function(t){return t.loop})},e.prototype.load=function(){var t=this;if(!this._loadedAudio){var e=new XMLHttpRequest;e.open("GET",this.path,!0),e.responseType="blob",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(i){return 200!==e.status?(t._log.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t._isLoaded=!0,t.setData(e.response),t.onload(i),void 0)},e.send()}},e.prototype.getData=function(){return this._loadedAudio},e.prototype.setData=function(t){this._isLoaded=!0,this._loadedAudio=this.processData(t)},e.prototype.processData=function(t){var e=URL.createObjectURL(t);return this._audioElements.forEach(function(t){t.src=e}),this._audioLoaded(),e},e.prototype.play=function(){var e=this;this._audioElements[this._index].load(),this._audioElements[this._index].play(),this._currentOffset=0;var i=new t.Promise;return this._isPlaying=!0,this.getLoop()||this._audioElements[this._index].addEventListener("ended",function(){e._isPlaying=!1,i.resolve(!0)}),this._index=(this._index+1)%this._audioElements.length,i},e.prototype.pause=function(){this._index=(this._index-1+this._audioElements.length)%this._audioElements.length,this._currentOffset=this._audioElements[this._index].currentTime,this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e.prototype.stop=function(){this._audioElements.forEach(function(t){t.pause()}),this._isPlaying=!1},e}();if(e.AudioTag=n,window.AudioContext)var s=new window.AudioContext;var o=function(){function e(e,i){this.path=e,this._context=s,this._volume=this._context.createGain(),this._buffer=null,this._sound=null,this._isLoaded=!1,this._loop=!1,this._isPlaying=!1,this._isPaused=!1,this._currentOffset=0,this._logger=t.Logger.getInstance(),this._data=null,this.onload=function(){},this.onprogress=function(){},this.onerror=function(){},this._volume.gain.value=i?t.Util.clamp(i,0,1):1}return e.prototype.setVolume=function(t){this._volume.gain.value=t},e.prototype.load=function(){var t=this;if(null===this._data){var e=new XMLHttpRequest;e.open("GET",this.path),e.responseType="arraybuffer",e.onprogress=this.onprogress,e.onerror=this.onerror,e.onload=function(){return 200!==e.status?(t._logger.error("Failed to load audio resource ",t.path," server responded with error code",e.status),t.onerror(e.response),t._isLoaded=!1,void 0):(t.setData(e.response),void 0)};try{e.send()}catch(i){console.error("Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.")}}},e.prototype.getData=function(){return this._data},e.prototype.setData=function(t){this._data=this.processData(t)},e.prototype.processData=function(t){var e=this;return this._context.decodeAudioData(t,function(t){e._buffer=t,e._isLoaded=!0,e.onload(e)},function(){e._logger.error("Unable to decode "+e.path+" this browser may not fully support this format, or the file may be corrupt, "+"if this is an mp3 try removing id3 tags and album art from the file."),e._isLoaded=!1,e.onload(e)}),t},e.prototype.setLoop=function(t){this._loop=t},e.prototype.isPlaying=function(){return this._isPlaying},e.prototype.play=function(){var e=this;if(this._isLoaded){this._sound=this._context.createBufferSource(),this._sound.buffer=this._buffer,this._sound.loop=this._loop,this._sound.connect(this._volume),this._volume.connect(this._context.destination),this._sound.start(0,this._currentOffset%this._buffer.duration),this._currentOffset=0;var i;return i=this._isPaused&&this._playPromise?this._playPromise:new t.Promise,this._isPaused=!1,this._isPlaying=!0,this._loop||(this._sound.onended=function(){e._isPlaying=!1,e._isPaused||i.resolve(!0)}.bind(this)),this._playPromise=i,i}return t.Promise.wrap(!0)},e.prototype.pause=function(){if(this._isPlaying)try{window.clearTimeout(this._playingTimer),this._sound.stop(0),this._currentOffset=this._context.currentTime,this._isPlaying=!1,this._isPaused=!0}catch(t){this._logger.warn("The sound clip",this.path,"has already been paused!")}},e.prototype.stop=function(){if(this._sound)try{window.clearTimeout(this._playingTimer),this._currentOffset=0,this._sound.stop(0),this._isPlaying=!1,this._isPaused=!1}catch(t){this._logger.warn("The sound clip",this.path,"has already been stopped!")}},e.unlock=function(){if(!this._unlocked&&s){var t=s.createBuffer(1,1,22050),e=s.createBufferSource();e.buffer=t,e.connect(s.destination),e.noteOn?e.noteOn(0):e.start(0),setTimeout(function(){(e.playbackState===e.PLAYING_STATE||e.playbackState===e.FINISHED_STATE)&&(this._unlocked=!0)},0)}},e.isUnlocked=function(){return this._unlocked},e._unlocked=!1,e}();e.WebAudio=o})(e=t.Internal||(t.Internal={}))})(ex||(ex={}));var ex;(function(t){var e=function(e){function i(i){e.call(this),this._resourceList=[],this._index=0,this._resourceCount=0,this._numLoaded=0,this._progressCounts={},this._totalCounts={},this.getData=function(){},this.setData=function(){},this.processData=function(){},this.onprogress=function(e){t.Logger.getInstance().debug("[ex.Loader] Loading "+(100*e.loaded/e.total).toFixed(0))},this.oncomplete=function(){},this.onerror=function(){},i&&this.addResources(i)}return __extends(i,e),i.prototype.wireEngine=function(t){this._engine=t},i.prototype.addResource=function(t){var e=this._index++;this._resourceList.push(t),this._progressCounts[e]=0,this._totalCounts[e]=1,this._resourceCount++},i.prototype.addResources=function(t){var e=0,i=t.length;for(e;i>e;e++)this.addResource(t[e])},i.prototype._sumCounts=function(t){var e=0;for(var i in t)e+=0|t[i];return e},i.prototype.isLoaded=function(){return this._numLoaded===this._resourceCount},i.prototype.load=function(){function e(t,i){t[i]&&t[i].load().then(function(){e(t,i+1)})}var i=this,n=new t.Promise,s=this;if(0===this._resourceList.length)return s.oncomplete.call(s),n;var o=Array(this._resourceList.length),r=this._resourceList.length;return this._resourceList.forEach(function(t,e){i._engine&&t.wireEngine(i._engine),t.onprogress=function(t){var i=t.total,n=t.loaded;o[e]={loaded:n/i*(100/r),total:100};var h=o.reduce(function(t,e){return{loaded:t.loaded+e.loaded,total:100}},{loaded:0,total:100});s.onprogress.call(s,h)},t.oncomplete=t.onerror=function(){s._numLoaded++,s._numLoaded===s._resourceCount&&(s.oncomplete.call(s),n.resolve())}}),e(this._resourceList,0),n},i.prototype.draw=function(t){t.fillStyle="black",t.fillRect(0,0,this._engine.width,this._engine.height);var e=this._engine.canvas.height/2,i=this._engine.canvas.width/3,n=i,s=new Image;s.src="data:image/png;base64,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"; +var o=3*i/8,r=this._engine.getAntialiasing();this._engine.setAntialiasing(!0),t.drawImage(s,0,0,800,300,n,e-o-20,i,o),t.strokeStyle="white",t.lineWidth=2,t.strokeRect(n,e,i,20);var h=i*(this._numLoaded/this._resourceCount);t.fillStyle="white";var a=5,c=h-2*a,u=20-2*a;t.fillRect(n+a,e+a,c>0?c:0,u),this._engine.setAntialiasing(r)},i.prototype.update=function(){},i}(t.Class);t.Loader=e;var i=function(e){function i(i,n){var s=this;e.call(this,n),this._handleOnTrigger=function(){return s._waitPromise.state()!==t.PromiseState.Pending?!1:(t.Internal.WebAudio.unlock(),s._waitPromise.resolve(s._loadedValue),s._playTrigger.style.display="none",!1)},this._playTrigger=document.getElementById(i),this._playTrigger.addEventListener("click",this._handleOnTrigger)}return __extends(i,e),i.prototype.load=function(){var i=this;return this._waitPromise=new t.Promise,e.prototype.load.call(this).then(function(t){i._loaded=!0,i._loadedValue=t,i._playTrigger.style.display="block"},function(t){i._waitPromise.reject(t)}),this._waitPromise},i}(e);t.PauseAfterLoader=i})(ex||(ex={}));var ex;(function(t){var e=function(){function e(){this.failedTests=[],this._criticalTests={canvasSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("2d"))},arrayBufferSupport:function(){var t=new XMLHttpRequest;t.open("GET","/");try{t.responseType="arraybuffer"}catch(e){return!1}return"arraybuffer"===t.responseType},dataUrlSupport:function(){var t=document.createElement("canvas");return 0===t.toDataURL("image/png").indexOf("data:image/png")},objectUrlSupport:function(){return"URL"in window&&"revokeObjectURL"in URL&&"createObjectURL"in URL},rgbaSupport:function(){var t=document.createElement("a").style;return t.cssText="background-color:rgba(150,255,150,.5)",(""+t.backgroundColor).indexOf("rgba")>-1}},this._warningTest={webAudioSupport:function(){return!!(window.AudioContext||window.webkitAudioContext||window.mozAudioContext||window.msAudioContext||window.oAudioContext)},webglSupport:function(){var t=document.createElement("canvas");return!(!t.getContext||!t.getContext("webgl"))}}}return e.prototype.test=function(){var e=!1;for(var i in this._criticalTests)this._criticalTests[i]()||(this.failedTests.push(i),t.Logger.getInstance().error("Critical browser feature missing, Excalibur requires:",i),e=!0);if(e)return!1;for(var n in this._warningTest)this._warningTest[n]()||t.Logger.getInstance().warn("Warning browser feature missing, Excalibur will have reduced performance:",n);return!0},e}();t.Detector=e})(ex||(ex={}));var ex;(function(t){var e=function(){function e(e){this.path=e,this._isLoaded=!1,this.logger=t.Logger.getInstance(),this.onprogress=function(){},this.oncomplete=function(){},this.onerror=function(){},this._innerElement=document.createElement("div"),this._innerElement.className="excalibur-template"}return e.prototype.wireEngine=function(t){this._engine=t},e.prototype.getTemplateString=function(){return this._isLoaded?this._htmlString:""},e.prototype._compile=function(){this._innerElement.innerHTML=this._htmlString,this._styleElements=this._innerElement.querySelectorAll("[data-style]"),this._textElements=this._innerElement.querySelectorAll("[data-text]")},e.prototype._evaluateExpresion=function(t,e){var i=Function("return "+t+";"),n=i.call(e);return n},e.prototype.apply=function(t){for(var e=this,i=0;this._styleElements.length>i;i++)(function(){var n={};e._styleElements[i].dataset.style.split(";").forEach(function(t){if(t){var e=t.split(":");n[e[0].trim()]=e[1].trim()}});for(var s in n)(function(){var o=n[s];e._styleElements[i].style[s]=e._evaluateExpresion(o,t)})()})();for(var n=0;this._textElements.length>n;n++)(function(){var i=e._textElements[n].dataset.text;e._textElements[n].innerText=e._evaluateExpresion(i,t)})();return 1===this._innerElement.children.length&&(this._innerElement=this._innerElement.firstChild),this._innerElement},e.prototype.load=function(){var e=this,i=new t.Promise,n=new XMLHttpRequest;return n.open("GET",this.path,!0),n.responseType="text",n.onprogress=this.onprogress,n.onerror=this.onerror,n.onload=function(){return 200!==n.status?(e.logger.error("Failed to load html template resource ",e.path," server responded with error code",n.status),e.onerror(n.response),e._isLoaded=!1,i.resolve("error"),void 0):(e.setData(n.response),e.oncomplete(),e.logger.debug("Completed loading template",e.path),i.resolve(e._htmlString),void 0)},n.overrideMimeType&&n.overrideMimeType("text/plain; charset=x-user-defined"),n.send(),i},e.prototype.getData=function(){return this._htmlString},e.prototype.setData=function(t){this._htmlString=this.processData(t),this._compile(),this._isLoaded=!0},e.prototype.processData=function(t){return t},e.prototype.isLoaded=function(){return this._isLoaded},e}();t.Template=e;var i=function(){function t(t,e,i){this.parent=document.getElementById(t),this.template=e,this._ctx=i,this.update()}return t.prototype.listen=function(t,e,i){var n=this;i||(i=function(){n.update()}),t.addEventListener&&e.forEach(function(e){t.addEventListener(e,i)})},t.prototype.update=function(){var t=this._applyTemplate(this.template,this._ctx);t instanceof String&&(this.parent.innerHTML=t),t instanceof Node&&this.parent.lastChild!==t&&this.parent.appendChild(t)},t.prototype._applyTemplate=function(t,e){return t.isLoaded()?t.apply(e):void 0},t}();t.Binding=i})(ex||(ex={}));var ex;(function(t){(function(t){t[t.Em=0]="Em",t[t.Rem=1]="Rem",t[t.Px=2]="Px",t[t.Pt=3]="Pt",t[t.Percent=4]="Percent"})(t.FontUnit||(t.FontUnit={}));var e=t.FontUnit;(function(t){t[t.Left=0]="Left",t[t.Right=1]="Right",t[t.Center=2]="Center",t[t.Start=3]="Start",t[t.End=4]="End"})(t.TextAlign||(t.TextAlign={}));var i=t.TextAlign;(function(t){t[t.Top=0]="Top",t[t.Hanging=1]="Hanging",t[t.Middle=2]="Middle",t[t.Alphabetic=3]="Alphabetic",t[t.Ideographic=4]="Ideographic",t[t.Bottom=5]="Bottom"})(t.BaseAlign||(t.BaseAlign={}));var n=t.BaseAlign,s=function(s){function o(o,r,h,a,c){s.call(this,r,h),this.fontSize=10,this.fontUnit=e.Px,this.textAlign=i.Left,this.baseAlign=n.Bottom,this.letterSpacing=0,this.caseInsensitive=!0,this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone(),this._shadowColorDirty=!1,this._textSprites={},this._shadowSprites={},this._color=t.Color.Black.clone(),this.text=o||"",this.color=t.Color.Black.clone(),this.spriteFont=c,this.collisionType=t.CollisionType.PreventCollision,this.fontFamily=a||"10px sans-serif"}return __extends(o,s),o.prototype.getTextWidth=function(t){var e=t.font;t.font=this.fontFamily;var i=t.measureText(this.text).width;return t.font=e,i},o.prototype._lookupFontUnit=function(t){switch(t){case e.Em:return"em";case e.Rem:return"rem";case e.Pt:return"pt";case e.Px:return"px";case e.Percent:return"%";default:return"px"}},o.prototype._lookupTextAlign=function(t){switch(t){case i.Left:return"left";case i.Right:return"right";case i.Center:return"center";case i.End:return"end";case i.Start:return"start";default:return"start"}},o.prototype._lookupBaseAlign=function(t){switch(t){case n.Alphabetic:return"alphabetic";case n.Bottom:return"bottom";case n.Hanging:return"hangin";case n.Ideographic:return"ideographic";case n.Middle:return"middle";case n.Top:return"top";default:return"alphabetic"}},o.prototype.setTextShadow=function(t,e,i){this.spriteFont.setTextShadow(t,e,i)},o.prototype.useTextShadow=function(t){this.spriteFont.useTextShadow(t)},o.prototype.clearTextShadow=function(){this._textShadowOn=!1,this._shadowOffsetX=0,this._shadowOffsetY=0,this._shadowColor=t.Color.Black.clone()},o.prototype.update=function(t,e){s.prototype.update.call(this,t,e)},o.prototype.draw=function(t,e){t.save(),t.translate(this.x,this.y),t.scale(this.scale.x,this.scale.y),t.rotate(this.rotation),this._textShadowOn&&(t.save(),t.translate(this._shadowOffsetX,this._shadowOffsetY),this._fontDraw(t,e,this._shadowSprites),t.restore()),this._fontDraw(t,e,this._textSprites),s.prototype.draw.call(this,t,e),t.restore()},o.prototype._fontDraw=function(t){if(this.spriteFont)this.spriteFont.draw(t,this.text,0,0,{color:this.color.clone(),baseAlign:this.baseAlign,textAlign:this.textAlign,fontSize:this.fontSize,letterSpacing:this.letterSpacing,opacity:this.opacity});else{var e=t.textAlign,i=t.textBaseline;t.textAlign=this._lookupTextAlign(this.textAlign),t.textBaseline=this._lookupBaseAlign(this.baseAlign),this.color&&(this.color.a=this.opacity),t.fillStyle=""+this.color,t.font=""+this.fontSize+this._lookupFontUnit(this.fontUnit)+" "+this.fontFamily,this.maxWidth?t.fillText(this.text,0,0,this.maxWidth):t.fillText(this.text,0,0),t.textAlign=e,t.textBaseline=i}},o.prototype.debugDraw=function(t){s.prototype.debugDraw.call(this,t)},o}(t.Actor);t.Label=s})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Touch=0]="Touch",t[t.Mouse=1]="Mouse",t[t.Pen=2]="Pen",t[t.Unknown=3]="Unknown"})(e.PointerType||(e.PointerType={}));var i=e.PointerType;(function(t){t[t.Left=0]="Left",t[t.Middle=1]="Middle",t[t.Right=2]="Right",t[t.Unknown=3]="Unknown"})(e.PointerButton||(e.PointerButton={}));var n=e.PointerButton;(function(t){t[t.Canvas=0]="Canvas",t[t.Document=1]="Document"})(e.PointerScope||(e.PointerScope={}));var s=e.PointerScope,o=function(t){function e(e,i,n,s,o,r){t.call(this),this.x=e,this.y=i,this.index=n,this.pointerType=s,this.button=o,this.ev=r}return __extends(e,t),e}(t.GameEvent);e.PointerEvent=o;var r=function(e){function r(t){e.call(this),this._pointerDown=[],this._pointerUp=[],this._pointerMove=[],this._pointerCancel=[],this._pointers=[],this._activePointers=[],this._engine=t,this._pointers.push(new h),this._activePointers=[-1],this.primary=this._pointers[0]}return __extends(r,e),r.prototype.init=function(t){void 0===t&&(t=s.Document);var e=document;e=t===s.Document?document:this._engine.canvas,e.addEventListener("touchstart",this._handleTouchEvent("down",this._pointerDown)),e.addEventListener("touchend",this._handleTouchEvent("up",this._pointerUp)),e.addEventListener("touchmove",this._handleTouchEvent("move",this._pointerMove)),e.addEventListener("touchcancel",this._handleTouchEvent("cancel",this._pointerCancel)),window.PointerEvent?(this._engine.canvas.style.touchAction="none",e.addEventListener("pointerdown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("pointerup",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("pointermove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("pointercancel",this._handlePointerEvent("cancel",this._pointerMove))):window.MSPointerEvent?(this._engine.canvas.style.msTouchAction="none",e.addEventListener("MSPointerDown",this._handlePointerEvent("down",this._pointerDown)),e.addEventListener("MSPointerUp",this._handlePointerEvent("up",this._pointerUp)),e.addEventListener("MSPointerMove",this._handlePointerEvent("move",this._pointerMove)),e.addEventListener("MSPointerCancel",this._handlePointerEvent("cancel",this._pointerMove))):(e.addEventListener("mousedown",this._handleMouseEvent("down",this._pointerDown)),e.addEventListener("mouseup",this._handleMouseEvent("up",this._pointerUp)),e.addEventListener("mousemove",this._handleMouseEvent("move",this._pointerMove)))},r.prototype.update=function(){this._pointerUp.length=0,this._pointerDown.length=0,this._pointerMove.length=0,this._pointerCancel.length=0},r.prototype.at=function(t){if(t>=this._pointers.length)for(var e=this._pointers.length-1,i=t;i>e;e++)this._pointers.push(new h),this._activePointers.push(-1);return this._pointers[t]},r.prototype.count=function(){return this._pointers.length},r.prototype.propogate=function(e){var i=e instanceof t.UIActor,n=0,s=this._pointerUp.length;for(n;s>n;n++)e.contains(this._pointerUp[n].x,this._pointerUp[n].y,!i)&&e.eventDispatcher.emit("pointerup",this._pointerUp[n]);for(n=0,s=this._pointerDown.length,n;s>n;n++)e.contains(this._pointerDown[n].x,this._pointerDown[n].y,!i)&&e.eventDispatcher.emit("pointerdown",this._pointerDown[n]);if(e.capturePointer.captureMoveEvents)for(n=0,s=this._pointerMove.length,n;s>n;n++)e.contains(this._pointerMove[n].x,this._pointerMove[n].y,!i)&&e.eventDispatcher.emit("pointermove",this._pointerMove[n]);for(n=0,s=this._pointerCancel.length,n;s>n;n++)e.contains(this._pointerCancel[n].x,this._pointerCancel[n].y,!i)&&e.eventDispatcher.emit("pointercancel",this._pointerCancel[n])},r.prototype._handleMouseEvent=function(e,n){var s=this;return function(r){r.preventDefault();var h=r.pageX-t.Util.getPosition(s._engine.canvas).x,a=r.pageY-t.Util.getPosition(s._engine.canvas).y,c=s._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,0,i.Mouse,r.button,r);n.push(u),s.at(0).eventDispatcher.emit(e,u)}},r.prototype._handleTouchEvent=function(e,s){var r=this;return function(h){h.preventDefault();for(var a=0,c=h.changedTouches.length;c>a;a++){var u=r._pointers.length>1?r._getPointerIndex(h.changedTouches[a].identifier):0;if(-1!==u){var l=h.changedTouches[a].pageX-t.Util.getPosition(r._engine.canvas).x,p=h.changedTouches[a].pageY-t.Util.getPosition(r._engine.canvas).y,d=r._engine.screenToWorldCoordinates(new t.Point(l,p)),f=new o(d.x,d.y,u,i.Touch,n.Unknown,h);s.push(f),r.at(u).eventDispatcher.emit(e,f),r._pointers.length>1&&("up"===e?r._activePointers[u]=-1:"down"===e&&(r._activePointers[u]=h.changedTouches[a].identifier))}}}},r.prototype._handlePointerEvent=function(e,i){var n=this;return function(s){s.preventDefault();var r=n._pointers.length>1?n._getPointerIndex(s.pointerId):0;if(-1!==r){var h=s.pageX-t.Util.getPosition(n._engine.canvas).x,a=s.pageY-t.Util.getPosition(n._engine.canvas).y,c=n._engine.screenToWorldCoordinates(new t.Point(h,a)),u=new o(c.x,c.y,r,n._stringToPointerType(s.pointerType),s.button,s);i.push(u),n.at(r).eventDispatcher.emit(e,u),n._pointers.length>1&&("up"===e?n._activePointers[r]=-1:"down"===e&&(n._activePointers[r]=s.pointerId))}}},r.prototype._getPointerIndex=function(t){var e;if((e=this._activePointers.indexOf(t))>-1)return e;for(var i=0;this._activePointers.length>i;i++)if(-1===this._activePointers[i])return i;return-1},r.prototype._stringToPointerType=function(t){switch(t){case"touch":return i.Touch;case"mouse":return i.Mouse;case"pen":return i.Pen;default:return i.Unknown}},r}(t.Class);e.Pointers=r;var h=function(t){function e(){t.apply(this,arguments)}return __extends(e,t),e}(t.Class);e.Pointer=h})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){(function(t){t[t.Num1=97]="Num1",t[t.Num2=98]="Num2",t[t.Num3=99]="Num3",t[t.Num4=100]="Num4",t[t.Num5=101]="Num5",t[t.Num6=102]="Num6",t[t.Num7=103]="Num7",t[t.Num8=104]="Num8",t[t.Num9=105]="Num9",t[t.Num0=96]="Num0",t[t.Numlock=144]="Numlock",t[t.Semicolon=186]="Semicolon",t[t.A=65]="A",t[t.B=66]="B",t[t.C=67]="C",t[t.D=68]="D",t[t.E=69]="E",t[t.F=70]="F",t[t.G=71]="G",t[t.H=72]="H",t[t.I=73]="I",t[t.J=74]="J",t[t.K=75]="K",t[t.L=76]="L",t[t.M=77]="M",t[t.N=78]="N",t[t.O=79]="O",t[t.P=80]="P",t[t.Q=81]="Q",t[t.R=82]="R",t[t.S=83]="S",t[t.T=84]="T",t[t.U=85]="U",t[t.V=86]="V",t[t.W=87]="W",t[t.X=88]="X",t[t.Y=89]="Y",t[t.Z=90]="Z",t[t.Shift=16]="Shift",t[t.Alt=18]="Alt",t[t.Up=38]="Up",t[t.Down=40]="Down",t[t.Left=37]="Left",t[t.Right=39]="Right",t[t.Space=32]="Space",t[t.Esc=27]="Esc"})(e.Keys||(e.Keys={})),e.Keys;var i=function(t){function e(e){t.call(this),this.key=e}return __extends(e,t),e}(t.GameEvent);e.KeyEvent=i;var n=function(t){function e(e){t.call(this),this._keys=[],this._keysUp=[],this._keysDown=[],this._engine=e}return __extends(e,t),e.prototype.init=function(){var t=this;window.addEventListener("blur",function(){t._keys.length=0}),window.addEventListener("keyup",function(e){var n=t._keys.indexOf(e.keyCode);t._keys.splice(n,1),t._keysUp.push(e.keyCode);var s=new i(e.keyCode);t.eventDispatcher.emit("up",s),t.eventDispatcher.emit("release",s)}),window.addEventListener("keydown",function(e){if(-1===t._keys.indexOf(e.keyCode)){t._keys.push(e.keyCode),t._keysDown.push(e.keyCode);var n=new i(e.keyCode);t.eventDispatcher.emit("down",n),t.eventDispatcher.emit("press",n)}})},e.prototype.update=function(){this._keysDown.length=0,this._keysUp.length=0;for(var t=0;this._keys.length>t;t++)this.eventDispatcher.emit("hold",new i(this._keys[t]))},e.prototype.getKeys=function(){return this._keys},e.prototype.wasPressed=function(t){return this._keysDown.indexOf(t)>-1},e.prototype.isHeld=function(t){return this._keys.indexOf(t)>-1},e.prototype.wasReleased=function(t){return this._keysUp.indexOf(t)>-1},e}(t.Class);e.Keyboard=n})(e=t.Input||(t.Input={}))})(ex||(ex={}));var ex;(function(t){var e;(function(e){var i=function(e){function i(t){e.call(this),this.enabled=!1,this.supported=!!navigator.getGamepads,this._gamePadTimeStamps=[0,0,0,0],this._oldPads=[],this._pads=[],this._initSuccess=!1,this._navigator=navigator,this._minimumConfiguration=null,this._engine=t}return __extends(i,e),i.prototype.init=function(){this.supported&&(this._initSuccess||(this._oldPads=this._clonePads(this._navigator.getGamepads()),this._oldPads.length&&this._oldPads[0]&&(this._initSuccess=!0)))},i.prototype.setMinimumGamepadConfiguration=function(t){this._enableAndUpdate(),this._minimumConfiguration=t},i.prototype._enableAndUpdate=function(){this.enabled||(this.enabled=!0,this.update(100))},i.prototype._isGamepadValid=function(t){if(!this._minimumConfiguration)return!0;if(!t)return!1;var e=t.axes.filter(function(t){return void 0!==typeof t}).length,i=t.buttons.filter(function(t){return void 0!==typeof t}).length;return e>=this._minimumConfiguration.axis&&i>=this._minimumConfiguration.buttons&&t.connected},i.prototype.on=function(t,i){this._enableAndUpdate(),e.prototype.on.call(this,t,i)},i.prototype.off=function(t,i){this._enableAndUpdate(),e.prototype.off.call(this,t,i)},i.prototype.update=function(){if(this.enabled&&this.supported){this.init();for(var e=this._navigator.getGamepads(),i=0;e.length>i;i++)if(e[i]){if(!this.at(i).connected&&this._isGamepadValid(e[i])&&this.eventDispatcher.emit("connect",new t.GamepadConnectEvent(i,this.at(i))),this.at(i).connected=!0,!e[i].timestamp||e[i].timestamp!==this._gamePadTimeStamps[i]){this._gamePadTimeStamps[i]=e[i].timestamp,this.at(i).navigatorGamepad=e[i];var n,r,h,a,c;for(n in s)"number"==typeof s[n]&&(a=s[n],e[i].buttons[a]&&(h=e[i].buttons[a].value,h!==this._oldPads[i].getButton(a)&&(e[i].buttons[a].pressed?(this.at(i).updateButton(a,h),this.at(i).eventDispatcher.publish("button",new t.GamepadButtonEvent(a,h))):this.at(i).updateButton(a,0))));for(r in o)"number"==typeof o[r]&&(c=o[r],h=e[i].axes[c],h!==this._oldPads[i].getAxes(c)&&(this.at(i).updateAxes(c,h),this.at(i).eventDispatcher.emit("axis",new t.GamepadAxisEvent(c,h))));this._oldPads[i]=this._clonePad(e[i])}}else this.at(i).connected&&this.eventDispatcher.emit("disconnect",new t.GamepadDisconnectEvent(i)),this.at(i).connected=!1}},i.prototype.at=function(t){if(this._enableAndUpdate(),t>=this._pads.length)for(var e=this._pads.length-1,i=t;i>e;e++)this._pads.push(new n),this._oldPads.push(new n);return this._pads[t]},i.prototype.getValidGamepads=function(){this._enableAndUpdate();for(var t=[],e=0;this._pads.length>e;e++)this._isGamepadValid(this.at(e).navigatorGamepad)&&this.at(e).connected&&t.push(this.at(e));return t},i.prototype.count=function(){return this._pads.filter(function(t){return t.connected}).length},i.prototype._clonePads=function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(this._clonePad(t[i]));return e},i.prototype._clonePad=function(t){var e,i,s=new n;if(!t)return s;for(e=0,i=t.buttons.length;i>e;e++)t.buttons[e]&&s.updateButton(e,t.buttons[e].value);for(e=0,i=t.axes.length;i>e;e++)s.updateAxes(e,t.axes[e]);return s},i.MinAxisMoveThreshold=.05,i}(t.Class);e.Gamepads=i;var n=function(t){function e(){t.call(this),this.connected=!1,this._buttons=Array(16),this._axes=Array(4);var e;for(e=0;this._buttons.length>e;e++)this._buttons[e]=0;for(e=0;this._axes.length>e;e++)this._axes[e]=0}return __extends(e,t),e.prototype.isButtonPressed=function(t,e){return void 0===e&&(e=1),this._buttons[t]>=e},e.prototype.getButton=function(t){return this._buttons[t]},e.prototype.getAxes=function(t){var e=this._axes[t];return Math.abs(e)n;n++)this._animations[n].animation.draw(i,this._animations[n].x,this._animations[n].y);if(this.fps=1/(e/1e3),this.isDebug){this.ctx.font="Consolas",this.ctx.fillStyle=""+this.debugColor;for(var o=this.input.keyboard.getKeys(),r=0;o.length>r;r++)this.ctx.fillText(""+o[r]+" : "+(t.Input.Keys[o[r]]?t.Input.Keys[o[r]]:"Not Mapped"),100,10*r+10);this.ctx.fillText("FPS:"+(""+this.fps.toFixed(2)),10,10)}for(var h=0;this.postProcessors.length>h;h++)this.postProcessors[h].process(this.ctx.getImageData(0,0,this.width,this.height),this.ctx);this.emit("postdraw",new t.PreDrawEvent(i,e,this))},s.prototype.start=function(e){if(!this._compatible){var i=new t.Promise;return i.reject("Excalibur is incompatible with your browser")}var n;if(e?(this._loader=e,this._loader.wireEngine(this),n=this.load(this._loader)):n=t.Promise.wrap(),!this._hasStarted){this._hasStarted=!0,this._logger.debug("Starting game...");var s=Date.now(),o=this;(function r(){if(o._hasStarted)try{o._requestId=window.requestAnimationFrame(r);var t=Date.now(),e=Math.floor(t-s)||1;e>200&&(e=1),o._update(e),o._draw(e),s=t}catch(i){window.cancelAnimationFrame(o._requestId),o.stop(),o.onFatalException(i)}})(),this._logger.debug("Game started")}return n},s.prototype.stop=function(){this._hasStarted&&(this._hasStarted=!1,this._logger.debug("Game stopped"))},s.prototype.screenshot=function(){var t=new Image,e=this.canvas.toDataURL("image/png");return t.src=e,t},s.prototype.load=function(e){var i=this,n=new t.Promise;return this._isLoading=!0,e.load().then(function(){setTimeout(function(){i._isLoading=!1,n.resolve()},500)}),n},s}(t.Class);t.Engine=e,function(t){t[t.FullScreen=0]="FullScreen",t[t.Container=1]="Container",t[t.Fixed=2]="Fixed"}(t.DisplayMode||(t.DisplayMode={}));var i=t.DisplayMode,n=function(){function t(t,e,i){this.animation=t,this.x=e,this.y=i}return t}()})(ex||(ex={})); ; // Concatenated onto excalibur after build // Exports the excalibur module so it can be used with browserify diff --git a/sandbox/web/Excalibur.js b/sandbox/web/Excalibur.js index b62b46962..d36c58af0 100644 --- a/sandbox/web/Excalibur.js +++ b/sandbox/web/Excalibur.js @@ -8213,1769 +8213,1816 @@ var ex; return HSLColor; })(); })(ex || (ex = {})); -/// -var ex; -(function (ex) { - /** - * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does - * not participate in collisions. Drawn on top of all other actors. - */ - var UIActor = (function (_super) { - __extends(UIActor, _super); - /** - * @param x The starting x coordinate of the actor - * @param y The starting y coordinate of the actor - * @param width The starting width of the actor - * @param height The starting height of the actor - */ - function UIActor(x, y, width, height) { - _super.call(this, x, y, width, height); - this.traits = []; - this.traits.push(new ex.Traits.Movement()); - this.traits.push(new ex.Traits.CapturePointer()); - this.anchor.setTo(0, 0); - this.collisionType = ex.CollisionType.PreventCollision; - this.enableCapturePointer = true; - } - UIActor.prototype.onInitialize = function (engine) { - this._engine = engine; - }; - UIActor.prototype.contains = function (x, y, useWorld) { - if (useWorld === void 0) { useWorld = true; } - if (useWorld) { - return _super.prototype.contains.call(this, x, y); - } - var coords = this._engine.worldToScreenCoordinates(new ex.Point(x, y)); - return _super.prototype.contains.call(this, coords.x, coords.y); - }; - return UIActor; - })(ex.Actor); - ex.UIActor = UIActor; -})(ex || (ex = {})); -/// -/// +/// var ex; (function (ex) { /** - * Triggers + * Generic Resources * - * Triggers are a method of firing arbitrary code on collision. These are useful - * as 'buttons', 'switches', or to trigger effects in a game. By default triggers - * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * The [[Resource]] type allows games built in Excalibur to load generic resources. + * For any type of remote resource it is recommended to use [[Resource]] for preloading. * - * ## Creating a trigger + * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before + * a level or game. * - * ```js - * var game = new ex.Game(); + * Example usages: JSON, compressed files, blobs. * - * // create a handler - * function onTrigger() { + * ## Pre-loading generic resources * - * // `this` will be the Trigger instance - * ex.Logger.getInstance().info("Trigger was triggered!", this); - * } + * ```js + * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); + * var loader = new ex.Loader(resLevel1); * - * // set a trigger at (100, 100) that is 40x40px - * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * // attach a handler to process once loaded + * resLevel1.processData = function (data) { * - * // create an actor across from the trigger - * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * // process JSON + * var json = JSON.parse(data); * - * // tell the actor to move towards the trigger over 3 seconds - * actor.moveTo(100, 200, 3000); + * // create a new level (inherits Scene) with the JSON configuration + * var level = new Level(json); * - * game.add(trigger); - * game.add(actor); + * // add a new scene + * game.add(level.name, level); + * } * - * game.start(); + * game.start(loader); * ``` */ - var Trigger = (function (_super) { - __extends(Trigger, _super); + var Resource = (function (_super) { + __extends(Resource, _super); /** - * @param x The x position of the trigger - * @param y The y position of the trigger - * @param width The width of the trigger - * @param height The height of the trigger - * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance - * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely + * @param path Path to the remote resource + * @param responseType The Content-Type to expect (e.g. `application/json`) + * @param bustCache Whether or not to cache-bust requests */ - function Trigger(x, y, width, height, action, repeats) { - _super.call(this, x, y, width, height); - this._action = function () { return; }; - this.repeats = 1; - this.target = null; - this.repeats = repeats || this.repeats; - this._action = action || this._action; - this.collisionType = ex.CollisionType.PreventCollision; - this.eventDispatcher = new ex.EventDispatcher(this); - this.actionQueue = new ex.Internal.Actions.ActionQueue(this); + function Resource(path, responseType, bustCache) { + if (bustCache === void 0) { bustCache = true; } + _super.call(this); + this.path = path; + this.responseType = responseType; + this.bustCache = bustCache; + this.data = null; + this.logger = ex.Logger.getInstance(); + this.onprogress = function () { return; }; + this.oncomplete = function () { return; }; + this.onerror = function () { return; }; } - Trigger.prototype.update = function (engine, delta) { - // Update action queue - this.actionQueue.update(delta); - // Update placements based on linear algebra - this.x += this.dx * delta / 1000; - this.y += this.dy * delta / 1000; - this.rotation += this.rx * delta / 1000; - this.scale.x += this.sx * delta / 1000; - this.scale.y += this.sy * delta / 1000; - // check for trigger collisions - if (this.target) { - if (this.collides(this.target)) { - this._dispatchAction(); - } + /** + * Returns true if the Resource is completely loaded and is ready + * to be drawn. + */ + Resource.prototype.isLoaded = function () { + return this.data !== null; + }; + Resource.prototype.wireEngine = function (engine) { + this._engine = engine; + }; + Resource.prototype._cacheBust = function (uri) { + var query = /\?\w*=\w*/; + if (query.test(uri)) { + uri += ('&__=' + Date.now()); } else { - for (var i = 0; i < engine.currentScene.children.length; i++) { - var other = engine.currentScene.children[i]; - if (other !== this && - other.collisionType !== ex.CollisionType.PreventCollision && - this.collides(other)) { - this._dispatchAction(); - } - } + uri += ('?__=' + Date.now()); } - // remove trigger if its done, -1 repeat forever - if (this.repeats === 0) { - this.kill(); + return uri; + }; + Resource.prototype._start = function (e) { + this.logger.debug('Started loading resource ' + this.path); + }; + /** + * Begin loading the resource and returns a promise to be resolved on completion + */ + Resource.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + // Exit early if we already have data + if (this.data !== null) { + this.logger.debug('Already have data for resource', this.path); + complete.resolve(this.data); + this.oncomplete(); + return complete; } + var request = new XMLHttpRequest(); + request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true); + request.responseType = this.responseType; + request.onloadstart = function (e) { _this._start(e); }; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function (e) { + if (request.status !== 200) { + _this.logger.error('Failed to load resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + complete.resolve(request.response); + return; + } + _this.data = _this.processData(request.response); + _this.oncomplete(); + _this.logger.debug('Completed loading resource', _this.path); + complete.resolve(_this.data); + }; + request.send(); + return complete; }; - Trigger.prototype._dispatchAction = function () { - this._action.call(this); - this.repeats--; + /** + * Returns the loaded data once the resource is loaded + */ + Resource.prototype.getData = function () { + return this.data; }; - Trigger.prototype.draw = function (ctx, delta) { - // does not draw - return; + /** + * Sets the data for this resource directly + */ + Resource.prototype.setData = function (data) { + this.data = this.processData(data); }; - Trigger.prototype.debugDraw = function (ctx) { - _super.prototype.debugDraw.call(this, ctx); - // Meant to draw debug information about actors - ctx.save(); - ctx.translate(this.x, this.y); - var bb = this.getBounds(); - bb.left = bb.left - this.getWorldX(); - bb.right = bb.right - this.getWorldX(); - bb.top = bb.top - this.getWorldY(); - bb.bottom = bb.bottom - this.getWorldY(); - // Currently collision primitives cannot rotate - // ctx.rotate(this.rotation); - ctx.fillStyle = ex.Color.Violet.toString(); - ctx.strokeStyle = ex.Color.Violet.toString(); - ctx.fillText('Trigger', 10, 10); - bb.debugDraw(ctx); - ctx.restore(); + /** + * This method is meant to be overriden to handle any additional + * processing. Such as decoding downloaded audio bits. + */ + Resource.prototype.processData = function (data) { + // Handle any additional loading after the xhr has completed. + return URL.createObjectURL(data); }; - return Trigger; - })(ex.Actor); - ex.Trigger = Trigger; + return Resource; + })(ex.Class); + ex.Resource = Resource; })(ex || (ex = {})); -/// -/// -/// -/// +/// +// Promises/A+ Spec http://promises-aplus.github.io/promises-spec/ var ex; (function (ex) { /** - * An enum that represents the types of emitter nozzles + * Valid states for a promise to be in */ - (function (EmitterType) { - /** - * Constant for the circular emitter type - */ - EmitterType[EmitterType["Circle"] = 0] = "Circle"; - /** - * Constant for the rectangular emitter type - */ - EmitterType[EmitterType["Rectangle"] = 1] = "Rectangle"; - })(ex.EmitterType || (ex.EmitterType = {})); - var EmitterType = ex.EmitterType; - /** - * Particle is used in a [[ParticleEmitter]] - */ - var Particle = (function () { - function Particle(emitter, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) { - this.position = new ex.Vector(0, 0); - this.velocity = new ex.Vector(0, 0); - this.acceleration = new ex.Vector(0, 0); - this.particleRotationalVelocity = 0; - this.currentRotation = 0; - this.focus = null; - this.focusAccel = 0; - this.opacity = 1; - this.beginColor = ex.Color.White.clone(); - this.endColor = ex.Color.White.clone(); - // Life is counted in ms - this.life = 300; - this.fadeFlag = false; - // Color transitions - this._rRate = 1; - this._gRate = 1; - this._bRate = 1; - this._aRate = 0; - this._currentColor = ex.Color.White.clone(); - this.emitter = null; - this.particleSize = 5; - this.particleSprite = null; - this.sizeRate = 0; - this.elapsedMultiplier = 0; - this.emitter = emitter; - this.life = life || this.life; - this.opacity = opacity || this.opacity; - this.endColor = endColor || this.endColor.clone(); - this.beginColor = beginColor || this.beginColor.clone(); - this._currentColor = this.beginColor.clone(); - this.position = position || this.position; - this.velocity = velocity || this.velocity; - this.acceleration = acceleration || this.acceleration; - this._rRate = (this.endColor.r - this.beginColor.r) / this.life; - this._gRate = (this.endColor.g - this.beginColor.g) / this.life; - this._bRate = (this.endColor.b - this.beginColor.b) / this.life; - this._aRate = this.opacity / this.life; - this.startSize = startSize || 0; - this.endSize = endSize || 0; - if ((this.endSize > 0) && (this.startSize > 0)) { - this.sizeRate = (this.endSize - this.startSize) / this.life; - this.particleSize = this.startSize; - } - } - Particle.prototype.kill = function () { - this.emitter.removeParticle(this); - }; - Particle.prototype.update = function (delta) { - this.life = this.life - delta; - this.elapsedMultiplier = this.elapsedMultiplier + delta; - if (this.life < 0) { - this.kill(); - } - if (this.fadeFlag) { - this.opacity = ex.Util.clamp(this._aRate * this.life, 0.0001, 1); - } - if ((this.startSize > 0) && (this.endSize > 0)) { - this.particleSize = ex.Util.clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize)); - } - this._currentColor.r = ex.Util.clamp(this._currentColor.r + this._rRate * delta, 0, 255); - this._currentColor.g = ex.Util.clamp(this._currentColor.g + this._gRate * delta, 0, 255); - this._currentColor.b = ex.Util.clamp(this._currentColor.b + this._bRate * delta, 0, 255); - this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); - if (this.focus) { - var accel = this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(delta / 1000); - this.velocity = this.velocity.add(accel); - } - else { - this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000)); - } - this.position = this.position.add(this.velocity.scale(delta / 1000)); - if (this.particleRotationalVelocity) { - this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI); - } - }; - Particle.prototype.draw = function (ctx) { - if (this.particleSprite) { - this.particleSprite.rotation = this.currentRotation; - this.particleSprite.scale.setTo(this.particleSize, this.particleSize); - this.particleSprite.draw(ctx, this.position.x, this.position.y); - return; - } - this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); - ctx.fillStyle = this._currentColor.toString(); - ctx.beginPath(); - ctx.arc(this.position.x, this.position.y, this.particleSize, 0, Math.PI * 2); - ctx.fill(); - ctx.closePath(); - }; - return Particle; - })(); - ex.Particle = Particle; + (function (PromiseState) { + PromiseState[PromiseState["Resolved"] = 0] = "Resolved"; + PromiseState[PromiseState["Rejected"] = 1] = "Rejected"; + PromiseState[PromiseState["Pending"] = 2] = "Pending"; + })(ex.PromiseState || (ex.PromiseState = {})); + var PromiseState = ex.PromiseState; /** - * Particle Emitters + * Promises/A+ spec implementation of promises * - * Using a particle emitter is a great way to create interesting effects - * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` - * extend [[Actor]] allowing you to use all of the features that come with. + * Promises are used to do asynchronous work and they are useful for + * creating a chain of actions. In Excalibur they are used for loading, + * sounds, animation, actions, and more. * - * The easiest way to create a `ParticleEmitter` is to use the - * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. + * ## A Promise Chain * - * ## Example: Adding an emitter + * Promises can be chained together and can be useful for creating a queue + * of functions to be called when something is done. + * + * The first [[Promise]] you will encounter is probably [[Engine.start]] + * which resolves when the game has finished loading. * * ```js - * var actor = new ex.Actor(...); - * var emitter = new ex.ParticleEmitter(...); + * var game = new ex.Engine(); * - * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle - * emitter.radius = 5; - * emitter.minVel = 100; - * emitter.maxVel = 200; - * emitter.minAngle = 0; - * emitter.maxAngle = Math.PI * 2; - * emitter.emitRate = 300; // 300 particles/second - * emitter.opacity = 0.5; - * emitter.fadeFlag = true; // fade particles overtime - * emitter.particleLife = 1000; // in milliseconds = 1 sec - * emitter.maxSize = 10; // in pixels - * emitter.minSize = 1; - * emitter.particleColor = ex.Color.Rose; + * // perform start-up logic once game is ready + * game.start().then(function () { * - * // set emitter settings - * emitter.isEmitting = true; // should the emitter be emitting + * // start-up & initialization logic * - * // add the emitter as a child actor, it will draw on top of the parent actor - * // and move with the parent - * actor.add(emitter); + * }); + * ``` * - * // or, alternatively, add it to the current scene - * engine.add(emitter); + * ## Handling errors + * + * You can optionally pass an error handler to [[Promise.then]] which will handle + * any errors that occur during Promise execution. + * + * ```js + * var game = new ex.Engine(); + * + * game.start().then( + * // success handler + * function () { + * }, + * + * // error handler + * function (err) { + * } + * ); * ``` + * + * Any errors that go unhandled will be bubbled up to the browser. */ - var ParticleEmitter = (function (_super) { - __extends(ParticleEmitter, _super); + var Promise = (function () { + function Promise() { + this._state = PromiseState.Pending; + this._successCallbacks = []; + this._rejectCallback = function () { return; }; + this._logger = ex.Logger.getInstance(); + } /** - * @param x The x position of the emitter - * @param y The y position of the emitter - * @param width The width of the emitter - * @param height The height of the emitter + * Wrap a value in a resolved promise + * @param value An optional value to wrap in a resolved promise */ - function ParticleEmitter(x, y, width, height) { - _super.call(this, x, y, width, height, ex.Color.White); - this._particlesToEmit = 0; - this.numParticles = 0; - /** - * Gets or sets the isEmitting flag - */ - this.isEmitting = true; - /** - * Gets or sets the backing particle collection - */ - this.particles = null; - /** - * Gets or sets the backing deadParticle collection - */ - this.deadParticles = null; - /** - * Gets or sets the minimum partical velocity - */ - this.minVel = 0; - /** - * Gets or sets the maximum partical velocity - */ - this.maxVel = 0; - /** - * Gets or sets the acceleration vector for all particles - */ - this.acceleration = new ex.Vector(0, 0); - /** - * Gets or sets the minimum angle in radians - */ - this.minAngle = 0; - /** - * Gets or sets the maximum angle in radians - */ - this.maxAngle = 0; - /** - * Gets or sets the emission rate for particles (particles/sec) - */ - this.emitRate = 1; //particles/sec - /** - * Gets or sets the life of each particle in milliseconds - */ - this.particleLife = 2000; - /** - * Gets or sets the opacity of each particle from 0 to 1.0 - */ - this.opacity = 1; - /** - * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. - */ - this.fadeFlag = false; - /** - * Gets or sets the optional focus where all particles should accelerate towards - */ - this.focus = null; - /** - * Gets or sets the acceleration for focusing particles if a focus has been specified - */ - this.focusAccel = 1; - /* - * Gets or sets the optional starting size for the particles - */ - this.startSize = null; - /* - * Gets or sets the optional ending size for the particles - */ - this.endSize = null; - /** - * Gets or sets the minimum size of all particles - */ - this.minSize = 5; - /** - * Gets or sets the maximum size of all particles - */ - this.maxSize = 5; - /** - * Gets or sets the beginning color of all particles - */ - this.beginColor = ex.Color.White; - /** - * Gets or sets the ending color of all particles - */ - this.endColor = ex.Color.White; - /** - * Gets or sets the sprite that a particle should use - * @warning Performance intensive - */ - this.particleSprite = null; - /** - * Gets or sets the emitter type for the particle emitter - */ - this.emitterType = EmitterType.Rectangle; - /** - * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] - */ - this.radius = 0; - /** - * Gets or sets the particle rotational speed velocity - */ - this.particleRotationalVelocity = 0; - /** - * Indicates whether particles should start with a random rotation - */ - this.randomRotation = false; - this.collisionType = ex.CollisionType.PreventCollision; - this.particles = new ex.Util.Collection(); - this.deadParticles = new ex.Util.Collection(); - // Remove offscreen culling from particle emitters - for (var trait in this.traits) { - if (this.traits[trait] instanceof ex.Traits.OffscreenCulling) { - this.traits.splice(trait, 1); - } - } - } - ParticleEmitter.prototype.removeParticle = function (particle) { - this.deadParticles.push(particle); + Promise.wrap = function (value) { + var promise = (new Promise()).resolve(value); + return promise; }; /** - * Causes the emitter to emit particles - * @param particleCount Number of particles to emit right now + * Returns a new promise that resolves when all the promises passed to it resolve, or rejects + * when at least 1 promise rejects. */ - ParticleEmitter.prototype.emitParticles = function (particleCount) { - for (var i = 0; i < particleCount; i++) { - this.particles.push(this._createParticle()); + Promise.join = function () { + var promises = []; + for (var _i = 0; _i < arguments.length; _i++) { + promises[_i - 0] = arguments[_i]; } + var joinedPromise = new Promise(); + if (!promises || !promises.length) { + return joinedPromise.resolve(); + } + var total = promises.length; + var successes = 0; + var rejects = 0; + var errors = []; + promises.forEach(function (p) { + p.then(function () { + successes += 1; + if (successes === total) { + joinedPromise.resolve(); + } + else if (successes + rejects + errors.length === total) { + joinedPromise.reject(errors); + } + }, function () { + rejects += 1; + if (successes + rejects + errors.length === total) { + joinedPromise.reject(errors); + } + }).error(function (e) { + errors.push(e); + if ((errors.length + successes + rejects) === total) { + joinedPromise.reject(errors); + } + }); + }); + return joinedPromise; }; - ParticleEmitter.prototype.clearParticles = function () { - this.particles.clear(); - }; - // Creates a new particle given the contraints of the emitter - ParticleEmitter.prototype._createParticle = function () { - // todo implement emitter contraints; - var ranX = 0; - var ranY = 0; - var angle = ex.Util.randomInRange(this.minAngle, this.maxAngle); - var vel = ex.Util.randomInRange(this.minVel, this.maxVel); - var size = this.startSize || ex.Util.randomInRange(this.minSize, this.maxSize); - var dx = vel * Math.cos(angle); - var dy = vel * Math.sin(angle); - if (this.emitterType === EmitterType.Rectangle) { - ranX = ex.Util.randomInRange(this.x, this.x + this.getWidth()); - ranY = ex.Util.randomInRange(this.y, this.y + this.getHeight()); + /** + * Chain success and reject callbacks after the promise is resovled + * @param successCallback Call on resolution of promise + * @param rejectCallback Call on rejection of promise + */ + Promise.prototype.then = function (successCallback, rejectCallback) { + if (successCallback) { + this._successCallbacks.push(successCallback); + // If the promise is already resovled call immediately + if (this.state() === PromiseState.Resolved) { + try { + successCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); + } + } } - else if (this.emitterType === EmitterType.Circle) { - var radius = ex.Util.randomInRange(0, this.radius); - ranX = radius * Math.cos(angle) + this.x; - ranY = radius * Math.sin(angle) + this.y; + if (rejectCallback) { + this._rejectCallback = rejectCallback; + // If the promise is already rejected call immediately + if (this.state() === PromiseState.Rejected) { + try { + rejectCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); + } + } } - var p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new ex.Vector(ranX, ranY), new ex.Vector(dx, dy), this.acceleration, this.startSize, this.endSize); - p.fadeFlag = this.fadeFlag; - p.particleSize = size; - if (this.particleSprite) { - p.particleSprite = this.particleSprite; + return this; + }; + /** + * Add an error callback to the promise + * @param errorCallback Call if there was an error in a callback + */ + Promise.prototype.error = function (errorCallback) { + if (errorCallback) { + this._errorCallback = errorCallback; } - p.particleRotationalVelocity = this.particleRotationalVelocity; - if (this.randomRotation) { - p.currentRotation = ex.Util.randomInRange(0, Math.PI * 2); + return this; + }; + /** + * Resolve the promise and pass an option value to the success callbacks + * @param value Value to pass to the success callbacks + */ + Promise.prototype.resolve = function (value) { + var _this = this; + if (this._state === PromiseState.Pending) { + this._value = value; + try { + this._state = PromiseState.Resolved; + this._successCallbacks.forEach(function (cb) { + cb.call(_this, _this._value); + }); + } + catch (e) { + this._handleError(e); + } } - if (this.focus) { - p.focus = this.focus.add(new ex.Vector(this.x, this.y)); - p.focusAccel = this.focusAccel; + else { + throw new Error('Cannot resolve a promise that is not in a pending state!'); } - return p; + return this; }; - ParticleEmitter.prototype.update = function (engine, delta) { - var _this = this; - _super.prototype.update.call(this, engine, delta); - if (this.isEmitting) { - this._particlesToEmit += this.emitRate * (delta / 1000); - //var numParticles = Math.ceil(this.emitRate * delta / 1000); - if (this._particlesToEmit > 1.0) { - this.emitParticles(Math.floor(this._particlesToEmit)); - this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit); + /** + * Reject the promise and pass an option value to the reject callbacks + * @param value Value to pass to the reject callbacks + */ + Promise.prototype.reject = function (value) { + if (this._state === PromiseState.Pending) { + this._value = value; + try { + this._state = PromiseState.Rejected; + this._rejectCallback.call(this, this._value); + } + catch (e) { + this._handleError(e); } } - this.particles.forEach(function (p) { return p.update(delta); }); - this.deadParticles.forEach(function (p) { return _this.particles.removeElement(p); }); - this.deadParticles.clear(); + else { + throw new Error('Cannot reject a promise that is not in a pending state!'); + } + return this; }; - ParticleEmitter.prototype.draw = function (ctx, delta) { - // todo is there a more efficient to draw - // possibly use a webgl offscreen canvas and shaders to do particles? - this.particles.forEach(function (p) { return p.draw(ctx); }); + /** + * Inpect the current state of a promise + */ + Promise.prototype.state = function () { + return this._state; }; - ParticleEmitter.prototype.debugDraw = function (ctx) { - _super.prototype.debugDraw.call(this, ctx); - ctx.fillStyle = ex.Color.Black.toString(); - ctx.fillText('Particles: ' + this.particles.count(), this.x, this.y + 20); - if (this.focus) { - ctx.fillRect(this.focus.x + this.x, this.focus.y + this.y, 3, 3); - ex.Util.drawLine(ctx, 'yellow', this.focus.x + this.x, this.focus.y + this.y, _super.prototype.getCenter.call(this).x, _super.prototype.getCenter.call(this).y); - ctx.fillText('Focus', this.focus.x + this.x, this.focus.y + this.y); + Promise.prototype._handleError = function (e) { + if (this._errorCallback) { + this._errorCallback.call(this, e); + } + else { + // rethrow error + throw e; } }; - return ParticleEmitter; - })(ex.Actor); - ex.ParticleEmitter = ParticleEmitter; + return Promise; + })(); + ex.Promise = Promise; })(ex || (ex = {})); +/// +/// +/// +/// var ex; (function (ex) { /** - * Animations + * Textures * - * Animations allow you to display a series of images one after another, - * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. + * The [[Texture]] object allows games built in Excalibur to load image resources. + * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] + * to pre-load before starting a level or game. * - * ## Creating an animation + * Textures are the raw image so to add a drawing to a game, you must create + * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite + * instance. * - * Create a [[Texture]] that contains the frames of your animation. Once the texture - * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] - * and using [[SpriteSheet.getAnimationForAll]]. + * ## Pre-loading textures * - * ```js - * var game = new ex.Engine(); - * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); + * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] + * is loaded, you can generate a [[Sprite]] with it. * - * // load assets - * var loader = new ex.Loader(txAnimPlayerIdle); + * ```js + * var txPlayer = new ex.Texture("/assets/tx/player.png"); * - * // start game - * game.start(loader).then(function () { - * var player = new ex.Actor(); + * var loader = new ex.Loader(txPlayer); * - * // create sprite sheet with 5 columns, 1 row, 80x80 frames - * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); + * game.start(loader).then(function () { * - * // create animation (125ms frame speed) - * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); + * var player = new ex.Actor(); * - * // add drawing to player as "idle" - * player.addDrawing("idle", playerIdleAnimation); + * player.addDrawing(txPlayer); * - * // add player to game * game.add(player); * }); * ``` - * - * ## Sprite effects - * - * You can add [[SpriteEffect|sprite effects]] to an animation through methods - * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this - * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - var Animation = (function () { + var Texture = (function (_super) { + __extends(Texture, _super); /** - * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. - * - * @param engine Reference to the current game engine - * @param images An array of sprites to create the frames for the animation - * @param speed The number in milliseconds to display each frame in the animation - * @param loop Indicates whether the animation should loop after it is completed + * @param path Path to the image resource + * @param bustCache Optionally load texture with cache busting */ - function Animation(engine, images, speed, loop) { - /** - * Current frame index being shown - */ - this.currentFrame = 0; - this._oldTime = Date.now(); - this.anchor = new ex.Point(0.0, 0.0); - this.rotation = 0.0; - this.scale = new ex.Point(1, 1); - /** - * Indicates whether the animation should loop after it is completed - */ - this.loop = false; - /** - * Indicates the frame index the animation should freeze on for a non-looping - * animation. By default it is the last frame. - */ - this.freezeFrame = -1; - /** - * Flip each frame vertically. Sets [[Sprite.flipVertical]]. - */ - this.flipVertical = false; + function Texture(path, bustCache) { + if (bustCache === void 0) { bustCache = true; } + _super.call(this, path, 'blob', bustCache); + this.path = path; + this.bustCache = bustCache; /** - * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + * A [[Promise]] that resolves when the Texture is loaded. */ - this.flipHorizontal = false; - this.width = 0; - this.height = 0; - this.naturalWidth = 0; - this.naturalHeight = 0; - this.sprites = images; - this.speed = speed; - this._engine = engine; - if (loop != null) { - this.loop = loop; - } - if (images && images[0]) { - this.height = images[0] ? images[0].height : 0; - this.width = images[0] ? images[0].width : 0; - this.naturalWidth = images[0] ? images[0].naturalWidth : 0; - this.naturalHeight = images[0] ? images[0].naturalHeight : 0; - this.freezeFrame = images.length - 1; - } + this.loaded = new ex.Promise(); + this._isLoaded = false; + this._sprite = null; + this._sprite = new ex.Sprite(this, 0, 0, 0, 0); } /** - * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + * Returns true if the Texture is completely loaded and is ready + * to be drawn. */ - Animation.prototype.opacity = function (value) { - this.addEffect(new ex.Effects.Opacity(value)); + Texture.prototype.isLoaded = function () { + return this._isLoaded; }; /** - * Applies the grayscale effect to a sprite, removing color information. + * Begins loading the texture and returns a promise to be resolved on completion */ - Animation.prototype.grayscale = function () { - this.addEffect(new ex.Effects.Grayscale()); + Texture.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + var loaded = _super.prototype.load.call(this); + loaded.then(function () { + _this.image = new Image(); + _this.image.addEventListener('load', function () { + _this._isLoaded = true; + _this.width = _this._sprite.swidth = _this._sprite.naturalWidth = _this._sprite.width = _this.image.naturalWidth; + _this.height = _this._sprite.sheight = _this._sprite.naturalHeight = _this._sprite.height = _this.image.naturalHeight; + _this.loaded.resolve(_this.image); + complete.resolve(_this.image); + }); + _this.image.src = _super.prototype.getData.call(_this); + }, function () { + complete.reject('Error loading texture.'); + }); + return complete; }; - /** - * Applies the invert effect to a sprite, inverting the pixel colors. - */ - Animation.prototype.invert = function () { - this.addEffect(new ex.Effects.Invert()); + Texture.prototype.asSprite = function () { + return this._sprite; }; + return Texture; + })(ex.Resource); + ex.Texture = Texture; +})(ex || (ex = {})); +/// +/// +/// +/// +var ex; +(function (ex) { + /** + * Sounds + * + * The [[Sound]] object allows games built in Excalibur to load audio + * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] + * which means it can be passed to a [[Loader]] to pre-load before a game or level. + * + * ## Pre-loading sounds + * + * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] + * is loaded, you can [[Sound.play|play]] it. + * + * ```js + * // define multiple sources (such as mp3/wav/ogg) as a browser fallback + * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); + * + * var loader = new ex.Loader(sndPlayerDeath); + * + * game.start(loader).then(function () { + * + * sndPlayerDeath.play(); + * }); + * ``` + */ + var Sound = (function () { /** - * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color + * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. */ - Animation.prototype.fill = function (color) { - this.addEffect(new ex.Effects.Fill(color)); - }; + function Sound() { + var paths = []; + for (var _i = 0; _i < arguments.length; _i++) { + paths[_i - 0] = arguments[_i]; + } + this._logger = ex.Logger.getInstance(); + this.onprogress = function () { return; }; + this.oncomplete = function () { return; }; + this.onerror = function () { return; }; + this.onload = function () { return; }; + this._isLoaded = false; + this._wasPlayingOnHidden = false; + /* Chrome : MP3, WAV, Ogg + * Firefox : WAV, Ogg, + * IE : MP3, WAV coming soon + * Safari MP3, WAV, Ogg + */ + this.path = ''; + for (var i = 0; i < paths.length; i++) { + if (Sound.canPlayFile(paths[i])) { + this.path = paths[i]; + break; + } + } + if (!this.path) { + this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); + this._logger.warn('Attempting to use', paths[0]); + this.path = paths[0]; // select the first specified + } + this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); + } /** - * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the - * provided color. + * Whether or not the browser can play this file as HTML5 Audio */ - Animation.prototype.colorize = function (color) { - this.addEffect(new ex.Effects.Colorize(color)); + Sound.canPlayFile = function (file) { + try { + var a = new Audio(); + var filetype = /.*\.([A-Za-z0-9]+)$/; + var type = file.match(filetype)[1]; + if (a.canPlayType('audio/' + type)) { + return true; + } + { + return false; + } + } + catch (e) { + ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); + return false; + } + }; + Sound.prototype.wireEngine = function (engine) { + var _this = this; + if (engine) { + this._engine = engine; + this._engine.on('hidden', function () { + if (engine.pauseAudioWhenHidden && _this.isPlaying()) { + _this._wasPlayingOnHidden = true; + _this.pause(); + } + }); + this._engine.on('visible', function () { + if (engine.pauseAudioWhenHidden && _this._wasPlayingOnHidden) { + _this.play(); + _this._wasPlayingOnHidden = false; + } + }); + } }; /** - * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl + * Sets the volume of the sound clip + * @param volume A volume value between 0-1.0 */ - Animation.prototype.lighten = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Lighten(factor)); + Sound.prototype.setVolume = function (volume) { + if (this.sound) { + this.sound.setVolume(volume); + } }; /** - * Applies the darken effect to a sprite, changes the darkness of the color according to hsl + * Indicates whether the clip should loop when complete + * @param loop Set the looping flag */ - Animation.prototype.darken = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Darken(factor)); + Sound.prototype.setLoop = function (loop) { + if (this.sound) { + this.sound.setLoop(loop); + } }; /** - * Applies the saturate effect to a sprite, saturates the color acccording to hsl + * Whether or not the sound is playing right now */ - Animation.prototype.saturate = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Saturate(factor)); + Sound.prototype.isPlaying = function () { + if (this.sound) { + return this.sound.isPlaying(); + } }; /** - * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl + * Play the sound, returns a promise that resolves when the sound is done playing */ - Animation.prototype.desaturate = function (factor) { - if (factor === void 0) { factor = 0.1; } - this.addEffect(new ex.Effects.Desaturate(factor)); + Sound.prototype.play = function () { + if (this.sound) { + return this.sound.play(); + } }; /** - * Add a [[ISpriteEffect]] manually + * Stop the sound, and do not rewind */ - Animation.prototype.addEffect = function (effect) { - for (var i in this.sprites) { - this.sprites[i].addEffect(effect); + Sound.prototype.pause = function () { + if (this.sound) { + this.sound.pause(); } }; - Animation.prototype.removeEffect = function (param) { - for (var i in this.sprites) { - this.sprites[i].removeEffect(param); + /** + * Stop the sound and rewind + */ + Sound.prototype.stop = function () { + if (this.sound) { + this.sound.stop(); } }; /** - * Clear all sprite effects + * Returns true if the sound is loaded */ - Animation.prototype.clearEffects = function () { - for (var i in this.sprites) { - this.sprites[i].clearEffects(); - } + Sound.prototype.isLoaded = function () { + return this._isLoaded; }; - Animation.prototype._setAnchor = function (point) { - //if (!this.anchor.equals(point)) { - for (var i in this.sprites) { - this.sprites[i].anchor.setTo(point.x, point.y); + /** + * Begins loading the sound and returns a promise to be resolved on completion + */ + Sound.prototype.load = function () { + var _this = this; + var complete = new ex.Promise(); + if (this.sound.getData() !== null) { + this._logger.debug('Already have data for resource', this.path); + complete.resolve(this.sound); + return complete; } - //} + this._logger.debug('Started loading sound', this.path); + this.sound.onprogress = this.onprogress; + this.sound.onload = function () { + _this.oncomplete(); + _this._isLoaded = true; + _this._logger.debug('Completed loading sound', _this.path); + complete.resolve(_this.sound); + }; + this.sound.onerror = function (e) { + _this.onerror(e); + complete.resolve(e); + }; + this.sound.load(); + return complete; }; - Animation.prototype._setRotation = function (radians) { - //if (this.rotation !== radians) { - for (var i in this.sprites) { - this.sprites[i].rotation = radians; - } - //} + Sound.prototype.getData = function () { + return this.sound.getData(); }; - Animation.prototype._setScale = function (scale) { - //if (!this.scale.equals(scale)) { - for (var i in this.sprites) { - this.sprites[i].scale = scale; - } - //} + Sound.prototype.setData = function (data) { + this.sound.setData(data); }; - /** - * Resets the animation to first frame. - */ - Animation.prototype.reset = function () { - this.currentFrame = 0; + Sound.prototype.processData = function (data) { + return this.sound.processData(data); }; + return Sound; + })(); + ex.Sound = Sound; +})(ex || (ex = {})); +/// +var ex; +(function (ex) { + /** + * Helper [[Actor]] primitive for drawing UI's, optimized for UI drawing. Does + * not participate in collisions. Drawn on top of all other actors. + */ + var UIActor = (function (_super) { + __extends(UIActor, _super); /** - * Indicates whether the animation is complete, animations that loop are never complete. + * @param x The starting x coordinate of the actor + * @param y The starting y coordinate of the actor + * @param width The starting width of the actor + * @param height The starting height of the actor */ - Animation.prototype.isDone = function () { - return (!this.loop && this.currentFrame >= this.sprites.length); + function UIActor(x, y, width, height) { + _super.call(this, x, y, width, height); + this.traits = []; + this.traits.push(new ex.Traits.Movement()); + this.traits.push(new ex.Traits.CapturePointer()); + this.anchor.setTo(0, 0); + this.collisionType = ex.CollisionType.PreventCollision; + this.enableCapturePointer = true; + } + UIActor.prototype.onInitialize = function (engine) { + this._engine = engine; }; - /** - * Not meant to be called by game developers. Ticks the animation forward internally and - * calculates whether to change to the frame. - * @internal - */ - Animation.prototype.tick = function () { - var time = Date.now(); - if ((time - this._oldTime) > this.speed) { - this.currentFrame = (this.loop ? (this.currentFrame + 1) % this.sprites.length : this.currentFrame + 1); - this._oldTime = time; + UIActor.prototype.contains = function (x, y, useWorld) { + if (useWorld === void 0) { useWorld = true; } + if (useWorld) { + return _super.prototype.contains.call(this, x, y); } + var coords = this._engine.worldToScreenCoordinates(new ex.Point(x, y)); + return _super.prototype.contains.call(this, coords.x, coords.y); }; - Animation.prototype._updateValues = function () { - this._setAnchor(this.anchor); - this._setRotation(this.rotation); - this._setScale(this.scale); - }; + return UIActor; + })(ex.Actor); + ex.UIActor = UIActor; +})(ex || (ex = {})); +/// +/// +var ex; +(function (ex) { + /** + * Triggers + * + * Triggers are a method of firing arbitrary code on collision. These are useful + * as 'buttons', 'switches', or to trigger effects in a game. By default triggers + * are invisible, and can only be seen when [[Engine.isDebug]] is set to `true`. + * + * ## Creating a trigger + * + * ```js + * var game = new ex.Game(); + * + * // create a handler + * function onTrigger() { + * + * // `this` will be the Trigger instance + * ex.Logger.getInstance().info("Trigger was triggered!", this); + * } + * + * // set a trigger at (100, 100) that is 40x40px + * var trigger = new ex.Trigger(100, 100, 40, 40, onTrigger, 1); + * + * // create an actor across from the trigger + * var actor = new ex.Actor(100, 0, 40, 40, ex.Color.Red); + * + * // tell the actor to move towards the trigger over 3 seconds + * actor.moveTo(100, 200, 3000); + * + * game.add(trigger); + * game.add(actor); + * + * game.start(); + * ``` + */ + var Trigger = (function (_super) { + __extends(Trigger, _super); /** - * Skips ahead a specified number of frames in the animation - * @param frames Frames to skip ahead + * @param x The x position of the trigger + * @param y The y position of the trigger + * @param width The width of the trigger + * @param height The height of the trigger + * @param action Callback to fire when trigger is activated, `this` will be bound to the Trigger instance + * @param repeats The number of times that this trigger should fire, by default it is 1, if -1 is supplied it will fire indefinitely */ - Animation.prototype.skip = function (frames) { - this.currentFrame = (this.currentFrame + frames) % this.sprites.length; - }; - Animation.prototype.draw = function (ctx, x, y) { - this.tick(); - this._updateValues(); - var currSprite; - if (this.currentFrame < this.sprites.length) { - currSprite = this.sprites[this.currentFrame]; - if (this.flipVertical) { - currSprite.flipVertical = this.flipVertical; - } - if (this.flipHorizontal) { - currSprite.flipHorizontal = this.flipHorizontal; + function Trigger(x, y, width, height, action, repeats) { + _super.call(this, x, y, width, height); + this._action = function () { return; }; + this.repeats = 1; + this.target = null; + this.repeats = repeats || this.repeats; + this._action = action || this._action; + this.collisionType = ex.CollisionType.PreventCollision; + this.eventDispatcher = new ex.EventDispatcher(this); + this.actionQueue = new ex.Internal.Actions.ActionQueue(this); + } + Trigger.prototype.update = function (engine, delta) { + // Update action queue + this.actionQueue.update(delta); + // Update placements based on linear algebra + this.x += this.dx * delta / 1000; + this.y += this.dy * delta / 1000; + this.rotation += this.rx * delta / 1000; + this.scale.x += this.sx * delta / 1000; + this.scale.y += this.sy * delta / 1000; + // check for trigger collisions + if (this.target) { + if (this.collides(this.target)) { + this._dispatchAction(); } - currSprite.draw(ctx, x, y); } - if (this.freezeFrame !== -1 && this.currentFrame >= this.sprites.length) { - currSprite = this.sprites[ex.Util.clamp(this.freezeFrame, 0, this.sprites.length - 1)]; - currSprite.draw(ctx, x, y); + else { + for (var i = 0; i < engine.currentScene.children.length; i++) { + var other = engine.currentScene.children[i]; + if (other !== this && + other.collisionType !== ex.CollisionType.PreventCollision && + this.collides(other)) { + this._dispatchAction(); + } + } } - // add the calculated width - if (currSprite) { - this.width = currSprite.width; - this.height = currSprite.height; + // remove trigger if its done, -1 repeat forever + if (this.repeats === 0) { + this.kill(); } }; - /** - * Plays an animation at an arbitrary location in the game. - * @param x The x position in the game to play - * @param y The y position in the game to play - */ - Animation.prototype.play = function (x, y) { - this.reset(); - this._engine.playAnimation(this, x, y); + Trigger.prototype._dispatchAction = function () { + this._action.call(this); + this.repeats--; }; - return Animation; - })(); - ex.Animation = Animation; + Trigger.prototype.draw = function (ctx, delta) { + // does not draw + return; + }; + Trigger.prototype.debugDraw = function (ctx) { + _super.prototype.debugDraw.call(this, ctx); + // Meant to draw debug information about actors + ctx.save(); + ctx.translate(this.x, this.y); + var bb = this.getBounds(); + bb.left = bb.left - this.getWorldX(); + bb.right = bb.right - this.getWorldX(); + bb.top = bb.top - this.getWorldY(); + bb.bottom = bb.bottom - this.getWorldY(); + // Currently collision primitives cannot rotate + // ctx.rotate(this.rotation); + ctx.fillStyle = ex.Color.Violet.toString(); + ctx.strokeStyle = ex.Color.Violet.toString(); + ctx.fillText('Trigger', 10, 10); + bb.debugDraw(ctx); + ctx.restore(); + }; + return Trigger; + })(ex.Actor); + ex.Trigger = Trigger; })(ex || (ex = {})); -/// +/// +/// /// -/// +/// var ex; (function (ex) { - var Internal; - (function (Internal) { - var FallbackAudio = (function () { - function FallbackAudio(path, volume) { - this.path = path; - this._log = ex.Logger.getInstance(); - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - if (window.AudioContext) { - this._log.debug('Using new Web Audio Api for ' + path); - this._soundImpl = new WebAudio(path, volume); - } - else { - this._log.debug('Falling back to Audio Element for ' + path); - this._soundImpl = new AudioTag(path, volume); - } + /** + * An enum that represents the types of emitter nozzles + */ + (function (EmitterType) { + /** + * Constant for the circular emitter type + */ + EmitterType[EmitterType["Circle"] = 0] = "Circle"; + /** + * Constant for the rectangular emitter type + */ + EmitterType[EmitterType["Rectangle"] = 1] = "Rectangle"; + })(ex.EmitterType || (ex.EmitterType = {})); + var EmitterType = ex.EmitterType; + /** + * Particle is used in a [[ParticleEmitter]] + */ + var Particle = (function () { + function Particle(emitter, life, opacity, beginColor, endColor, position, velocity, acceleration, startSize, endSize) { + this.position = new ex.Vector(0, 0); + this.velocity = new ex.Vector(0, 0); + this.acceleration = new ex.Vector(0, 0); + this.particleRotationalVelocity = 0; + this.currentRotation = 0; + this.focus = null; + this.focusAccel = 0; + this.opacity = 1; + this.beginColor = ex.Color.White.clone(); + this.endColor = ex.Color.White.clone(); + // Life is counted in ms + this.life = 300; + this.fadeFlag = false; + // Color transitions + this._rRate = 1; + this._gRate = 1; + this._bRate = 1; + this._aRate = 0; + this._currentColor = ex.Color.White.clone(); + this.emitter = null; + this.particleSize = 5; + this.particleSprite = null; + this.sizeRate = 0; + this.elapsedMultiplier = 0; + this.emitter = emitter; + this.life = life || this.life; + this.opacity = opacity || this.opacity; + this.endColor = endColor || this.endColor.clone(); + this.beginColor = beginColor || this.beginColor.clone(); + this._currentColor = this.beginColor.clone(); + this.position = position || this.position; + this.velocity = velocity || this.velocity; + this.acceleration = acceleration || this.acceleration; + this._rRate = (this.endColor.r - this.beginColor.r) / this.life; + this._gRate = (this.endColor.g - this.beginColor.g) / this.life; + this._bRate = (this.endColor.b - this.beginColor.b) / this.life; + this._aRate = this.opacity / this.life; + this.startSize = startSize || 0; + this.endSize = endSize || 0; + if ((this.endSize > 0) && (this.startSize > 0)) { + this.sizeRate = (this.endSize - this.startSize) / this.life; + this.particleSize = this.startSize; } - FallbackAudio.prototype.setVolume = function (volume) { - this._soundImpl.setVolume(volume); - }; - FallbackAudio.prototype.setLoop = function (loop) { - this._soundImpl.setLoop(loop); - }; - FallbackAudio.prototype.load = function () { - this._soundImpl.onload = this.onload; - this._soundImpl.onprogress = this.onprogress; - this._soundImpl.onerror = this.onerror; - this._soundImpl.load(); - }; - FallbackAudio.prototype.processData = function (data) { - return this._soundImpl.processData(data); - }; - FallbackAudio.prototype.getData = function () { - return this._soundImpl.getData(); - }; - FallbackAudio.prototype.setData = function (data) { - this._soundImpl.setData(data); - }; - FallbackAudio.prototype.isPlaying = function () { - return this._soundImpl.isPlaying(); - }; - FallbackAudio.prototype.play = function () { - return this._soundImpl.play(); - }; - FallbackAudio.prototype.pause = function () { - this._soundImpl.pause(); - }; - FallbackAudio.prototype.stop = function () { - this._soundImpl.stop(); - }; - return FallbackAudio; - })(); - Internal.FallbackAudio = FallbackAudio; - var AudioTag = (function () { - function AudioTag(path, volume) { - var _this = this; - this.path = path; - this._audioElements = new Array(5); - this._loadedAudio = null; - this._isLoaded = false; - this._index = 0; - this._log = ex.Logger.getInstance(); - this._isPlaying = false; - this._currentOffset = 0; - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - for (var i = 0; i < this._audioElements.length; i++) { - (function (i) { - _this._audioElements[i] = new Audio(); - })(i); - } - if (volume) { - this.setVolume(ex.Util.clamp(volume, 0, 1.0)); - } - else { - this.setVolume(1.0); - } + } + Particle.prototype.kill = function () { + this.emitter.removeParticle(this); + }; + Particle.prototype.update = function (delta) { + this.life = this.life - delta; + this.elapsedMultiplier = this.elapsedMultiplier + delta; + if (this.life < 0) { + this.kill(); } - AudioTag.prototype.isPlaying = function () { - return this._isPlaying; - }; - AudioTag.prototype._audioLoaded = function () { - this._isLoaded = true; - }; - AudioTag.prototype.setVolume = function (volume) { - var i = 0, len = this._audioElements.length; - for (i; i < len; i++) { - this._audioElements[i].volume = volume; - } - }; - AudioTag.prototype.setLoop = function (loop) { - var i = 0, len = this._audioElements.length; - for (i; i < len; i++) { - this._audioElements[i].loop = loop; - } - }; - AudioTag.prototype.getLoop = function () { - this._audioElements.some(function (a) { return a.loop; }); - }; - AudioTag.prototype.load = function () { - var _this = this; - if (!!this._loadedAudio) { - return; - } - var request = new XMLHttpRequest(); - request.open('GET', this.path, true); - request.responseType = 'blob'; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function (e) { - if (request.status !== 200) { - _this._log.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - _this._isLoaded = false; - return; - } - _this._isLoaded = true; - _this.setData(request.response); - _this.onload(e); - }; - request.send(); - }; - AudioTag.prototype.getData = function () { - return this._loadedAudio; - }; - AudioTag.prototype.setData = function (data) { - this._isLoaded = true; - this._loadedAudio = this.processData(data); - }; - AudioTag.prototype.processData = function (data) { - var blobUrl = URL.createObjectURL(data); - this._audioElements.forEach(function (a) { - a.src = blobUrl; - }); - this._audioLoaded(); - return blobUrl; - }; - AudioTag.prototype.play = function () { - var _this = this; - this._audioElements[this._index].load(); - //this.audioElements[this.index].currentTime = this._currentOffset; - this._audioElements[this._index].play(); - this._currentOffset = 0; - var done = new ex.Promise(); - this._isPlaying = true; - if (!this.getLoop()) { - this._audioElements[this._index].addEventListener('ended', function () { - _this._isPlaying = false; - done.resolve(true); - }); - } - this._index = (this._index + 1) % this._audioElements.length; - return done; - }; - AudioTag.prototype.pause = function () { - this._index = (this._index - 1 + this._audioElements.length) % this._audioElements.length; - this._currentOffset = this._audioElements[this._index].currentTime; - this._audioElements.forEach(function (a) { - a.pause(); - }); - this._isPlaying = false; - }; - AudioTag.prototype.stop = function () { - this._audioElements.forEach(function (a) { - a.pause(); - //a.currentTime = 0; - }); - this._isPlaying = false; - }; - return AudioTag; - })(); - Internal.AudioTag = AudioTag; - if (window.AudioContext) { - var audioContext = new window.AudioContext(); - } - var WebAudio = (function () { - function WebAudio(path, volume) { - this.path = path; - this._context = audioContext; - this._volume = this._context.createGain(); - this._buffer = null; - this._sound = null; - this._isLoaded = false; - this._loop = false; - this._isPlaying = false; - this._isPaused = false; - this._currentOffset = 0; - this._logger = ex.Logger.getInstance(); - this._data = null; - this.onload = function () { return; }; - this.onprogress = function () { return; }; - this.onerror = function () { return; }; - if (volume) { - this._volume.gain.value = ex.Util.clamp(volume, 0, 1.0); - } - else { - this._volume.gain.value = 1.0; // max volume - } + if (this.fadeFlag) { + this.opacity = ex.Util.clamp(this._aRate * this.life, 0.0001, 1); } - WebAudio.prototype.setVolume = function (volume) { - this._volume.gain.value = volume; - }; - WebAudio.prototype.load = function () { - var _this = this; - // Exit early if we already have data - if (this._data !== null) { - return; - } - var request = new XMLHttpRequest(); - request.open('GET', this.path); - request.responseType = 'arraybuffer'; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function () { - if (request.status !== 200) { - _this._logger.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - _this._isLoaded = false; - return; - } - _this.setData(request.response); - }; - try { - request.send(); - } - catch (e) { - console.error('Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.'); - } - }; - WebAudio.prototype.getData = function () { - return this._data; - }; - WebAudio.prototype.setData = function (data) { - this._data = this.processData(data); - }; - WebAudio.prototype.processData = function (data) { - var _this = this; - this._context.decodeAudioData(data, function (buffer) { - _this._buffer = buffer; - _this._isLoaded = true; - _this.onload(_this); - }, function (e) { - _this._logger.error('Unable to decode ' + _this.path + - ' this browser may not fully support this format, or the file may be corrupt, ' + - 'if this is an mp3 try removing id3 tags and album art from the file.'); - _this._isLoaded = false; - _this.onload(_this); - }); - return data; - }; - WebAudio.prototype.setLoop = function (loop) { - this._loop = loop; - }; - WebAudio.prototype.isPlaying = function () { - return this._isPlaying; - }; - WebAudio.prototype.play = function () { - var _this = this; - if (this._isLoaded) { - this._sound = this._context.createBufferSource(); - this._sound.buffer = this._buffer; - this._sound.loop = this._loop; - this._sound.connect(this._volume); - this._volume.connect(this._context.destination); - this._sound.start(0, this._currentOffset % this._buffer.duration); - this._currentOffset = 0; - var done; - if (!this._isPaused || !this._playPromise) { - done = new ex.Promise(); - } - else { - done = this._playPromise; - } - this._isPaused = false; - this._isPlaying = true; - if (!this._loop) { - this._sound.onended = (function () { - _this._isPlaying = false; - if (!_this._isPaused) { - done.resolve(true); - } - }).bind(this); - } - this._playPromise = done; - return done; - } - else { - return ex.Promise.wrap(true); - } - }; - WebAudio.prototype.pause = function () { - if (this._isPlaying) { - try { - window.clearTimeout(this._playingTimer); - this._sound.stop(0); - this._currentOffset = this._context.currentTime; - this._isPlaying = false; - this._isPaused = true; - } - catch (e) { - this._logger.warn('The sound clip', this.path, 'has already been paused!'); - } - } - }; - WebAudio.prototype.stop = function () { - if (this._sound) { - try { - window.clearTimeout(this._playingTimer); - this._currentOffset = 0; - this._sound.stop(0); - this._isPlaying = false; - this._isPaused = false; - } - catch (e) { - this._logger.warn('The sound clip', this.path, 'has already been stopped!'); - } - } - }; - return WebAudio; - })(); - Internal.WebAudio = WebAudio; - })(Internal = ex.Internal || (ex.Internal = {})); -})(ex || (ex = {})); -/// -// Promises/A+ Spec http://promises-aplus.github.io/promises-spec/ -var ex; -(function (ex) { - /** - * Valid states for a promise to be in - */ - (function (PromiseState) { - PromiseState[PromiseState["Resolved"] = 0] = "Resolved"; - PromiseState[PromiseState["Rejected"] = 1] = "Rejected"; - PromiseState[PromiseState["Pending"] = 2] = "Pending"; - })(ex.PromiseState || (ex.PromiseState = {})); - var PromiseState = ex.PromiseState; + if ((this.startSize > 0) && (this.endSize > 0)) { + this.particleSize = ex.Util.clamp(this.sizeRate * delta + this.particleSize, Math.min(this.startSize, this.endSize), Math.max(this.startSize, this.endSize)); + } + this._currentColor.r = ex.Util.clamp(this._currentColor.r + this._rRate * delta, 0, 255); + this._currentColor.g = ex.Util.clamp(this._currentColor.g + this._gRate * delta, 0, 255); + this._currentColor.b = ex.Util.clamp(this._currentColor.b + this._bRate * delta, 0, 255); + this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); + if (this.focus) { + var accel = this.focus.minus(this.position).normalize().scale(this.focusAccel).scale(delta / 1000); + this.velocity = this.velocity.add(accel); + } + else { + this.velocity = this.velocity.add(this.acceleration.scale(delta / 1000)); + } + this.position = this.position.add(this.velocity.scale(delta / 1000)); + if (this.particleRotationalVelocity) { + this.currentRotation = (this.currentRotation + this.particleRotationalVelocity * delta / 1000) % (2 * Math.PI); + } + }; + Particle.prototype.draw = function (ctx) { + if (this.particleSprite) { + this.particleSprite.rotation = this.currentRotation; + this.particleSprite.scale.setTo(this.particleSize, this.particleSize); + this.particleSprite.draw(ctx, this.position.x, this.position.y); + return; + } + this._currentColor.a = ex.Util.clamp(this.opacity, 0.0001, 1); + ctx.fillStyle = this._currentColor.toString(); + ctx.beginPath(); + ctx.arc(this.position.x, this.position.y, this.particleSize, 0, Math.PI * 2); + ctx.fill(); + ctx.closePath(); + }; + return Particle; + })(); + ex.Particle = Particle; /** - * Promises/A+ spec implementation of promises - * - * Promises are used to do asynchronous work and they are useful for - * creating a chain of actions. In Excalibur they are used for loading, - * sounds, animation, actions, and more. + * Particle Emitters * - * ## A Promise Chain + * Using a particle emitter is a great way to create interesting effects + * in your game, like smoke, fire, water, explosions, etc. `ParticleEmitter` + * extend [[Actor]] allowing you to use all of the features that come with. * - * Promises can be chained together and can be useful for creating a queue - * of functions to be called when something is done. + * The easiest way to create a `ParticleEmitter` is to use the + * [Particle Tester](http://excaliburjs.com/particle-tester/) to generate code for emitters. * - * The first [[Promise]] you will encounter is probably [[Engine.start]] - * which resolves when the game has finished loading. + * ## Example: Adding an emitter * * ```js - * var game = new ex.Engine(); - * - * // perform start-up logic once game is ready - * game.start().then(function () { - * - * // start-up & initialization logic + * var actor = new ex.Actor(...); + * var emitter = new ex.ParticleEmitter(...); * - * }); - * ``` - * - * ## Handling errors - * - * You can optionally pass an error handler to [[Promise.then]] which will handle - * any errors that occur during Promise execution. + * emitter.emitterType = ex.EmitterType.Circle; // Shape of emitter nozzle + * emitter.radius = 5; + * emitter.minVel = 100; + * emitter.maxVel = 200; + * emitter.minAngle = 0; + * emitter.maxAngle = Math.PI * 2; + * emitter.emitRate = 300; // 300 particles/second + * emitter.opacity = 0.5; + * emitter.fadeFlag = true; // fade particles overtime + * emitter.particleLife = 1000; // in milliseconds = 1 sec + * emitter.maxSize = 10; // in pixels + * emitter.minSize = 1; + * emitter.particleColor = ex.Color.Rose; * - * ```js - * var game = new ex.Engine(); + * // set emitter settings + * emitter.isEmitting = true; // should the emitter be emitting * - * game.start().then( - * // success handler - * function () { - * }, + * // add the emitter as a child actor, it will draw on top of the parent actor + * // and move with the parent + * actor.add(emitter); * - * // error handler - * function (err) { - * } - * ); + * // or, alternatively, add it to the current scene + * engine.add(emitter); * ``` - * - * Any errors that go unhandled will be bubbled up to the browser. */ - var Promise = (function () { - function Promise() { - this._state = PromiseState.Pending; - this._successCallbacks = []; - this._rejectCallback = function () { return; }; - this._logger = ex.Logger.getInstance(); - } - /** - * Wrap a value in a resolved promise - * @param value An optional value to wrap in a resolved promise - */ - Promise.wrap = function (value) { - var promise = (new Promise()).resolve(value); - return promise; - }; - /** - * Returns a new promise that resolves when all the promises passed to it resolve, or rejects - * when at least 1 promise rejects. - */ - Promise.join = function () { - var promises = []; - for (var _i = 0; _i < arguments.length; _i++) { - promises[_i - 0] = arguments[_i]; - } - var joinedPromise = new Promise(); - if (!promises || !promises.length) { - return joinedPromise.resolve(); - } - var total = promises.length; - var successes = 0; - var rejects = 0; - var errors = []; - promises.forEach(function (p) { - p.then(function () { - successes += 1; - if (successes === total) { - joinedPromise.resolve(); - } - else if (successes + rejects + errors.length === total) { - joinedPromise.reject(errors); - } - }, function () { - rejects += 1; - if (successes + rejects + errors.length === total) { - joinedPromise.reject(errors); - } - }).error(function (e) { - errors.push(e); - if ((errors.length + successes + rejects) === total) { - joinedPromise.reject(errors); - } - }); - }); - return joinedPromise; - }; + var ParticleEmitter = (function (_super) { + __extends(ParticleEmitter, _super); /** - * Chain success and reject callbacks after the promise is resovled - * @param successCallback Call on resolution of promise - * @param rejectCallback Call on rejection of promise + * @param x The x position of the emitter + * @param y The y position of the emitter + * @param width The width of the emitter + * @param height The height of the emitter */ - Promise.prototype.then = function (successCallback, rejectCallback) { - if (successCallback) { - this._successCallbacks.push(successCallback); - // If the promise is already resovled call immediately - if (this.state() === PromiseState.Resolved) { - try { - successCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); - } - } - } - if (rejectCallback) { - this._rejectCallback = rejectCallback; - // If the promise is already rejected call immediately - if (this.state() === PromiseState.Rejected) { - try { - rejectCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); - } + function ParticleEmitter(x, y, width, height) { + _super.call(this, x, y, width, height, ex.Color.White); + this._particlesToEmit = 0; + this.numParticles = 0; + /** + * Gets or sets the isEmitting flag + */ + this.isEmitting = true; + /** + * Gets or sets the backing particle collection + */ + this.particles = null; + /** + * Gets or sets the backing deadParticle collection + */ + this.deadParticles = null; + /** + * Gets or sets the minimum partical velocity + */ + this.minVel = 0; + /** + * Gets or sets the maximum partical velocity + */ + this.maxVel = 0; + /** + * Gets or sets the acceleration vector for all particles + */ + this.acceleration = new ex.Vector(0, 0); + /** + * Gets or sets the minimum angle in radians + */ + this.minAngle = 0; + /** + * Gets or sets the maximum angle in radians + */ + this.maxAngle = 0; + /** + * Gets or sets the emission rate for particles (particles/sec) + */ + this.emitRate = 1; //particles/sec + /** + * Gets or sets the life of each particle in milliseconds + */ + this.particleLife = 2000; + /** + * Gets or sets the opacity of each particle from 0 to 1.0 + */ + this.opacity = 1; + /** + * Gets or sets the fade flag which causes particles to gradually fade out over the course of their life. + */ + this.fadeFlag = false; + /** + * Gets or sets the optional focus where all particles should accelerate towards + */ + this.focus = null; + /** + * Gets or sets the acceleration for focusing particles if a focus has been specified + */ + this.focusAccel = 1; + /* + * Gets or sets the optional starting size for the particles + */ + this.startSize = null; + /* + * Gets or sets the optional ending size for the particles + */ + this.endSize = null; + /** + * Gets or sets the minimum size of all particles + */ + this.minSize = 5; + /** + * Gets or sets the maximum size of all particles + */ + this.maxSize = 5; + /** + * Gets or sets the beginning color of all particles + */ + this.beginColor = ex.Color.White; + /** + * Gets or sets the ending color of all particles + */ + this.endColor = ex.Color.White; + /** + * Gets or sets the sprite that a particle should use + * @warning Performance intensive + */ + this.particleSprite = null; + /** + * Gets or sets the emitter type for the particle emitter + */ + this.emitterType = EmitterType.Rectangle; + /** + * Gets or sets the emitter radius, only takes effect when the [[emitterType]] is [[EmitterType.Circle]] + */ + this.radius = 0; + /** + * Gets or sets the particle rotational speed velocity + */ + this.particleRotationalVelocity = 0; + /** + * Indicates whether particles should start with a random rotation + */ + this.randomRotation = false; + this.collisionType = ex.CollisionType.PreventCollision; + this.particles = new ex.Util.Collection(); + this.deadParticles = new ex.Util.Collection(); + // Remove offscreen culling from particle emitters + for (var trait in this.traits) { + if (this.traits[trait] instanceof ex.Traits.OffscreenCulling) { + this.traits.splice(trait, 1); } } - return this; + } + ParticleEmitter.prototype.removeParticle = function (particle) { + this.deadParticles.push(particle); }; /** - * Add an error callback to the promise - * @param errorCallback Call if there was an error in a callback + * Causes the emitter to emit particles + * @param particleCount Number of particles to emit right now */ - Promise.prototype.error = function (errorCallback) { - if (errorCallback) { - this._errorCallback = errorCallback; + ParticleEmitter.prototype.emitParticles = function (particleCount) { + for (var i = 0; i < particleCount; i++) { + this.particles.push(this._createParticle()); } - return this; }; - /** - * Resolve the promise and pass an option value to the success callbacks - * @param value Value to pass to the success callbacks - */ - Promise.prototype.resolve = function (value) { - var _this = this; - if (this._state === PromiseState.Pending) { - this._value = value; - try { - this._state = PromiseState.Resolved; - this._successCallbacks.forEach(function (cb) { - cb.call(_this, _this._value); - }); - } - catch (e) { - this._handleError(e); - } + ParticleEmitter.prototype.clearParticles = function () { + this.particles.clear(); + }; + // Creates a new particle given the contraints of the emitter + ParticleEmitter.prototype._createParticle = function () { + // todo implement emitter contraints; + var ranX = 0; + var ranY = 0; + var angle = ex.Util.randomInRange(this.minAngle, this.maxAngle); + var vel = ex.Util.randomInRange(this.minVel, this.maxVel); + var size = this.startSize || ex.Util.randomInRange(this.minSize, this.maxSize); + var dx = vel * Math.cos(angle); + var dy = vel * Math.sin(angle); + if (this.emitterType === EmitterType.Rectangle) { + ranX = ex.Util.randomInRange(this.x, this.x + this.getWidth()); + ranY = ex.Util.randomInRange(this.y, this.y + this.getHeight()); } - else { - throw new Error('Cannot resolve a promise that is not in a pending state!'); + else if (this.emitterType === EmitterType.Circle) { + var radius = ex.Util.randomInRange(0, this.radius); + ranX = radius * Math.cos(angle) + this.x; + ranY = radius * Math.sin(angle) + this.y; } - return this; + var p = new Particle(this, this.particleLife, this.opacity, this.beginColor, this.endColor, new ex.Vector(ranX, ranY), new ex.Vector(dx, dy), this.acceleration, this.startSize, this.endSize); + p.fadeFlag = this.fadeFlag; + p.particleSize = size; + if (this.particleSprite) { + p.particleSprite = this.particleSprite; + } + p.particleRotationalVelocity = this.particleRotationalVelocity; + if (this.randomRotation) { + p.currentRotation = ex.Util.randomInRange(0, Math.PI * 2); + } + if (this.focus) { + p.focus = this.focus.add(new ex.Vector(this.x, this.y)); + p.focusAccel = this.focusAccel; + } + return p; }; - /** - * Reject the promise and pass an option value to the reject callbacks - * @param value Value to pass to the reject callbacks - */ - Promise.prototype.reject = function (value) { - if (this._state === PromiseState.Pending) { - this._value = value; - try { - this._state = PromiseState.Rejected; - this._rejectCallback.call(this, this._value); - } - catch (e) { - this._handleError(e); + ParticleEmitter.prototype.update = function (engine, delta) { + var _this = this; + _super.prototype.update.call(this, engine, delta); + if (this.isEmitting) { + this._particlesToEmit += this.emitRate * (delta / 1000); + //var numParticles = Math.ceil(this.emitRate * delta / 1000); + if (this._particlesToEmit > 1.0) { + this.emitParticles(Math.floor(this._particlesToEmit)); + this._particlesToEmit = this._particlesToEmit - Math.floor(this._particlesToEmit); } } - else { - throw new Error('Cannot reject a promise that is not in a pending state!'); - } - return this; + this.particles.forEach(function (p) { return p.update(delta); }); + this.deadParticles.forEach(function (p) { return _this.particles.removeElement(p); }); + this.deadParticles.clear(); }; - /** - * Inpect the current state of a promise - */ - Promise.prototype.state = function () { - return this._state; + ParticleEmitter.prototype.draw = function (ctx, delta) { + // todo is there a more efficient to draw + // possibly use a webgl offscreen canvas and shaders to do particles? + this.particles.forEach(function (p) { return p.draw(ctx); }); }; - Promise.prototype._handleError = function (e) { - if (this._errorCallback) { - this._errorCallback.call(this, e); - } - else { - // rethrow error - throw e; + ParticleEmitter.prototype.debugDraw = function (ctx) { + _super.prototype.debugDraw.call(this, ctx); + ctx.fillStyle = ex.Color.Black.toString(); + ctx.fillText('Particles: ' + this.particles.count(), this.x, this.y + 20); + if (this.focus) { + ctx.fillRect(this.focus.x + this.x, this.focus.y + this.y, 3, 3); + ex.Util.drawLine(ctx, 'yellow', this.focus.x + this.x, this.focus.y + this.y, _super.prototype.getCenter.call(this).x, _super.prototype.getCenter.call(this).y); + ctx.fillText('Focus', this.focus.x + this.x, this.focus.y + this.y); } }; - return Promise; - })(); - ex.Promise = Promise; + return ParticleEmitter; + })(ex.Actor); + ex.ParticleEmitter = ParticleEmitter; })(ex || (ex = {})); -/// var ex; (function (ex) { /** - * Generic Resources - * - * The [[Resource]] type allows games built in Excalibur to load generic resources. - * For any type of remote resource it is recommended to use [[Resource]] for preloading. + * Animations * - * [[Resource]] is an [[ILoadable]] so it can be passed to a [[Loader]] to pre-load before - * a level or game. + * Animations allow you to display a series of images one after another, + * creating the illusion of change. Generally these images will come from a [[SpriteSheet]] source. * - * Example usages: JSON, compressed files, blobs. + * ## Creating an animation * - * ## Pre-loading generic resources + * Create a [[Texture]] that contains the frames of your animation. Once the texture + * is [[Loader|loaded]], you can then generate an [[Animation]] by creating a [[SpriteSheet]] + * and using [[SpriteSheet.getAnimationForAll]]. * * ```js - * var resLevel1 = new ex.Resource("/assets/levels/1.json", "application/json"); - * var loader = new ex.Loader(resLevel1); + * var game = new ex.Engine(); + * var txAnimPlayerIdle = new ex.Texture("/assets/tx/anim-player-idle.png"); * - * // attach a handler to process once loaded - * resLevel1.processData = function (data) { + * // load assets + * var loader = new ex.Loader(txAnimPlayerIdle); * - * // process JSON - * var json = JSON.parse(data); + * // start game + * game.start(loader).then(function () { + * var player = new ex.Actor(); * - * // create a new level (inherits Scene) with the JSON configuration - * var level = new Level(json); + * // create sprite sheet with 5 columns, 1 row, 80x80 frames + * var playerIdleSheet = new ex.SpriteSheet(txAnimPlayerIdle, 5, 1, 80, 80); * - * // add a new scene - * game.add(level.name, level); - * } + * // create animation (125ms frame speed) + * var playerIdleAnimation = playerIdleSheet.getAnimationForAll(game, 125); * - * game.start(loader); + * // add drawing to player as "idle" + * player.addDrawing("idle", playerIdleAnimation); + * + * // add player to game + * game.add(player); + * }); * ``` + * + * ## Sprite effects + * + * You can add [[SpriteEffect|sprite effects]] to an animation through methods + * like [[Animation.invert]] or [[Animation.lighten]]. Keep in mind, since this + * manipulates the raw pixel values of a [[Sprite]], it can have a performance impact. */ - var Resource = (function (_super) { - __extends(Resource, _super); - /** - * @param path Path to the remote resource - * @param responseType The Content-Type to expect (e.g. `application/json`) - * @param bustCache Whether or not to cache-bust requests - */ - function Resource(path, responseType, bustCache) { - if (bustCache === void 0) { bustCache = true; } - _super.call(this); - this.path = path; - this.responseType = responseType; - this.bustCache = bustCache; - this.data = null; - this.logger = ex.Logger.getInstance(); - this.onprogress = function () { return; }; - this.oncomplete = function () { return; }; - this.onerror = function () { return; }; - } + var Animation = (function () { /** - * Returns true if the Resource is completely loaded and is ready - * to be drawn. + * Typically you will use a [[SpriteSheet]] to generate an [[Animation]]. + * + * @param engine Reference to the current game engine + * @param images An array of sprites to create the frames for the animation + * @param speed The number in milliseconds to display each frame in the animation + * @param loop Indicates whether the animation should loop after it is completed */ - Resource.prototype.isLoaded = function () { - return this.data !== null; - }; - Resource.prototype.wireEngine = function (engine) { + function Animation(engine, images, speed, loop) { + /** + * Current frame index being shown + */ + this.currentFrame = 0; + this._oldTime = Date.now(); + this.anchor = new ex.Point(0.0, 0.0); + this.rotation = 0.0; + this.scale = new ex.Point(1, 1); + /** + * Indicates whether the animation should loop after it is completed + */ + this.loop = false; + /** + * Indicates the frame index the animation should freeze on for a non-looping + * animation. By default it is the last frame. + */ + this.freezeFrame = -1; + /** + * Flip each frame vertically. Sets [[Sprite.flipVertical]]. + */ + this.flipVertical = false; + /** + * Flip each frame horizontally. Sets [[Sprite.flipHorizontal]]. + */ + this.flipHorizontal = false; + this.width = 0; + this.height = 0; + this.naturalWidth = 0; + this.naturalHeight = 0; + this.sprites = images; + this.speed = speed; this._engine = engine; - }; - Resource.prototype._cacheBust = function (uri) { - var query = /\?\w*=\w*/; - if (query.test(uri)) { - uri += ('&__=' + Date.now()); + if (loop != null) { + this.loop = loop; } - else { - uri += ('?__=' + Date.now()); + if (images && images[0]) { + this.height = images[0] ? images[0].height : 0; + this.width = images[0] ? images[0].width : 0; + this.naturalWidth = images[0] ? images[0].naturalWidth : 0; + this.naturalHeight = images[0] ? images[0].naturalHeight : 0; + this.freezeFrame = images.length - 1; } - return uri; + } + /** + * Applies the opacity effect to a sprite, setting the alpha of all pixels to a given value + */ + Animation.prototype.opacity = function (value) { + this.addEffect(new ex.Effects.Opacity(value)); }; - Resource.prototype._start = function (e) { - this.logger.debug('Started loading resource ' + this.path); + /** + * Applies the grayscale effect to a sprite, removing color information. + */ + Animation.prototype.grayscale = function () { + this.addEffect(new ex.Effects.Grayscale()); }; /** - * Begin loading the resource and returns a promise to be resolved on completion + * Applies the invert effect to a sprite, inverting the pixel colors. */ - Resource.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - // Exit early if we already have data - if (this.data !== null) { - this.logger.debug('Already have data for resource', this.path); - complete.resolve(this.data); - this.oncomplete(); - return complete; - } - var request = new XMLHttpRequest(); - request.open('GET', this.bustCache ? this._cacheBust(this.path) : this.path, true); - request.responseType = this.responseType; - request.onloadstart = function (e) { _this._start(e); }; - request.onprogress = this.onprogress; - request.onerror = this.onerror; - request.onload = function (e) { - if (request.status !== 200) { - _this.logger.error('Failed to load resource ', _this.path, ' server responded with error code', request.status); - _this.onerror(request.response); - complete.resolve(request.response); - return; - } - _this.data = _this.processData(request.response); - _this.oncomplete(); - _this.logger.debug('Completed loading resource', _this.path); - complete.resolve(_this.data); - }; - request.send(); - return complete; + Animation.prototype.invert = function () { + this.addEffect(new ex.Effects.Invert()); }; /** - * Returns the loaded data once the resource is loaded + * Applies the fill effect to a sprite, changing the color channels of all non-transparent pixels to match a given color */ - Resource.prototype.getData = function () { - return this.data; + Animation.prototype.fill = function (color) { + this.addEffect(new ex.Effects.Fill(color)); }; /** - * Sets the data for this resource directly + * Applies the colorize effect to a sprite, changing the color channels of all pixesl to be the average of the original color and the + * provided color. */ - Resource.prototype.setData = function (data) { - this.data = this.processData(data); + Animation.prototype.colorize = function (color) { + this.addEffect(new ex.Effects.Colorize(color)); }; /** - * This method is meant to be overriden to handle any additional - * processing. Such as decoding downloaded audio bits. + * Applies the lighten effect to a sprite, changes the lightness of the color according to hsl */ - Resource.prototype.processData = function (data) { - // Handle any additional loading after the xhr has completed. - return URL.createObjectURL(data); + Animation.prototype.lighten = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Lighten(factor)); }; - return Resource; - })(ex.Class); - ex.Resource = Resource; -})(ex || (ex = {})); -/// -/// -/// -/// -/// -var ex; -(function (ex) { - /** - * Textures - * - * The [[Texture]] object allows games built in Excalibur to load image resources. - * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] - * to pre-load before starting a level or game. - * - * Textures are the raw image so to add a drawing to a game, you must create - * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite - * instance. - * - * ## Pre-loading textures - * - * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] - * is loaded, you can generate a [[Sprite]] with it. - * - * ```js - * var txPlayer = new ex.Texture("/assets/tx/player.png"); - * - * var loader = new ex.Loader(txPlayer); - * - * game.start(loader).then(function () { - * - * var player = new ex.Actor(); - * - * player.addDrawing(txPlayer); - * - * game.add(player); - * }); - * ``` - */ - var Texture = (function (_super) { - __extends(Texture, _super); /** - * @param path Path to the image resource - * @param bustCache Optionally load texture with cache busting + * Applies the darken effect to a sprite, changes the darkness of the color according to hsl */ - function Texture(path, bustCache) { - if (bustCache === void 0) { bustCache = true; } - _super.call(this, path, 'blob', bustCache); - this.path = path; - this.bustCache = bustCache; - /** - * A [[Promise]] that resolves when the Texture is loaded. - */ - this.loaded = new ex.Promise(); - this._isLoaded = false; - this._sprite = null; - this._sprite = new ex.Sprite(this, 0, 0, 0, 0); - } + Animation.prototype.darken = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Darken(factor)); + }; /** - * Returns true if the Texture is completely loaded and is ready - * to be drawn. + * Applies the saturate effect to a sprite, saturates the color acccording to hsl */ - Texture.prototype.isLoaded = function () { - return this._isLoaded; + Animation.prototype.saturate = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Saturate(factor)); }; /** - * Begins loading the texture and returns a promise to be resolved on completion + * Applies the desaturate effect to a sprite, desaturates the color acccording to hsl */ - Texture.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - var loaded = _super.prototype.load.call(this); - loaded.then(function () { - _this.image = new Image(); - _this.image.addEventListener('load', function () { - _this._isLoaded = true; - _this.width = _this._sprite.swidth = _this._sprite.naturalWidth = _this._sprite.width = _this.image.naturalWidth; - _this.height = _this._sprite.sheight = _this._sprite.naturalHeight = _this._sprite.height = _this.image.naturalHeight; - _this.loaded.resolve(_this.image); - complete.resolve(_this.image); - }); - _this.image.src = _super.prototype.getData.call(_this); - }, function () { - complete.reject('Error loading texture.'); - }); - return complete; + Animation.prototype.desaturate = function (factor) { + if (factor === void 0) { factor = 0.1; } + this.addEffect(new ex.Effects.Desaturate(factor)); }; - Texture.prototype.asSprite = function () { - return this._sprite; + /** + * Add a [[ISpriteEffect]] manually + */ + Animation.prototype.addEffect = function (effect) { + for (var i in this.sprites) { + this.sprites[i].addEffect(effect); + } + }; + Animation.prototype.removeEffect = function (param) { + for (var i in this.sprites) { + this.sprites[i].removeEffect(param); + } }; - return Texture; - })(ex.Resource); - ex.Texture = Texture; - /** - * Sounds - * - * The [[Sound]] object allows games built in Excalibur to load audio - * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] - * which means it can be passed to a [[Loader]] to pre-load before a game or level. - * - * ## Pre-loading sounds - * - * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] - * is loaded, you can [[Sound.play|play]] it. - * - * ```js - * // define multiple sources (such as mp3/wav/ogg) as a browser fallback - * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); - * - * var loader = new ex.Loader(sndPlayerDeath); - * - * game.start(loader).then(function () { - * - * sndPlayerDeath.play(); - * }); - * ``` - */ - var Sound = (function () { /** - * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. + * Clear all sprite effects */ - function Sound() { - var paths = []; - for (var _i = 0; _i < arguments.length; _i++) { - paths[_i - 0] = arguments[_i]; + Animation.prototype.clearEffects = function () { + for (var i in this.sprites) { + this.sprites[i].clearEffects(); } - this._logger = ex.Logger.getInstance(); - this.onprogress = function () { return; }; - this.oncomplete = function () { return; }; - this.onerror = function () { return; }; - this.onload = function () { return; }; - this._isLoaded = false; - this._wasPlayingOnHidden = false; - /* Chrome : MP3, WAV, Ogg - * Firefox : WAV, Ogg, - * IE : MP3, WAV coming soon - * Safari MP3, WAV, Ogg + }; + Animation.prototype._setAnchor = function (point) { + //if (!this.anchor.equals(point)) { + for (var i in this.sprites) { + this.sprites[i].anchor.setTo(point.x, point.y); + } + //} + }; + Animation.prototype._setRotation = function (radians) { + //if (this.rotation !== radians) { + for (var i in this.sprites) { + this.sprites[i].rotation = radians; + } + //} + }; + Animation.prototype._setScale = function (scale) { + //if (!this.scale.equals(scale)) { + for (var i in this.sprites) { + this.sprites[i].scale = scale; + } + //} + }; + /** + * Resets the animation to first frame. + */ + Animation.prototype.reset = function () { + this.currentFrame = 0; + }; + /** + * Indicates whether the animation is complete, animations that loop are never complete. + */ + Animation.prototype.isDone = function () { + return (!this.loop && this.currentFrame >= this.sprites.length); + }; + /** + * Not meant to be called by game developers. Ticks the animation forward internally and + * calculates whether to change to the frame. + * @internal + */ + Animation.prototype.tick = function () { + var time = Date.now(); + if ((time - this._oldTime) > this.speed) { + this.currentFrame = (this.loop ? (this.currentFrame + 1) % this.sprites.length : this.currentFrame + 1); + this._oldTime = time; + } + }; + Animation.prototype._updateValues = function () { + this._setAnchor(this.anchor); + this._setRotation(this.rotation); + this._setScale(this.scale); + }; + /** + * Skips ahead a specified number of frames in the animation + * @param frames Frames to skip ahead + */ + Animation.prototype.skip = function (frames) { + this.currentFrame = (this.currentFrame + frames) % this.sprites.length; + }; + Animation.prototype.draw = function (ctx, x, y) { + this.tick(); + this._updateValues(); + var currSprite; + if (this.currentFrame < this.sprites.length) { + currSprite = this.sprites[this.currentFrame]; + if (this.flipVertical) { + currSprite.flipVertical = this.flipVertical; + } + if (this.flipHorizontal) { + currSprite.flipHorizontal = this.flipHorizontal; + } + currSprite.draw(ctx, x, y); + } + if (this.freezeFrame !== -1 && this.currentFrame >= this.sprites.length) { + currSprite = this.sprites[ex.Util.clamp(this.freezeFrame, 0, this.sprites.length - 1)]; + currSprite.draw(ctx, x, y); + } + // add the calculated width + if (currSprite) { + this.width = currSprite.width; + this.height = currSprite.height; + } + }; + /** + * Plays an animation at an arbitrary location in the game. + * @param x The x position in the game to play + * @param y The y position in the game to play + */ + Animation.prototype.play = function (x, y) { + this.reset(); + this._engine.playAnimation(this, x, y); + }; + return Animation; + })(); + ex.Animation = Animation; +})(ex || (ex = {})); +/// +/// +/// +var ex; +(function (ex) { + var Internal; + (function (Internal) { + var FallbackAudio = (function () { + function FallbackAudio(path, volume) { + this.path = path; + this._log = ex.Logger.getInstance(); + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + if (window.AudioContext) { + this._log.debug('Using new Web Audio Api for ' + path); + this._soundImpl = new WebAudio(path, volume); + } + else { + this._log.debug('Falling back to Audio Element for ' + path); + this._soundImpl = new AudioTag(path, volume); + } + } + FallbackAudio.prototype.setVolume = function (volume) { + this._soundImpl.setVolume(volume); + }; + FallbackAudio.prototype.setLoop = function (loop) { + this._soundImpl.setLoop(loop); + }; + FallbackAudio.prototype.load = function () { + this._soundImpl.onload = this.onload; + this._soundImpl.onprogress = this.onprogress; + this._soundImpl.onerror = this.onerror; + this._soundImpl.load(); + }; + FallbackAudio.prototype.processData = function (data) { + return this._soundImpl.processData(data); + }; + FallbackAudio.prototype.getData = function () { + return this._soundImpl.getData(); + }; + FallbackAudio.prototype.setData = function (data) { + this._soundImpl.setData(data); + }; + FallbackAudio.prototype.isPlaying = function () { + return this._soundImpl.isPlaying(); + }; + FallbackAudio.prototype.play = function () { + return this._soundImpl.play(); + }; + FallbackAudio.prototype.pause = function () { + this._soundImpl.pause(); + }; + FallbackAudio.prototype.stop = function () { + this._soundImpl.stop(); + }; + return FallbackAudio; + })(); + Internal.FallbackAudio = FallbackAudio; + var AudioTag = (function () { + function AudioTag(path, volume) { + var _this = this; + this.path = path; + this._audioElements = new Array(5); + this._loadedAudio = null; + this._isLoaded = false; + this._index = 0; + this._log = ex.Logger.getInstance(); + this._isPlaying = false; + this._currentOffset = 0; + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + for (var i = 0; i < this._audioElements.length; i++) { + (function (i) { + _this._audioElements[i] = new Audio(); + })(i); + } + if (volume) { + this.setVolume(ex.Util.clamp(volume, 0, 1.0)); + } + else { + this.setVolume(1.0); + } + } + AudioTag.prototype.isPlaying = function () { + return this._isPlaying; + }; + AudioTag.prototype._audioLoaded = function () { + this._isLoaded = true; + }; + AudioTag.prototype.setVolume = function (volume) { + var i = 0, len = this._audioElements.length; + for (i; i < len; i++) { + this._audioElements[i].volume = volume; + } + }; + AudioTag.prototype.setLoop = function (loop) { + var i = 0, len = this._audioElements.length; + for (i; i < len; i++) { + this._audioElements[i].loop = loop; + } + }; + AudioTag.prototype.getLoop = function () { + this._audioElements.some(function (a) { return a.loop; }); + }; + AudioTag.prototype.load = function () { + var _this = this; + if (!!this._loadedAudio) { + return; + } + var request = new XMLHttpRequest(); + request.open('GET', this.path, true); + request.responseType = 'blob'; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function (e) { + if (request.status !== 200) { + _this._log.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + _this._isLoaded = false; + return; + } + _this._isLoaded = true; + _this.setData(request.response); + _this.onload(e); + }; + request.send(); + }; + AudioTag.prototype.getData = function () { + return this._loadedAudio; + }; + AudioTag.prototype.setData = function (data) { + this._isLoaded = true; + this._loadedAudio = this.processData(data); + }; + AudioTag.prototype.processData = function (data) { + var blobUrl = URL.createObjectURL(data); + this._audioElements.forEach(function (a) { + a.src = blobUrl; + }); + this._audioLoaded(); + return blobUrl; + }; + AudioTag.prototype.play = function () { + var _this = this; + this._audioElements[this._index].load(); + //this.audioElements[this.index].currentTime = this._currentOffset; + this._audioElements[this._index].play(); + this._currentOffset = 0; + var done = new ex.Promise(); + this._isPlaying = true; + if (!this.getLoop()) { + this._audioElements[this._index].addEventListener('ended', function () { + _this._isPlaying = false; + done.resolve(true); + }); + } + this._index = (this._index + 1) % this._audioElements.length; + return done; + }; + AudioTag.prototype.pause = function () { + this._index = (this._index - 1 + this._audioElements.length) % this._audioElements.length; + this._currentOffset = this._audioElements[this._index].currentTime; + this._audioElements.forEach(function (a) { + a.pause(); + }); + this._isPlaying = false; + }; + AudioTag.prototype.stop = function () { + this._audioElements.forEach(function (a) { + a.pause(); + //a.currentTime = 0; + }); + this._isPlaying = false; + }; + return AudioTag; + })(); + Internal.AudioTag = AudioTag; + if (window.AudioContext) { + var audioContext = new window.AudioContext(); + } + var WebAudio = (function () { + function WebAudio(path, volume) { + this.path = path; + this._context = audioContext; + this._volume = this._context.createGain(); + this._buffer = null; + this._sound = null; + this._isLoaded = false; + this._loop = false; + this._isPlaying = false; + this._isPaused = false; + this._currentOffset = 0; + this._logger = ex.Logger.getInstance(); + this._data = null; + this.onload = function () { return; }; + this.onprogress = function () { return; }; + this.onerror = function () { return; }; + if (volume) { + this._volume.gain.value = ex.Util.clamp(volume, 0, 1.0); + } + else { + this._volume.gain.value = 1.0; // max volume + } + } + WebAudio.prototype.setVolume = function (volume) { + this._volume.gain.value = volume; + }; + WebAudio.prototype.load = function () { + var _this = this; + // Exit early if we already have data + if (this._data !== null) { + return; + } + var request = new XMLHttpRequest(); + request.open('GET', this.path); + request.responseType = 'arraybuffer'; + request.onprogress = this.onprogress; + request.onerror = this.onerror; + request.onload = function () { + if (request.status !== 200) { + _this._logger.error('Failed to load audio resource ', _this.path, ' server responded with error code', request.status); + _this.onerror(request.response); + _this._isLoaded = false; + return; + } + _this.setData(request.response); + }; + try { + request.send(); + } + catch (e) { + console.error('Error loading sound! If this is a cross origin error, you must host your sound with your html and javascript.'); + } + }; + WebAudio.prototype.getData = function () { + return this._data; + }; + WebAudio.prototype.setData = function (data) { + this._data = this.processData(data); + }; + WebAudio.prototype.processData = function (data) { + var _this = this; + this._context.decodeAudioData(data, function (buffer) { + _this._buffer = buffer; + _this._isLoaded = true; + _this.onload(_this); + }, function (e) { + _this._logger.error('Unable to decode ' + _this.path + + ' this browser may not fully support this format, or the file may be corrupt, ' + + 'if this is an mp3 try removing id3 tags and album art from the file.'); + _this._isLoaded = false; + _this.onload(_this); + }); + return data; + }; + WebAudio.prototype.setLoop = function (loop) { + this._loop = loop; + }; + WebAudio.prototype.isPlaying = function () { + return this._isPlaying; + }; + WebAudio.prototype.play = function () { + var _this = this; + if (this._isLoaded) { + this._sound = this._context.createBufferSource(); + this._sound.buffer = this._buffer; + this._sound.loop = this._loop; + this._sound.connect(this._volume); + this._volume.connect(this._context.destination); + this._sound.start(0, this._currentOffset % this._buffer.duration); + this._currentOffset = 0; + var done; + if (!this._isPaused || !this._playPromise) { + done = new ex.Promise(); + } + else { + done = this._playPromise; + } + this._isPaused = false; + this._isPlaying = true; + if (!this._loop) { + this._sound.onended = (function () { + _this._isPlaying = false; + if (!_this._isPaused) { + done.resolve(true); + } + }).bind(this); + } + this._playPromise = done; + return done; + } + else { + return ex.Promise.wrap(true); + } + }; + WebAudio.prototype.pause = function () { + if (this._isPlaying) { + try { + window.clearTimeout(this._playingTimer); + this._sound.stop(0); + this._currentOffset = this._context.currentTime; + this._isPlaying = false; + this._isPaused = true; + } + catch (e) { + this._logger.warn('The sound clip', this.path, 'has already been paused!'); + } + } + }; + WebAudio.prototype.stop = function () { + if (this._sound) { + try { + window.clearTimeout(this._playingTimer); + this._currentOffset = 0; + this._sound.stop(0); + this._isPlaying = false; + this._isPaused = false; + } + catch (e) { + this._logger.warn('The sound clip', this.path, 'has already been stopped!'); + } + } + }; + /** + * Play an empty sound to unlock Safari WebAudio context. Call this function + * right after a user interaction event. Typically used by [[PauseAfterLoader]] + * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/ */ - this.path = ''; - for (var i = 0; i < paths.length; i++) { - if (Sound.canPlayFile(paths[i])) { - this.path = paths[i]; - break; + WebAudio.unlock = function () { + if (this._unlocked || !audioContext) { + return; } - } - if (!this.path) { - this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); - this._logger.warn('Attempting to use', paths[0]); - this.path = paths[0]; // select the first specified - } - this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); - } - /** - * Whether or not the browser can play this file as HTML5 Audio - */ - Sound.canPlayFile = function (file) { - try { - var a = new Audio(); - var filetype = /.*\.([A-Za-z0-9]+)$/; - var type = file.match(filetype)[1]; - if (a.canPlayType('audio/' + type)) { - return true; + // create empty buffer and play it + var buffer = audioContext.createBuffer(1, 1, 22050); + var source = audioContext.createBufferSource(); + source.buffer = buffer; + source.connect(audioContext.destination); + if (source.noteOn) { + source.noteOn(0); } - { - return false; + else { + source.start(0); } - } - catch (e) { - ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); - return false; - } - }; - Sound.prototype.wireEngine = function (engine) { - var _this = this; - if (engine) { - this._engine = engine; - this._engine.on('hidden', function () { - if (engine.pauseAudioWhenHidden && _this.isPlaying()) { - _this._wasPlayingOnHidden = true; - _this.pause(); - } - }); - this._engine.on('visible', function () { - if (engine.pauseAudioWhenHidden && _this._wasPlayingOnHidden) { - _this.play(); - _this._wasPlayingOnHidden = false; + // by checking the play state after some time, we know if we're really unlocked + setTimeout(function () { + if (source.playbackState === source.PLAYING_STATE || + source.playbackState === source.FINISHED_STATE) { + this._unlocked = true; } - }); - } - }; - /** - * Sets the volume of the sound clip - * @param volume A volume value between 0-1.0 - */ - Sound.prototype.setVolume = function (volume) { - if (this.sound) { - this.sound.setVolume(volume); - } - }; - /** - * Indicates whether the clip should loop when complete - * @param loop Set the looping flag - */ - Sound.prototype.setLoop = function (loop) { - if (this.sound) { - this.sound.setLoop(loop); - } - }; - /** - * Whether or not the sound is playing right now - */ - Sound.prototype.isPlaying = function () { - if (this.sound) { - return this.sound.isPlaying(); - } - }; - /** - * Play the sound, returns a promise that resolves when the sound is done playing - */ - Sound.prototype.play = function () { - if (this.sound) { - return this.sound.play(); - } - }; - /** - * Stop the sound, and do not rewind - */ - Sound.prototype.pause = function () { - if (this.sound) { - this.sound.pause(); - } - }; - /** - * Stop the sound and rewind - */ - Sound.prototype.stop = function () { - if (this.sound) { - this.sound.stop(); - } - }; - /** - * Returns true if the sound is loaded - */ - Sound.prototype.isLoaded = function () { - return this._isLoaded; - }; - /** - * Begins loading the sound and returns a promise to be resolved on completion - */ - Sound.prototype.load = function () { - var _this = this; - var complete = new ex.Promise(); - if (this.sound.getData() !== null) { - this._logger.debug('Already have data for resource', this.path); - complete.resolve(this.sound); - return complete; - } - this._logger.debug('Started loading sound', this.path); - this.sound.onprogress = this.onprogress; - this.sound.onload = function () { - _this.oncomplete(); - _this._isLoaded = true; - _this._logger.debug('Completed loading sound', _this.path); - complete.resolve(_this.sound); + }, 0); }; - this.sound.onerror = function (e) { - _this.onerror(e); - complete.resolve(e); + WebAudio.isUnlocked = function () { + return this._unlocked; }; - this.sound.load(); - return complete; - }; - Sound.prototype.getData = function () { - return this.sound.getData(); - }; - Sound.prototype.setData = function (data) { - this.sound.setData(data); - }; - Sound.prototype.processData = function (data) { - return this.sound.processData(data); - }; - return Sound; - })(); - ex.Sound = Sound; + WebAudio._unlocked = false; + return WebAudio; + })(); + Internal.WebAudio = WebAudio; + })(Internal = ex.Internal || (ex.Internal = {})); +})(ex || (ex = {})); +/// +/// +/// +/// +/// +/// +var ex; +(function (ex) { /** * Pre-loading assets * @@ -10010,11 +10057,13 @@ var ex; * }); * ``` */ - var Loader = (function () { + var Loader = (function (_super) { + __extends(Loader, _super); /** * @param loadables Optionally provide the list of resources you want to load at constructor time */ function Loader(loadables) { + _super.call(this); this._resourceList = []; this._index = 0; this._resourceCount = 0; @@ -10024,7 +10073,10 @@ var ex; this.getData = function () { return; }; this.setData = function (data) { return; }; this.processData = function (data) { return; }; - this.onprogress = function () { return; }; + this.onprogress = function (e) { + ex.Logger.getInstance().debug('[ex.Loader] Loading ' + (100 * e.loaded / e.total).toFixed(0)); + return; + }; this.oncomplete = function () { return; }; this.onerror = function () { return; }; if (loadables) { @@ -10099,7 +10151,6 @@ var ex; r.oncomplete = r.onerror = function () { me._numLoaded++; if (me._numLoaded === me._resourceCount) { - me.onprogress.call(me, { loaded: 100, total: 100 }); me.oncomplete.call(me); complete.resolve(); } @@ -10116,9 +10167,160 @@ var ex; loadNext(this._resourceList, 0); return complete; }; + /** + * Loader draw function. Draws the default Excalibur loading screen. Override to customize the drawing. + */ + Loader.prototype.draw = function (ctx, delta) { + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, this._engine.width, this._engine.height); + var y = this._engine.canvas.height / 2; + var width = this._engine.canvas.width / 3; + var x = width; + // loading image + var image = new Image(); + /* tslint:disable:max-line-length */ + // 64 bit string encoding of the excalibur logo + image.src = 'data:image/png;base64,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'; + /* tslint:enable:max-line-length */ + var imageHeight = width * 3 / 8; + var oldAntialias = this._engine.getAntialiasing(); + this._engine.setAntialiasing(true); + ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); + // loading box + ctx.strokeStyle = 'white'; + ctx.lineWidth = 2; + ctx.strokeRect(x, y, width, 20); + var progress = width * (this._numLoaded / this._resourceCount); + ctx.fillStyle = 'white'; + var margin = 5; + var progressWidth = progress - margin * 2; + var height = 20 - margin * 2; + ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); + this._engine.setAntialiasing(oldAntialias); + }; + /** + * Perform any calculations or logic in the `update` method. The default `Loader` does not + * do anything in this method so it is safe to override. + */ + Loader.prototype.update = function (engine, delta) { + // overridable update + }; return Loader; - })(); + })(ex.Class); ex.Loader = Loader; + /** + * A [[Loader]] that pauses after loading to allow user + * to proceed to play the game. Typically you will + * want to use this loader for iOS to allow sounds + * to play after loading (Apple Safari requires user + * interaction to allow sounds, even for games) + * + * **Note:** Because Loader is not part of a Scene, you must + * call `update` and `draw` manually on "child" objects. + * + * ## Implementing a Trigger + * + * The `PauseAfterLoader` requires an element to act as the trigger button + * to start the game. + * + * For example, let's create an `` tag to be our trigger and call it `tap-to-play`. + * + * ```html + * + * ``` + * + * We've put it inside a wrapper to position it properly over the game canvas. + * + * Now let's add some CSS to style it (insert into ``): + * + * ```html + * + * ``` + * + * Now we can create a `PauseAfterLoader` with a reference to our trigger button: + * + * ```ts + * var loader = new ex.PauseAfterLoader('tap-to-play', [...]); + * ``` + * + * ## Use PauseAfterLoader for iOS + * + * The primary use case for pausing before starting the game is to + * pass Apple's requirement of user interaction. The Web Audio context + * in Safari is disabled by default until user interaction. + * + * Therefore, you can use this snippet to only use PauseAfterLoader when + * iOS is detected (see [this thread](http://stackoverflow.com/questions/9038625/detect-if-device-is-ios) + * for more techniques). + * + * ```ts + * var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window).MSStream; + * var loader: ex.Loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); + * + * loader.addResource(...); + * ``` + */ + var PauseAfterLoader = (function (_super) { + __extends(PauseAfterLoader, _super); + function PauseAfterLoader(triggerElementId, loadables) { + var _this = this; + _super.call(this, loadables); + this._handleOnTrigger = function () { + if (_this._waitPromise.state() !== ex.PromiseState.Pending) { + return false; + } + // unlock Safari WebAudio context + ex.Internal.WebAudio.unlock(); + // continue to play game + _this._waitPromise.resolve(_this._loadedValue); + // hide DOM element + _this._playTrigger.style.display = 'none'; + return false; + }; + this._playTrigger = document.getElementById(triggerElementId); + this._playTrigger.addEventListener('click', this._handleOnTrigger); + } + PauseAfterLoader.prototype.load = function () { + var _this = this; + this._waitPromise = new ex.Promise(); + // wait until user indicates to proceed before finishing load + var superLoad = _super.prototype.load.call(this).then(function (value) { + _this._loaded = true; + _this._loadedValue = value; + // show element + _this._playTrigger.style.display = 'block'; + }, function (value) { + _this._waitPromise.reject(value); + }); + return this._waitPromise; + }; + return PauseAfterLoader; + })(Loader); + ex.PauseAfterLoader = PauseAfterLoader; })(ex || (ex = {})); /// var ex; @@ -11936,6 +12138,9 @@ var ex; /// /// /// +/// +/// +/// /// /// /// @@ -12259,8 +12464,6 @@ var ex; this.onFatalException = function (e) { ex.Logger.getInstance().fatal(e); }; this._isSmoothingEnabled = true; this._isLoading = false; - this._progress = 0; - this._total = 1; var width; var height; var canvasElementId; @@ -12651,6 +12854,11 @@ var ex; Engine.prototype._update = function (delta) { if (this._isLoading) { // suspend updates untill loading is finished + this._loader.update(this, delta); + // Update input listeners + this.input.keyboard.update(delta); + this.input.pointers.update(delta); + this.input.gamepads.update(delta); return; } this.emit('preupdate', new ex.PreUpdateEvent(this, delta, this)); @@ -12676,9 +12884,7 @@ var ex; var ctx = this.ctx; this.emit('predraw', new ex.PreDrawEvent(ctx, delta, this)); if (this._isLoading) { - ctx.fillStyle = 'black'; - ctx.fillRect(0, 0, this.width, this.height); - this._drawLoadingBar(ctx, this._progress, this._total); + this._loader.draw(ctx, delta); // Drawing nothing else while loading return; } @@ -12711,8 +12917,8 @@ var ex; /** * Starts the internal game loop for Excalibur after loading * any provided assets. - * @param loader Optional resources to load before starting the main loop. Some [[ILoadable]] such as a [[Loader]] collection, - * [[Sound]], or [[Texture]]. + * @param loader Optional [[ILoader]] to use to load resources. The default loader is [[Loader]], override to provide your own + * custom loader. */ Engine.prototype.start = function (loader) { if (!this._compatible) { @@ -12721,8 +12927,9 @@ var ex; } var loadingComplete; if (loader) { - loader.wireEngine(this); - loadingComplete = this.load(loader); + this._loader = loader; + this._loader.wireEngine(this); + loadingComplete = this.load(this._loader); } else { loadingComplete = ex.Promise.wrap(); @@ -12784,50 +12991,6 @@ var ex; result.src = raw; return result; }; - /** - * Draws the Excalibur loading bar - * @param ctx The canvas rendering context - * @param loaded Number of bytes loaded - * @param total Total number of bytes to load - */ - Engine.prototype._drawLoadingBar = function (ctx, loaded, total) { - if (this._loadingDraw) { - this._loadingDraw(ctx, loaded, total); - return; - } - var y = this.canvas.height / 2; - var width = this.canvas.width / 3; - var x = width; - // loading image - var image = new Image(); - /* tslint:disable:max-line-length */ - // 64 bit string encoding of the excalibur logo - image.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAEsCAYAAAA7Ldc6AAAACXBIWXMAAA7CAAAOwgEVKEqAAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAOBFJREFUeNrs3U9zE1fC7/GfAXvAgBE4mTg84xuReSpTtzJVI+pRNlk8ETW7WTjOK0BessLeU4Wpmj3OykubV4DCU0XNZgplFtngqihVT+6tcO+Acj0DzjiGtjHCsY24C5027UZ/TkvdUrf0/VRRWLIstfqc7j6/7nNOD71+/VoAAAAA0A1HWAUAAAAAuuWY+8PQ0BBrA0BsrKyspCRNS7os6cv/+I//KLBWAABIviG3CxYBBEBMgkde0ucmfEiSk81mz9JdFACA/nCMVQAgBqFj2hM6Ur5fF1hDAAAQQACg09CRkXS1Qejw+pK1BQBA/6ALFoBuh47LJnSkLf6knM1mL0gSXbAAAOgPXAEBEHXoSJvAcbVR6Dhy5IhGR0d14sQJvXjxQpVKxf1VgTUIAAABBABsQ8dlSZlGrzt16pROnDih0dFRSVK1WtX6+rr3JbdYmwAAEEAAoF7oSJnQ4Z3B6i3ulY7R0VEdOXL4VkTb29veh6VsNltizQIAQAABAG/wyLcKHSMjIzp9+nTd0OH14sUL70OufgAAQAABgJbT5h6EjpMnT2p0dFTHjrXe1ezv72t3d9f7VIE1DQAAAQTA4IaOjFpMm3vs2DGNjo7q9OnTVqHDyzPwXKp1vyqz1gEAIIAAGLzQ0XTaXDd0nDx5UiMjI21/1vPnz70PufcHAAAEEAADEjrSCjBtrjuDVSd2d3e1v7/vfapASQAAQAAB0P+hI9C0uWHxDT4vZLNZh1IBAIAAAqC/QkdKHU6bGxbf+I+vKB0AAAggAPoneOQV0rS5YdjZ2fF2v3JE9ysAAAggABIfOqYV8rS5YaH7FQAABBAA/RE6Mopw2tyw0P0KAAACCIBkh46uTJsbVvioVqvuQyebzRYoRQAACCAAkhE+8pKW6v0u7Glzw/Ly5UvvQ8IHAAAEEABJDh9RTZsbhmq1qu3tbe9T3HwQAAACCICkhY8jR47o7NmzXZnBqhO+sR/lbDZbojQBACCAAEhY+Hjvvfd6PrbDBt2vAAAYTEdYBQDho9uq1ar/CsgtShQAAAIIAMJHJHxjP0p0vwIAgAACgPARGd/NB7n6AQAAAQQA4SMa+/v72t3d9T5VoGQBACCAACB8RMJ39aOUzWbLlC4AAIODWbCABIaPkZERjY+PJy58SOLeHwAAEEAAJC18vPfee7G+x0cju7u72t/f9z5VoIQBABgsdMECCB9d4+t+Vchmsw6lDAAAAQQA4SMSvnt/fEUpAwBAAAFA+IgsfHi6Xzmi+xUAAAQQAISPqLx8+dL7kO5XAAAQQAAQPqJD9ysAAEAAAQgfXQsf1WrVfehks9kCJQ4AAAEEAOEjEr7Zr5YpcQAACCAACB+RqFar/u5Xtyh1AAAIIAAIH5HwhY9yNpstUfIAABBAABA+IuGf/YqSBwCAAAKA8BGJ/f19/xWQLyl9AAAIIAAIH5HwhY9SNpstUwMAACCAACB8RMI3+xWDzwEAAAEEIHxEY39/X7u7u96nCtQCAABAAAEIH5HwXf0o0v0KAAAQQADCR2S2t7e9D+l+BQAACCAA4SMau7u72t/f9z5VoDYAAAACCED4iISv+1Uhm8061AgAAEAAAQgfkfBNv/sVNQIAALiGXr9+XfthaIi1ARA+Qgkf6+vr7kMnm82eDeN93X0VAABINq6AAISPUL18+dL7sECtAAAABBCA8BEZul8BAIBm6IIFED5Cs7W1pWfPnrkPQ+t+JdEFCwCAfsEVEIDwEYrt7W1v+JCkZWoHAAAggACEj0jCx8bGhvepkqQb1BAAAEAAAQgf3Qgfl7j3BwAAIIAAhA/CBwAAIIAAhA/CBwAAIIAAIHwQPgAAAAEEIHwQPgAAAAEEIHwQPgAAAAggAOGD8AEAAAggAOGD8AEAAAggAEz4uEn4IHwAAIBwHWMVAHXDx5KkPOGD8AEAAMLFFRCA8EH4AAAABBCA8EH4AAAABBCA8EH4AAAAIIAAhA/CBwAAIIAAhA/CBwAAAAEEIHwQPgAAAAEEIHwQPgAAAAEEIHwQPgAAAAggAOGD8AEAAAggAOGD8AEAAEAAAeGD8EH4AAAABBCA8EH4AAAABBCA8EH4AAAAIIAAhA/CBwAAIIAAhA/CBwAAAAEEhA/CB+EDAAAQQADCB+EDAAAQQADCB+EDAACAAAIQPggfAACAAAIQPggfAAAABBAQPggfhA8AABArx1gFIHwk3+bmphzHIXwAAAACCED4iNbGxoa2t7cJHwAAIBHoggXCB+EDAACAAAIQPggfAACAAAIQPggfAAAABBAQPggfhA8AAEAAAQgfhA8AAAACCAgfhA8AAAACCED4IHwAAAACCED4IHwAAAAQQED4IHwAAAAkCHdCB+GD8IGEev36NSuh965bvu4G3xeAa2hoaLC/v3sAG/QVAcIH4YPGNusE7RSD7fGW7wuAAFJDFywQPggfAAAABBAQPggfhA8ATaUl3ZT0SLUrE+6/R5KWzO8BdE+KbdIOXbBA+CB8JALdjVgncS0G2+NtyJ+bNw2dVJPXOJLmJC33wfcF4i4n6bbFNjkjqcAYEAIICB99ET5ojBJAMDABJCfpXoDXfyGpQAABIpMx22TK8vUXh4aGSgQQAggIH4kOHzRGCSAYqADySMG6cpQlXSCAAJG5Z04M2CoODQ1dIoAQQED4SHT4oDFKAMHABJCMpG/b+LtLkooEECB0aXNSIKgL5uRA/4ULi0zBIHQQPvogfAAYGLk2/+4zVh0QWQDp5t/1BQIICB+EDwDJcYZVAPSFFAEEIHwQPgAkwXdt/t0mqw6IlYE+5hNAQPggfABIjlKbf1dk1QGx2iZLg7zSCCAgfBA+ACRHWcGn1C0OemMHiJCj4PfaWdaAXwFhFiwQPvokfDAj0uChzONRDLbH2xA/M6XarDspy8bRRYU32w6zYAH1t8l7qs1SZ3MS4WI/BxBmwUKswsfx48cJHxGFDwADxQ0VxRavK6k2/W6ZVQZEvk3aTHVd7PfwYR1SuAKCboSPU6dOaXx8fODWQzfDB2fDBw9lHo9isD3eRvT505I+1+EpPcuSvlJ4dz+P0/cF4i4n6XIXt8n4hQuLTEEAAeGjD8IHjVECCAY2gPB9ASQugNAFC4SPPggfAAAASUEAAeGD8AEAAEAAAeGD8AEAAEAAAQgfhA8AAAACCAgfhA8AAAACCAgfhA8AAAAQQED4IHwAAAAQQED4IHwAAAAQQADCB+EDAACgc8dYBSB8JCd8VKvVhr9r867YKUk5SX+QlDGP6ylJ+tH8X2RriIWUKbPPPD83UvSUXymm3ydj/n3Qoi4m5fsgmLTZF31g/q+nbP59bcrdYbX15X4tZ/ZrGVMv0qasS57t/yu2/baP9e469e57S90+3g+5jRab26aD8EH46O2Vj2YBJOCOKC/pcotGazMFcwAohNwI8O8Ym3EbI91oGNkuU9SNorSk6Q7LzjHldqvHYTIj6XNzUMx18D7u9/myRw0S2+Q/1KN6GfZ2Eub37bQ+F009Lqi7YaRX677V9pSyXGdhnwQJ4/PSkq6b+pAKUP6XYhai41QvwjhetHW8t8kUBBAQPhISPkIIIO4OPh/iIjmSFkzjL4z1kJb0reUByJF0oQsNj0eWB5WSpIsRLcO0pKsdNtQbHQhvSFruYiPpsvk+6Qjev2i+TzeDVa8CyHVJ8xavmzfrJE7fN2Pqc1j7orD3Q3Fd983cs9w/hFkPc+ZzO/m8lKkL821u73EKIHGpF1Ec693trGCWvdxpAGEMCAgfCQkfHUhJumka0vkI3nvevPdsSA3ihQCffT3idTcboKE8E8Hn58y6vR1B+HAPVEvmM3IRrse8aah8G3Cdttsguin7s6joHre+fRvyvsi7H5pmNSdGxmyv823+fZFVWDcERXGsd7ezvHn/pU734wQQED76O3zkPI2+boSceyE0/G7IvivNrDq7tBxWwFlQuN1/UiZ03Iuwse5vGEbRcPcerHJdrPezIdVFtH8ioZsNI/92s0QRxOoY1OxkQSf7769ZvYf24d92EOba3be3fcwggIDw0b/h43oXG7BhHlSkYFcTbkb0Xa7KvitYmJfTp9W7M7mzIZWfN3ike1T/M4SQWASQTJcbRm79+5ayj618SNtmiVV5aBvL9OCzZ9v9bAIICB/9GT6WunzAr9fw62RnWJJ9V6ycwr/Ckw6w/uYUXr/zWdXO4Pay4eSWXzsBKGcORr0MHvW+C3rb0Mz0sOwJIfFrLIdxhaokZkFzj1W9rudptdGtkgACwkd/hY+Uwu9f3e5yLHW4U2w50M3jesg7YNuuV0WFN4B7SdFdzWmn/NpZZ71qbLZq8NwUum0phH0AZZ98n9VpLIehxKqV1PsTVl6B2kfcBwSEj/4JH+5Bv50GYMk0pr+usxNJmYNILuB7Z8zOsd1ZShzVumLZHLBSpqERxkDwTIAANxNiuXUSGh01nrM9ozfz6dtaUG22kyB+DGE9FNX4zGY738M1q9o0kkX29F2R66D8ZU48pD2N1nQHy5KX9J3sr6giGY1lxn/UTvoEPd6Xzb7dPdYXfdttSrV7hUwHfO/AxwwCCAgf/RU+pgP+zbLsrjQUPI3AINNn5kzjr92Df9F8ts33yiuce1vYnjGdVzhzuc92ED6W9WZ+dptgZVN2RdW6lbWzLFcDHrRKejPHfClAQGxnCtfrBJDYcWR3T5qU3tzPoJ1wc918TplVHvvGsuM5EeENGZ/pzc0q0+IKSErBuh6X1XrK9aLneH/DrOfLZl+bbrEfD3zMoAsWCB+Nw0cxQeEjH7BBVlTtHhozAQ/KJfM3lxSse1S6g+82I/tLu512t8hZNnDKqt1zQCF8XjvLXPCUXyFg2V1o8jeOpC86+D42ByHHHAQvmn9BZj3z10EngrJFd4LHjKcOFy3rzCVTZ4IGyZSYGatXMubfvEUZz5k68YXe3M/H/XfDU2cuEECsJ0mRZ3+7HPAz3NByQY3HOrZ9zCCAED4IH/XDx3I2m01K+EgHbMTOBwwQjQLMRcuDQEqd3a/Dkf0sUxl1NiDdtpESxsDzlGpdEoKuiy/Mv3bLr+x5D/93uNTh9yo2aRw6pu65jc5OGxDFNpb3Knv9nnPrwHKbda1kyn0+4N8RQHsjZXF8WjZ1YsGyTpRZrdYnHAsKdhKvkQVPGXnNtFsedMFq050r1v1SbXZ4H/je69bUYvR3JiZ8NA0fMwn6CkEGes4ovEHTjmkI2Aw8zivYoPJ6O7/PLbendrtb5C236YKCj4/otNzchlcnwaPe9yiZEJQxoaoUwvvOqDYFr7+BEeZsYf7G6LeWr58269wRuq0UUvB03VBt3FGQKxt0w+u+TIv9XJjHpEFapzbHKkfh3iDXMfvxr8xxY7mTY+HABJA7V5RTrS9bWKEhSpEPriJ89E34mA5QX6PY0bs7OJtpAK+qvbEFzRq29aRUO+MW5LKw+ze2O+BO5RRsvI7b0A674Vw275tXeIN0y6ae5SNodDZaN/OyPyM+TYOn66IKoMuqncCbD7DdZUT3nW4ifIQvF2D7cCL4/KJqV0M6eu8jA1Zgeb25DNvsX6/9gfBB+LBk2/VqIcIdfcmy8ZoPoWEbpJEZZFu27U+7oHCuQATpkuaofnepMEPkQsjvOWfKyrabXqe+DLB+PqP90lUzCqcLSCPuWIEg2zriUS8IH+05Y/m6ryJcho63Z7pgtWl4+KjGxo63riVnfqXh4aPNC+FY7ffff79mc8aA8EH48Dbo05YBYS7iZflStbEXzepuygSDQoeNjWnZzaaypNpZmlbSshs3UlY4dzwPeqIjzG5X3eIo3LvD23xewTLk5oRulcmlLgXQOQXrhjdD8fTUAuGj42OIjWKcv8RABpDJyZQmJxu3k8bGWoeGsFUqe94AEskBkvDRV+FDsj+T143v5piDynyL132uzsdPzMnu3iBusFho8TrbmxiGtR6DXP1YEH3WbX1lGUDSYhxIN3QrfMh8zrJl+afMMZbtqjdKiv6EGBJgIGfBGh0d1vj4aMN/3Q4f7jJ5mUHuhA/CRyMZ2V0FWO5iI+CWxWvCCNdF2XcZahUucpaNluWQGizpAOvAUXevIiRdMeD2g+gbmt10K8BrP6d4eobw0T3pOC8c0/DGyPj4yUgOkISPvgsfkv3Vj242YMsWjY50SDtF2xm1Ump+xcHmaoQT4kEzSP/zBXGWPghHwW5miP4LoGXL1+ZYXT2xLK48hXWsTXw9H6QA8oH7gzvmIm58V0FCOUASPvoyfEh2MygFOSCH2Qjoxk4xSCiYbbA95SyX5UaIQWA6wPf7UminXtg4w6rqSwUCaKxxRbe7AcS2ezEBJGLpgyPPmeOxXMDx8VHvw45naiF89G34yFjuVG71YNlsppD+IMTGhm2Do95sYTb3DygpvBmi0rK/+rMsrn60o8QqGGhBZv3Jsbq6alncQLCbx1n3mHMzrl+CLlgx4gtGGcIH4aMB2/7LhR4sm02jOcwD/0yAz8x7Huctw0CYdWU6wGtvCVHVPxqf/asY4LUZVldXcfUj3Hpuu6/Lq3bTwBQBBA2NjR33DoBP3bnS3g6S8NHX4cO28VRSb86gF7v8eU6AA9tNz07YZuzHgsI9o257f5+yOJPfrjSrYODZbjt0w+uegrj6EbblAK+dVm2a6mkCCBrydcPKBfnblZWV1MrKyj3CR1+HD8nuzF0xxsufC/n9Fiy/b8oEj7xFQzVIsAmz3OJedr2WMvVn1pTlPXNgfW3+5VlFA8+2oZtjVcUuFMJe0LGJadWuhNyLS93nRoSxCyAntbb23H34uSz7n6+srKRMxcoQPvo6fKRldyn1ux4uo6PuX+6dkfTI4nWzljvtKO7cbBtAvhbcup5T7cpRRvZjn0Bjd5rVgD7nmBASdIxHzvwrm78vqEfjDbkCEjMTE6cPVZQ7V1ofcAkfAxM+3EaZjXKPGwDdVlbrmyC6Wm1TRYU/fiYT8LsMauCYVe0s3TMTKJfMcznCByxthrQfAOJuQe3fUT5t9q/PzP+5bi88V0BiZnR0WKOjw6pU9tynpptVMMLHQIWPIAHkpno3i1KmR597Q/aDy5uJos4EaewUB2izzUi6bPZzaQGdK8V8PwWEyT1e5Tt4j7z5VzbtzVvqwokwAkgMTUyc1sOHT92HnzcKIISPgQsfkv0UtoN6cJ0x20S75iPa8aYEb4i+HFJYBABCSOchxN03z5t/RRNElqNa6EHqgpVzfzhxYjjWCzo5eaitMt2kG9YS4WOgwgdaK6r9+3aUFd3N//4QYPn7eR98W7WuVfOEDwAINYSEOXYxpzddtK5Hsb8eyDEgvjuOx87Y2HH/Mk43eOmhgcZnz54lfBA+0P7sVVEMPEftwHXP/JuO6DPKJryVWd0ABtSypIsKdwxjSrUTRu6YvNCCCIPQY8o3GP1yg5cteBtMz58/J3wQPiBdbeNvimL62yhcNweuXEjv55hympf0haRLkoYkXTA/L7PKAQywsmffGPYxLW/259cVQrdiAkhMXbhwqCtV7s6Vt1NnNpt15OkysrW1pWq1SvjAIMvIfjasQ9uYGJQaprRq9+eY7/B9SqqdaPnChIyz5sDqTh9JaASAtxXNvjKKIDJv9u85AkgfGh0d1vj4Se9Tjc7qLshcBalWqwNxFYTwkXilCN/7Zgd/u0TRhBYCv+0g0BVU6w53QbXuBHPiTsoA0EkQuSBfr5kOpVXrVjvb7hswC1aMTU6e0cbGC/dh/s4V3ZhaPFx5stmss7Ky8qVql8TkOI5OnjypY8f6s2gJH9bmFN+7zzoRve+sOjsjkzHb0Q2qT0fr8J6CX54vq4vTP6Kv2dY9h1WFAVI27YI51cbiudOfd+qmapOsBG6HEUBiHUBSevBg3b0nSEq1/ncL/tdls9n5lZWVyyaR6tmzZ3r33XcJH+xsigPW6LgeUoiJohH8Y4AGfJLL4HbA8FE2gW+ZTRYhsZ1xrsSqwoAqmH9uu/KqOhtcnvfsy63RBSsBIcSj2eDaOfeHSqWinZ0dwkd/sm3I/mHA1suSwrnXRkrRdMUqB/j8JJdBkIPYgmpdrAgfCDsIA2jNMfvhMCbxmFfAHggDEUCa3Ecj9i5cOKfh4aPuw/SdK/VvNJPNZgvynPHe2NjomwHphI+2GrLpAVonOdldSp6TXbeLnDro1xqCTB+XgXvQuxSgPIAotp8Sqwo4UNSbsXftBpFAJ+8G5QrIwQ7JN7A79oaHj+rDD895n2rWzeTgPgb7+/va3NwkfAxuAMkMyPpIWe70llU707Ng+b5h33ip2OcBxLb7mxs+igJ6G0B+ZFUBddsYM6pdnQ66n04rwN3Y6YKVAHWugszXe102my3LNy1vkrtiET4a7hwcy4NwagDWh03fVUdvuijekN2Zz5Q6m1Grk/D4WQIbfDnL186IM8+Iti7a7veoh0Dz7eOSgk+lbj0WkwCSAHWuglxt1K0sm83Oe3es6+vrieyKRfgI5cCZ6/P1kLHcOS74Qtuc5ftPK9w7d/druV22fN2ywr1DL9DJtlOK2fIAcXRDwWa4SsvyKiQBJCF8V0FSsuyKVa1WtbGxQfjoL0XL133e5+vB5gpFWW/PzFGUfVessAa3B2nwWO/AE9boY3pjRO2zANuiw+oCrCzL/sSd9TGBAJIQw8NH9dFHh6bWnb1zpX4jJZvNlrwH+0qlkpjxIIQPK19bvm5a/dsNa9ZyJzfXpDFs0wBJKbyuWF8HeO3lBJWFTVgqift7IFop2V+xLLK6gEAWAmw3HxBA+syHH57T2Nhx71MNG0bZbHZBnu4OjuPEfjwI4cNaMUDjeboPv39Kdv1Mi2rc5ceR/RmdvMLpSmFbbu5nJkHa8nUlNltELMg283WXlilDsaCP3Aqz3hNAEub3v5/wPszdudJ0utBDAz7X19e1u7tL+OgPBcvXXe/D727bLapVl59l2Z/RCasrlm25pRISQmwDSJlNFhG7avk6R52PRdoMsB2nuvDdc2K8CeLT7rBCAEmY8fFR/80Jr9+5Ur8RkM1mHdUZDxKnQenValXr6+uEj+jORKT7LITkZHdVp2AZLua6vB6/CvDa6+KmaoCNfIAwHEYjqhTgtZmIv3tG0m2qALrAIYAEd7BjGh5O/lf++OP3/APSG94HwYwHOWjM7+7u6qeffopFCKlWq/rpp59UqVQIH8EVZX9WeVb9cWPCpnW9zWBRkv2A9Fl1fpaxoGA3k7xKVQ9cRzB4ZR5knNaXXW6IfR7xd1+i3iOJBi6AnDlzPPFfZnj4qDKZ896nco3uDWJCSMEfQtbX12MRPnxdwggfwdjOKpRSf5whs7054LKCdfmxHZAuhTMgfTnAa+fVH/3Ic12qH7PsFgZOkAZ4UeGMRwryHtMRho97YpxJvfberKkX98z/+T4Naekuf14mzO2DLlgJNTFx+q07pN+50vggn81ml70Nn52dnZ5Nz0v4CE2QhnZG9lcP4ihj2bh0FGy6wKB/k1HnXbG+VLAzqPe6dPBMtdFYKgVYb1Eu95KC3zAL0QeDqOUD1tkwp4K2rfvpCAI44aO+m5Iemf/zZr3nTV181GcnKHKe79rNz7TxIwGkz3300bv+WbFuN7pBoQkhM94Qsr293fUQQvgIXZDGdj7BIcR2uYNczfCHuaLla+c7PPA7su/25W1sRBlCMuZgtqRgZ9WcAN8hH8Fyp826ybMriJ28pG8V3VnaoPuzosKdfrcU4LVhjsMjfNT3bYuAkTKN9aU++K4pvenVMGvqQ7oLn3s1wLZGAOlnw8NHdfHief94kHvN/qZRCOnGmBDCRyQKCjaoMm92XKmIlyujN5e/OzVrebAtB2zY+wWph51+rxsK1k0sE2GjY9YcvFMKNs4m0MFG4Q+qnzbLTUMsvjIWDcNuhA93mwtTkAklciGtg5w5UUCdP+xmgHWS74MTFv5jeC6i7cy//7YJOWXRBWswjI0d18cfv3doh3/nSvMdc70QEvXAdMJHpA5mOgvYcMtFsCxp0zBw3z/f4cEyLfuzh53WpbLsu/FkQtjZB11eN4RMh1hW9/T2JfygjaWvAnzezZCW+3aXgjQ6lzLlHtY+p52z2AsK/+aDxTaWO9/BOryu7nXHTJJ0G/viJM8Meb3BduRuZ/ciOLbnAxwbC7ZvSgDpA5OTKf94kHyzQen1QkiUs2MRPiLntNGYdRufYe2scnrTzzZf58DbSWPD5oBbCKmBcUP2XStszwg1a8AstNEQud1huaU9ZZVr8t1sGzqFAJ+dV/vdBdxG2LeK1w02bcP/tAZbxrPPaachnld7/fjLCv/qh1vuywH/ZknBujmm9KYrW6sG4PyA1qt2tqt0QrfHnEU550I+tl8PGPitZ5kjgPSJjz+e0MTE6UOV5s6V5jv5eiHkn//8Z6g3KyR8dE1BwQdfe3dW7uXbTIAD47TeDPpr1qjItbkjnA5wkJgLcV3OBVgHSyF8VjGEcmvVoEl7Gv+PLBqAQb5bOeB3yJnltu02MW2W5Zk5+KZitu0FCawpIecpT3eGokyDOpjz7GOCjk9yfaGQ71/gcauNv3GD1G29mdo75/m+OfP87QDfe1ntj39LunanOf5Dwr5nSsFmswx6jKgXfB8FDLYLCtC1+Nig1dSff65ofLyiEyeGNTo63FffLZM5r2+++VFbWzsHZ1vuXJGmFhufpclmszMrKys/moPjQWA4e/asTp06RfhIlgWzU823U318jYCiOZiVfI1Y77+gZ1GCNFJTsr9yMq9w77RdNOty1nInn1fwM6H+BlK74zvccrtZp7y8r2mn4esGwILFa28EDJkps35nTdmVzbI7vmUOGlxL5r2mu7jdlQOU1SNfGV0a4P2V28jx76+cEIPajMKZdrfZvqLYhRMsrcLHjKf+5wQb6YQtb77N7cJ7jHD3syVJm75tIyPpjNo/YVhWwCuNgxJADpLuxsYLffPNi4NfjI+f1Jkzv9L4+EmNj496B3QnzvDwUX366Qf6298eqlLZCxJC5ldWVsrmTMvBHdN/+eUXjY+PEz6SZcazs+pEznOQDEMuQGPWDSw2B4iywrmxWL0Gte0O/6b5Xk6bn+WYhming8zbabCHdZAumnUw3eZnpBXOTR5nQmzY2fo6wPbmL6OU+u+stWPKIt9BPQ5rX7jche87p9pZ5l7whg/0pp51y4LneNPJ/jwdwf7RURtXGo8MekXb2Hihhw+f6v79Vf3lLz/o668f6vvv17S29jyxIeSTTyb9QWrJojvWsqSL3gq0vb2tJ0+eBO6SRfiIRQiJ47q+bPm6jOz7ec9F1IBzAqzDlDrviuWGkGKMGpFfKNgYlRn1rjE95zkAlrv82YUO/jaj/lMydWGuh8vQrfDhft/5mISPshCk3JJmwbTT4rbsc+0s06AEEPfgdEMt5vvf2to5CCT/9V//S/fvr2p11dHe3qvEfNmxseP69NMP2gkhJUkXvBXJHZy+tbVF+EiWZdOgjcMByfFsgzZsG/PFDht/Ng1L20Awrc7PKrkhZKHH5VU0B7lCm8vfzRBSMsu60MNGmNNBY/ezPtz3lH2NpXKXy+KLLoYP142I90X1AtZMk3U/SL5q8+++S3BwumhCr9PjZXH3+W1tbwMRQKYWVZpaVGFqUfNTi5qZWtSlqUUNmUKcMTvKuultbe25SqXH+stfflCp9DgxV0Y6CCFONps9dECvVqt69uyZfvrpJ+3v7xM+kqNYp3HWbfMm1Nouw6zszwp34wxrkLP6Swrnsv5cj8KjY75vJ59d6lIIcUNtvbOBvWiEtTvLUrqPA0ijgBh1w6zQo+89o+ivYJbNd1wWXIU212Mh4d/7Ro/rgruvb7vOD/QsWCaYLE8tam5qURclndWbsydvHcRWVx3dv7+qv/71/+jBg/XYXxVpEkJanmHOZrNvNYJ2dnb0z3/+U5ubm29N10v4iC1vQ63Yxc+cN9tTkJlZ0rKfn73hSYMIDvi2jcuUwptfvmiC23yXGvNuUAzjYFaKsL45lqG22yGkrPa6PWbUf75rsA+6FGGdcPdx5R5+b0fRXsGcV+vuN99p8JQVvAvcXB999xnPvtvpUj23qYsEkICBxDFXSmamFnVBb87cHNqpVSp7+uGHdf31r/9XpdJj74DvWIaQP/7x3zU2dtz7dP7OFd27c6X52dpsNlusl7Adx9GTJ09UqVQIH8nhnq24GOGOqujZGbYzJaTtFQRH0czrH0bYmVW4A8FvmPUZxWw+ZXMgbre8Wr33JbPcYTQKvcHDZll70RBdVns3l+zHkx6N9g+XQgwitmG028IOW8sB6r2jwXQjwMmTeSX/6kezIBLVzG9l3z64Y0OvX7+u/TA0RBOtiTtXlFNtEG2+3u8nJ1P66KN3Yzu1797eK/8UvW6jdGZqsXVlXVlZyanOfOTHjx9XtVolfHRJiDeKTJmG8ufm/3SbO6SiarMAFQb44NdNGV+5tRMSi6r1my51cbnzZpmn26hfXyWswZBR7UrYtOV3jMtYrW5Lm3V0OUAQc0xdSEqdcNsNQfexJdXuMbLMfjWQWTW+307ZhMMo68112V2NmVf0J9HSnmNFps1jfMl3jLcPFxaZggASPIikzMH0ar0CjXsQKZUea3XV8e/Q55pN0+sJISmzgV9V4zPVhI9kBJB6gSSjN3OBextT3obqj3r7ng3obWM3peaDmb/zlFlcGmXeepY2dcnxLG+pDxrlbsivd8OzTXNgL1GFD+1/PmtSh5NeJ9LmOza6Ad6mp8GHcLe777oUWOMUQOrVv3SdY7yfe4zvqB4SQKIPI24QyXifHx4+qg8/PKcLF87F8r4iDx8+1fffr/mfLqh2NaRlo3JlZSVtNrQ84SM+3G0ZlDkAoOsCBZBBb3cTQMIJIjnV6Z40Ojqsjz+e0MTE6dgt88ZGRffvr/oH0pdNCLFKvisrKxnVboqTI3zQGAVlDgAEEAIIAaT7QSSvOndwnpg4rUzmfOyuhuztvdL9+//QxsYL/6+WVeuW5dgGEXMPEdAYBWUOAAQQAggBpAdBZF6+cRLDw0eVyZyP5dWQhw+f1ptW2JHl2BDQGAVlDgAEEAKILabhjcDU4sEcyUX3udrVhtV63Z567sMPz+k///NDjY+f9D6dUu2eId+aLmYAAADozCargADSlvf/9Oe0RQgpTy3qkmo3NnTc59fWnutvf3vonw6350ZHh/Xppx/o448n/F3FMpLumfuGEEQAAADaV2IV0AWrnfAxr9plthuSFp7cvea0+hszde9t+ebtz2TOa3IyFbvvuLf3St9//5N/ul5XUdIN24Hq6B6641DmAICeuS27+/9cklRkDAgBJEj4mDYVzOVIuvHk7rUFm7+/c0Wzqs0adWByMqVM5nwsv+/W1o7++79/qjdI3Q0iX04t9t0dRWmMgjIHAAR1T3Y3iCWAEEAChY+MqVypOr8uSZp5cvdaySKEZEyISbvPjY+f1Cef/CaW9wyRalP2/vDDeqMgUpa5Y+vU4kDezZfGKChzAAABhAASevhImYqVkaQjR2pBoVp9azD5gmpXRJwWIeTQ+0nS2NhxffrpB7ENIRZBRKpdFbklqWA7hS9ojIIyB4B+2CVbvu6sJIcAQgCxCSCH+vWdn/itRkZO6Jnzkza31v0vL8n+asiSPHcTHx4+qk8//UBjY8djvT4qlT09eLCutbXnzWb0Kkr6yoSRMrWIxigocwDoUxlJ39q2vWl3E0Bswse8aoPOJUnj587rzNi7B7/f2dnWz08fa3f3pf9Pbzy5e23eIoTMyjMuJCkhRKoNVl9be66HD5+2mtWrbALJ15JKU4vMAEFjFJQ5APSNQ225JoqqdcEigBBAmoaPaXkGnZ8+dU7vvjNZ97XPnJ/0zFmrV9G+sOiSlZe0lMQQ4qpU9vTo0YbW1p6rUtmT5UZYUm0+7KIkh2BCYxSUOQAk0CN5xvY2sSBpjnY3AaRZ+MjIM+h8ZOSEzk/89mD8Rz27uy+19q+y9vd3vU+XTQgp9XsI8YaRtbXnWlt73my8SF1Ti6Ii0hgFZQ4ASTEru6sfUu3ecAXa3QSQRuEjJd+g89+c/0jHjo20/Ntq9ZU2nj7W8+2n3qcdSXNP7l5bDhpC/vjHf4/1wHQbGxsVbWy80M8/V7S1tdP0TvAEEBqjoMwBoA/Dh2QGoNPuJoA0CiBvDTo/fvxUoPfY3FrXxtPH/qfnWt0zxB9CkjA7VlCVyp62tna0tbWjzc0dra09d39VNHePB41RUOYA0MtgcVW1LuLf6e27l2ckfS67aXddy5JmDhrgBBACiC98zKvJoPMgdndf6vHa3/3T9S4/uXttJmgI+eyzD/tyfW9sVPTNN2UCCI1RUOYAEBe29/QI4pIJNLS7JR2hjh0KH9Pe8HH61Lm2w4dUGzfym/MfaWTkhPfp/Pt/+vNSs7+bWtSyzCAlqXZH8lLpMQUEAAAQrVQE4aPgDR8ggHjDR0aeqw4jIyc0fu58x+977NjIwX1DAoaQBdUu10mSVlcdra46FBQAAEB0wg4fjjwnlUEA8YaPlAkfKak26Hzi1+mmM14FWslHjur8xG91+tS5oCFkxpuYS6XHre63AQAAgPZ9FvL7zUjckJkAUt+SzIxXkjTx67TVjFdBQ8i770wGDiGqTdl2UHHv319tOosUAAAA2jYdcvgosEoJIG8xg84PKtv4ufOBZ7wKImgImVqUY0KIpNoMUowHAQAACF1adjcUbKUs6aI8XelBAPGGj2mFOOi8wxAy2ySElOTpP7i29lwPHz6l9gIAAIQnpc66S5UlzUu6oLen7gUBJLpB57bGz533D0y/+f6f/pxvEkIW5LmM9+DBuiqVvcSXw+bmjn/DBQAA6IWSCQ8XVTvxW1Dz2asc8/sF1abZvSDpBquxtWMDGj5SinDQuVXyMwPTH6/9Xbu7L70hpPTk7rVGqXlGtdkZUnt7r1QqPdann36Q6LLY3z80nuVHNknAHvdvAoDIgkjJBAtE0Q4e0O8d+aBz2xDiCz4pSbdNQHqLGQ9ycBPDjY0X3ruIAwAAAASQuOn2oPNW3PuEeKQl3W70+qlFFeTpivX992vMigUAAAACSEzDx7R6MOi8lZGRE3r3nUnvUzkTlBqZU63foSqVPT16xIB0AAAAEEDiFj4y6uGg81ZOnzrnnxnrulnmt0wtqizpS/fxDz/0x4B0AAAAEED6JXyk1ONB5zbGz533j0VpNh5kXp5Zox48WKc2AwAAgAASE7EYdN6yMEww8kjL02WsjoN7g6yuOlwFAQAAAAGk1+I26LyVkZETOpua8D4126QrVkGe+amTeBWEAfQAAAAEkH4KH9OK4aDzVs6m3vPfpHCpycsPbniTxKsgm5u/eB8W2SQBAAAIIEkNHxnFeNB5K78+PCtW5v0//Xm23uumFlVUwq+CAAAAgACS9PCRkm/Q+a/fmYzdoPNmRkZO+K+CXG80IF2eGbEYCwIAAAACSPcdGnT+7juT/sZ8rFWrr/Rk7e/a3X3p/1XdAGLGgpTdx//4h0PNBgAAAAGkG/yDzs+mJnRy9Exiln9396X+8fiBXu5se58uSbr45O61cpM/PTQWBAAAACCARB8+puUZdH5y9IzOpt5LzPI/336qx2t/1/7+rvfpZUmXWoQPSSrIc3f0tbXn1O4BMzQ0pKGhIVYEAAAggHQpfGTkG3T+7uGB3LG28fSx1n9eVbV6aFrauSd3r808uXvNafX3U4tyTAiRxFUQAAAAEECiDB8pJXTQuTveY3Pr0OxVjmpdrhYCvt3BYPS1tefcYwMAAAAEkIgkctB5k/EeF57cvVYK+n5TiyrJMxg9Cd2wtrZ2vA/LbJIAAAD97VjSv0BSB50/336qjaeP/V2ulp/cvTbT4VsXJM26AWRyMhXr9eC9SjO1SAABAADod4m+ApLUQefrP6/WG+8xE0L4kKRb7g90wwIAAAABJLzwkVHCBp1Xq6/0j8cP9Hz7qfdpR7XxHsthfIa/G9bGRoVaDgAAAAJIh+EjpYQNOt/dfan/94//7b+5YEltjvdooeD+wHS8AAAAiJOkjgFJ1KDz59tPtf7zqv/p5ZC6XNXztcw4kI2NF9RyAAAAxEbiroAkbdC5O97DZybC8KGpxTdXQCqVPVUqe9R0AAAAEEDaCB/TSsig8wbjPcoKcbxHC0X3B66CAAAAgAASPHxklJBB5w3GexRN+Ch1aTG+dn/w3WsjNpihCwAAYPAkYgxIkgadNxjvsfDk7rW5Li/KQdDZ3PwlluW6tfWLP6ABAACAABILsR90Xq2+0sbTx/Wm2J3rUperhgGELlgAAACIi9h3wXr/T3+eVcwHne/v7+rx2t/rjfe41KPw4d5V3HEfx7UbFgAAAAggcQofOUk33cdxHHS+s7Otfzx+0OvxHo0cfD4zYQEAACAOYtsF6/0//Tkt6bb7OI6Dzje31rXx9LH/6V6M92gWQHJS7YaEw8Otx8xsbu5of7/14PCff259h/W9vVdceQEAAED8A4gZdH5bMR10HsPxHg3zhPvD6qqj1VWHGg8AAICeimsXrJuK6aDzOI73aKKYkHroyNNdDAAAAP0rdldAzKDzvPs4ToPOd3a2tfavsqrVV/5G/hdP7l5z+qSRX5b0o8XrSvIMcm9kapHpdQEAAPDG0OvXr2s/DA3FIXzkJN1zH58cPaP3fp2OxYpqMN7jxpO71+apRkD03H0VAABItthcAYnroPMm4z1mnty9VqAKAQAAAAkLIHEddL6/v6u1f5X9U+yWTPgoUX0AAACABAYQxXDQ+YvKptZ/XvWP9yiY8OFQdQAAAIAEBpA4Djp/5vykZ86a/2nGewAAAAAd6ukg9LgNOq9WX2n951W9qGx6n3bEeA+g5xiEDgBAf+jZFZC4DTrf3X2pf/28yngPAAAAoN8CiH/QuSS9c+58zwadM94DAAAA6OMAIt+gc0la+1dZZ8be1Zmxd7oaRBjvAQAAAPR/ALll/p+WuQpSrb7SM2dNz7efavzc+cgHojcZ7/HFk7vXilQNAAAAIHy9HoSeUm0GrKuS0t7fnT51TuMRdctqMt7jiyd3r5WpFkD8MAgdAAACSNhBZNYEkZT7/MjICf065HuCNBjvsSxpjvEeAAEEAAAMQADxBJG0pCVJOfe5I0eO6vzEb0MJIRtPH2tza93/9NyTu9cWqAoAAQQAAAxYAPEEkXlJ18MKIdXqK/30r7Je7mx7n3bEeA+AAAIAAJIZQO5cUU617lMZXyO/JKk8tahywBCSV222rFQnIWR396XW/lXW/v6u9+mSGO8BEEAAAEByAsidK0qrNovV5/J0mWrCUe3eGl9NLapgGUIyqt0p/SCE/I/f/E/rgenPt59q4+ljxnsABBAAAJDUAGKCx3XVZq9qV1nSjalFLVuGkG/dxyMjJ/Sb8x+1/ADGewAEEAAAkOAAcueKUiZ4zNb7/ejosE6cGNGZM7/S8HDtCkWlsqdKZU8bGy+aBZGZqUUVW4SQvGqD0yVJZ1MTOpt6r+5rGe8BEEAAAEDCA8idK8qYAJDxPj82dlyTkylNTJzW6Ohw0w9aW3t+8G9v75X/1wtTi5prEUJuesPPb85/9NZ4EMZ7AAQQAACQ8ABiwsfBOAypdrUjk/k3jY+PBv7Avb1XevToqX744a3uUUVJX0wtymkQQFKqdcVKS9KJ46f0/sRvD37faLzHk7vXZihmgAACAAASEEDqhY/f/e5dffTRux1/cKWyp/v3V7W1teN9uiTpUpMQkjPLI0k6P/FbHT9+qtF4j5knd68tU8QAAQQAACQggPjDx/DwUX3yyWRbVz2aKZUea3X1UN5YnlpUw6sW7//pz0syA+BPHD+lV9VX2t196X2JI+nSk7vXShQvQAABAADxcqTek2bA+ZI3fHz66Qehhw9JymTOa3Iy5X0qf+dK/YHuxg33h5c72/7wUZJ0gfABAAAAJCiAqDbbVcZ98MknkxobOx7ZQmQy5zUxcdr71E0z3e9bzGDy5Tq/Wn5y99pF7u8BAAAAJCiAmIb/rPv4d797N5IrH/VCiG8mraUmL7/lezzDYHMAAAAggQFEtasfkmrT7IYx4NzG8PBRZTL/5n0qd+dK/Tusm/t5lFUb73GRweYAAABAAgOIufqRdx///vcTXV2Y8fFRjY+f9D51ucnL58R4DwAAACBRDs2CZQZ/35RqVz8+++zDri/QxkZF33xT9j51ttG0vAAGB7NgAQDQH/xdsA6uOPhmpuqa8fFR/1iQaYoJAAAA6M8AknF/8M1K1VW+z/4DxQQAAAD0WQDxDvgeHR32X4XoKt84kAzFBAAAAPRZAJHe3HfjxImRni6U754jOYoJAAAA6OMA8s47oz1dqF5efQEAAADQnQACAAAAAAQQAAAAAH0cQPb2XrFmAAAAAEQaQIruD5ubv/R0oTY2Kt6HZYoJAAAA6L8A4rg/bG3t9HShKpVdAggAAADQzwFkalElN4Ts7b3qaQhZW3vuffg1xQQAAAD0WQAxiu4Pq6tOTxZob++VvwtWgWICAAAA+jOAfPUmgGz2ZDD62tpz7+eWzZUZAAAAAP0WQKYWtSxPN6xHj552dWH29l7pwYN171O3KCIAAACgTwOI8aX7w8OHT1Wp7HVtYR49OvR5jqQFiggAAADo7wCyIDPz1N7eK5VKj7uyIFtbO/rhh0NXP76cWnwzMxcAAACAPgwgptE/5z7e2HgReQipVPb0zTc/ep8qTS1qnuIBAAAA+jyAmBBSkLTsPl5ddSILIZXKnu7fX/UOPHckzVA0AAAAQP8Zev36de2HoaG3fnnnir6VlHEfT06m9PHH72l4+GgoH761taNvvvnRP9vWjBkMDwAH3H0VAABItmMtfn9J0j03hKyuOtrc3NHvfz+h8fHRjj74wYN1/5gPwgcAAADQ55peAZGkO1eUknRbUs77/ORkSh9+eE5jY8etP2xv75XW1p7rwYP1erNrET4ANMQVEAAABiSAeILIvKTr/ufHxo7r/fdPa3z8pMbGfvVW96ytrR1tbu5oY6Piv8mgqyzpC244CIAAAgAAAcQfQjKSbsp3NaRNjmr3HFlgul0ABBAAAAggzYJITtJVSdMEDwAEEAAAEGkA8QSRlAkhn6k2UD3TIHCUJH0tqTi1qCKrHQABBACAAQ8gAAAAABC1I6wCAAAAAAQQAAAAAH3n/w8AmB1j3tEUq4sAAAAASUVORK5CYII='; - /* tslint:enable:max-line-length */ - var imageHeight = width * 3 / 8; - var oldAntialias = this.getAntialiasing(); - this.setAntialiasing(true); - ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); - // loading box - ctx.strokeStyle = 'white'; - ctx.lineWidth = 2; - ctx.strokeRect(x, y, width, 20); - var progress = width * (loaded / total); - ctx.fillStyle = 'white'; - var margin = 5; - var progressWidth = progress - margin * 2; - var height = 20 - margin * 2; - ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); - this.setAntialiasing(oldAntialias); - }; - /** - * Sets the loading screen draw function if you want to customize the draw - * @param fcn Callback to draw the loading screen which is passed a rendering context, the number of bytes loaded, and the total - * number of bytes to load. - */ - Engine.prototype.setLoadingDrawFunction = function (fcn) { - this._loadingDraw = fcn; - }; /** * Another option available to you to load resources into the game. * Immediately after calling this the game will pause and the loading screen @@ -12838,18 +13001,12 @@ var ex; var _this = this; var complete = new ex.Promise(); this._isLoading = true; - loader.onprogress = function (e) { - _this._progress = e.loaded; - _this._total = e.total; - _this._logger.debug('Loading ' + (100 * _this._progress / _this._total).toFixed(0)); - }; - loader.oncomplete = function () { + loader.load().then(function () { setTimeout(function () { _this._isLoading = false; complete.resolve(); }, 500); - }; - loader.load(); + }); return complete; }; return Engine; diff --git a/sandbox/web/index.html b/sandbox/web/index.html index 13a474109..f9a501753 100644 --- a/sandbox/web/index.html +++ b/sandbox/web/index.html @@ -10,6 +10,8 @@
  • Sprite Culling
  • Input
  • Keyboard Input
  • +
  • Loader - PauseAfterLoader
  • +
  • Loader - PauseAfterLoader (iOS-only)
  • Pointer Input
  • GamePad Input
  • Scene Lifecycle
  • diff --git a/sandbox/web/tests/loader/pauseafter/index.html b/sandbox/web/tests/loader/pauseafter/index.html new file mode 100644 index 000000000..7cd648a2f --- /dev/null +++ b/sandbox/web/tests/loader/pauseafter/index.html @@ -0,0 +1,37 @@ + + + + PauseAfterLoader Test + + + +
    + + Tap to Play +
    + + +

    You should see a loader, then a button to press to play, then a sound

    + + \ No newline at end of file diff --git a/sandbox/web/tests/loader/pauseafter/ios.html b/sandbox/web/tests/loader/pauseafter/ios.html new file mode 100644 index 000000000..552e8f3ff --- /dev/null +++ b/sandbox/web/tests/loader/pauseafter/ios.html @@ -0,0 +1,37 @@ + + + + PauseAfterLoader Test - iOS + + + +
    + + Tap to Play +
    + + +

    On iOS, you should see the paused loader. On all other platforms, you shouldn't. On iOS you should also hear a sound every 2 seconds after starting the game.

    + + \ No newline at end of file diff --git a/sandbox/web/tests/loader/pauseafter/ios.js b/sandbox/web/tests/loader/pauseafter/ios.js new file mode 100644 index 000000000..0639b8b4e --- /dev/null +++ b/sandbox/web/tests/loader/pauseafter/ios.js @@ -0,0 +1,22 @@ +/// +var game = new ex.Engine({ + canvasElementId: 'game', + displayMode: ex.DisplayMode.FullScreen +}); +var jump = new ex.Sound('../../../sounds/jump.mp3', '../../../sounds/jump.wav'); +// if iOS, use PauseAfterLoader +var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; +var loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); +loader.addResource(jump); +var lbl = new ex.Label('Game started, you should hear a sound every 2 seconds', 20, 100, 'sans-serif'); +lbl.fontSize = 10; +lbl.color = ex.Color.White; +var tmr = new ex.Timer(function () { + jump.play(); +}, 2000, true); +game.add(lbl); +game.add(tmr); +game.start(loader).then(function () { + // should play immediately + jump.play(); +}); diff --git a/sandbox/web/tests/loader/pauseafter/ios.ts b/sandbox/web/tests/loader/pauseafter/ios.ts new file mode 100644 index 000000000..bc9dc139c --- /dev/null +++ b/sandbox/web/tests/loader/pauseafter/ios.ts @@ -0,0 +1,30 @@ +/// + +var game = new ex.Engine({ + canvasElementId: 'game', + displayMode: ex.DisplayMode.FullScreen +}); + +var jump = new ex.Sound('../../../sounds/jump.mp3', '../../../sounds/jump.wav'); + +// if iOS, use PauseAfterLoader +var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window).MSStream; +var loader: ex.Loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); + +loader.addResource(jump); + +var lbl = new ex.Label('Game started, you should hear a sound every 2 seconds', 20, 100, 'sans-serif'); +lbl.fontSize = 10; +lbl.color = ex.Color.White; +var tmr = new ex.Timer(() => { + jump.play(); +}, 2000, true); + +game.add(lbl); +game.add(tmr); + +game.start(loader).then(() => { + + // should play immediately + jump.play(); +}); \ No newline at end of file diff --git a/sandbox/web/tests/loader/pauseafter/pauseafter.js b/sandbox/web/tests/loader/pauseafter/pauseafter.js new file mode 100644 index 000000000..85207a93d --- /dev/null +++ b/sandbox/web/tests/loader/pauseafter/pauseafter.js @@ -0,0 +1,16 @@ +/// +var game = new ex.Engine({ + canvasElementId: 'game', + width: 500, + height: 500 +}); +var jump = new ex.Sound('../../../sounds/jump.mp3', '../../../sounds/jump.wav'); +var loader = new ex.PauseAfterLoader('tap-to-play', [jump]); +var lbl = new ex.Label('Game started, you should hear a sound', 20, 100, 'sans-serif'); +lbl.fontSize = 10; +lbl.color = ex.Color.White; +game.add(lbl); +game.start(loader).then(function () { + // should play immediately + jump.play(); +}); diff --git a/sandbox/web/tests/loader/pauseafter/pauseafter.ts b/sandbox/web/tests/loader/pauseafter/pauseafter.ts new file mode 100644 index 000000000..a9705a32a --- /dev/null +++ b/sandbox/web/tests/loader/pauseafter/pauseafter.ts @@ -0,0 +1,22 @@ +/// + +var game = new ex.Engine({ + canvasElementId: 'game', + width: 500, + height: 500 +}); + +var jump = new ex.Sound('../../../sounds/jump.mp3', '../../../sounds/jump.wav'); +var loader: ex.Loader = new ex.PauseAfterLoader('tap-to-play', [jump]); + +var lbl = new ex.Label('Game started, you should hear a sound', 20, 100, 'sans-serif'); +lbl.fontSize = 10; +lbl.color = ex.Color.White; + +game.add(lbl); + +game.start(loader).then(() => { + + // should play immediately + jump.play(); +}); \ No newline at end of file diff --git a/sandbox/web/tests/spritefont/spritefont.js b/sandbox/web/tests/spritefont/spritefont.js index 7631f1f44..b6f00841e 100644 --- a/sandbox/web/tests/spritefont/spritefont.js +++ b/sandbox/web/tests/spritefont/spritefont.js @@ -7,7 +7,8 @@ var game = new ex.Engine({ }); var spriteFontTex = new ex.Texture('spritefont.png'); var label = null; -game.start(spriteFontTex).then(function () { +var loader = new ex.Loader([spriteFontTex]); +game.start(loader).then(function () { var spriteFont = new ex.SpriteFont(spriteFontTex, '0123456789abcdefghijklmnopqrstuvwxyz,!\'&."?- ', true, 16, 3, 16, 16); label = new ex.Label("This is a sprite Font test", game.width / 2, game.height / 2, null, spriteFont); label.color = ex.Color.Azure.clone(); diff --git a/sandbox/web/tests/spritefont/spritefont.ts b/sandbox/web/tests/spritefont/spritefont.ts index 44abc8d9f..de39fc77c 100644 --- a/sandbox/web/tests/spritefont/spritefont.ts +++ b/sandbox/web/tests/spritefont/spritefont.ts @@ -10,8 +10,9 @@ var game = new ex.Engine({ var spriteFontTex = new ex.Texture('spritefont.png'); var label : ex.Label = null; +var loader = new ex.Loader([spriteFontTex]); -game.start(spriteFontTex).then(() => { +game.start(loader).then(() => { var spriteFont = new ex.SpriteFont(spriteFontTex, '0123456789abcdefghijklmnopqrstuvwxyz,!\'&."?- ', true, 16, 3, 16, 16); diff --git a/sandbox/web/tests/zoom/zoom.js b/sandbox/web/tests/zoom/zoom.js index 067b142c8..6799c2c4e 100644 --- a/sandbox/web/tests/zoom/zoom.js +++ b/sandbox/web/tests/zoom/zoom.js @@ -44,4 +44,5 @@ game.input.keyboard.on('down', function (ev) { game.currentScene.camera.setFocus(currentFocus.x, currentFocus.y + 10); } }); -game.start(raptorTex); +var loader = new ex.Loader([raptorTex]); +game.start(loader); diff --git a/sandbox/web/tests/zoom/zoom.ts b/sandbox/web/tests/zoom/zoom.ts index 0096b5674..eb85f7c78 100644 --- a/sandbox/web/tests/zoom/zoom.ts +++ b/sandbox/web/tests/zoom/zoom.ts @@ -60,5 +60,5 @@ game.input.keyboard.on('down', (ev: ex.Input.KeyEvent) => { }); - -game.start(raptorTex); \ No newline at end of file +var loader = new ex.Loader([raptorTex]); +game.start(loader); \ No newline at end of file diff --git a/src/engine/Engine.ts b/src/engine/Engine.ts index 5c39b668f..dcaea8963 100644 --- a/src/engine/Engine.ts +++ b/src/engine/Engine.ts @@ -4,6 +4,9 @@ /// /// /// +/// +/// +/// /// /// /// @@ -26,6 +29,7 @@ /// /// + /** * # Welcome to the Excalibur API * @@ -412,11 +416,8 @@ module ex { private _compatible: boolean; // loading - private _loader: ILoadable; + private _loader: ILoader; private _isLoading: boolean = false; - private _progress: number = 0; - private _total: number = 1; - private _loadingDraw: (ctx: CanvasRenderingContext2D, loaded: number, total: number) => void; /** * Creates a new game using the given [[IEngineOptions]] @@ -971,6 +972,11 @@ module ex { private _update(delta: number) { if (this._isLoading) { // suspend updates untill loading is finished + this._loader.update(this, delta); + // Update input listeners + this.input.keyboard.update(delta); + this.input.pointers.update(delta); + this.input.gamepads.update(delta); return; } this.emit('preupdate', new PreUpdateEvent(this, delta, this)); @@ -999,10 +1005,8 @@ module ex { private _draw(delta: number) { var ctx = this.ctx; this.emit('predraw', new PreDrawEvent(ctx, delta, this)); - if (this._isLoading) { - ctx.fillStyle = 'black'; - ctx.fillRect(0, 0, this.width, this.height); - this._drawLoadingBar(ctx, this._progress, this._total); + if (this._isLoading) { + this._loader.draw(ctx, delta); // Drawing nothing else while loading return; } @@ -1045,10 +1049,10 @@ module ex { /** * Starts the internal game loop for Excalibur after loading * any provided assets. - * @param loader Optional resources to load before starting the main loop. Some [[ILoadable]] such as a [[Loader]] collection, - * [[Sound]], or [[Texture]]. + * @param loader Optional [[ILoader]] to use to load resources. The default loader is [[Loader]], override to provide your own + * custom loader. */ - public start(loader?: ILoadable) : Promise { + public start(loader?: ILoader) : Promise { if(!this._compatible) { var promise = new Promise(); return promise.reject('Excalibur is incompatible with your browser'); @@ -1056,8 +1060,9 @@ module ex { var loadingComplete: Promise; if (loader) { - loader.wireEngine(this); - loadingComplete = this.load(loader); + this._loader = loader; + this._loader.wireEngine(this); + loadingComplete = this.load(this._loader); } else { loadingComplete = Promise.wrap(); } @@ -1066,8 +1071,6 @@ module ex { this._hasStarted = true; this._logger.debug('Starting game...'); - - // Mainloop var lastTime = Date.now(); var game = this; @@ -1129,58 +1132,6 @@ module ex { return result; } - /** - * Draws the Excalibur loading bar - * @param ctx The canvas rendering context - * @param loaded Number of bytes loaded - * @param total Total number of bytes to load - */ - private _drawLoadingBar(ctx: CanvasRenderingContext2D, loaded: number, total: number) { - if (this._loadingDraw) { - this._loadingDraw(ctx, loaded, total); - return; - } - - var y = this.canvas.height / 2; - var width = this.canvas.width / 3; - var x = width; - - - // loading image - var image = new Image(); - /* tslint:disable:max-line-length */ - // 64 bit string encoding of the excalibur logo - image.src = 'data:image/png;base64,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'; - - /* tslint:enable:max-line-length */ - var imageHeight = width * 3 / 8; - var oldAntialias = this.getAntialiasing(); - this.setAntialiasing(true); - ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); - - // loading box - ctx.strokeStyle = 'white'; - ctx.lineWidth = 2; - ctx.strokeRect(x, y, width, 20); - - var progress = width * (loaded / total); - ctx.fillStyle = 'white'; - var margin = 5; - var progressWidth = progress - margin * 2; - var height = 20 - margin * 2; - ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); - this.setAntialiasing(oldAntialias); - } - - /** - * Sets the loading screen draw function if you want to customize the draw - * @param fcn Callback to draw the loading screen which is passed a rendering context, the number of bytes loaded, and the total - * number of bytes to load. - */ - public setLoadingDrawFunction(fcn: (ctx: CanvasRenderingContext2D, loaded: number, total: number) => void) { - this._loadingDraw = fcn; - } - /** * Another option available to you to load resources into the game. * Immediately after calling this the game will pause and the loading screen @@ -1192,18 +1143,12 @@ module ex { this._isLoading = true; - loader.onprogress = (e) => { - this._progress = e.loaded; - this._total = e.total; - this._logger.debug('Loading ' + (100 * this._progress / this._total).toFixed(0)); - }; - loader.oncomplete = () => { + loader.load().then(() => { setTimeout(() => { this._isLoading = false; complete.resolve(); }, 500); - }; - loader.load(); + }); return complete; } diff --git a/src/engine/Interfaces/ILoader.ts b/src/engine/Interfaces/ILoader.ts new file mode 100644 index 000000000..bdf513af7 --- /dev/null +++ b/src/engine/Interfaces/ILoader.ts @@ -0,0 +1,9 @@ +/// + +module ex { + + export interface ILoader extends ILoadable { + draw(ctx: CanvasRenderingContext2D, delta: number); + update(engine: Engine, delta: number); + } +} \ No newline at end of file diff --git a/src/engine/Loader.ts b/src/engine/Loader.ts index 5778ae822..4bf730e22 100644 --- a/src/engine/Loader.ts +++ b/src/engine/Loader.ts @@ -1,324 +1,10 @@ -/// /// /// -/// +/// /// +/// -module ex { - - - /** - * Textures - * - * The [[Texture]] object allows games built in Excalibur to load image resources. - * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] - * to pre-load before starting a level or game. - * - * Textures are the raw image so to add a drawing to a game, you must create - * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite - * instance. - * - * ## Pre-loading textures - * - * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] - * is loaded, you can generate a [[Sprite]] with it. - * - * ```js - * var txPlayer = new ex.Texture("/assets/tx/player.png"); - * - * var loader = new ex.Loader(txPlayer); - * - * game.start(loader).then(function () { - * - * var player = new ex.Actor(); - * - * player.addDrawing(txPlayer); - * - * game.add(player); - * }); - * ``` - */ - export class Texture extends Resource { - - /** - * The width of the texture in pixels - */ - public width: number; - - /** - * The height of the texture in pixels - */ - public height: number; - - /** - * A [[Promise]] that resolves when the Texture is loaded. - */ - public loaded: Promise = new Promise(); - - private _isLoaded: boolean = false; - private _sprite: Sprite = null; - - /** - * Populated once loading is complete - */ - public image: HTMLImageElement; - - private _progressCallback: (progress: number, total: number) => void; - private _doneCallback: () => void; - private _errorCallback: (e: string) => void; - - /** - * @param path Path to the image resource - * @param bustCache Optionally load texture with cache busting - */ - constructor(public path: string, public bustCache = true) { - super(path, 'blob', bustCache); - this._sprite = new Sprite(this, 0, 0, 0, 0); - } - - - /** - * Returns true if the Texture is completely loaded and is ready - * to be drawn. - */ - public isLoaded(): boolean { - return this._isLoaded; - } - - /** - * Begins loading the texture and returns a promise to be resolved on completion - */ - public load(): Promise { - var complete = new Promise(); - - var loaded = super.load(); - loaded.then(() => { - this.image = new Image(); - this.image.addEventListener('load', () => { - this._isLoaded = true; - this.width = this._sprite.swidth = this._sprite.naturalWidth = this._sprite.width = this.image.naturalWidth; - this.height = this._sprite.sheight = this._sprite.naturalHeight = this._sprite.height = this.image.naturalHeight; - this.loaded.resolve(this.image); - complete.resolve(this.image); - }); - this.image.src = super.getData(); - - - }, () => { - complete.reject('Error loading texture.'); - }); - return complete; - } - - public asSprite(): Sprite { - return this._sprite; - } - - } - - /** - * Sounds - * - * The [[Sound]] object allows games built in Excalibur to load audio - * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] - * which means it can be passed to a [[Loader]] to pre-load before a game or level. - * - * ## Pre-loading sounds - * - * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] - * is loaded, you can [[Sound.play|play]] it. - * - * ```js - * // define multiple sources (such as mp3/wav/ogg) as a browser fallback - * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); - * - * var loader = new ex.Loader(sndPlayerDeath); - * - * game.start(loader).then(function () { - * - * sndPlayerDeath.play(); - * }); - * ``` - */ - export class Sound implements ILoadable, ex.Internal.ISound { - private _logger: Logger = Logger.getInstance(); - - public path: string; - - public onprogress: (e: any) => void = () => { return; }; - - public oncomplete: () => void = () => { return; }; - - public onerror: (e: any) => void = () => { return; }; - - public onload: (e: any) => void = () => { return; }; - - private _isLoaded: boolean = false; - - private _engine: Engine; - private _wasPlayingOnHidden: boolean = false; - - /** - * Populated once loading is complete - */ - public sound: ex.Internal.FallbackAudio; - - /** - * Whether or not the browser can play this file as HTML5 Audio - */ - public static canPlayFile(file: string): boolean { - try { - var a = new Audio(); - var filetype = /.*\.([A-Za-z0-9]+)$/; - var type = file.match(filetype)[1]; - if (a.canPlayType('audio/' + type)) { - return true; - } - { - return false; - } - } catch (e) { - ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); - return false; - } - } - - /** - * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. - */ - constructor(...paths: string[]) { - /* Chrome : MP3, WAV, Ogg - * Firefox : WAV, Ogg, - * IE : MP3, WAV coming soon - * Safari MP3, WAV, Ogg - */ - this.path = ''; - for(var i = 0; i < paths.length; i++) { - if(Sound.canPlayFile(paths[i])) { - this.path = paths[i]; - break; - } - } - - if(!this.path) { - this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); - this._logger.warn('Attempting to use', paths[0]); - this.path = paths[0]; // select the first specified - } - - this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); - } - - public wireEngine(engine: Engine) { - if (engine) { - this._engine = engine; - this._engine.on('hidden', () => { - if (engine.pauseAudioWhenHidden && this.isPlaying()) { - this._wasPlayingOnHidden = true; - this.pause(); - } - }); - - this._engine.on('visible', () => { - if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) { - this.play(); - this._wasPlayingOnHidden = false; - } - }); - } - } - - /** - * Sets the volume of the sound clip - * @param volume A volume value between 0-1.0 - */ - public setVolume(volume: number) { - if (this.sound) { this.sound.setVolume(volume); } - } - - /** - * Indicates whether the clip should loop when complete - * @param loop Set the looping flag - */ - public setLoop(loop: boolean) { - if (this.sound) { this.sound.setLoop(loop); } - } - - /** - * Whether or not the sound is playing right now - */ - public isPlaying(): boolean { - if (this.sound) { return this.sound.isPlaying(); } - } - - /** - * Play the sound, returns a promise that resolves when the sound is done playing - */ - public play(): ex.Promise { - if (this.sound) { return this.sound.play(); } - } - - /** - * Stop the sound, and do not rewind - */ - public pause() { - if (this.sound) { this.sound.pause(); } - } - - /** - * Stop the sound and rewind - */ - public stop() { - if (this.sound) { this.sound.stop(); } - } - - /** - * Returns true if the sound is loaded - */ - public isLoaded() { - return this._isLoaded; - } - - /** - * Begins loading the sound and returns a promise to be resolved on completion - */ - public load(): Promise { - var complete = new Promise(); - - if (this.sound.getData() !== null) { - this._logger.debug('Already have data for resource', this.path); - complete.resolve(this.sound); - return complete; - } - - this._logger.debug('Started loading sound', this.path); - this.sound.onprogress = this.onprogress; - this.sound.onload = () => { - this.oncomplete(); - this._isLoaded = true; - this._logger.debug('Completed loading sound', this.path); - complete.resolve(this.sound); - }; - this.sound.onerror = (e) => { - this.onerror(e); - complete.resolve(e); - }; - this.sound.load(); - return complete; - } - - public getData(): any { - return this.sound.getData(); - } - - public setData(data: any) { - this.sound.setData(data); - } - - public processData(data: any): any { - return this.sound.processData(data); - } - } +module ex { /** * Pre-loading assets @@ -354,7 +40,7 @@ module ex { * }); * ``` */ - export class Loader implements ILoadable { + export class Loader extends Class implements ILoader { private _resourceList: ILoadable[] = []; private _index = 0; @@ -368,6 +54,8 @@ module ex { * @param loadables Optionally provide the list of resources you want to load at constructor time */ constructor(loadables?: ILoadable[]) { + super(); + if (loadables) { this.addResources(loadables); } @@ -440,8 +128,8 @@ module ex { r.onprogress = function (e) { var total = e.total; var loaded = e.loaded; - progressArray[i] = {loaded: ((loaded / total) * (100 / progressChunks)), total: 100}; - + progressArray[i] = {loaded: ((loaded / total) * (100 / progressChunks)), total: 100}; + var progressResult: any = progressArray.reduce(function(accum, next){ return {loaded: (accum.loaded + next.loaded), total: 100}; }, {loaded: 0, total: 100}); @@ -450,8 +138,7 @@ module ex { }; r.oncomplete = r.onerror = function () { me._numLoaded++; - if (me._numLoaded === me._resourceCount) { - me.onprogress.call(me, {loaded: 100, total: 100}); + if (me._numLoaded === me._resourceCount) { me.oncomplete.call(me); complete.resolve(); } @@ -469,17 +156,194 @@ module ex { return complete; } + /** + * Loader draw function. Draws the default Excalibur loading screen. Override to customize the drawing. + */ + public draw(ctx: CanvasRenderingContext2D, delta: number) { + ctx.fillStyle = 'black'; + ctx.fillRect(0, 0, this._engine.width, this._engine.height); + + var y = this._engine.canvas.height / 2; + var width = this._engine.canvas.width / 3; + var x = width; + + // loading image + var image = new Image(); + /* tslint:disable:max-line-length */ + // 64 bit string encoding of the excalibur logo + image.src = 'data:image/png;base64,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'; + + /* tslint:enable:max-line-length */ + var imageHeight = width * 3 / 8; + var oldAntialias = this._engine.getAntialiasing(); + this._engine.setAntialiasing(true); + ctx.drawImage(image, 0, 0, 800, 300, x, y - imageHeight - 20, width, imageHeight); + + // loading box + ctx.strokeStyle = 'white'; + ctx.lineWidth = 2; + ctx.strokeRect(x, y, width, 20); + + var progress = width * (this._numLoaded / this._resourceCount); + ctx.fillStyle = 'white'; + var margin = 5; + var progressWidth = progress - margin * 2; + var height = 20 - margin * 2; + ctx.fillRect(x + margin, y + margin, progressWidth > 0 ? progressWidth : 0, height); + this._engine.setAntialiasing(oldAntialias); + } + + /** + * Perform any calculations or logic in the `update` method. The default `Loader` does not + * do anything in this method so it is safe to override. + */ + public update(engine: ex.Engine, delta: number) { + // overridable update + } + public getData: () => any = () => { return; }; public setData: (data: any) => any = (data) => { return; }; public processData: (data: any) => any = (data) => { return; }; - public onprogress: (e: any) => void = () => { return; }; + public onprogress: (e: any) => void = (e: any) => { + + Logger.getInstance().debug('[ex.Loader] Loading ' + (100 * e.loaded / e.total).toFixed(0)); + + return; + }; public oncomplete: () => void = () => { return; }; public onerror: () => void = () => { return; }; } + + /** + * A [[Loader]] that pauses after loading to allow user + * to proceed to play the game. Typically you will + * want to use this loader for iOS to allow sounds + * to play after loading (Apple Safari requires user + * interaction to allow sounds, even for games) + * + * **Note:** Because Loader is not part of a Scene, you must + * call `update` and `draw` manually on "child" objects. + * + * ## Implementing a Trigger + * + * The `PauseAfterLoader` requires an element to act as the trigger button + * to start the game. + * + * For example, let's create an `` tag to be our trigger and call it `tap-to-play`. + * + * ```html + * + * ``` + * + * We've put it inside a wrapper to position it properly over the game canvas. + * + * Now let's add some CSS to style it (insert into ``): + * + * ```html + * + * ``` + * + * Now we can create a `PauseAfterLoader` with a reference to our trigger button: + * + * ```ts + * var loader = new ex.PauseAfterLoader('tap-to-play', [...]); + * ``` + * + * ## Use PauseAfterLoader for iOS + * + * The primary use case for pausing before starting the game is to + * pass Apple's requirement of user interaction. The Web Audio context + * in Safari is disabled by default until user interaction. + * + * Therefore, you can use this snippet to only use PauseAfterLoader when + * iOS is detected (see [this thread](http://stackoverflow.com/questions/9038625/detect-if-device-is-ios) + * for more techniques). + * + * ```ts + * var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window).MSStream; + * var loader: ex.Loader = iOS ? new ex.PauseAfterLoader('tap-to-play') : new ex.Loader(); + * + * loader.addResource(...); + * ``` + */ + export class PauseAfterLoader extends Loader { + + private _loaded: boolean; + private _loadedValue: any; + private _waitPromise: Promise; + private _playTrigger: HTMLElement; + + constructor(triggerElementId: string, loadables?: ILoadable[]) { + super(loadables); + + this._playTrigger = document.getElementById(triggerElementId); + this._playTrigger.addEventListener('click', this._handleOnTrigger); + } + + public load(): Promise { + this._waitPromise = new ex.Promise(); + + // wait until user indicates to proceed before finishing load + var superLoad = super.load().then((value?) => { + this._loaded = true; + this._loadedValue = value; + + // show element + this._playTrigger.style.display = 'block'; + + }, (value?) => { + this._waitPromise.reject(value); + }); + + return this._waitPromise; + } + + private _handleOnTrigger = () => { + + if (this._waitPromise.state() !== PromiseState.Pending) { + return false; + } + + // unlock Safari WebAudio context + Internal.WebAudio.unlock(); + + // continue to play game + this._waitPromise.resolve(this._loadedValue); + + // hide DOM element + this._playTrigger.style.display = 'none'; + + return false; + }; + } } \ No newline at end of file diff --git a/src/engine/Resource.ts b/src/engine/Resources/Resource.ts similarity index 98% rename from src/engine/Resource.ts rename to src/engine/Resources/Resource.ts index b59ffcca4..7f0997e40 100644 --- a/src/engine/Resource.ts +++ b/src/engine/Resources/Resource.ts @@ -1,4 +1,4 @@ -/// +/// module ex { diff --git a/src/engine/Resources/Sound.ts b/src/engine/Resources/Sound.ts new file mode 100644 index 000000000..610694b2c --- /dev/null +++ b/src/engine/Resources/Sound.ts @@ -0,0 +1,211 @@ +/// +/// +/// +/// + +module ex { + + /** + * Sounds + * + * The [[Sound]] object allows games built in Excalibur to load audio + * components, from soundtracks to sound effects. [[Sound]] is an [[ILoadable]] + * which means it can be passed to a [[Loader]] to pre-load before a game or level. + * + * ## Pre-loading sounds + * + * Pass the [[Sound]] to a [[Loader]] to pre-load the asset. Once a [[Sound]] + * is loaded, you can [[Sound.play|play]] it. + * + * ```js + * // define multiple sources (such as mp3/wav/ogg) as a browser fallback + * var sndPlayerDeath = new ex.Sound("/assets/snd/player-death.mp3", "/assets/snd/player-death.wav"); + * + * var loader = new ex.Loader(sndPlayerDeath); + * + * game.start(loader).then(function () { + * + * sndPlayerDeath.play(); + * }); + * ``` + */ + export class Sound implements ILoadable, ex.Internal.ISound { + private _logger: Logger = Logger.getInstance(); + + public path: string; + + public onprogress: (e: any) => void = () => { return; }; + + public oncomplete: () => void = () => { return; }; + + public onerror: (e: any) => void = () => { return; }; + + public onload: (e: any) => void = () => { return; }; + + private _isLoaded: boolean = false; + + private _engine: Engine; + private _wasPlayingOnHidden: boolean = false; + + /** + * Populated once loading is complete + */ + public sound: ex.Internal.FallbackAudio; + + /** + * Whether or not the browser can play this file as HTML5 Audio + */ + public static canPlayFile(file: string): boolean { + try { + var a = new Audio(); + var filetype = /.*\.([A-Za-z0-9]+)$/; + var type = file.match(filetype)[1]; + if (a.canPlayType('audio/' + type)) { + return true; + } + { + return false; + } + } catch (e) { + ex.Logger.getInstance().warn('Cannot determine audio support, assuming no support for the Audio Tag', e); + return false; + } + } + + /** + * @param paths A list of audio sources (clip.wav, clip.mp3, clip.ogg) for this audio clip. This is done for browser compatibility. + */ + constructor(...paths: string[]) { + /* Chrome : MP3, WAV, Ogg + * Firefox : WAV, Ogg, + * IE : MP3, WAV coming soon + * Safari MP3, WAV, Ogg + */ + this.path = ''; + for(var i = 0; i < paths.length; i++) { + if(Sound.canPlayFile(paths[i])) { + this.path = paths[i]; + break; + } + } + + if(!this.path) { + this._logger.warn('This browser does not support any of the audio files specified:', paths.join(', ')); + this._logger.warn('Attempting to use', paths[0]); + this.path = paths[0]; // select the first specified + } + + this.sound = new ex.Internal.FallbackAudio(this.path, 1.0); + } + + public wireEngine(engine: Engine) { + if (engine) { + this._engine = engine; + this._engine.on('hidden', () => { + if (engine.pauseAudioWhenHidden && this.isPlaying()) { + this._wasPlayingOnHidden = true; + this.pause(); + } + }); + + this._engine.on('visible', () => { + if (engine.pauseAudioWhenHidden && this._wasPlayingOnHidden) { + this.play(); + this._wasPlayingOnHidden = false; + } + }); + } + } + + /** + * Sets the volume of the sound clip + * @param volume A volume value between 0-1.0 + */ + public setVolume(volume: number) { + if (this.sound) { this.sound.setVolume(volume); } + } + + /** + * Indicates whether the clip should loop when complete + * @param loop Set the looping flag + */ + public setLoop(loop: boolean) { + if (this.sound) { this.sound.setLoop(loop); } + } + + /** + * Whether or not the sound is playing right now + */ + public isPlaying(): boolean { + if (this.sound) { return this.sound.isPlaying(); } + } + + /** + * Play the sound, returns a promise that resolves when the sound is done playing + */ + public play(): ex.Promise { + if (this.sound) { return this.sound.play(); } + } + + /** + * Stop the sound, and do not rewind + */ + public pause() { + if (this.sound) { this.sound.pause(); } + } + + /** + * Stop the sound and rewind + */ + public stop() { + if (this.sound) { this.sound.stop(); } + } + + /** + * Returns true if the sound is loaded + */ + public isLoaded() { + return this._isLoaded; + } + + /** + * Begins loading the sound and returns a promise to be resolved on completion + */ + public load(): Promise { + var complete = new Promise(); + + if (this.sound.getData() !== null) { + this._logger.debug('Already have data for resource', this.path); + complete.resolve(this.sound); + return complete; + } + + this._logger.debug('Started loading sound', this.path); + this.sound.onprogress = this.onprogress; + this.sound.onload = () => { + this.oncomplete(); + this._isLoaded = true; + this._logger.debug('Completed loading sound', this.path); + complete.resolve(this.sound); + }; + this.sound.onerror = (e) => { + this.onerror(e); + complete.resolve(e); + }; + this.sound.load(); + return complete; + } + + public getData(): any { + return this.sound.getData(); + } + + public setData(data: any) { + this.sound.setData(data); + } + + public processData(data: any): any { + return this.sound.processData(data); + } + } +} \ No newline at end of file diff --git a/src/engine/Resources/Texture.ts b/src/engine/Resources/Texture.ts new file mode 100644 index 000000000..864dc8c35 --- /dev/null +++ b/src/engine/Resources/Texture.ts @@ -0,0 +1,117 @@ +/// +/// +/// +/// + +module ex { + + + /** + * Textures + * + * The [[Texture]] object allows games built in Excalibur to load image resources. + * [[Texture]] is an [[ILoadable]] which means it can be passed to a [[Loader]] + * to pre-load before starting a level or game. + * + * Textures are the raw image so to add a drawing to a game, you must create + * a [[Sprite]]. You can use [[Texture.asSprite]] to quickly generate a Sprite + * instance. + * + * ## Pre-loading textures + * + * Pass the [[Texture]] to a [[Loader]] to pre-load the asset. Once a [[Texture]] + * is loaded, you can generate a [[Sprite]] with it. + * + * ```js + * var txPlayer = new ex.Texture("/assets/tx/player.png"); + * + * var loader = new ex.Loader(txPlayer); + * + * game.start(loader).then(function () { + * + * var player = new ex.Actor(); + * + * player.addDrawing(txPlayer); + * + * game.add(player); + * }); + * ``` + */ + export class Texture extends Resource { + + /** + * The width of the texture in pixels + */ + public width: number; + + /** + * The height of the texture in pixels + */ + public height: number; + + /** + * A [[Promise]] that resolves when the Texture is loaded. + */ + public loaded: Promise = new Promise(); + + private _isLoaded: boolean = false; + private _sprite: Sprite = null; + + /** + * Populated once loading is complete + */ + public image: HTMLImageElement; + + private _progressCallback: (progress: number, total: number) => void; + private _doneCallback: () => void; + private _errorCallback: (e: string) => void; + + /** + * @param path Path to the image resource + * @param bustCache Optionally load texture with cache busting + */ + constructor(public path: string, public bustCache = true) { + super(path, 'blob', bustCache); + this._sprite = new Sprite(this, 0, 0, 0, 0); + } + + + /** + * Returns true if the Texture is completely loaded and is ready + * to be drawn. + */ + public isLoaded(): boolean { + return this._isLoaded; + } + + /** + * Begins loading the texture and returns a promise to be resolved on completion + */ + public load(): Promise { + var complete = new Promise(); + + var loaded = super.load(); + loaded.then(() => { + this.image = new Image(); + this.image.addEventListener('load', () => { + this._isLoaded = true; + this.width = this._sprite.swidth = this._sprite.naturalWidth = this._sprite.width = this.image.naturalWidth; + this.height = this._sprite.sheight = this._sprite.naturalHeight = this._sprite.height = this.image.naturalHeight; + this.loaded.resolve(this.image); + complete.resolve(this.image); + }); + this.image.src = super.getData(); + + + }, () => { + complete.reject('Error loading texture.'); + }); + return complete; + } + + public asSprite(): Sprite { + return this._sprite; + } + + } +} \ No newline at end of file diff --git a/src/engine/Sound.ts b/src/engine/Sound.ts index 0e11931b2..85691a2ae 100644 --- a/src/engine/Sound.ts +++ b/src/engine/Sound.ts @@ -386,5 +386,44 @@ module ex.Internal { } } } + + private static _unlocked: boolean = false; + + /** + * Play an empty sound to unlock Safari WebAudio context. Call this function + * right after a user interaction event. Typically used by [[PauseAfterLoader]] + * @source https://paulbakaus.com/tutorials/html5/web-audio-on-ios/ + */ + static unlock() { + + if (this._unlocked || !audioContext) { + return; + } + + // create empty buffer and play it + var buffer = audioContext.createBuffer(1, 1, 22050); + var source = audioContext.createBufferSource(); + source.buffer = buffer; + source.connect(audioContext.destination); + + if (source.noteOn) { + source.noteOn(0); + } else { + source.start(0); + } + + // by checking the play state after some time, we know if we're really unlocked + setTimeout(function() { + if (source.playbackState === source.PLAYING_STATE || + source.playbackState === source.FINISHED_STATE) { + this._unlocked = true; + } + }, 0); + + } + + static isUnlocked() { + return this._unlocked; + } } } \ No newline at end of file