1
0
mirror of https://github.com/rockam/xgamejs synced 2024-12-26 13:59:19 +01:00

first project upload

This commit is contained in:
Víctor Hernández Molpeceres 2015-11-21 17:29:35 +01:00
commit f720fa90b0
89 changed files with 10629 additions and 0 deletions

BIN
images/ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

BIN
images/cerbero.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
images/cerdo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 KiB

BIN
images/enemy1_anim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
images/fairy_anim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
images/fairy_anim2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
images/game_over_screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
images/help.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

BIN
images/interfaz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
images/pearl_anim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
images/punch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
images/rayman_anim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

BIN
images/room.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

BIN
images/shield_anim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
images/test_sprite.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

BIN
images/vaca.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
images/water_particle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 583 B

BIN
images/win_screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

2010
maps/level1.json Normal file

File diff suppressed because one or more lines are too long

BIN
maps/level1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 KiB

154
maps/level1.tmx Normal file
View File

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="256" height="64" tilewidth="16" tileheight="16" backgroundcolor="#bbfaff" nextobjectid="160">
<tileset firstgid="1" name="RA_DreamForestTileset" tilewidth="16" tileheight="16" spacing="1" margin="1">
<image source="../images/tilesets/RA_DreamForestTileset.png" trans="f800f8" width="1006" height="583"/>
</tileset>
<tileset firstgid="2007" name="RA_DreamForestTileset_3" tilewidth="16" tileheight="16">
<image source="../images/tilesets/RA_DreamForestTileset_3.png" trans="709ad1" width="943" height="1023"/>
</tileset>
<layer name="Fondo" width="256" height="64">
<data encoding="base64" compression="zlib">
eJzt3Qe0VNWhBuChXHoTG1WjeYn0jh3pvUm3Ji8WkKp5SV5Uegepdo1YkK4xiUrvRaomdo0aC5ZoXpQq3ZJvHrjW9XoRZpgCl/2v9S3Gw71nzpyZfzjnzJ5tJBISEhISkq40KBCJNKQRjWlCU5rRnBa0LJDurQwJCUlGbg/dDgkJCQkJCQkJCTlpUqFgurcgJCQkXbku9D/kBE12161DYssU/X/40HvAo/58jKk8zjSmMyO8R4SE5MhEr//3ZwADGcRghjCUYQwP76shITkyc3V7HvNZwEIWsZglLGVZ6H9ISI7MFt3eyja2s4OdfMkudrMn9D8khyWMeTuY6PX/ilSiMlWoSjWqU4Oa4fw/5ARLL6/Z3j/yug3nvAcTvf5/PTdwI93pwU30LHjk/RgSkq5kvW79XY7munU45z2Y767/P1IwXP8POXkSznkPJlz/DzkZE855DyZc/w85GXOs57zxXj98t0gk8h7v8wGb+ZCP+JhP+Cef8hn/KpL4x5454fp/yMmYYz3njfeY+cyikUgpSlOGspSjfNHEP8ajSazX/3d7P9rDXvaxnwNJfo8KCTneEu8xcwc970gnOtOFrnRLU/9jvf5fw3bWpBa1qUPdNG17SEi6Eu8x8zhdGc8EJjKJyWnsT6zX/3vZ1t70oS/9uDn0P+QkS7zXD9fqyjrWs4GNbOJ5XsimRy8nuVuxzv8z3fbMYCazmM2c0P+QkyzxXj/8NtqVYpFILnKTh7xkkI/8FKAghShcLLmPY26M/X/P9r/PB2zmQz4K/Q85yRLv9cOL9PliLuFS6nEZ9WlAQxrRmCY0TXL/t8TY/1K2pzRlKEs5yid5G0NCckp+oyu/5Xf8L7/nVm7jdvozgIEMYnCSuxXr/D8dbU8nOtOFrnQL/Q8JOao8pSt/4s/8had5hmeZyzzms4CFLEpyt2Kd/2e87ZnARCYxmTtD/0NCjiqf6spn/Iv/4998zhdsYSvb2M4Odia5W1Oy9D+M/w9JdY63MXHJzDnFI5Fz+Sn/xc/4OedRgYpUojJVqFo8+/Ukap+F8f8h6c7xNiYumblan6/hWn7BL/lvfsV1XM8N3Eh3ehym/4naZ2H8f0i6c7yNiUtm7tXn+7ifB3iQP/AQU3iYR3iUx5h6mP4nap+F8f8h6c7xNiYumXlRn1/iZV7hVV7jdd7gTf7OW7zNO4fpf6L2WZj/JyTdScSYuFaFIpHWtKEt7WjP5XSgI50KJf+xHCkFS0QihShMEYpSjOKU4BRKciqncXqJ7NeTqHGEYf6fkHQnEWPiRuj2SEYxmjGM5Q7GMZ4Jx0H/G+tzE5rSjOa0oCWtaE0b2tKO9ofpf6LGEYb5f0LSnUSMiVuu2ytYySpWs4bnWMs61h8H/R+oz4MYzBCGMozhjGAkoxjNGMYepv+JGkcYrv+HpDuJGBO3V7f3sZ8DfMXXfMO30d4X9m9l4ZQ/tB9kgT4vZBGLWcJSlrGcFaxkFatZc5j+J2ocYbzX/1sfB++lITkjiRgTV0u3a1OHupzPBVzIRVzMJZn6f6LPY5GocYTh+n9IupOIMXF9dLsv/biZW/g1/8Nv+C2/y9T/E30ei0SNIwzX/0PSnUSMiZup27OYzRye4En+yFP8iT9n6n+s81i86tjgNV7nDd7k77zF27yT4mOHRI0jDNf/Q9KdRI2Ji+Zoj+tjnceiqL8rRnFKcAolOZXTOD3Fxw6J2mfh+n9IupOoMXHRHO1xfazzWDT3dy1oSSta04a2tKN9ivufyH0WEpLOJGpMXDRHe1wf6zwWQ61jGMMZwUhGMZoxjE1x/xO5z0JC0plEjYmL5miP62Odx2KJdSxlGctZwUpWsZo1Ke5/IvdZSEg6E8+YuMOd2x/tcX2s81jsso7d7GEv+9jPAb7i6xT3P1HjCKNpUCD8/5BD0pd4xsQd7tw+WfPTVbeOGtSkFrWpQ13O54IE3EcsSdQ4wmjCGMCQdCaeMXGHO7dP1vx0Pa2jF73pQ1/6cTO38OsU9z9R4wijCXMAhJwIOZpz+2TNTzfNOqYzg5nMYjZzeIInU9z/RCaeMYBH+q5lSEiik86559/V7/d4nw/YzId8xMd8cgL3P54xgEf6rmVISKKTzrnnzyzu/ilNGcpSjvKcxdkn8Odr8YwBPNJ3LUNCEp10zj3fQb870onOdKEr3biCK4ufuN8pimcM4JG+axkSkuikc+75cfo9nglMZBKTuZO7uLt47N8pOiO34wpKUZoyuVPzWBKRI33XMiQkJ2Wtfq9jPRvYyCae5wX+Wjz27xR10PeOdKIzXdLc/1jGABzpu5YhJ2fuyRuJ3Mt93M8DPJj34N89lDe925bsxPqdovH6PoGJTGJymvsfxgCEHEv+pt8v8hIv8wqv8hqv8wZv5uD3gFg+n1in6+vZwEY28TwvpPE9IIwBCIkn+TMikQIUpBCFKUJRilGcEpxCyYx0b23yEsvnE7nyRCK5yUNeMshHfgrkSe12f5cwD1BILGmgyw1pRGOa0JRmNKcFLWlFa9rQNgf3P9bPJ+rp+WXUpwEND/W+cZr6H+YBCokl/XV5AAMZxGCGMJRhDGcEIxnFaMbkgP5Xpko2y2P9fOJWPb+N2+nPAAYyiMEMYSjDUvR+EOYBCok3i/R6MUtYyjKWs4KVOaDzmdOdHtxEzzh+/2l9foZnmcs85rOAhSxiMUtYyrIU9T/MAxRyLNml57vZw172sZ8DOaz/U3mcaXH+/uf6/AVb2Mo2trODnXzJLnazh71pOh8ICYkntfJFIrWpQ9186d6axOQt3uYd/sG7x7Cu8/JGIhWoSCUqU4WqVKM6NahJLWrn4M9MQnJe+up8P27mliP0P/pxV/Sft+hLPHqYEP3x/EQvNUcPN78bThodRpviKTb+PyVzRSKnchqncwZnUorSlMn1/Z8/y3+fzU84h3Nz/XCd13mw13MDN9KdHtxET3rRmz70pd+h/qd6Xx3vz83JnuPt+ZlpA2Yxmzk8wZP8kaeyeR+4lHpcRn0a0JBGNKYJTWlGc1okYBsb6mOjbDqZNa39TBva0o72XE4HOtKJznShK90OrfNKf17F1VzDtT9yX4964h5jKo8zjenMYCazmM2cvKnfV6m4v794TTzNMzzLXOYxnwU55LgxWUlHd46UzZ6zD/mIj/mEf/Ipn2XzfP6eW7mN2+nPAAYyiMEMYSjDGM4IRjKK0YxhLHcwjvFMYGKW25MO3ecAfRzIIAYzhKEMy9TTkW6PYjRjGMsdjGM8E5jIJCZzJ3dxN/dwL/dxPw/wIH/gIaZkup+39fod/sG7vMf7fMDmLMf88eyrzPsm8+3s9tWkLMuT/dxE7+/fXhOf8wVb2Mo2trMj9P9Hk4rnJ5bfKevAoxzlOYuz+QnncC4/zf/D+3iGZ5nLPOazgIUsYjFLWMoylrOClaxiNWt4jrWsYz0b2Jjl9qbo+nVvAQtZxGKWsJRlLGcFK1nFatbwHGtZx3o2sJFNPM8L/JW/8SIv8TKv8Cqv8Tpv8GaW44EzHLidSSlKU4aylKM8Z3F2Rnz7KvO+yXw7u321KcvyZD830fv7udfEeVSgIpWoTBWqUo3q1KBmWPa9Zal4fmL5na62qRtXcCVXcTXXcC2/yP/D+/iCLWxlG9vZwU6+ZBe72cNe9rGfA3zF13zDt9Ei6VUucpOHvFluZ7CdHezkS3axmz3sZR/7OcBXfM03fBvtrJOtXOQmD3nJIB/5KUBBClGYIhSlGMUpwSmU5FTa6/TldKAjnehMF7rSjSu4kqsy4ttXmfdN5tvZ7auMLMuT/dxE7+9XXhPXcT03cCPd6cFN9KQXvekTln1vWSqen3h+J5blFahIJSpThapUozo1qEktalOHupzPBVzIRVzMJVxKPS6jfpbbDaLr17uqVKM6NahJLWpTh7qczwVcyEVczCVcSj0uoz4NaEgjGtOEpjSjOS1oSSta04a2tOMOnR7HeCYwkUlM5k7u4m7u4d6M+PZV5n2T+XZ2+6pBluXJfm6i9zfF6/hhHuFRHmMqjzON6cxgJrPCsu8tS8XzE8/vxLL8P6LQ/Y0=
</data>
</layer>
<layer name="Fondo2" width="256" height="64">
<data encoding="base64" compression="zlib">
eJzt3GlQlHUAx/FHwQsFQVROu7VX5YFyqfXKm0NOtUOtNyoCguDxMk9ATu1Oa6YEjxSvepWmAoKg2Uxp2qFy2OXxLm+uvrxohgyqZXefZeH3nfnMOI31f5z4LbuyzxqGUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllFJKKaWUUkoppZRSSimllLJHs90MYw4iEIkoRGMuYhDr5hxnKKUsbyPb24TNyEI2crAFucizwTbNOEMpZXnH2d4JnEQZylGBU6hElQ22acYZSinLu8/2HuAhGtGEZrSgtW2Xgzv+9+4OMYx7uI8HeIjGIbY9Qyll3yawvSBMxCQEIwShCEN4J9sc524Y4zEBQZiISe62PUMpZd+S2V4KUrECaUjHSmQgs5NtJrH15UhGClKxopP9d/UMpVT3rJitl2AXdmMP9nayf6VUz+oqW69FHerRgGvav1K9Il8Pw/CDPwIQiFEe5l7DlSE8DqEWdahHQyd/B6mUsl2xbD0O8UhAIuaZvH8fnm/4wg/+CECgnoMoZffy2Ho+ClCIImw1ef8xbD0WcYhHAhK1f+UEebkaxjB4uzrm/PM8T76A73ARl/A9fsCP+MkJnkfnsvU85KMAhSiy0f693Pj/A28MxwiMhA989X4lZWUR7D4SUYjGXMSY+Fjgzk48MBSe8MIweGM4RjjB99FKrrEKp1GNGpyx0XXrfgVlz7LYejZysAW5yEO+SY8BM9jJTMzCbMxBBCIRhWgn2H9r2zXymqMP+sIFrjZ6DaL7FZS9KmPj5ajAKVSiCqdRbdL+17Gd9diAjdiEzchCNnKcYP9t9RnI9uEC14G2++/qfoWe2Q32ddNBr7nbauTsJjSjBa1t19KPr2P0hQtc+9n/Oo6y72P4EsdxAidRhnJUOMn+J7P5KZiKF2y4f92v0PN6hl2NxhgT9tVZwZwdglCEIRyTMQVT8QJeNOH67rDvu7iH+3iAh2hEE5qdZP+r2PxqrMFaG+5f9yv0rBayqUVYjNfwugMeA9I4Mx0rkYFMrMJqrMFaE69pLK+Tx2E8JiAIEzEJwQgx+Wd5Xe0gmz+Ewzhiw/3rfoWe1fts6wNsxw58iI8c8BiwnzNLcQAHcQiHcQSfmXg9y9h3EpYjGSlIxQqkId1J9n+dzd/ATdyy4f5Vz+k8u7qA73ARl/A9fnDg64DrnH0DN3HLAdexk30XowS7sBt7sBefYp+T7P/pQbyuw2iMGeToq1HdIbf+hjEYQ+AODwyFJ7wwDN4YjhH9HXONz3DuaIzBsw64hivs+ypqUYd6NOAafsYvTrL/V9n8QizCYu2/w5a4GMZSLEOSi6Ovxv5NY0/TMQMzMQuzMQcRiEQUotvtLpZfxyEeCSbu8TUrz+roHpj/k89Qw/CFH/wRgECMwmN4fKh112VW77L59/A+PtD+/9HH7P0T7EQxSnrB/v9qPdvagI3YhM3IQjZysKXd9vL5dQEKUWTS/rdzzg58aMV5Xb0HJoZ9xyIO8UhAIuZhPhY8sv8/BhjGbdzBXdzDfTzAQzSiCc1oQSsMC16PW/J5Yu37hs1/i/O4oP3/o8vs/QquohZ1qEdDL3gc+JJdHccJnEQZylGBU6hEFU6jGjUmPw+/yHmXrDyzq/fA5LLvPOSjAIUowlZsw5uP7P85tvw8xmIcxmMCgjARkxCMEIQiDOEW7N+SzxNr32A3XufBHR42fF/Ofv78pZ08B/qMf/65kzw/8nHl+wP84I8ABGKUA98D44ga2VkTmtGC1rbd8T2qD/rCBa4DzL0mL84bBm8rzu3qPTCVfP1W4TSqUYMzOIuvcO6Rr+8lbHkpliEJy5GMFKRiBdKQjpXIQKYF+7fk88TaN43NT8cMzLTh/n/lz/+bk2z834pl53GIRwISMQ/ze9n+g9lYCEIRhnBMxhRMNXn3fxXBuZGIsuL8ju6B+T+1tn1te/L4h75wgSv6oT8GeP7993/Mlj/BThSjBLuwG3uwF59iH/ajFAcs2L81nyf2Brtfh/U23P8Tnv/9ezqqrB/PMVHhwJ8tPVoBWy9EEbZiWy/bfhr7SsdKZCATq7Aaaxy0/bayODsbOVZcQ0f3wNijn9jyZVzBVdSiDvVowDX8jF/wK37D7xbs35rPE/uC3R/FsW7wvvwmdt+Mlm60/xr2fgZn8RXO4ete9Biwj33tRykO4CAO4TCOOGj/ZZxbjgqcQmUXryOMvYdjMqZgqp32P2KQYYyED3zhB38EIBCj8BgexxN4Ek9Z8Pdx1nye2G12fwd3u8H+Q3hdGYowB/1cWfWuMthIJlZhNdbYaf/RbHkuYhCLOMQjAYmYh/lYgJfwMl6xYP/WfJ7Y84MNYyzG6X25qpdVykYO4CAO4bCd9p/DlrcgF3nIRwEKUYSt2IY38RbexjsW7N+azxNbyu6XIakH7f9POCvieg==
</data>
</layer>
<objectgroup color="#000000" name="Platforms">
<object id="3" x="2" y="987" width="443" height="13"/>
<object id="4" x="483" y="979" width="42" height="16"/>
<object id="5" x="529" y="985" width="75" height="13"/>
<object id="7" x="606" y="978" width="33" height="14"/>
<object id="8" x="630" y="970" width="39" height="12"/>
<object id="9" x="647" y="960" width="37" height="13"/>
<object id="10" x="662" y="950" width="43" height="12"/>
<object id="11" x="683" y="941" width="83" height="14"/>
<object id="12" x="757" y="949" width="27" height="18"/>
<object id="13" x="775" y="956" width="32" height="17"/>
<object id="14" x="801" y="965" width="24" height="20"/>
<object id="15" x="813" y="977" width="40" height="15"/>
<object id="16" x="848" y="983" width="125" height="14"/>
<object id="17" x="881" y="944" width="35" height="13"/>
<object id="18" x="997" y="915" width="195" height="13"/>
<object id="19" x="1014" y="903" width="165" height="12"/>
<object id="20" x="1030" y="893" width="119" height="13"/>
<object id="21" x="843" y="836" width="71" height="12"/>
<object id="22" x="704" y="753" width="61" height="13"/>
<object id="23" x="702" y="674" width="121" height="12"/>
<object id="24" x="715" y="617" width="80" height="14"/>
<object id="25" x="199" y="737" width="80" height="13"/>
<object id="26" x="342" y="675" width="82" height="9"/>
<object id="27" x="505" y="623" width="77" height="17"/>
<object id="28" x="323" y="528" width="116" height="14"/>
<object id="30" x="191.333" y="611.333" width="43.3333" height="12.6667"/>
<object id="31" x="165.333" y="615.333" width="28" height="10"/>
<object id="32" x="48.6667" y="606" width="60" height="14"/>
<object id="33" x="96" y="598" width="36" height="13.3333"/>
<object id="34" x="124" y="605.333" width="32.6667" height="10.6667"/>
<object id="35" x="147.333" y="610" width="21.3333" height="12.6667"/>
<object id="36" x="82" y="601.333" width="22.6667" height="11.3333"/>
<object id="37" x="48.6667" y="460" width="65.3333" height="12.6667"/>
<object id="39" x="496.667" y="228" width="121.333" height="13.3333"/>
<object id="40" x="753" y="307" width="121" height="15"/>
<object id="41" x="992" y="295" width="68" height="14"/>
<object id="42" x="992" y="443" width="50" height="16"/>
<object id="43" x="1138" y="446" width="39" height="13"/>
<object id="44" x="1109" y="454" width="34" height="12"/>
<object id="45" x="1033" y="436" width="46" height="14"/>
<object id="46" x="1074" y="444" width="27" height="10"/>
<object id="47" x="1095" y="450" width="21" height="14"/>
<object id="48" x="1281" y="459" width="64" height="12"/>
<object id="49" x="1280" y="606" width="52" height="13"/>
<object id="50" x="1313" y="595" width="32" height="17"/>
<object id="51" x="1340" y="597" width="33" height="15"/>
<object id="52" x="1365" y="604" width="37" height="15"/>
<object id="53" x="1397" y="614" width="35" height="15"/>
<object id="54" x="1424" y="604" width="42" height="16"/>
<object id="56" x="1570" y="262" width="122" height="10"/>
<object id="60" x="1569" y="450" width="124" height="14"/>
<object id="62" x="1567" y="550" width="124" height="12"/>
<object id="64" x="1585" y="707" width="122" height="17"/>
<object id="65" x="1777" y="746" width="121" height="14"/>
<object id="66" x="1601" y="836" width="121" height="12"/>
<object id="67" x="1265" y="881" width="47" height="11"/>
<object id="68" x="1486" y="895" width="46" height="15"/>
<object id="70" x="1349" y="873" width="90" height="13"/>
<object id="71" x="1199" y="991" width="847" height="17"/>
<object id="88" x="1573" y="163" width="113" height="15"/>
<object id="92" x="486" y="985" width="190" height="9"/>
<object id="93" x="784" y="978" width="62" height="20"/>
<object id="94" x="663" y="970" width="148" height="18"/>
<object id="109" x="3314.67" y="995.333" width="776.667" height="16"/>
<object id="122" x="2224" y="922" width="67" height="14"/>
<object id="123" x="2448" y="896" width="64" height="16"/>
<object id="124" x="2445" y="813" width="120" height="16"/>
<object id="125" x="2458" y="760" width="83" height="16"/>
<object id="126" x="2481" y="590" width="119" height="17"/>
<object id="127" x="2695" y="674" width="81" height="21"/>
<object id="128" x="2704" y="967" width="78" height="16"/>
<object id="129" x="2727" y="960" width="57" height="13"/>
<object id="130" x="2743" y="952" width="43" height="13"/>
<object id="131" x="2635" y="1003" width="42" height="17"/>
<object id="132" x="2051" y="994" width="83" height="17"/>
<object id="134" x="2050" y="981" width="69" height="15"/>
<object id="135" x="2062" y="974" width="42" height="10"/>
<object id="136" x="3015" y="979" width="79" height="14"/>
<object id="138" x="3231" y="714" width="67" height="15"/>
<object id="139" x="2881" y="588" width="122" height="16"/>
<object id="140" x="3586" y="780" width="121" height="20"/>
<object id="141" x="3858" y="843" width="52" height="19"/>
<object id="142" x="3899" y="824" width="49" height="19"/>
<object id="143" x="3940" y="811" width="110" height="21"/>
<object id="157" x="1751" y="353" width="80" height="12"/>
</objectgroup>
<objectgroup color="#37ff00" name="Player">
<object id="72" x="178" y="867" width="74" height="72"/>
</objectgroup>
<objectgroup color="#002eff" name="PickableObjects">
<object id="75" name="PEARL" x="843" y="751" width="74" height="72"/>
<object id="77" name="ETERNAL_FLY" x="1592" y="185" width="74" height="72"/>
<object id="78" name="SHIELD" x="1283" y="355" width="74" height="72"/>
<object id="79" name="PUNCH_SPEED" x="779" y="208" width="74" height="72"/>
<object id="95" name="PEARL" x="341" y="435" width="74" height="72"/>
<object id="96" name="PEARL" x="46" y="361" width="74" height="72"/>
<object id="97" name="PEARL" x="524" y="890" width="74" height="72"/>
<object id="98" name="PEARL" x="1060" y="800" width="74" height="72"/>
<object id="99" name="PEARL" x="1610" y="624" width="74" height="72"/>
<object id="100" name="PEARL" x="1358" y="779" width="74" height="72"/>
<object id="102" name="PEARL" x="1608" y="371" width="74" height="72"/>
<object id="103" name="PEARL" x="1075" y="351" width="74" height="72"/>
<object id="104" name="PEARL" x="53" y="899" width="74" height="72"/>
<object id="111" name="PEARL" x="2219" y="833.333" width="74" height="72"/>
<object id="112" name="PEARL" x="2460.33" y="674.667" width="74" height="72"/>
<object id="113" name="PEARL" x="2504.33" y="500" width="74" height="72"/>
<object id="114" name="PEARL" x="2709.67" y="861.333" width="74" height="72"/>
<object id="115" name="PEARL" x="3020.33" y="889.333" width="74" height="72"/>
<object id="116" name="PEARL" x="3224.33" y="624" width="74" height="72"/>
<object id="117" name="PEARL" x="2908.33" y="502.667" width="74" height="72"/>
<object id="118" name="PEARL" x="3929.67" y="713.333" width="74" height="72"/>
<object id="119" name="PEARL" x="4007" y="908" width="74" height="72"/>
<object id="120" name="PEARL" x="3549.67" y="912" width="74" height="72"/>
<object id="121" name="PEARL" x="3611" y="689.333" width="74" height="72"/>
<object id="155" name="SHIELD" x="2699" y="576" width="74" height="72"/>
<object id="156" name="SHIELD" x="3813.67" y="756" width="74" height="72"/>
</objectgroup>
<objectgroup color="#ff4000" name="Enemys">
<object id="82" x="1603" y="898" width="74" height="72"/>
<object id="83" x="1383" y="485" width="74" height="72"/>
<object id="84" x="520" y="142" width="74" height="72"/>
<object id="86" x="688" y="847" width="74" height="72"/>
<object id="87" x="720" y="521" width="74" height="72"/>
<object id="147" x="2698" y="568" width="74" height="72"/>
<object id="148" x="2451" y="809" width="74" height="72"/>
<object id="149" x="3369" y="905" width="74" height="72"/>
<object id="150" x="3942" y="903" width="74" height="72"/>
<object id="151" x="3634" y="663" width="74" height="72"/>
<object id="152" x="3732.33" y="913" width="74" height="72"/>
<object id="153" x="3957" y="721" width="74" height="72"/>
</objectgroup>
<objectgroup color="#ffff00" name="Win">
<object id="159" x="3813.67" y="941.667" width="37.6667" height="51.3333"/>
</objectgroup>
</map>

Binary file not shown.

BIN
sounds/Rayman/flying.wav Normal file

Binary file not shown.

BIN
sounds/Rayman/game_over.mp3 Normal file

Binary file not shown.

Binary file not shown.

BIN
sounds/Rayman/idle.wav Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
sounds/Rayman/song.mp3 Normal file

Binary file not shown.

BIN
sounds/Rayman/win_level.wav Normal file

Binary file not shown.

BIN
sounds/test_song.mp3 Normal file

Binary file not shown.

BIN
sounds/test_sound1.wav Normal file

Binary file not shown.

BIN
sounds/test_sound2.WAV Normal file

Binary file not shown.

BIN
sounds/test_sound3.WAV Normal file

Binary file not shown.

50
src/HTML/Demo_Balls.html Normal file
View File

@ -0,0 +1,50 @@
<!doctype html>
<meta charset="UTF-8">
<title>Ball physics simulation</title>
<!-- The canvas -->
<canvas width="800" height="600" style="border:3px solid #000; margin:5px auto;">
No canvas supported
</canvas>
<form style="position:absolute; top:16px; left:832px;">
<input type="button" id="generate" value="Generate ball">
<br>
<input type="checkbox" name="gravity" id="gravity" value="ON">Gravedad
<br>
<input type="radio" name="gravityDir" id="gravityDir" value="0" checked disabled>Down
<br>
<input type="radio" name="gravityDir" id="gravityDir" value="1" disabled>Up
<br>
<input type="radio" name="gravityDir" id="gravityDir" value="2" disabled>Left
<br>
<input type="radio" name="gravityDir" id="gravityDir" value="3" disabled>Right
<br>
<input type="button" id="reset" value="Remove all balls">
</form>
<!-- The game code -->
<script src="../JS/XgameJS/requestAnimationFramePolyfill.js"></script>
<script src="../JS/XgameJS/Sprite.js"></script>
<script src="../JS/XgameJS/AnimatedSprite.js"></script>
<script src="../JS/XgameJS/Ball.js"></script>
<script src="../JS/XgameJS/Circle.js"></script>
<script src="../JS/XgameJS/GameStates.js"></script>
<script src="../JS/XgameJS/GravityDirections.js"></script>
<script src="../JS/Demo_Balls.js"></script>
<!-- XNA -->
<script src="../JS/XNA_Classes/ContentManager.js"></script>
<script src="../JS/XNA_Classes/GraphicsDevice.js"></script>
<script src="../JS/XNA_Classes/Keyboard.js"></script>
<script src="../JS/XNA_Classes/Keys.js"></script>
<script src="../JS/XNA_Classes/Mouse.js"></script>
<script src="../JS/XNA_Classes/Point.js"></script>
<script src="../JS/XNA_Classes/Program.js"></script>
<script src="../JS/XNA_Classes/Rectangle.js"></script>
<script src="../JS/XNA_Classes/Song.js"></script>
<script src="../JS/XNA_Classes/SoundEffect.js"></script>
<script src="../JS/XNA_Classes/SpriteBatch.js"></script>
<script src="../JS/XNA_Classes/SpriteEffects.js"></script>
<script src="../JS/XNA_Classes/Texture2D.js"></script>
<script src="../JS/XNA_Classes/Vector2.js"></script>

44
src/HTML/Rayman.html Normal file
View File

@ -0,0 +1,44 @@
<!doctype html>
<meta charset="UTF-8">
<title>Rayman Demo XgameJS</title>
<!-- The canvas -->
<canvas width="800" height="600" style="border:3px solid #000; margin:4px auto;">
No canvas supported on this browser :(
</canvas>
<!-- The game code -->
<script src="../JS/XgameJS/requestAnimationFramePolyfill.js"></script>
<script src="../JS/XgameJS/Sprite.js"></script>
<script src="../JS/XgameJS/AnimationTypes.js"></script>
<script src="../JS/Rayman_Classes/Ball.js"></script>
<script src="../JS/XgameJS/Camera.js"></script>
<script src="../JS/XgameJS/Circle.js"></script>
<script src="../JS/Rayman_Classes/Enemy.js"></script>
<script src="../JS/Rayman_Classes/Enums.js"></script>
<script src="../JS/XgameJS/GameStates.js"></script>
<script src="../JS/XgameJS/GravityDirections.js"></script>
<script src="../JS/Rayman_Classes/Level.js"></script>
<script src="../JS/XgameJS/PickableObject.js"></script>
<script src="../JS/Rayman_Classes/Player.js"></script>
<script src="../JS/XgameJS/Polygon.js"></script>
<script src="../JS/Rayman_Classes/Projectile.js"></script>
<script src="../JS/XgameJS/Segment.js"></script>
<script src="../JS/XgameJS/AnimatedSprite.js"></script>
<script src="../JS/Rayman.js"></script>
<!-- XNA -->
<script src="../JS/XNA_Classes/ContentManager.js"></script>
<script src="../JS/XNA_Classes/GraphicsDevice.js"></script>
<script src="../JS/XNA_Classes/Keyboard.js"></script>
<script src="../JS/XNA_Classes/Keys.js"></script>
<script src="../JS/XNA_Classes/Mouse.js"></script>
<script src="../JS/XNA_Classes/Point.js"></script>
<script src="../JS/XNA_Classes/Program.js"></script>
<script src="../JS/XNA_Classes/Rectangle.js"></script>
<script src="../JS/XNA_Classes/Song.js"></script>
<script src="../JS/XNA_Classes/SoundEffect.js"></script>
<script src="../JS/XNA_Classes/SpriteBatch.js"></script>
<script src="../JS/XNA_Classes/SpriteEffects.js"></script>
<script src="../JS/XNA_Classes/Texture2D.js"></script>
<script src="../JS/XNA_Classes/Vector2.js"></script>

View File

@ -0,0 +1,32 @@
<!doctype html>
<meta charset="UTF-8">
<title>Test for GraphicsDevice and AnimatedSprite</title>
<!-- The canvas -->
<canvas width="800" height="600" style="border:3px solid #000; margin:5px auto;">
No canvas supported
</canvas>
<!-- XgameJS -->
<script src="../JS/XgameJS/GameStates.js"></script>
<script src="../JS/XgameJS/Segment.js"></script>
<script src="../JS/XgameJS/Sprite.js"></script>
<script src="../JS/XgameJS/AnimatedSprite.js"></script>
<script src="../JS/XgameJS/AnimationTypes.js"></script>
<!-- XNA_Classes -->
<script src="../JS/XgameJS/requestAnimationFramePolyfill.js"></script>
<script src="../JS/XNA_Classes/GraphicsDevice.js"></script>
<script src="../JS/XNA_Classes/ContentManager.js"></script>
<script src="../JS/XNA_Classes/SpriteBatch.js"></script>
<script src="../JS/XNA_Classes/SpriteEffects.js"></script>
<script src="../JS/XNA_Classes/Mouse.js"></script>
<script src="../JS/XNA_Classes/Keyboard.js"></script>
<script src="../JS/XNA_Classes/Keys.js"></script>
<script src="../JS/XNA_Classes/Point.js"></script>
<script src="../JS/XNA_Classes/Vector2.js"></script>
<script src="../JS/XNA_Classes/Rectangle.js"></script>
<script src="../JS/XNA_Classes/Texture2D.js"></script>
<script src="../JS/XNA_Classes/SpriteEffects.js"></script>
<script src="../JS/Unit_Testing/Test_GraphicsDevice_AnimatedSprite.js"></script>
<script src="../JS/XNA_Classes/Program.js"></script>

View File

@ -0,0 +1,23 @@
<!doctype html>
<meta charset="UTF-8">
<title>Test Mouse and Keyboard</title>
<!-- The canvas -->
<canvas width="800" height="600" style="border:3px solid #000; margin:5px auto;">
No canvas supported
</canvas>
<!-- XNA_Classes -->
<script src="../JS/XgameJS/requestAnimationFramePolyfill.js"></script>
<script src="../JS/XNA_Classes/GraphicsDevice.js"></script>
<script src="../JS/XNA_Classes/ContentManager.js"></script>
<script src="../JS/XgameJS/GameStates.js"></script>
<script src="../JS/XNA_Classes/SpriteBatch.js"></script>
<script src="../JS/XNA_Classes/Mouse.js"></script>
<script src="../JS/XNA_Classes/Keyboard.js"></script>
<script src="../JS/XNA_Classes/Keys.js"></script>
<script src="../JS/XNA_Classes/Point.js"></script>
<script src="../JS/XNA_Classes/Vector2.js"></script>
<script src="../JS/Unit_Testing/Test_Mouse_Keyboard.js"></script>
<script src="../JS/XNA_Classes/Program.js"></script>

View File

@ -0,0 +1,25 @@
<!doctype html>
<meta charset="UTF-8">
<title>Test for Point, Vector2 and Rectangle classes</title>
<!-- The canvas -->
<canvas width="800" height="600" style="border:3px solid #000; margin:5px auto;">
No canvas supported
</canvas>
<!-- XNA_Classes -->
<script src="../JS/XgameJS/requestAnimationFramePolyfill.js"></script>
<script src="../JS/XNA_Classes/GraphicsDevice.js"></script>
<script src="../JS/XNA_Classes/ContentManager.js"></script>
<script src="../JS/XgameJS/GameStates.js"></script>
<script src="../JS/XgameJS/Segment.js"></script>
<script src="../JS/XNA_Classes/SpriteBatch.js"></script>
<script src="../JS/XNA_Classes/Mouse.js"></script>
<script src="../JS/XNA_Classes/Keyboard.js"></script>
<script src="../JS/XNA_Classes/Keys.js"></script>
<script src="../JS/XNA_Classes/Point.js"></script>
<script src="../JS/XNA_Classes/Vector2.js"></script>
<script src="../JS/XNA_Classes/Rectangle.js"></script>
<script src="../JS/Unit_Testing/Test_Point_Vector2_Rectangle.js"></script>
<script src="../JS/XNA_Classes/Program.js"></script>

View File

@ -0,0 +1,30 @@
<!doctype html>
<meta charset="UTF-8">
<title>Test for Song and SoundEffect</title>
<!-- The canvas -->
<canvas width="800" height="600" style="border:3px solid #000; margin:5px auto;">
No canvas supported
</canvas>
<!-- XNA_Classes -->
<script src="../JS/XgameJS/requestAnimationFramePolyfill.js"></script>
<script src="../JS/XNA_Classes/GraphicsDevice.js"></script>
<script src="../JS/XNA_Classes/ContentManager.js"></script>
<script src="../JS/XgameJS/GameStates.js"></script>
<script src="../JS/XNA_Classes/SpriteBatch.js"></script>
<script src="../JS/XNA_Classes/Mouse.js"></script>
<script src="../JS/XNA_Classes/Keyboard.js"></script>
<script src="../JS/XNA_Classes/Keys.js"></script>
<script src="../JS/XNA_Classes/Point.js"></script>
<script src="../JS/XNA_Classes/Vector2.js"></script>
<script src="../JS/XNA_Classes/Rectangle.js"></script>
<script src="../JS/XNA_Classes/Song.js"></script>
<script src="../JS/XNA_Classes/SoundEffect.js"></script>
<script src="../JS/XNA_Classes/Texture2D.js"></script>
<script src="../JS/XNA_Classes/SpriteEffects.js"></script>
<script src="../JS/XgameJS/Segment.js"></script>
<script src="../JS/XgameJS/Sprite.js"></script>
<script src="../JS/Unit_Testing/Test_Song_SoundEffect.js"></script>
<script src="../JS/XNA_Classes/Program.js"></script>

248
src/JS/Demo_Balls.js Normal file
View File

@ -0,0 +1,248 @@
/**
* Provides basic graphics device initialization, game logic, and rendering code.
*/
function Game() {
"use strict";
/*globals ContentManager, GraphicsDevice, document, SpriteBatch, GameStates, GravityDirections*/
this.Content = new ContentManager();
this.GraphicsDevice = new GraphicsDevice(document);
this.spriteBatch = null;
this.gameState = GameStates.Initializing;
//The HTML elements
this.generateButton = document.querySelector("#generate");
this.gravityCheckBox = document.querySelector("#gravity");
this.gravityDirRadioButtons = document.querySelectorAll("#gravityDir");
this.removeAllBallsButton = document.querySelector("#reset");
//The ball image
this.ballTexture = null;
//The room image
this.roomImage = null;
//The balls array
this.balls = [];
//The room Sprite
this.roomSprite = null;
//Gravity properties
this.gravityActivated = false;
this.gravityDir = GravityDirections.G_DOWN;
this.gravityForce = 0.4;
//Other
this.preloading = true;
}
/**
* Allows the game to perform any initialization it needs to before starting to run.
* This is where it can query for any required services and load any non-graphic
* related content.
* @name Initialize
* @function
* @memberOf Game
*/
Game.prototype.Initialize = function () {
"use strict";
/*globals GenerateBall*/
var self = this,
len,
i;
//Add the event listener to the generate ball button
self.generateButton.addEventListener("mousedown", self.GenerateBall.bind(self), false);
//Remove all the balls in the room if this button is pressed
self.removeAllBallsButton.addEventListener("mousedown", function (event) {
self.balls.splice(0, self.balls.length);
}, false);
//Enable or disable the radiobuttons depending on the gravity checkbox
self.gravityCheckBox.addEventListener("mousedown", function (event) {
if (self.gravityCheckBox.checked) {
self.gravityActivated = false;
for (i = 0, len = self.gravityDirRadioButtons.length; i < len; i += 1) {
self.gravityDirRadioButtons[i].disabled = true;
}
} else {
self.gravityActivated = true;
for (i = 0, len = self.gravityDirRadioButtons.length; i < len; i += 1) {
self.gravityDirRadioButtons[i].disabled = false;
}
}
}, false);
//Depending on which radiobutton is checked the gravity direction changes
for (i = 0, len = self.gravityDirRadioButtons.length; i < len; i += 1) {
self.gravityDirRadioButtons[i].addEventListener("mousedown", function (event) {
self.gravityDir = parseInt(this.value, 10);
}, false);
}
self.gameState = GameStates.Loading;
};
/**
* LoadContent will be called once per game and is the place to load
* all of your content.
* @name LoadContent
* @function
* @memberOf Game
*/
Game.prototype.LoadContent = function () {
"use strict";
/*globals Sprite, Rectangle, Point, Vector2*/
var self = this;
if (self.preloading) {
// Create a new SpriteBatch, which can be used to draw textures.
self.spriteBatch = new SpriteBatch(self.GraphicsDevice);
// TODO: use this.Content.Load... to load your game content here
self.ballTexture = self.Content.LoadTexture2D("../../images/ball.png");
self.roomImage = self.Content.LoadTexture2D("../../images/room.jpg");
self.preloading = false;
}
if (self.Content.AllContentLoaded()) {
//Create the room sprite and add it to the sprites list
self.roomSprite = new Sprite(self.roomImage, Vector2.One(),
new Rectangle(0, 0, self.roomImage.Width(), self.roomImage.Height()),
Point.Zero(), true
);
self.gameState = GameStates.Playing;
}
};
/**
* Allows the game to run logic such as updating the world,
* checking for collisions, gathering input, and playing audio.
* @name Update
* @function
* @memberOf Game
*/
Game.prototype.Update = function () {
"use strict";
var self = this,
len = self.balls.length,
i;
// TODO: Add your update logic here
if (len > 0) {
for (i = 0; i < len; i += 1) {
self.balls[i].Update(
self.GraphicsDevice.PreferredBackBufferWidth(),
self.GraphicsDevice.PreferredBackBufferHeight(),
self.balls,
self.gravityActivated,
self.gravityDir,
self.gravityForce
);
}
}
};
/**
* This is called when the game should draw itself.
* @name Draw
* @function
* @memberOf Game
*/
Game.prototype.Draw = function () {
"use strict";
/*globals Vector2, SpriteEffects*/
var self = this,
len = self.balls.length,
i,
auxSprite = null;
self.GraphicsDevice.Clear();
//Draw the room
self.spriteBatch.Draw(self.roomSprite.Texture,
Vector2.Zero(),
new Rectangle(0, 0, self.roomSprite.Width(), self.roomSprite.Height()), 0, self.roomSprite.Scale, SpriteEffects.None);
//Draw the balls
if (len > 0) {
for (i = 0; i < len; i += 1) {
auxSprite = self.balls[i].Sprite;
//console.log(self.balls[i].Sprite.Scale);console.log(auxSprite.Position.Y);
if (auxSprite.IsVisible) {
self.spriteBatch.Draw(
auxSprite.Texture,
auxSprite.Position,
new Rectangle(0, 0, auxSprite.Texture.Width(), auxSprite.Texture.Height()),
auxSprite.Rotation,
auxSprite.Scale,
SpriteEffects.None
);
}
}
}
};
Game.prototype.GenerateBall = function () {
"use strict";
/*globals Sprite, Ball, Rectangle, Point*/
//Create a ball with random scale
var self = this,
scale = (Math.floor(Math.random() * 20) + 10) / 100,
canvasWidth = self.GraphicsDevice.PreferredBackBufferWidth(),
canvasHeight = self.GraphicsDevice.PreferredBackBufferHeight(),
sprite = new Sprite(
self.ballTexture,
new Vector2(scale, scale),
new Rectangle(0, 0, self.ballTexture.Width(), self.ballTexture.Height()),
Point.Zero(),
true
),
position = new Point((canvasWidth / 2 - sprite.HalfWidth()), (canvasHeight / 2 - sprite.HalfHeight())),
ball = new Ball(
sprite,
sprite.HalfWidth(),
position,
self.balls.length,
true,
true
);
self.balls.push(ball);
};
/**
* Call this method to initialize the game, begin running the game loop, and
* start processing events for the game.
* @name Run
* @function
* @memberOf Game
*/
Game.prototype.Run = function () {
"use strict";
/*globals requestAnimationFrame*/
var self = this;
//Call the game loop
requestAnimationFrame(self.Run.bind(self), self.GraphicsDevice.canvas);
//Choose the method to run according to the game state
switch (self.gameState) {
case GameStates.Initializing:
self.Initialize();
break;
case GameStates.Loading:
self.LoadContent();
break;
case GameStates.Playing:
self.Update();
self.Draw();
break;
}
};

784
src/JS/Rayman.js Normal file
View File

@ -0,0 +1,784 @@
/**
* Provides basic graphics device initialization, game logic, and rendering code.
*/
function Game() {
"use strict";
/*globals ContentManager, GraphicsDevice, document, SpriteBatch, GameStates, setInterval, clearInterval, Mouse, SpriteEffects*/
this.Content = new ContentManager();
this.GraphicsDevice = new GraphicsDevice(document);
this.spriteBatch = null;
this.gameState = GameStates.Initializing;
this.preloading = true;
this.level = null;
this.sprites = [];
this.gravityForce = 0.3;
this.pearlsToCollect = 0;
//The images
this.levelTexture = null;
this.distantBackgroundTexture = null;
this.raymanTexture = null;
this.enemyTexture = null;
this.punchTexture = null;
this.flyPowerTexture = null;
this.punchSpeedTexture = null;
this.pearlTexture = null;
this.shieldTexture = null;
this.helpTexture = null;
this.gameOverTexture = null;
this.winTexture = null;
this.hudTexture = null;
//The song
this.song = null;
//Sound effects
this.soundEffects = [];
//Create the platforms, pickable objects and enemys arrays
this.platforms = [];
this.pickableObjects = [];
this.enemys = [];
//Create the player
this.player = null;
//Create the game camera
this.camera = null;
//The win zone rectangle
this.winRect = null;
//The help screen sprite
this.helpSprite = null;
//The game over screen sprite
this.gameOverSprite = null;
//The win screen sprite
this.winSprite = null;
//The win screen sprite
this.hudSprite = null;
//Flags
this.moveRight = false;
this.moveLeft = false;
this.jump = false;
this.punch = false;
this.showCollisions = false;
this.interval = null;
}
/**
* Allows the game to perform any initialization it needs to before starting to run.
* This is where it can query for any required services and load any non-graphic
* related content.
* @name Initialize
* @function
* @memberOf Game
*/
Game.prototype.Initialize = function () {
"use strict";
var self = this;
self.gameState = GameStates.Loading;
};
/**
* LoadContent will be called once per game and is the place to load
* all of your content.
* @name LoadContent
* @function
* @memberOf Game
*/
Game.prototype.LoadContent = function () {
"use strict";
/*globals Level, Sprite, Point, Rectangle, Vector2, PickableObject, AnimationTypes, PickableObjectTypes, AnimatedSprite, Enemy, Player, Projectile, Camera*/
var self = this,
distantBackgroundRepeats = 0,
i = 0,
len = 0,
currentPlatform = null,
currentObject = null,
currentEnemy = null,
objSprite = null,
type = null,
aux = 0;
if (self.preloading) {
// Create a new SpriteBatch, which can be used to draw textures.
self.spriteBatch = new SpriteBatch(self.GraphicsDevice);
//Textures
self.levelTexture = self.Content.LoadTexture2D("../../maps/level1.png");
self.distantBackgroundTexture = self.Content.LoadTexture2D("../../images/dream_forest_background.png");
self.raymanTexture = self.Content.LoadTexture2D("../../images/rayman_anim.png");
self.enemyTexture = self.Content.LoadTexture2D("../../images/enemy1_anim.png");
self.punchTexture = self.Content.LoadTexture2D("../../images/punch.png");
self.flyPowerTexture = self.Content.LoadTexture2D("../../images/fairy_anim.png");
self.punchSpeedTexture = self.Content.LoadTexture2D("../../images/fairy_anim2.png");
self.pearlTexture = self.Content.LoadTexture2D("../../images/pearl_anim.png");
self.shieldTexture = self.Content.LoadTexture2D("../../images/shield_anim.png");
self.helpTexture = self.Content.LoadTexture2D("../../images/help.jpg");
self.gameOverTexture = self.Content.LoadTexture2D("../../images/game_over_screen.png");
self.winTexture = self.Content.LoadTexture2D("../../images/win_screen.png");
self.hudTexture = self.Content.LoadTexture2D("../../images/interfaz.png");
//The song
self.song = self.Content.LoadSong("../../sounds/Rayman/song.mp3");
//Sound Effects
self.soundEffects.push(["enemy_hitted", self.Content.LoadSoundEffect("../../sounds/Rayman/enemy_hitted.wav")]);
self.soundEffects.push(["flying", self.Content.LoadSoundEffect("../../sounds/Rayman/flying.wav")]);
self.soundEffects.push(["game_over", self.Content.LoadSoundEffect("../../sounds/Rayman/game_over.mp3")]);
self.soundEffects.push(["pearl_picked", self.Content.LoadSoundEffect("../../sounds/Rayman/pearl_picked.wav")]);
self.soundEffects.push(["power_picked", self.Content.LoadSoundEffect("../../sounds/Rayman/power_picked.wav")]);
self.soundEffects.push(["punch_thrown", self.Content.LoadSoundEffect("../../sounds/Rayman/punch_thrown.wav")]);
self.soundEffects.push(["rayman_hitted", self.Content.LoadSoundEffect("../../sounds/Rayman/rayman_hitted.wav")]);
self.soundEffects.push(["shield_picked", self.Content.LoadSoundEffect("../../sounds/Rayman/shield_picked.wav")]);
self.soundEffects.push(["win_level", self.Content.LoadSoundEffect("../../sounds/Rayman/win_level.wav")]);
self.soundEffects.push(["idle", self.Content.LoadSoundEffect("../../sounds/Rayman/idle.wav")]);
self.soundEffects.push(["ground_hit", self.Content.LoadSoundEffect("../../sounds/Rayman/ground_hit.wav")]);
self.preloading = false;
}
if (self.Content.AllContentLoaded()) {
//Create the level
self.level = new Level(
new Sprite(
self.levelTexture,
Vector2.One(),
new Rectangle(0, 0, self.levelTexture.Width(), self.levelTexture.Height()),
Point.Zero(),
true
)
);
distantBackgroundRepeats = Math.ceil(self.levelTexture.Width() / self.distantBackgroundTexture.Width());
for (i = 0; i < distantBackgroundRepeats; i += 1) {
self.level.DistantBackgroundsSprites.push(
new Sprite(
self.distantBackgroundTexture,
Vector2.One(),
new Rectangle(0, 0, self.distantBackgroundTexture.Width(), self.distantBackgroundTexture.Height()),
new Point(self.distantBackgroundTexture.Width() * i, 0),
true
)
);
}
///////////////////////
/// Build the level ///
///////////////////////
for (i = 0, len = self.level.DistantBackgroundsSprites.length; i < len; i += 1) {
self.sprites.push(self.level.DistantBackgroundsSprites[i]);
}
self.sprites.push(self.level.Sprite);
//Create all the platforms and add them to the platforms array
for (i = 0, len = self.level.Platforms.length; i < len; i += 1) {
currentPlatform = self.level.Platforms[i];
self.platforms.push(
new Rectangle(
currentPlatform.x,
currentPlatform.y,
currentPlatform.width,
currentPlatform.height
)
);
}
//Create all the pickable objects and add them to the pickable objects array
for (i = 0, len = self.level.PickableObjects.length; i < len; i += 1) {
currentObject = self.level.PickableObjects[i];
switch (currentObject.name) {
case "PEARL":
objSprite = new AnimatedSprite(
self.pearlTexture,
new Vector2(1.35, 1.35),
new Rectangle(0, 0, 24, 24),
new Point(currentObject.x, currentObject.y),
true,
AnimationTypes.PingPongLoop,
8,
90
);
type = PickableObjectTypes.PEARL;
self.pearlsToCollect += 1;
break;
case "LIFE":
objSprite = new AnimatedSprite(
self.flyPowerTexture,
Vector2.One(),
new Rectangle(0, 0, 64, 64),
new Point(currentObject.x, currentObject.y),
true,
AnimationTypes.PingPongLoop,
10,
25
);
type = PickableObjectTypes.LIFE;
break;
case "MINI_SHIELD":
objSprite = new AnimatedSprite(
self.flyPowerTexture,
Vector2.One(),
new Rectangle(0, 0, 64, 64),
new Point(currentObject.x, currentObject.y),
true,
AnimationTypes.PingPongLoop,
10,
25
);
type = PickableObjectTypes.MINI_SHIELD;
break;
case "SHIELD":
objSprite = new AnimatedSprite(
self.shieldTexture,
new Vector2(2.1, 1.7),
new Rectangle(0, 0, 24, 19),
new Point(currentObject.x, currentObject.y),
true,
AnimationTypes.PingPongLoop,
4,
120
);
type = PickableObjectTypes.SHIELD;
break;
case "PUNCH_SPEED":
objSprite = new AnimatedSprite(
self.punchSpeedTexture,
new Vector2(1.2, 1.2),
new Rectangle(0, 0, 64, 64),
new Point(currentObject.x, currentObject.y),
true,
AnimationTypes.PingPongLoop,
10,
35
);
type = PickableObjectTypes.PUNCH_SPEED;
break;
case "PUNCH_POWER":
objSprite = new AnimatedSprite(
self.flyPowerTexture,
Vector2.One(),
new Rectangle(0, 0, 64, 64),
new Point(currentObject.x, currentObject.y),
true,
AnimationTypes.PingPongLoop,
10,
25
);
type = PickableObjectTypes.PUNCH_POWER;
break;
case "ETERNAL_FLY":
objSprite = new AnimatedSprite(
self.flyPowerTexture,
new Vector2(1.2, 1.2),
new Rectangle(0, 0, 64, 64),
new Point(currentObject.x, currentObject.y),
true,
AnimationTypes.PingPongLoop,
10,
30
);
type = PickableObjectTypes.ETERNAL_FLY;
break;
}
if (objSprite !== null && type !== null) {
self.sprites.push(objSprite);
self.pickableObjects.push(new PickableObject(objSprite, type));
}
}
//Create all the enemys and add them to the enemys array
for (i = 0, len = self.level.Enemys.length; i < len; i += 1) {
currentEnemy = self.level.Enemys[i];
self.enemys.push(
new Enemy(
new AnimatedSprite(
self.enemyTexture,
new Vector2(0.3, 0.3),
new Rectangle(0, 0, 80, 80),
new Point(currentEnemy.x, currentEnemy.y),
true,
AnimationTypes.Loop,
20,
35
)
)
);
self.sprites.push(self.enemys[i].Sprite);
}
//Create the player (Rayman) and his punch
self.player = new Player(
new AnimatedSprite(
self.raymanTexture,
new Vector2(0.1, 0.1),
new Rectangle(0, 0, 80, 80),
new Point(self.level.Player.x, self.level.Player.y),
true,
AnimationTypes.Loop,
11,
45
)
);
self.player.Punch = new Projectile(
new Sprite(
self.punchTexture,
new Vector2(1.2, 1.2),
new Rectangle(0, 0, self.punchTexture.HalfWidth(), self.punchTexture.Height()),
Point.Zero(),
false
)
);
self.sprites.push(self.player.Sprite);
self.sprites.push(self.player.Punch.Sprite);
//Instanciate the game camera
self.camera = new Camera(
self.GraphicsDevice.DefaultBackBufferWidth(),
self.GraphicsDevice.DefaultBackBufferHeight(),
self.levelTexture.Width(),
self.levelTexture.Height(),
1.2
);
//Initialize the win zone rectangle
self.winRect = new Rectangle(self.level.WinRect.x, self.level.WinRect.y, self.level.WinRect.width, self.level.WinRect.height);
//Initialize the help screen sprite
self.helpSprite = new Sprite(
self.helpTexture,
Vector2.One(),
new Rectangle(0, 0, self.helpTexture.Width(), self.helpTexture.Height()),
Point.Zero(),
true
);
//Initialize the game over screen sprite
self.gameOverSprite = new Sprite(
self.gameOverTexture,
Vector2.One(),
new Rectangle(0, 0, self.gameOverTexture.Width(), self.gameOverTexture.Height()),
Point.Zero(),
true
);
//Initialize the win screen sprite
self.winSprite = new Sprite(
self.winTexture,
Vector2.One(),
new Rectangle(0, 0, self.winTexture.Width(), self.winTexture.Height()),
Point.Zero(),
true
);
//Initialize the hud sprite
self.hudSprite = new Sprite(
self.hudTexture,
Vector2.One(),
new Rectangle(0, 0, self.hudTexture.Width(), self.hudTexture.Height()),
Point.Zero(),
true
);
/////////////////////////
//If mouse left button clicked enter full screen mode
self.GraphicsDevice.canvas.addEventListener("click", self.GraphicsDevice.ToggleFullScreen.bind(self.GraphicsDevice));
//Play the game song
self.song.Play();
self.interval = setInterval(function () {
if (self.gameState === GameStates.Playing && self.player.CurrentState === self.player.IDLE) {
self.soundEffects[9][1].Play();
}
}, 3500);
//Change game state to "playing"
self.gameState = GameStates.Paused;
}
};
/**
* Allows the game to run logic such as updating the world,
* checking for collisions, gathering input, and playing audio.
* @name Update
* @function
* @memberOf Game
*/
Game.prototype.Update = function () {
"use strict";
/*globals Keyboard, Keys*/
var self = this,
i = 0,
len = 0,
playerPunch = null,
levelWidth = self.level.Sprite.Width();
//Show help screen if 'h' key pressed
if (Keyboard.IsKeyPressed(Keys.h)) {
self.gameState = GameStates.Paused;
}
//Toggle full page mode if mouse right button pressed
if (Mouse.IsButtonClicked(Mouse.RightButton)) {
self.GraphicsDevice.ToggleFullPage();
}
//Catch the Mouse and Keyboard buttons
self.moveLeft = Keyboard.IsKeyDown(Keys.a) || Keyboard.IsKeyDown(Keys.left_arrow);
self.moveRight = Keyboard.IsKeyDown(Keys.d) || Keyboard.IsKeyDown(Keys.right_arrow);
self.jump = Keyboard.IsKeyDown(Keys.w) || Keyboard.IsKeyDown(Keys.up_arrow);
if ((!self.showCollisions && Keyboard.IsKeyPressed(Keys.c)) ||
(self.showCollisions && !Keyboard.IsKeyPressed(Keys.c))) {
self.showCollisions = true;
} else {
self.showCollisions = false;
}
if (!self.punch && Keyboard.IsKeyUp(Keys.space)) {
self.punch = true;
self.soundEffects[5][1].Play();
}
if (Keyboard.IsKeyPressed(Keys.add)) {
self.camera.IncreaseZoom();
}
if (Keyboard.IsKeyPressed(Keys.subtract)) {
self.camera.DecreaseZoom();
}
//Update the player
self.player.Update(self.moveLeft, self.moveRight, self.jump, self.punch, self.platforms, levelWidth, self.pickableObjects, self.sprites, self.gravityForce, self.soundEffects, self.enemys);
//Check if the player have all pearls and is in the win zone
if (self.player.Pearls === self.pearlsToCollect && self.player.Bounds().Intersects(self.winRect) !== false) {
self.song.Stop();
self.soundEffects[8][1].Play();
self.gameState = GameStates.GameWin;
return;
}
//If player dies go to game over game state
if (self.player.Shield <= 0 || self.player.Sprite.Position.Y > self.level.Sprite.Height()) {
self.song.Stop();
self.soundEffects[2][1].Play();
self.gameState = GameStates.GameOver;
return;
}
//Control the punch collision with Rayman
playerPunch = self.player.Punch;
if (self.punch &&
playerPunch.IsReturning &&
(self.player.Bounds().Intersects(playerPunch.Sprite.Bounds()) !== false)) {
playerPunch.Sprite.IsVisible = false;
playerPunch.IsReturning = false;
self.punch = false;
}
//Update the camera
self.camera.Update(self.player);
//Update the enemys
for (i = 0, len = self.enemys.length; i < len; i += 1) {
self.enemys[i].Update(levelWidth, self.platforms, self.gravityForce);
}
//Move the distantBackground at half the speed of the camera
for (i = 0, len = self.level.DistantBackgroundsSprites.length; i < len; i += 1) {
self.level.DistantBackgroundsSprites[i].Position.X += self.camera.SpeedV.X / 2;
}
//Capture the camera's current x position so we can use it as the
//previousX value in the next frame
self.camera.PreviousSpeedX = self.camera.Position.X;
};
/**
* This is called when the game should draw itself.
* @name Draw
* @function
* @memberOf Game
*/
Game.prototype.Draw = function () {
"use strict";
var self = this,
len = self.sprites.length,
i = 0,
auxSprite = null,
hudSprite = self.hudSprite;
self.GraphicsDevice.Clear();
self.spriteBatch.ctx.save();
self.spriteBatch.ctx.scale(self.camera.Zoom, self.camera.Zoom);
self.spriteBatch.ctx.translate(-self.camera.Position.X, -self.camera.Position.Y);
//Draw the sprites if visibles
if (len > 0) {
for (i = 0; i < len; i += 1) {
auxSprite = self.sprites[i];
if (auxSprite.IsVisible) {
self.spriteBatch.Draw(
auxSprite.Texture,
auxSprite.Position,
new Rectangle(auxSprite.SourceRect.X, auxSprite.SourceRect.Y, auxSprite.SourceRect.Width, auxSprite.SourceRect.Height),
auxSprite.Rotation,
auxSprite.Scale,
auxSprite.SpriteEffects
);
}
}
}
//Display the collision rectangles if requested
if (self.showCollisions) {
for (i = 0, len = self.platforms.length; i < len; i += 1) {
self.spriteBatch.DrawRectangle(self.platforms[i], "2", null);
}
//Draw the player bounds
self.spriteBatch.DrawRectangle(self.player.Bounds(), "2", "#00FF00");
//Draw the Rayman's punch
if (self.player.Punch.Sprite.IsVisible) {
self.spriteBatch.DrawRectangle(self.player.Punch.Sprite.Bounds(), "2", "#0000FF");
}
//Draw the enemy bounds
for (i = 0, len = self.enemys.length; i < len; i += 1) {
self.spriteBatch.DrawRectangle(self.enemys[i].Bounds(), "2", "#FF0000");
}
//Draw the pickable objects bounds
for (i = 0, len = self.pickableObjects.length; i < len; i += 1) {
self.spriteBatch.DrawRectangle(self.pickableObjects[i].Bounds(), "2", "#FF00FF");
}
//Draw the win zone bounds
self.spriteBatch.DrawRectangle(self.winRect, "2", "#ffee00");
}
self.spriteBatch.ctx.restore();
//Draw the hud
self.spriteBatch.Draw(
hudSprite.Texture,
hudSprite.Position,
new Rectangle(hudSprite.SourceRect.X, hudSprite.SourceRect.Y, hudSprite.SourceRect.Width, hudSprite.SourceRect.Height),
hudSprite.Rotation,
hudSprite.Scale,
hudSprite.SpriteEffects
);
self.spriteBatch.DrawString(
"normal bold 24px Helvetica",
self.player.Shield + " / 5",
new Point(77, 25),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 20px Helvetica",
self.player.Pearls + " / " + self.pearlsToCollect,
new Point(735, 28),
"#000000",
Vector2.One()
);
if (self.player.CanFly) {
self.spriteBatch.Draw(
self.flyPowerTexture,
new Point(348, -2),
new Rectangle(0, 0, 64, 64),
0,
new Vector2(1.3, 1.21),
SpriteEffects.None
);
}
if (self.player.PunchImproved) {
self.spriteBatch.Draw(
self.punchSpeedTexture,
new Point(404, -2),
new Rectangle(0, 0, 64, 64),
0,
new Vector2(1.3, 1.21),
SpriteEffects.None
);
}
};
/**
* Call this method to initialize the game, begin running the game loop, and
* start processing events for the game.
* @name Run
* @function
* @memberOf Game
*/
Game.prototype.Run = function () {
"use strict";
/*globals requestAnimationFrame*/
var self = this,
helpSprite = self.helpSprite,
gameOverSprite = self.gameOverSprite,
winSprite = self.winSprite;
//Call the game loop
requestAnimationFrame(self.Run.bind(self), self.GraphicsDevice.canvas);
//Choose the method to run according to the game state
switch (self.gameState) {
case GameStates.Initializing:
self.Initialize();
break;
case GameStates.Loading:
self.LoadContent();
break;
case GameStates.Playing:
self.Update();
self.Draw();
break;
case GameStates.Paused:
self.spriteBatch.Draw(
helpSprite.Texture,
helpSprite.Position,
new Rectangle(helpSprite.SourceRect.X, helpSprite.SourceRect.Y, helpSprite.SourceRect.Width, helpSprite.SourceRect.Height),
helpSprite.Rotation,
helpSprite.Scale,
helpSprite.SpriteEffects
);
//Go back to game if 'h' key pressed
if (Keyboard.IsKeyPressed(Keys.h)) {
self.gameState = GameStates.Playing;
}
//Toggle full page mode if mouse right button pressed
if (Mouse.IsButtonClicked(Mouse.RightButton)) {
self.GraphicsDevice.ToggleFullPage();
}
break;
case GameStates.GameOver:
self.spriteBatch.Draw(
gameOverSprite.Texture,
gameOverSprite.Position,
new Rectangle(gameOverSprite.SourceRect.X, gameOverSprite.SourceRect.Y, gameOverSprite.SourceRect.Width, gameOverSprite.SourceRect.Height),
gameOverSprite.Rotation,
gameOverSprite.Scale,
gameOverSprite.SpriteEffects
);
//Go reset the game if 'r' key pressed
if (Keyboard.IsKeyPressed(Keys.r)) {
self.Reset();
self.gameState = GameStates.Loading;
}
break;
case GameStates.GameWin:
self.spriteBatch.Draw(
winSprite.Texture,
winSprite.Position,
new Rectangle(winSprite.SourceRect.X, winSprite.SourceRect.Y, winSprite.SourceRect.Width, winSprite.SourceRect.Height),
winSprite.Rotation,
winSprite.Scale,
winSprite.SpriteEffects
);
//Go reset the game if 'r' key pressed
if (Keyboard.IsKeyPressed(Keys.r)) {
self.Reset();
self.gameState = GameStates.Loading;
}
break;
}
};
/**
* Reset the game
*/
Game.prototype.Reset = function () {
"use strict";
var self = this;
self.Content = new ContentManager();
self.GraphicsDevice = new GraphicsDevice(document);
self.spriteBatch = null;
self.gameState = GameStates.Initializing;
self.preloading = true;
self.level = null;
self.sprites = [];
self.pearlsToCollect = 0;
//Create the platforms, pickable objects and enemys arrays
self.platforms = [];
self.pickableObjects = [];
self.enemys = [];
//Create the player
self.player = null;
//Create the game camera
self.camera = null;
//The win zone rectangle
self.winRect = null;
//The help screen sprite
self.helpSprite = null;
//The game over screen sprite
self.gameOverSprite = null;
//The win screen sprite
self.winSprite = null;
//Flags
self.moveRight = false;
self.moveLeft = false;
self.jump = false;
self.punch = false;
self.showCollisions = false;
clearInterval(self.interval);
/*if (self.GraphicsDevice.IsFullScreen()) {
self.GraphicsDevice.ToggleFullScreen();
}*/
};

View File

@ -0,0 +1,348 @@
/**
* Defines a Ball.
* @constructor
* @param {Sprite} sprite - The sprite that represents the ball.
* @param {Number} radius - The radius of the circle of the ball.
* @param {Point} position - The position of the ball.
* @param {Number} position - The position of the ball.
* @param {Boolean} bounce - Determines if the ball can bounce or not.
*/
function Ball(sprite, radius, position, index, bounce, rotate) {
"use strict";
/*global Vector2, Circle*/
this.Sprite = sprite;
this.Circle = new Circle(radius, position.X, position.Y);
//Physics properties
this.SpeedV = Vector2.Zero();
this.GroundFriction = 0.975; //balls 0.975 fluid 0.99
this.BallBounceFriction = 0.85; //balls 0.85 fluid 0.0
this.WallBounceFriction = 0.7; //balls 0.7 fluid 0.4
this.MaxRotationSpeedTransmision = 25;
this.CurrentRotationSpeed = 0;
//Platform game properties
this.IsOnGround = false;
//Drag & Drop properties
this.IsDraggable = true;
this.IsBeenDragged = false;
//Other properties
this.RandomDir = [-0.1, 0.1];
this.Index = index;
this.IsBounceOn = bounce;
this.IsRotationOn = rotate;
}
/**
* Updates the ball.
* @name Update
* @function
* @param {Number} worldWidth - The width of the game world.
* @param {Number} worldHeight - The height of the game world.
* @param {Array} balls - Array of existing balls.
* @param {Boolean} isGravityOn - Determines if the gravity is activated or not.
* @param {GravityDirections} gravityDir - The gravity direction of the game world.
* @param {Number} gravityForce - The gravity force value.
* @memberOf Ball
*/
Ball.prototype.Update = function (worldWidth, worldHeight, balls, isGravityOn, gravityDir, gravityForce) {
"use strict";
/*global GravityDirections, Mouse, Point, hitTestPoint*/
var self = this,
randomDirImpulse = 0,
len = 0,
i = 0,
j = 0;
//Check if the mouse clicked a ball to drag it
if (self.Circle.Contains(new Point(Mouse.X, Mouse.Y)) && self.IsDraggable && Mouse.LeftButtonPressed && !Mouse.IsDraggingSomething) { //Si quitamos IsDraggingSom... ocurren cosas divertidas
//Assign the sprite to the dragSprite variable
self.IsBeenDragged = true;
Mouse.IsDraggingSomething = true;
self.CurrentRotationSpeed = 0;
self.SpeedV.X = 0;
self.SpeedV.Y = 0;
i = self.Index;
len = balls.length;
//push the dragSprite to the end of the sprites
//array so that it's displayed last
self.Index = balls.length - 1;
balls.push(self);
//Splice the dragSprite from its previous
//position in the sprites array
balls.splice(i, 1);
for (j = i; j < len - 1; j += 1) {
balls[j].Index -= 1;
}
}
//Update the Circle position with the mouse position
if (Mouse.IsMoving && self.IsBeenDragged) {
self.Circle.X = Mouse.X - self.Circle.Radius;
self.Circle.Y = Mouse.Y - self.Circle.Radius;
}
//If the mouse left button was released drop the ball
if (self.IsBeenDragged && !Mouse.LeftButtonPressed) {
self.IsBeenDragged = false;
Mouse.IsDraggingSomething = false;
}
//Apply gravity depending on the gravity direction
if (isGravityOn && !self.IsBeenDragged) {
//Random impulse when the balls are generated
if (!self.IsOnGround && self.SpeedV.X === 0 && self.SpeedV.Y === 0) {
randomDirImpulse = self.RandomDir[Math.floor(Math.random() * 2)];
}
switch (gravityDir) {
//Gravity down
case GravityDirections.G_DOWN:
self.SpeedV.Y += gravityForce;
self.SpeedV.X += randomDirImpulse;
if (self.Circle.Bottom() >= worldHeight) {
self.SpeedV.X *= self.GroundFriction;
self.IsOnGround = true;
}
break;
//Gravity up
case GravityDirections.G_UP:
self.SpeedV.Y -= gravityForce;
self.SpeedV.X += randomDirImpulse;
if (self.Circle.Top() <= 0) {
self.SpeedV.X *= self.GroundFriction;
self.IsOnGround = true;
}
break;
//Gravity left
case GravityDirections.G_LEFT:
self.SpeedV.X -= gravityForce;
self.SpeedV.Y += randomDirImpulse;
if (self.Circle.Left() <= 0) {
self.SpeedV.Y *= self.GroundFriction;
self.IsOnGround = true;
}
break;
//Gravity right
case GravityDirections.G_RIGHT:
self.SpeedV.X += gravityForce;
self.SpeedV.Y += randomDirImpulse;
if (self.Circle.Right() >= worldWidth) {
self.SpeedV.Y *= self.GroundFriction;
self.IsOnGround = true;
}
break;
}
}
//Move the ball if it isn't dragged
if (!self.IsBeenDragged) {
self.Circle.X += self.SpeedV.X;
self.Circle.Y += self.SpeedV.Y;
}
//Collision with balls
len = balls.length;
if (len > 1 && !self.IsBeenDragged) {
for (i = 0; i < len; i += 1) {
if (self.Index !== i) {
self.CollisionWithBall(balls[i], self.IsBounceOn, self.IsRotationOn);
}
}
}
//Screen boundaries
//Left
if (self.Circle.Left() < 0) {
if (self.IsBounceOn) {
self.SpeedV.X *= -self.WallBounceFriction;
}
self.Circle.X = 0;
}
//Up
if (self.Circle.Top() < 0) {
if (self.IsBounceOn) {
self.SpeedV.Y *= -self.WallBounceFriction;
}
self.Circle.Y = 0;
}
//Right
if (self.Circle.Right() > worldWidth) {
if (self.IsBounceOn) {
self.SpeedV.X *= -self.WallBounceFriction;
}
self.Circle.X = worldWidth - self.Circle.Diameter();
}
//Down
if (self.Circle.Bottom() > worldHeight) {
if (self.IsBounceOn) {
self.SpeedV.Y *= -self.WallBounceFriction;
}
self.Circle.Y = worldHeight - self.Circle.Diameter();
}
//Update the sprite
self.Sprite.Position.X = self.Circle.X;
self.Sprite.Position.Y = self.Circle.Y;
//Update the sprite rotation
self.Sprite.Rotation += self.CurrentRotationSpeed;
self.CurrentRotationSpeed *= self.GroundFriction;
//console.log(self.CurrentRotationSpeed);
};
/**
* Check if a ball collide with other ball. Besides, bounce and rotate the balls if needed.
* @name CollisionWithBall
* @function
* @param {Ball} ball - The ball which will be checked to find a collision.
* @memberOf Ball
*/
Ball.prototype.CollisionWithBall = function (ball) {
"use strict";
var self = this,
overlapV = self.Circle.IsInsideCircle(ball.Circle),
vector = null,
d = null,
angle = 0,
b1Magnitude = 0,
b2Magnitude = 0,
s = null;
//If the other ball is inside the other
if (overlapV !== false) {
self.Circle.X += overlapV.X;
self.Circle.Y += overlapV.Y;
return true;
}
//Check if this ball is inside the other
overlapV = self.Circle.Intersects(ball.Circle);
//If there is a collision with the other ball move it away of the other
if (overlapV !== false) {
vector = overlapV.Y; //the vector between the balls centers
d = vector.Normalize();
angle = Math.atan2(d.X, d.X) * 180 / Math.PI;
b1Magnitude = self.SpeedV.Length();
b2Magnitude = ball.SpeedV.Length();
//If rotation is activated then rotate the ball
if (self.IsRotationOn) {
if (
(angle >= 0 && angle <= 90 && self.SpeedV.X > 0) ||
(angle > 90 && angle <= 180 && self.SpeedV.X >= 0) ||
(angle < 0 && angle >= -90 && self.SpeedV.X <= 0) ||
(angle < -90 && angle >= -180 && self.SpeedV.X < 0)
) {
self.CurrentRotationSpeed = Math.min(Math.abs(b1Magnitude), self.MaxRotationSpeedTransmision);
ball.CurrentRotationSpeed = -Math.min(Math.abs(b2Magnitude), ball.MaxRotationSpeedTransmision);
} else {
self.CurrentRotationSpeed = -Math.min(Math.abs(b1Magnitude), self.MaxRotationSpeedTransmision);
ball.CurrentRotationSpeed = Math.min(Math.abs(b2Magnitude), ball.MaxRotationSpeedTransmision);
}
//Limit the rotation speeds
if (Math.abs(self.CurrentRotationSpeed) < 1) {
self.CurrentRotationSpeed = 0;
}
if (Math.abs(ball.CurrentRotationSpeed) < 1) {
ball.CurrentRotationSpeed = 0;
}
}
//Move circle 1 out of the collision by multiplying
//the overlap with the normalized vector and add it to
//ball 1's position
self.Circle.X += overlapV.X * d.X;
self.Circle.Y += overlapV.X * d.Y;
//Ocurren cosas diver al poner esto
//ball.Circle.X += overlapV.X * overlapV.Y[0];
//ball.Circle.Y += overlapV.X * overlapV.Y[1];
if (self.IsBounceOn) {
//Create a collision vector object to represent the bounce surface
//Find the bounce surface's X and Y properties
//(This represents the normal of the distance vector between the circles)
s = new Vector2(vector.Y, -vector.X);
//var s = {};
//s.X = vector.Y;
//s.Y = -vector.X;
//Bounce b1 off the surface
self.BounceOffSurface(ball, s);
}
return true;
}
return false;
};
/**
* Bounces the current ball with other ball given the virtual surface between them.
* @name BounceOffSurface
* @function
* @param {Ball} ball - The ball which will bounced.
* @param {Vector2} s - The surface to bounce off.
* @memberOf Ball
*/
Ball.prototype.BounceOffSurface = function (ball, s) {
"use strict";
//1. Calculate the collision surface's properties
var self = this,
//Find the surface vector's left normal
leftNormalV = new Vector2(s.Y, -s.X),
//s.lx = s.Y;
//s.ly = -s.X;
//Find its magnitude
sLength = s.Length(),
//Find its normalized/unit vector values
dV = s.Normalize(),
//2. Bounce the ball off the surface (s)
//Find the dot product between the object and the surface
dp1 = self.SpeedV.X * dV.X + self.SpeedV.Y * dV.Y,
//Project the object's velocity onto the collision surface
p1V = new Vector2(dp1 * dV.X, dp1 * dV.Y),
//Find the dot product of the object and the surface's left normal (s.lx and s.ly)
dp2 = self.SpeedV.X * (leftNormalV.X / sLength) + self.SpeedV.Y * (leftNormalV.Y / sLength),
//Project the object's velocity onto the surface's left normal
p2V = new Vector2(dp2 * (leftNormalV.X / sLength), dp2 * (leftNormalV.Y / sLength)),
bounceV = null;
//Reverse the projection on the surface's left normal
p2V.X *= -1;
p2V.Y *= -1;
//Add up the projections to create a new bounce vector
bounceV = new Vector2(p1V.X + p2V.X, p1V.Y + p2V.Y);
//Assign the bounce vector to the object's velocity
self.SpeedV.X = bounceV.X * self.BallBounceFriction;
self.SpeedV.Y = bounceV.Y * self.BallBounceFriction;
if (!ball.IsBeenDragged) {
ball.SpeedV.X = -bounceV.X * ball.BallBounceFriction;
ball.SpeedV.Y = -bounceV.Y * ball.BallBounceFriction;
}
};

View File

@ -0,0 +1,186 @@
/**
* Represents one enemy.
* @constructor
* @param {AnimatedSprite|Sprite} sprite - The enemys's sprite.
*/
function Enemy(sprite) {
"use strict";
/*globals Vector2, setInterval, AnimatedSprite, SpriteEffects*/
this.Sprite = sprite;
//Physics properties
this.SpeedV = Vector2.Zero();
this.Speed = 0;
//Platform game properties
this.IsOnGround = undefined;
//Enemy States
this.IDLE = 0;
this.MOVING = 1;
this.HITTED = 2;
//this.TURNING = 3;
//[...]
this.CurrentState = 0;
//Enemy attributtes
//this.life = 2;
//If the sprite is animated starts the sprite animation
if (this.Sprite instanceof AnimatedSprite) {
this.Sprite.StartAnimation();
}
//Change the enemy state every 1,8 seconds
this.interval = setInterval(this.ChangeEnemyState.bind(this), 1800);
}
/**
* Updates de enemy.
* @name Update
* @function
* @param {Number} levelWidth - The width of the level.
* @param {Array} platforms - The platforms array.
* @param {Number} gravityForce - The gravity force.
* @memberOf Enemy
*/
Enemy.prototype.Update = function (levelWidth, platforms, gravityForce) {
"use strict";
var self = this,
enemySprite = self.Sprite,
bounds = null,
i = 0,
overlapV = null,
currentPlatform = null,
len = 0;
//If the enemy was hitted stop it
if (self.CurrentState !== self.HITTED) {
switch (self.CurrentState) {
case self.IDLE:
//enemySprite.currentFrame = 0;
enemySprite.NumberOfFrames = 20;
self.Speed = 0;
break;
case self.MOVING:
//enemySprite.currentFrame = 0;
enemySprite.NumberOfFrames = 14;
self.Speed = 1.5;
break;
}
//Apply the acceleration
self.SpeedV.X = self.Speed;
if (enemySprite.SpriteEffects === SpriteEffects.FlipHorizontally) {
self.SpeedV.X *= -1;
}
//Apply gravityForce
self.SpeedV.Y += gravityForce;
//Check for a collision between the enemy and the platforms
bounds = self.Bounds();
for (i = 0, len = platforms.length; i < len; i += 1) {
currentPlatform = platforms[i];
overlapV = bounds.Intersects(currentPlatform);
if (overlapV !== false && self.SpeedV.Y >= 0) {
if (bounds.Bottom() >= currentPlatform.Top() &&
bounds.Bottom() <= currentPlatform.Bottom()) {
//Move the rectangle out of the collision
enemySprite.Position.Y -= overlapV.Y;
//Tell the game that the player is on the ground if
//it's standing on top of a platform
self.IsOnGround = true;
//Neutralize gravity by applying its
//exact opposite force to the character's vy
self.SpeedV.Y = -gravityForce;
}
} else if (overlapV === false && self.SpeedV.Y > 0) {
self.IsOnGround = false;
}
}
//Screen boundaries
//Left
if (bounds.X < 0) {
self.SpeedV.X = 0;
enemySprite.Position.X = enemySprite.Position.X - bounds.Position.X;
}
//Up
if (bounds.Y < 0) {
self.SpeedV.Y = 0;
enemySprite.Position.Y = enemySprite.Position.Y - bounds.Position.Y;
}
//Right
if (bounds.X + bounds.Width > levelWidth) {
self.SpeedV.X = 0;
enemySprite.Position.X = levelWidth - (enemySprite.Right() - bounds.Right()) - bounds.Width;
}
}
//Move the enemy
enemySprite.Position.X += self.SpeedV.X;
enemySprite.Position.Y += self.SpeedV.Y;
//If the sprite is animated change its vertical offset depending on the player's state
if (self.Sprite instanceof AnimatedSprite) {
self.Sprite.VerticalOffset = self.CurrentState;
}
};
/**
* Changes the enemy state randomly
* @name ChangeEnemysState
* @function
* @memberOf Enemy
*/
Enemy.prototype.ChangeEnemyState = function () {
"use strict";
/*globals SpriteEffects*/
var self = this,
enemySprite = self.Sprite;
self.CurrentState = Math.floor((Math.random() * 2));
if (self.CurrentState === self.MOVING) {
if (enemySprite.SpriteEffects === SpriteEffects.FlipHorizontally) {
enemySprite.SpriteEffects = SpriteEffects.None;
} else {
enemySprite.SpriteEffects = SpriteEffects.FlipHorizontally;
}
}
//Reset the current frame if is an animated sprite
if (enemySprite instanceof AnimatedSprite) {
enemySprite.CurrentFrame = 0;
}
};
/**
* The enemys's collision rectangle.
* @name Bounds
* @function
* @memberOf Enemy
*/
Enemy.prototype.Bounds = function () {
"use strict";
/*globals Rectangle*/
var self = this,
spriteBounds = self.Sprite.Bounds();
return new Rectangle(
spriteBounds.X + spriteBounds.HalfWidth() / 2,
spriteBounds.Y + 20,
spriteBounds.HalfWidth(),
spriteBounds.Height - 20
);
};

View File

@ -0,0 +1,27 @@
/**
* Defines the types of the pickable objects.
* @readonly
* @enum {number}
*/
var PickableObjectTypes = Object.freeze({
"PEARL": 0,
"LIFE": 1,
"MINI_SHIELD": 2,
"SHIELD": 3,
"PUNCH_SPEED": 4,
"PUNCH_POWER": 5,
"ETERNAL_FLY": 6
});
/**
* Defines the powers.
* @readonly
* @enum {number}
*/
var Powers = Object.freeze({
"PUNCH": 0,
"HOLD": 1,
"FLY": 2,
"ENGAGE": 3,
"RUN": 4
});

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,342 @@
/**
* Represents the player, in this case, Rayman.
* @constructor
* @param {AnimatedSprite|Sprite} sprite - The player's sprite.
*/
function Player(sprite) {
"use strict";
/*globals Vector2, AnimatedSprite*/
this.Sprite = sprite; //The player sprite
//Physics properties
this.SpeedV = Vector2.Zero();
this.AccelerationV = Vector2.Zero();
this.SpeedLimit = 3;
this.GroundFriction = 1; //0.96
//this.bounce = -0.7;
//Platform game properties
this.IsOnGround = undefined;
this.JumpForce = -8;
//Player States
this.IDLE = 0;
this.MOVING = 3;
this.JUMPING = 4;
this.FLYING = 10;
this.HITTED = 5;
//this.CROUCHED = 4;
//[...]
this.CurrentState = 0;
//Player attributtes (Rayman)
this.Pearls = 0;
//this.Life = 3;
this.Shield = 5;
this.CanFly = false;
this.PunchImproved = false;
//The punch (Rayman)
this.Punch = null;
//If the sprite is animated starts the sprite animation
if (this.Sprite instanceof AnimatedSprite) {
this.Sprite.StartAnimation();
}
}
/**
* Updates de player.
* @name Update
* @function
* @param {Boolean} moveLeft - Tells if the player moved left or not.
* @param {Boolean} moveRight - Tells if the player moved right or not.
* @param {Boolean} jump - Tells if the player jumped or not.
* @param {Boolean} punchPressed - Tells if the player shoot the punch or not.
* @param {Array} platforms - The platforms array.
* @param {Number} levelWidth - The width of the level.
* @param {Array} pickableObjects - The pickable objects array.
* @param {Array} sprites - The sprites array.
* @param {Number} gravityForce - The gravity force.
* @memberOf Player
*/
Player.prototype.Update = function (moveLeft, moveRight, jump, punchPressed, platforms, levelWidth, pickableObjects, sprites, gravityForce, soundEffects, enemys) {
"use strict";
/*globals SpriteEffects, Keyboard, Keys*/
var self = this,
playerSprite = self.Sprite,
bounds = null,
i = 0,
len = 0,
overlapV = null,
currentPlatform = null,
currentPickableObject = null,
currentEnemy = null,
index = 0;
//If rayman was hitted remove any control
if (self.CurrentState !== self.HITTED) {
//Left
if (moveLeft && !moveRight) {
self.AccelerationV.X = -2.8; //0.2
self.GroundFriction = 1;
self.CurrentState = self.MOVING;
playerSprite.SpriteEffects = SpriteEffects.FlipHorizontally;
}
//Right
if (moveRight && !moveLeft) {
self.AccelerationV.X = 2.8; //0.2
self.GroundFriction = 1;
self.CurrentState = self.MOVING;
playerSprite.SpriteEffects = SpriteEffects.None;
}
//Space
if (jump && self.IsOnGround) {
self.SpeedV.Y += self.JumpForce;
self.IsOnGround = false;
self.GroundFriction = 1;
}
//Set the player's acceleration, friction and gravity
//to zero if none of the arrow keys are being pressed
if (!moveLeft && !moveRight) {
self.AccelerationV.X = 0;
self.GroundFriction = 0.1; //0.96
gravityForce = 0.3;
self.CurrentState = self.IDLE;
}
//If player is in the air set the state to "jumping"
if (!self.IsOnGround) {
self.CurrentState = self.JUMPING;
self.hitGroundCounter = 0;
}
//Apply the acceleration
self.SpeedV.X += self.AccelerationV.X;
self.SpeedV.Y += self.AccelerationV.Y;
//Apply friction
if (self.IsOnGround) {
self.SpeedV.X *= self.GroundFriction;
}
//If space pressed and is not on ground then fly
//If not apply gravity
if (self.CanFly && (Keyboard.IsKeyDown(Keys.w) || Keyboard.IsKeyDown(Keys.up_arrow)) && !self.IsOnGround && self.SpeedV.Y > 0) {
self.CurrentState = self.FLYING;
self.SpeedV.X /= 2;
self.SpeedV.Y = self.SpeedLimit / 3.2;
soundEffects[1][1].Play();
} else {
self.SpeedV.Y += gravityForce;
}
//Limit the speed
//Don't limit the upward speed because it will choke the jump effect
if (self.SpeedV.X > self.SpeedLimit) {
self.SpeedV.X = self.SpeedLimit;
}
if (self.SpeedV.X < -self.SpeedLimit) {
self.SpeedV.X = -self.SpeedLimit;
}
if (self.SpeedV.Y > self.SpeedLimit * 2) {
self.SpeedV.Y = self.SpeedLimit * 2;
}
}
//Move the player
playerSprite.Position.X += self.SpeedV.X;
playerSprite.Position.Y += self.SpeedV.Y;
//Update the punch
if (punchPressed) {
self.Punch.Update(playerSprite, levelWidth, sprites, enemys, soundEffects[0][1]);
}
bounds = self.Bounds();
//Check for a collision between the player and the platforms
for (i = 0, len = platforms.length; i < len; i += 1) {
currentPlatform = platforms[i];
overlapV = bounds.Intersects(currentPlatform);
if (overlapV !== false && self.SpeedV.Y >= 0) {
if (bounds.Bottom() >= currentPlatform.Top() &&
bounds.Bottom() <= currentPlatform.Bottom()) {
//Move the rectangle out of the collision
playerSprite.Position.Y -= overlapV.Y;
//Tell the game that the player is on the ground if
//it's standing on top of a platform
self.IsOnGround = true;
//Neutralize gravity by applying its
//exact opposite force to the character's vy
self.SpeedV.Y = -gravityForce;
//Play the hit the ground sound effect if rayman is not moving in the Y axis
if (self.hitGroundCounter === 0) {
soundEffects[10][1].Play();
self.hitGroundCounter += 1;
}
}
} else if (overlapV === false && self.SpeedV.Y > 0) {
self.IsOnGround = false;
}
}
//Check for a collision between the player and the pickable objects
for (i = 0, len = pickableObjects.length; i < len; i += 1) {
currentPickableObject = pickableObjects[i];
overlapV = bounds.Intersects(currentPickableObject.Bounds());
//If the collision occurs pick the object and delete the object from the level
if (overlapV !== false) {
self.PickObject(currentPickableObject, soundEffects);
index = sprites.indexOf(currentPickableObject.Sprite);
if (index !== -1) {
sprites.splice(index, 1);
}
index = pickableObjects.indexOf(currentPickableObject);
if (index !== -1) {
pickableObjects.splice(index, 1);
len -= 1;
}
}
}
//Check for a collision between the player and the enemys if the player wasn't hitted
//in one second
if (self.CurrentState !== self.HITTED) {
for (i = 0, len = enemys.length; i < len; i += 1) {
currentEnemy = enemys[i];
overlapV = bounds.Intersects(currentEnemy.Bounds());
//If the collision occurs throw rayman away
if (currentEnemy.CurrentState !== currentEnemy.HITTED && overlapV !== false) {
self.SpeedV.Y += self.JumpForce / 3;
if (playerSprite.SpriteEffects === SpriteEffects.FlipHorizontally) {
self.SpeedV.X += self.SpeedLimit * 2;
} else {
self.SpeedV.X -= self.SpeedLimit * 2;
}
self.IsOnGround = false;
self.GroundFriction = 1;
self.CurrentState = self.HITTED;
//Set timeout to avoid many hits in a row
setTimeout(function () {
self.CurrentState = self.IDLE;
}, 600);
//Play the hitted sound
soundEffects[6][1].Play();
//Decrement the shield by 1 point
self.Shield -= 1;
}
}
}
//Screen boundaries
bounds = self.Bounds();
//Left
if (bounds.X < 0) {
self.SpeedV.X = 0;
playerSprite.Position.X = playerSprite.Position.X - bounds.X;
}
//Up
if (bounds.Y < 0) {
self.SpeedV.Y = 0;
playerSprite.Position.Y = playerSprite.Position.Y - bounds.Y;
}
//Right
if (bounds.X + bounds.Width > levelWidth) {
self.SpeedV.X = 0;
playerSprite.Position.X = levelWidth - (playerSprite.Right() - bounds.Right()) - bounds.Width;
}
//If the sprite is animated change its vertical offset depending on the player's state
if (self.Sprite instanceof AnimatedSprite) {
self.Sprite.VerticalOffset = self.CurrentState;
}
};
Player.prototype.PickObject = function (object, soundEffects) {
"use strict";
/*globals PickableObjectTypes*/
var self = this;
switch (object.Type) {
case PickableObjectTypes.PEARL:
self.Pearls += 1;
if (self.Pearls >= 100) {
self.Pearls = 0;
self.Life += 1;
}
soundEffects[3][1].Play();
break;
case PickableObjectTypes.LIFE:
self.Life += 1;
break;
case PickableObjectTypes.MINI_SHIELD:
self.Shield += 1;
if (self.Shield > 5) {
self.Shield = 5;
}
break;
case PickableObjectTypes.SHIELD:
self.Shield = 5;
soundEffects[7][1].Play();
break;
case PickableObjectTypes.PUNCH_SPEED:
self.Punch.Speed = 8;
self.Punch.MaxScope = 290;
self.Punch.Sprite.SourceRect.X += 20;
self.PunchImproved = true;
soundEffects[4][1].Play();
break;
case PickableObjectTypes.PUNCH_POWER:
self.Punch.Power = 1.5;
break;
case PickableObjectTypes.ETERNAL_FLY:
self.CanFly = true;
soundEffects[4][1].Play();
break;
}
};
/**
* The player's collision rectangle.
* @name Bounds
* @function
* @memberOf Player
*/
Player.prototype.Bounds = function () {
"use strict";
/*globals Rectangle*/
var self = this,
spriteBounds = self.Sprite.Bounds();
return new Rectangle(
spriteBounds.X + spriteBounds.HalfWidth() / 2,
spriteBounds.Y + 20,
spriteBounds.HalfWidth(),
spriteBounds.Height - 20
);
};

View File

@ -0,0 +1,133 @@
/**
* Represents the Rayman's punch.
* @constructor
* @param {Sprite} sprite - The sprite of the punch.
*/
function Projectile(sprite) {
"use strict";
/*globals Vector2*/
this.Sprite = sprite;
this.Speed = 6;
this.MaxScope = 200;
this.ScopeCounter = 0;
this.IsReturning = false;
this.Power = 1;
this.SpeedV = Vector2.Zero();
}
/**
* Updates de player's (Rayman) punch.
* @name Update
* @function
* @param {Sprite} playerSprite - The player's sprite.
* @param {Number} levelWidth - The width of the level.
* @memberOf Projectile
*/
Projectile.prototype.Update = function (playerSprite, levelWidth, sprites, enemys, enemyHittedSound) {
"use strict";
/*globals SpriteEffects*/
var self = this,
moveDistance = 0,
moveVector = null,
d = null,
punchSprite = self.Sprite,
bounds = punchSprite.Bounds(),
currentEnemy = null,
i = 0,
len = 0,
overlapV = null,
aux = 0,
aux2 = null;
//If the punch isn't visible update its position with the player position
if (!punchSprite.IsVisible) {
punchSprite.IsVisible = true;
punchSprite.Position.X = playerSprite.Position.X + playerSprite.HalfWidth() - punchSprite.HalfWidth();
punchSprite.Position.Y = playerSprite.Position.Y + playerSprite.HalfHeight() - punchSprite.HalfHeight();
punchSprite.SpriteEffects = playerSprite.SpriteEffects;
} else {
//Control the scope
if (self.ScopeCounter >= self.MaxScope ||
bounds.X < 0 ||
bounds.Y < 0 ||
bounds.X + bounds.Width > levelWidth) {
self.ScopeCounter = 0;
self.IsReturning = true;
if (punchSprite.SpriteEffects === SpriteEffects.FlipHorizontally) {
punchSprite.SpriteEffects = SpriteEffects.None;
} else {
punchSprite.SpriteEffects = SpriteEffects.FlipHorizontally;
}
}
//If the punch is returning to the player update the movement
if (self.IsReturning) {
moveVector = new Vector2(playerSprite.Center().X - punchSprite.Center().X, playerSprite.Center().Y - punchSprite.Center().Y);
d = moveVector.Normalize();
//Increase the punch's velocity
self.SpeedV.X += d.X;
self.SpeedV.Y += d.Y;
d = self.SpeedV.Normalize();
//Apply easing
self.SpeedV.X = self.Speed * d.X;
self.SpeedV.Y = self.Speed * d.Y;
punchSprite.Position.X += self.SpeedV.X;
punchSprite.Position.Y += self.SpeedV.Y;
//If not update the position with the speed
} else {
if (punchSprite.SpriteEffects === SpriteEffects.FlipHorizontally) {
punchSprite.Position.X += self.Speed * -1;
} else {
punchSprite.Position.X += self.Speed;
}
self.ScopeCounter += self.Speed;
}
//Check for a collision between the punch and the enemys
for (i = 0, len = enemys.length; i < len; i += 1) {
currentEnemy = enemys[i];
overlapV = self.Sprite.Bounds().Intersects(currentEnemy.Bounds());
//If the collision occurs throw rayman away
if (currentEnemy.CurrentState !== currentEnemy.HITTED && overlapV !== false) {
//Set the punch returning
self.ScopeCounter = 0;
self.IsReturning = true;
if (punchSprite.SpriteEffects === SpriteEffects.FlipHorizontally) {
punchSprite.SpriteEffects = SpriteEffects.None;
} else {
punchSprite.SpriteEffects = SpriteEffects.FlipHorizontally;
}
currentEnemy.CurrentState = currentEnemy.HITTED;
currentEnemy.SpeedV.Y = -4;
clearInterval(currentEnemy.interval);
//Set timeout to avoid many hits in a row
aux = i;
aux2 = currentEnemy;
setTimeout(function () {
aux2.Sprite.IsVisible = false;
enemys.splice(aux, 1);
}, 600);
//Play the hitted sound
enemyHittedSound.Play();
}
}
}
};

View File

@ -0,0 +1,338 @@
/**
* Provides basic graphics device initialization, game logic, and rendering code.
*/
function Game() {
"use strict";
/*globals ContentManager, GraphicsDevice, document, SpriteBatch, GameStates, Vector2, Point, Sprite, AnimatedSprite, Rectangle, AnimationTypes, Segment, SpriteEffects, Mouse, Keys, Keyboard*/
this.Content = new ContentManager();
this.GraphicsDevice = new GraphicsDevice(document);
this.spriteBatch = null;
this.gameState = GameStates.Initializing;
this.preloading = true;
//Constants
this.FONT_LITTLE = "normal bold 15px Helvetica";
this.FONT_BIG = "normal bold 18px Helvetica";
this.BLACK = "#000000";
this.GREEN = "#00FF00";
this.RED = "#FF0000";
this.BLUE = "#0000FF";
this.SPEED = 3;
//The animated sprite
this.image = null;
this.sprite = null;
//Flags
this.showBounds = false;
this.animStarted = false;
//Other variables
this.animTypeIndex = 1;
}
/**
* Allows the game to perform any initialization it needs to before starting to run.
* This is where it can query for any required services and load any non-graphic
* related content.
* @name Initialize
* @function
* @memberOf Game
*/
Game.prototype.Initialize = function () {
"use strict";
var self = this;
// TODO: Add your initialization logic here
self.gameState = GameStates.Loading;
};
/**
* LoadContent will be called once per game and is the place to load
* all of your content.
* @name LoadContent
* @function
* @memberOf Game
*/
Game.prototype.LoadContent = function () {
"use strict";
var self = this;
if (self.preloading) {
// Create a new SpriteBatch, which can be used to draw textures.
self.spriteBatch = new SpriteBatch(self.GraphicsDevice);
self.image = self.Content.LoadTexture2D("../../images/test_sprite.png");
self.preloading = false;
}
if (self.Content.AllContentLoaded()) {
//texture, scale, sourceRect, position, isVisible, animationType, numberOfFrames, millisecondsPerFrame
self.sprite = new AnimatedSprite(
self.image,
new Vector2(0.5, 0.5),
new Rectangle(0, 0, 128, 128),
new Point(500, 200),
true,
AnimationTypes.Loop,
14,
100
);
self.GraphicsDevice.canvas.addEventListener("click", self.GraphicsDevice.ToggleFullScreen.bind(self.GraphicsDevice));
self.gameState = GameStates.Playing;
}
};
/**
* Allows the game to run logic such as updating the world,
* checking for collisions, gathering input, and playing audio.
* @name Update
* @function
* @memberOf Game
*/
Game.prototype.Update = function () {
"use strict";
var self = this;
//GraphicsDevice
if (Mouse.IsButtonClicked(Mouse.RightButton)) {
self.GraphicsDevice.ToggleFullPage();
}
//AnimatedSprite
if (Keyboard.IsKeyDown(Keys.left_arrow)) {
self.sprite.Position.X -= self.SPEED;
}
if (Keyboard.IsKeyDown(Keys.right_arrow)) {
self.sprite.Position.X += self.SPEED;
}
if (Keyboard.IsKeyDown(Keys.up_arrow)) {
self.sprite.Position.Y -= self.SPEED;
}
if (Keyboard.IsKeyDown(Keys.down_arrow)) {
self.sprite.Position.Y += self.SPEED;
}
if (Keyboard.IsKeyPressed(Keys.a)) {
self.animTypeIndex += 1;
if (self.animTypeIndex > 2) {
self.animTypeIndex = 0;
}
self.sprite.AnimationType = self.animTypeIndex;
self.sprite.CurrentFrame = 0;
self.sprite.Forward = true;
}
if (Keyboard.IsKeyPressed(Keys.b)) {
if (self.showBounds) {
self.showBounds = false;
} else {
self.showBounds = true;
}
}
if (Keyboard.IsKeyPressed(Keys.h)) {
if (self.sprite.SpriteEffects === SpriteEffects.FlipHorizontally) {
self.sprite.SpriteEffects = SpriteEffects.None;
} else {
self.sprite.SpriteEffects = SpriteEffects.FlipHorizontally;
}
}
if (Keyboard.IsKeyPressed(Keys.v)) {
if (self.sprite.SpriteEffects === SpriteEffects.FlipVertically) {
self.sprite.SpriteEffects = SpriteEffects.None;
} else {
self.sprite.SpriteEffects = SpriteEffects.FlipVertically;
}
}
if (Keyboard.IsKeyPressed(Keys.s)) {
if (self.animStarted) {
self.sprite.StopAnimation();
self.animStarted = false;
} else {
self.sprite.RunAnimation = true;
if (self.sprite.AnimationType === AnimationTypes.PlayOneTime) {
self.sprite.CurrentFrame = 0;
self.sprite.Forward = true;
}
self.sprite.StartAnimation();
self.animStarted = true;
}
}
if (Keyboard.IsKeyPressed(Keys.m)) {
self.sprite.MillisecondsPerFrame += 20;
//It's compulsory to restart animation
self.sprite.StopAnimation();
if (self.animStarted) {
self.sprite.StartAnimation();
}
}
if (Keyboard.IsKeyPressed(Keys.l)) {
self.sprite.MillisecondsPerFrame -= 20;
if (self.sprite.MillisecondsPerFrame < 0) {
self.sprite.MillisecondsPerFrame = 0;
}
//It's compulsory to restart animation
self.sprite.StopAnimation();
if (self.animStarted) {
self.sprite.StartAnimation();
}
}
if (Keyboard.IsKeyPressed(Keys.add)) {
self.sprite.Scale.X += 0.1;
self.sprite.Scale.Y += 0.1;
if (self.sprite.Scale.X > 1.1 || self.sprite.Scale.Y > 1.1) {
self.sprite.Scale.X = 1.1;
self.sprite.Scale.Y = 1.1;
}
}
if (Keyboard.IsKeyPressed(Keys.subtract)) {
self.sprite.Scale.X -= 0.1;
self.sprite.Scale.Y -= 0.1;
if (self.sprite.Scale.X < 0.1 || self.sprite.Scale.Y < 0.1) {
self.sprite.Scale.X = 0.1;
self.sprite.Scale.Y = 0.1;
}
}
//Map bounds
if (self.sprite.Position.X < 335) {
self.sprite.Position.X = 335;
}
if (self.sprite.Position.X + self.sprite.Width() > 800) {
self.sprite.Position.X = 800 - self.sprite.Width();
}
if (self.sprite.Position.Y < 0) {
self.sprite.Position.Y = 0;
}
if (self.sprite.Position.Y + self.sprite.Height() > 420) {
self.sprite.Position.Y = 420 - self.sprite.Height();
}
self.sprite.Rotation = Mouse.ScrollWheelValue * 10;
};
/**
* This is called when the game should draw itself.
* @name Draw
* @function
* @memberOf Game
*/
Game.prototype.Draw = function () {
"use strict";
var self = this,
position = self.sprite.Position,
scale = self.sprite.Scale,
center = self.sprite.Center();
self.GraphicsDevice.Clear();
//GraphicsDevice
self.spriteBatch.DrawString(self.FONT_BIG, "------ GraphicsDevice ------", new Point(30, 20), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "PreferredBackBufferWidth: " + self.GraphicsDevice.PreferredBackBufferWidth() + " pixels", new Point(30, 45), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "PreferredBackBufferHeight: " + self.GraphicsDevice.PreferredBackBufferHeight() + " pixels", new Point(30, 70), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Is canvas in full page mode? " + self.GraphicsDevice.IsFullPage(), new Point(30, 95), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Is canvas in full screen mode: " + self.GraphicsDevice.IsFullScreen(), new Point(30, 120), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "------ AnimatedSprite ------", new Point(30, 160), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "X: " + position.X.toFixed(2) + " Y: " + position.Y.toFixed(2), new Point(30, 185), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Scale (width): " + scale.X.toFixed(2) + " Scale (height): " + scale.Y.toFixed(2), new Point(30, 210), self.BLACK, Vector2.One());
switch (self.sprite.SpriteEffects) {
case SpriteEffects.None:
self.spriteBatch.DrawString(self.FONT_LITTLE, "Sprite effects: None", new Point(30, 235), self.BLACK, Vector2.One());
break;
case SpriteEffects.FlipHorizontally:
self.spriteBatch.DrawString(self.FONT_LITTLE, "Sprite effects: FlipHorizontally", new Point(30, 235), self.BLACK, Vector2.One());
break;
case SpriteEffects.FlipVertically:
self.spriteBatch.DrawString(self.FONT_LITTLE, "Sprite effects: FlipVertically", new Point(30, 235), self.BLACK, Vector2.One());
break;
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Rotation: " + self.sprite.Rotation, new Point(30, 260), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Top: " + self.sprite.Top().toFixed(2), new Point(30, 285), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Bottom: " + self.sprite.Bottom().toFixed(2), new Point(30, 310), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Left: " + self.sprite.Left().toFixed(2), new Point(30, 335), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Right: " + self.sprite.Right().toFixed(2), new Point(30, 360), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Half width: " + self.sprite.HalfWidth().toFixed(2), new Point(30, 385), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Half height: " + self.sprite.HalfHeight().toFixed(2), new Point(30, 410), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Center X: " + center.X.toFixed(2) + " Center Y: " + center.Y.toFixed(2), new Point(30, 435), self.BLACK, Vector2.One());
switch (self.sprite.AnimationType) {
case AnimationTypes.Loop:
self.spriteBatch.DrawString(self.FONT_LITTLE, "Animation type: Loop", new Point(30, 460), self.BLACK, Vector2.One());
break;
case AnimationTypes.PingPongLoop:
self.spriteBatch.DrawString(self.FONT_LITTLE, "Animation type: PingPongLoop", new Point(30, 460), self.BLACK, Vector2.One());
break;
case AnimationTypes.PlayOneTime:
self.spriteBatch.DrawString(self.FONT_LITTLE, "Animation type: PlayOneTime", new Point(30, 460), self.BLACK, Vector2.One());
break;
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Milliseconds per frame: " + self.sprite.MillisecondsPerFrame, new Point(30, 485), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Current frame / Number of frames: " + self.sprite.CurrentFrame + "/" + self.sprite.NumberOfFrames, new Point(30, 510), self.BLACK, Vector2.One());
//Draw the separating lines
self.spriteBatch.DrawSegment(new Segment(new Point(335, 0), new Point(335, 600)), "3", self.BLACK);
self.spriteBatch.DrawSegment(new Segment(new Point(335, 420), new Point(800, 420)), "3", self.BLACK);
//Instructions
self.spriteBatch.DrawString(self.FONT_LITTLE, "Left click to enter full screen", new Point(347, 440), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press B to show bounds", new Point(347, 465), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press arrow keys to move it", new Point(347, 490), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press M to increase milliseconds", new Point(347, 515), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press L to decrease milliseconds", new Point(347, 540), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press S to start/stop anim.", new Point(347, 565), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Right click to enter full page", new Point(592, 440), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press A to change anim. type", new Point(592, 465), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press H to flip horizontally", new Point(592, 490), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Press V to flip vertically", new Point(592, 515), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "+/- to incr./decr. scale", new Point(592, 540), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Mouse wheel to rotate sprite", new Point(592, 565), self.BLUE, Vector2.One());
//The sprite
self.spriteBatch.Draw(
self.sprite.Texture,
self.sprite.Position,
self.sprite.SourceRect,
self.sprite.Rotation,
self.sprite.Scale,
self.sprite.SpriteEffects
);
//Bounds
if (self.showBounds) {
self.spriteBatch.DrawRectangle(self.sprite.Bounds(), "3", self.GREEN);
}
};
/**
* Call this method to initialize the game, begin running the game loop, and
* start processing events for the game.
* @name Run
* @function
* @memberOf Game
*/
Game.prototype.Run = function () {
"use strict";
/*globals requestAnimationFrame*/
var self = this;
//Call the game loop
requestAnimationFrame(self.Run.bind(self), self.GraphicsDevice.canvas);
//Choose the method to run according to the game state
switch (self.gameState) {
case GameStates.Initializing:
self.Initialize();
break;
case GameStates.Loading:
self.LoadContent();
break;
case GameStates.Playing:
self.Update();
self.Draw();
break;
}
};

View File

@ -0,0 +1,183 @@
/**
* Provides basic graphics device initialization, game logic, and rendering code.
*/
function Game() {
"use strict";
/*globals ContentManager, GraphicsDevice, document, SpriteBatch, GameStates*/
this.Content = new ContentManager();
this.GraphicsDevice = new GraphicsDevice(document);
this.spriteBatch = null;
this.gameState = GameStates.Initializing;
this.preloading = true;
}
/**
* Allows the game to perform any initialization it needs to before starting to run.
* This is where it can query for any required services and load any non-graphic
* related content.
* @name Initialize
* @function
* @memberOf Game
*/
Game.prototype.Initialize = function () {
"use strict";
var self = this;
// TODO: Add your initialization logic here
self.gameState = GameStates.Loading;
};
/**
* LoadContent will be called once per game and is the place to load
* all of your content.
* @name LoadContent
* @function
* @memberOf Game
*/
Game.prototype.LoadContent = function () {
"use strict";
var self = this;
if (self.preloading) {
// Create a new SpriteBatch, which can be used to draw textures.
self.spriteBatch = new SpriteBatch(self.GraphicsDevice);
// TODO: use this.Content.Load... to load your game content here
self.preloading = false;
}
if (self.Content.AllContentLoaded) {
// TODO: create the objects that will use the content previously loaded
self.gameState = GameStates.Playing;
}
};
/**
* Allows the game to run logic such as updating the world,
* checking for collisions, gathering input, and playing audio.
* @name Update
* @function
* @memberOf Game
*/
Game.prototype.Update = function () {
"use strict";
var self = this;
// TODO: Add your update logic here
};
/**
* This is called when the game should draw itself.
* @name Draw
* @function
* @memberOf Game
*/
Game.prototype.Draw = function () {
"use strict";
var self = this;
self.GraphicsDevice.Clear();
// TODO: Add your drawing code here
self.GraphicsDevice.Clear();
self.spriteBatch.DrawString(
"normal bold 18px Helvetica",
"------ MOUSE ------",
new Point(30, 20),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 16px Helvetica",
"X: "+Mouse.X+" Y: "+Mouse.Y,
new Point(30, 50),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 16px Helvetica",
"Wheel: "+Mouse.ScrollWheelValue,
new Point(30, 80),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 16px Helvetica",
"LeftButtonPressed: "+Mouse.LeftButtonPressed,
new Point(30, 110),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 16px Helvetica",
"RightButtonPressed: "+Mouse.RightButtonPressed,
new Point(30, 140),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 16px Helvetica",
"MiddleButtonPressed: "+Mouse.MiddleButtonPressed,
new Point(30, 170),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 18px Helvetica",
"------ KEYBOARD ------",
new Point(30, 230),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 16px Helvetica",
"Teclas que están siendo pulsadas: "+Keyboard.keyDownList,
new Point(30, 260),
"#000000",
Vector2.One()
);
self.spriteBatch.DrawString(
"normal bold 16px Helvetica",
"Teclas pulsadas: "+Keyboard.keyUpList,
new Point(30, 290),
"#000000",
Vector2.One()
);
};
/**
* Call this method to initialize the game, begin running the game loop, and
* start processing events for the game.
* @name Run
* @function
* @memberOf Game
*/
Game.prototype.Run = function () {
"use strict";
/*globals requestAnimationFrame*/
var self = this;
//Call the game loop
requestAnimationFrame(self.Run.bind(self), self.GraphicsDevice.canvas);
//Choose the method to run according to the game state
switch (self.gameState) {
case GameStates.Initializing:
self.Initialize();
break;
case GameStates.Loading:
self.LoadContent();
break;
case GameStates.Playing:
self.Update();
self.Draw();
break;
}
};

View File

@ -0,0 +1,377 @@
/**
* Provides basic graphics device initialization, game logic, and rendering code.
*/
function Game() {
"use strict";
/*globals ContentManager, GraphicsDevice, document, SpriteBatch, GameStates, Point, Vector2, Rectangle, Keyboard, Keys, Mouse, Segment*/
this.Content = new ContentManager();
this.GraphicsDevice = new GraphicsDevice(document);
this.spriteBatch = null;
this.gameState = GameStates.Initializing;
this.preloading = true;
//Constants
this.FONT_LITTLE = "normal bold 15px Helvetica";
this.FONT_BIG = "normal bold 18px Helvetica";
this.BLACK = "#000000";
this.GREEN = "#00FF00";
this.RED = "#FF0000";
this.BLUE = "#0000FF";
this.RECT_VEL = 3;
this.RECT_INFLATE_VALUE = 2;
/***** TEST VARIABLES *****/
this.testingRectangle = false;
//Point
this.pointZero_OK = false;
this.pointOne_OK = false;
this.pointsAreEqual = false;
this.pointsAreDifferent = false;
//Vector2
this.vectorZero_OK = false;
this.vectorOne_OK = false;
this.vectorAdd_OK = false;
this.vectorSubstract_OK = false;
this.vectorDivide_OK = false;
this.vectorMultiply_OK = false;
this.vectorDistance_OK = false;
this.vectorLength_OK = false;
this.vectorsAreEqual = false;
this.vectorsAreDifferent = false;
//Rectangle
this.r1 = null;
this.r2 = null;
}
/**
* Allows the game to perform any initialization it needs to before starting to run.
* This is where it can query for any required services and load any non-graphic
* related content.
* @name Initialize
* @function
* @memberOf Game
*/
Game.prototype.Initialize = function () {
"use strict";
var self = this;
self.r1 = new Rectangle(430, 315, 20, 40);
self.r2 = new Rectangle(690, 30, 80, 50);
self.gameState = GameStates.Loading;
};
/**
* LoadContent will be called once per game and is the place to load
* all of your content.
* @name LoadContent
* @function
* @memberOf Game
*/
Game.prototype.LoadContent = function () {
"use strict";
var self = this;
if (self.preloading) {
// Create a new SpriteBatch, which can be used to draw textures.
self.spriteBatch = new SpriteBatch(self.GraphicsDevice);
// TODO: use this.Content.Load... to load your game content here
self.preloading = false;
}
if (self.Content.AllContentLoaded) {
// TODO: create the objects that will use the content previously loaded
self.gameState = GameStates.Playing;
}
};
/**
* Allows the game to run logic such as updating the world,
* checking for collisions, gathering input, and playing audio.
* @name Update
* @function
* @memberOf Game
*/
Game.prototype.Update = function () {
"use strict";
var self = this,
p1 = null,
p2 = null,
v1 = null,
v2 = null;
if (!self.testingRectangle && Keyboard.IsKeyPressed(Keys.r)) {
self.testingRectangle = true;
}
if (self.testingRectangle) {
//Rectangle
if (Keyboard.IsKeyDown(Keys.a) || Keyboard.IsKeyDown(Keys.left_arrow)) {
self.r1.X -= self.RECT_VEL;
}
if (Keyboard.IsKeyDown(Keys.d) || Keyboard.IsKeyDown(Keys.right_arrow)) {
self.r1.X += self.RECT_VEL;
}
if (Keyboard.IsKeyDown(Keys.w) || Keyboard.IsKeyDown(Keys.up_arrow)) {
self.r1.Y -= self.RECT_VEL;
}
if (Keyboard.IsKeyDown(Keys.s) || Keyboard.IsKeyDown(Keys.down_arrow)) {
self.r1.Y += self.RECT_VEL;
}
if (Keyboard.IsKeyDown(Keys.add)) {
self.r1.Inflate(self.RECT_INFLATE_VALUE, self.RECT_INFLATE_VALUE);
if (self.r1.Width > 400) {
self.r1.Width = 400;
}
if (self.r1.Height > 600) {
self.r1.Height = 600;
}
}
if (Keyboard.IsKeyDown(Keys.subtract)) {
self.r1.Inflate(-self.RECT_INFLATE_VALUE, -self.RECT_INFLATE_VALUE);
}
//Map bounds
if (self.r1.X < 400) {
self.r1.X = 400;
}
if (self.r1.X + self.r1.Width > 800) {
self.r1.X = 800 - self.r1.Width;
}
if (self.r1.Y < 0) {
self.r1.Y = 0;
}
if (self.r1.Y + self.r1.Height > 600) {
self.r1.Y = 600 - self.r1.Height;
}
} else {
//Point
p1 = Point.Zero();
p2 = Point.One();
if (p1.X === 0 && p1.Y === 0) {
self.pointZero_OK = true;
}
if (p2.X === 1 && p2.Y === 1) {
self.pointOne_OK = true;
}
p2 = new Point(25, 150);
self.pointsAreDifferent = !Point.Equals(p1, p2);
p2 = new Point(0, 0);
self.pointsAreEqual = Point.Equals(p1, p2);
//Vector2
v1 = Vector2.Zero();
v2 = Vector2.One();
if (v1.X === 0 && v1.Y === 0) {
self.vectorZero_OK = true;
}
if (v2.X === 1 && v2.Y === 1) {
self.vectorOne_OK = true;
}
v1 = new Vector2(100, 150);
self.vectorsAreDifferent = !Vector2.Equals(v1, v2);
v2 = new Vector2(100, 150);
self.vectorsAreEqual = Vector2.Equals(v1, v2);
v2 = new Vector2(20, 25);
self.vectorAdd_OK = Vector2.Equals(Vector2.Add(v1, v2), new Vector2(120, 175));
self.vectorSubstract_OK = Vector2.Equals(Vector2.Substract(v1, v2), new Vector2(80, 125));
self.vectorDivide_OK = Vector2.Equals(Vector2.Divide(v1, v2), new Vector2(5, 6));
self.vectorMultiply_OK = Vector2.Equals(Vector2.Multiply(v1, v2), new Vector2(2000, 3750));
self.vectorDistance_OK = Math.floor(Vector2.Distance(v1, v2)) === 148;
self.vectorLength_OK = Math.floor(v2.Length()) === 32;
}
};
/**
* This is called when the game should draw itself.
* @name Draw
* @function
* @memberOf Game
*/
Game.prototype.Draw = function () {
"use strict";
var self = this,
location = self.r1.Location(),
center = self.r1.Center(),
collision = (self.r2.Intersects(self.r1) !== false);
self.GraphicsDevice.Clear();
if (self.testingRectangle) {
//Rectangle data
self.spriteBatch.DrawString(self.FONT_BIG, "------ RECTANGLE ------", new Point(30, 20), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "X: " + location.X + " Y: " + location.Y, new Point(30, 50), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Top: " + self.r1.Top(), new Point(30, 80), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Bottom: " + self.r1.Bottom(), new Point(30, 110), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Left: " + self.r1.Left(), new Point(30, 140), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Right: " + self.r1.Right(), new Point(30, 170), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Half width: " + self.r1.HalfWidth(), new Point(30, 200), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Half height: " + self.r1.HalfHeight(), new Point(30, 230), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Center X: " + center.X + " Center Y: " + center.Y, new Point(30, 260), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Is empty? (width and height = 0): " + self.r1.IsEmpty(), new Point(30, 290), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Red rectangle contains the upper-left vertex", new Point(30, 320), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "of the green one?: " + self.r2.Contains(self.r1.Location()), new Point(30, 340), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Is there a collision between the rectangles?: " + collision, new Point(30, 370), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Use A, W, S, D or arrow keys to move", new Point(30, 450), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "the green rectangle", new Point(30, 470), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Use + key to inflate the rectangle", new Point(30, 510), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Use - key to deflate the rectangle", new Point(30, 540), self.BLUE, Vector2.One());
//Draw the separating line
self.spriteBatch.DrawSegment(new Segment(new Point(400, 0), new Point(400, 600)), "3", self.BLACK);
//Rectangle
self.spriteBatch.DrawRectangle(self.r1, "3", self.GREEN);
self.spriteBatch.DrawRectangle(self.r2, "3", self.RED);
} else {
//Point
self.spriteBatch.DrawString(self.FONT_BIG, "------ POINT ------", new Point(30, 20), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Point.Zero()...", new Point(30, 50), self.BLACK, Vector2.One());
if (self.pointZero_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "OK", new Point(300, 50), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "ERROR", new Point(300, 50), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Point.One()...", new Point(30, 80), self.BLACK, Vector2.One());
if (self.pointOne_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "OK", new Point(300, 80), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "ERROR", new Point(300, 80), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Point.Equals(). Are p1(0,0) and p2(25,150) different?", new Point(30, 110), self.BLACK, Vector2.One());
if (self.pointsAreDifferent) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(570, 110), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(570, 110), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Point.Equals(). Are p1(0,0) and p2(0,0) equals?", new Point(30, 140), self.BLACK, Vector2.One());
if (self.pointsAreEqual) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(570, 140), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(570, 140), self.RED, Vector2.One());
}
//Vector2
self.spriteBatch.DrawString(self.FONT_BIG, "----- VECTOR2 -----", new Point(30, 200), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Zero()...", new Point(30, 230), self.BLACK, Vector2.One());
if (self.vectorZero_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "OK", new Point(320, 230), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "ERROR", new Point(320, 230), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.One()...", new Point(30, 260), self.BLACK, Vector2.One());
if (self.vectorOne_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "OK", new Point(320, 260), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "ERROR", new Point(320, 260), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Equals(). Are v1(100,150) and v2(1,1) different?", new Point(30, 290), self.BLACK, Vector2.One());
if (self.vectorsAreDifferent) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(600, 290), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(600, 290), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Equals(). Are v1(100,150) and v2(100,150) equals?", new Point(30, 320), self.BLACK, Vector2.One());
if (self.vectorsAreEqual) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(600, 320), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(600, 320), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Add(). v1(100,150) + v2(20,25) = v(120,175)?", new Point(30, 350), self.BLACK, Vector2.One());
if (self.vectorAdd_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(600, 350), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(600, 350), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Substract(). v1(100,150) - v2(20,25) = v(80,125)?", new Point(30, 380), self.BLACK, Vector2.One());
if (self.vectorSubstract_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(600, 380), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(600, 380), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Divide(). v1(100,150) / v2(20,25) = v(5,6)?", new Point(30, 410), self.BLACK, Vector2.One());
if (self.vectorDivide_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(600, 410), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(600, 410), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Multiply(). v1(100,150) * v2(20,25) = v(2000,3750)?", new Point(30, 440), self.BLACK, Vector2.One());
if (self.vectorMultiply_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "YES", new Point(600, 440), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NO", new Point(600, 440), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Distance() between v1(100,150) and v2(20,25)...", new Point(30, 470), self.BLACK, Vector2.One());
if (self.vectorMultiply_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "148", new Point(600, 470), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NOT 148", new Point(600, 470), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_LITTLE, "Testing static method Vector2.Length() of v2(20,25)...", new Point(30, 500), self.BLACK, Vector2.One());
if (self.vectorMultiply_OK) {
self.spriteBatch.DrawString(self.FONT_BIG, "32", new Point(600, 500), self.GREEN, Vector2.One());
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "NOT 32", new Point(600, 500), self.RED, Vector2.One());
}
self.spriteBatch.DrawString(self.FONT_BIG, "Press R to test Rectangle methods...", new Point(30, 550), self.BLUE, Vector2.One());
}
};
/**
* Call this method to initialize the game, begin running the game loop, and
* start processing events for the game.
* @name Run
* @function
* @memberOf Game
*/
Game.prototype.Run = function () {
"use strict";
/*globals requestAnimationFrame*/
var self = this;
//Call the game loop
requestAnimationFrame(self.Run.bind(self), self.GraphicsDevice.canvas);
//Choose the method to run according to the game state
switch (self.gameState) {
case GameStates.Initializing:
self.Initialize();
break;
case GameStates.Loading:
self.LoadContent();
break;
case GameStates.Playing:
self.Update();
self.Draw();
break;
}
};

View File

@ -0,0 +1,281 @@
/**
* Provides basic graphics device initialization, game logic, and rendering code.
*/
function Game() {
"use strict";
/*globals ContentManager, GraphicsDevice, document, SpriteBatch, GameStates, Point, Vector2, Rectangle, Keyboard, Keys, Mouse, Segment, SpriteEffects, Sprite, Texture2D, setTimeout*/
this.Content = new ContentManager();
this.GraphicsDevice = new GraphicsDevice(document);
this.spriteBatch = null;
this.gameState = GameStates.Initializing;
this.preloading = true;
//Constants
this.FONT_LITTLE = "normal bold 15px Helvetica";
this.FONT_BIG = "normal bold 18px Helvetica";
this.BLACK = "#000000";
this.GREEN = "#00FF00";
this.RED = "#FF0000";
this.BLUE = "#0000FF";
/***** TEST VARIABLES *****/
//Song
this.song = null;
//SoundEffects
this.vacaSound = null;
this.cerdoSound = null;
this.cerberoSound = null;
//Images
this.vaca = null;
this.cerdo = null;
this.cerbero = null;
//Sprites
this.vacaSprite = null;
this.cerdoSprite = null;
this.cerberoSprite = null;
//Flags
this.playing = false;
}
/**
* Allows the game to perform any initialization it needs to before starting to run.
* This is where it can query for any required services and load any non-graphic
* related content.
* @name Initialize
* @function
* @memberOf Game
*/
Game.prototype.Initialize = function () {
"use strict";
var self = this;
// TODO: Add your initialization logic here
self.gameState = GameStates.Loading;
};
/**
* LoadContent will be called once per game and is the place to load
* all of your content.
* @name LoadContent
* @function
* @memberOf Game
*/
Game.prototype.LoadContent = function () {
"use strict";
var self = this;
if (self.preloading) {
// Create a new SpriteBatch, which can be used to draw textures.
self.spriteBatch = new SpriteBatch(self.GraphicsDevice);
self.song = self.Content.LoadSong("../../sounds/test_song.mp3");
self.vacaSound = self.Content.LoadSoundEffect("../../sounds/test_sound2.wav");
self.cerdoSound = self.Content.LoadSoundEffect("../../sounds/test_sound3.wav");
self.cerberoSound = self.Content.LoadSoundEffect("../../sounds/test_sound1.wav");
self.vaca = self.Content.LoadTexture2D("../../images/vaca.jpg");
self.cerdo = self.Content.LoadTexture2D("../../images/cerdo.png");
self.cerbero = self.Content.LoadTexture2D("../../images/cerbero.jpg");
self.preloading = false;
}
if (self.Content.AllContentLoaded()) {
self.vacaSprite = new Sprite(
self.vaca,
new Vector2(0.75, 0.75),
new Rectangle(0, 0, self.vaca.Width(), self.vaca.Height()),
new Point(500, 30),
false
);
self.cerdoSprite = new Sprite(
self.cerdo,
new Vector2(0.70, 0.70),
new Rectangle(0, 0, self.cerdo.Width(), self.cerdo.Height()),
new Point(540, 210),
false
);
self.cerberoSprite = new Sprite(
self.cerbero,
new Vector2(0.75, 0.75),
new Rectangle(0, 0, self.cerbero.Width(), self.cerbero.Height()),
new Point(500, 380),
false
);
self.gameState = GameStates.Playing;
}
};
/**
* Allows the game to run logic such as updating the world,
* checking for collisions, gathering input, and playing audio.
* @name Update
* @function
* @memberOf Game
*/
Game.prototype.Update = function () {
"use strict";
var self = this;
//Song
if (Keyboard.IsKeyPressed(Keys.p)) {
if (self.playing) {
self.song.Pause();
self.playing = false;
} else {
self.song.Play();
self.playing = true;
}
}
if (Keyboard.IsKeyPressed(Keys.s)) {
self.song.Stop();
self.playing = false;
}
if (Keyboard.IsKeyPressed(Keys.m)) {
if (self.song.IsMuted()) {
self.song.IsMuted(false);
} else {
self.song.IsMuted(true);
}
}
if (Keyboard.IsKeyPressed(Keys.l)) {
if (self.song.IsRepeating()) {
self.song.IsRepeating(false);
} else {
self.song.IsRepeating(true);
}
}
if (Keyboard.IsKeyPressed(Keys.add)) {
self.song.Volume(self.song.Volume() + 0.05);
}
if (Keyboard.IsKeyPressed(Keys.subtract)) {
self.song.Volume(self.song.Volume() - 0.05);
}
//Sounds
if (Keyboard.IsKeyPressed(Keys.num1) || Keyboard.IsKeyPressed(Keys.numpad_1)) {
self.vacaSound.Play();
self.vacaSprite.IsVisible = true;
setTimeout(function () { self.vacaSprite.IsVisible = false; }, self.vacaSound.Duration() * 1000);
}
if (Keyboard.IsKeyPressed(Keys.num2) || Keyboard.IsKeyPressed(Keys.numpad_2)) {
self.cerdoSound.Play();
self.cerdoSprite.IsVisible = true;
setTimeout(function () { self.cerdoSprite.IsVisible = false; }, self.cerdoSound.Duration() * 1000);
}
if (Keyboard.IsKeyPressed(Keys.num3) || Keyboard.IsKeyPressed(Keys.numpad_3)) {
self.cerberoSound.Play();
self.cerberoSprite.IsVisible = true;
setTimeout(function () { self.cerberoSprite.IsVisible = false; }, self.cerberoSound.Duration() * 1000);
}
};
/**
* This is called when the game should draw itself.
* @name Draw
* @function
* @memberOf Game
*/
Game.prototype.Draw = function () {
"use strict";
var self = this;
self.GraphicsDevice.Clear();
//Song attributes
self.spriteBatch.DrawString(self.FONT_BIG, "------ SONG ------", new Point(30, 20), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Duration (in seconds): " + self.song.Duration(), new Point(30, 50), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Is muted? " + self.song.IsMuted(), new Point(30, 80), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Play in loop? " + self.song.IsRepeating(), new Point(30, 110), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Current time (in seconds): " + self.song.PlayPosition(), new Point(30, 140), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_LITTLE, "Volume: " + (Math.round(self.song.Volume() * 100) / 100), new Point(30, 170), self.BLACK, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Press M to mute the song", new Point(30, 350), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Press L to activate loop", new Point(30, 390), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Press + to increase volume", new Point(30, 430), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Press - to decrease volume", new Point(30, 470), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Press P to play/pause the song", new Point(30, 510), self.BLUE, Vector2.One());
self.spriteBatch.DrawString(self.FONT_BIG, "Press S to stop the song", new Point(30, 550), self.BLUE, Vector2.One());
//Draw the separating line
self.spriteBatch.DrawSegment(new Segment(new Point(400, 0), new Point(400, 600)), "3", self.BLACK);
//Draw the images
if (self.vacaSprite.IsVisible) {
self.spriteBatch.Draw(
self.vacaSprite.Texture,
self.vacaSprite.Position,
self.vacaSprite.SourceRect,
self.vacaSprite.Rotation,
self.vacaSprite.Scale,
SpriteEffects.None
);
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "Press 1 to play sound effect 1", new Point(470, 60), self.BLUE, Vector2.One());
}
if (self.cerdoSprite.IsVisible) {
self.spriteBatch.Draw(
self.cerdoSprite.Texture,
self.cerdoSprite.Position,
self.cerdoSprite.SourceRect,
self.cerdoSprite.Rotation,
self.cerdoSprite.Scale,
SpriteEffects.None
);
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "Press 2 to play sound effect 2", new Point(470, 260), self.BLUE, Vector2.One());
}
if (self.cerberoSprite.IsVisible) {
self.spriteBatch.Draw(
self.cerberoSprite.Texture,
self.cerberoSprite.Position,
self.cerberoSprite.SourceRect,
self.cerberoSprite.Rotation,
self.cerberoSprite.Scale,
SpriteEffects.None
);
} else {
self.spriteBatch.DrawString(self.FONT_BIG, "Press 3 to play sound effect 3", new Point(470, 460), self.BLUE, Vector2.One());
}
};
/**
* Call this method to initialize the game, begin running the game loop, and
* start processing events for the game.
* @name Run
* @function
* @memberOf Game
*/
Game.prototype.Run = function () {
"use strict";
/*globals requestAnimationFrame*/
var self = this;
//Call the game loop
requestAnimationFrame(self.Run.bind(self), self.GraphicsDevice.canvas);
//Choose the method to run according to the game state
switch (self.gameState) {
case GameStates.Initializing:
self.Initialize();
break;
case GameStates.Loading:
self.LoadContent();
break;
case GameStates.Playing:
self.Update();
self.Draw();
break;
}
};

View File

@ -0,0 +1,108 @@
/**
* The ContentManager loads sound and images of the game into memory.
* @constructor
*/
function ContentManager() {
"use strict";
this.assetsToLoad = [];
this.assetsLoaded = 0;
this.allLoaded = false;
}
/**
* Function called when a content was loaded in memory.
* @name loadHandler
* @function
* @private
* @memberOf ContentManager
*/
ContentManager.prototype.loadHandler = function () {
"use strict";
var self = this,
len = self.assetsToLoad.length,
i;
self.assetsLoaded += 1;
//If all contents were loaded then remove listeners and reset variables
if (self.assetsLoaded === len) {
//Remove the load handlers
for (i = 0; i < len; i += 1) {
self.assetsToLoad[i].removeEventListener("load", self.loadHandler.bind(self), false);
}
self.allLoaded = true;
//self.assetsToLoad.splice(0, len);
//self.assetsLoaded = 0;
}
};
/**
* Loads an image and return a Texture2D instance.
* @name LoadTexture2D
* @function
* @param {String} src - The path to the image.
* @memberOf ContentManager
*/
ContentManager.prototype.LoadTexture2D = function (src) {
"use strict";
/*global Texture2D*/
var self = this,
texture = new Texture2D(src);
//Add load handler
texture.Image.addEventListener("load", self.loadHandler.bind(self), false);
self.assetsToLoad.push(texture.Image);
return texture;
};
/**
* Loads a song and return a Song instance.
* @name LoadSong
* @function
* @param {String} src - The path to the song.
* @memberOf ContentManager
*/
ContentManager.prototype.LoadSong = function (src) {
"use strict";
/*global Song*/
var self = this,
song = new Song(src);
//Add load handler
song.Audio.addEventListener("loadedmetadata", self.loadHandler.bind(self), false);
self.assetsToLoad.push(song.Audio);
return song;
};
/**
* Loads a sound effect and return a SoundEffect instance.
* @name LoadSoundEffect
* @function
* @param {String} src - The path to the sound effect.
* @memberOf ContentManager
*/
ContentManager.prototype.LoadSoundEffect = function (src) {
"use strict";
/*global SoundEffect*/
var self = this,
soundEffect = new SoundEffect(src);
//Add load handler
soundEffect.Audio.addEventListener("loadedmetadata", self.loadHandler.bind(self), false);
self.assetsToLoad.push(soundEffect.Audio);
return soundEffect;
};
/**
* Check if all contents were loaded or not.
* @name AllContentLoaded
* @function
* @memberOf ContentManager
*/
ContentManager.prototype.AllContentLoaded = function () {
"use strict";
return this.allLoaded;
};

115
src/JS/XNA_Classes/Game.js Normal file
View File

@ -0,0 +1,115 @@
/**
* Provides basic graphics device initialization, game logic, and rendering code.
*/
function Game() {
"use strict";
/*global ContentManager, GraphicsDevice, document, SpriteBatch, GameStates*/
this.Content = new ContentManager();
this.GraphicsDevice = new GraphicsDevice(document);
this.spriteBatch = null;
this.gameState = GameStates.Initializing;
this.preloading = true;
}
/**
* Allows the game to perform any initialization it needs to before starting to run.
* This is where it can query for any required services and load any non-graphic
* related content.
* @name Initialize
* @function
* @memberOf Game
*/
Game.prototype.Initialize = function () {
"use strict";
var self = this;
// TODO: Add your initialization logic here
self.gameState = GameStates.Loading;
};
/**
* LoadContent will be called once per game and is the place to load
* all of your content.
* @name LoadContent
* @function
* @memberOf Game
*/
Game.prototype.LoadContent = function () {
"use strict";
var self = this;
if (self.preloading) {
// Create a new SpriteBatch, which can be used to draw textures.
self.spriteBatch = new SpriteBatch(self.GraphicsDevice);
// TODO: use self.Content.Load... to load your game content here
self.preloading = false;
}
if (self.Content.AllContentLoaded()) {
// TODO: create the objects that will use the content previously loaded, like sprites or sounds
self.gameState = GameStates.Playing;
}
};
/**
* Allows the game to run logic such as updating the world,
* checking for collisions, gathering input, and playing audio.
* @name Update
* @function
* @memberOf Game
*/
Game.prototype.Update = function () {
"use strict";
var self = this;
// TODO: Add your update logic here
};
/**
* This is called when the game should draw itself.
* @name Draw
* @function
* @memberOf Game
*/
Game.prototype.Draw = function () {
"use strict";
var self = this;
self.GraphicsDevice.Clear();
// TODO: Add your drawing code here
};
/**
* Call this method to initialize the game, begin running the game loop, and
* start processing events for the game.
* @name Run
* @function
* @memberOf Game
*/
Game.prototype.Run = function () {
"use strict";
/*globals requestAnimationFrame*/
var self = this;
//Call the game loop
requestAnimationFrame(self.Run.bind(self), self.GraphicsDevice.canvas);
//Choose the method to run according to the game state
switch (self.gameState) {
case GameStates.Initializing:
self.Initialize();
break;
case GameStates.Loading:
self.LoadContent();
break;
case GameStates.Playing:
self.Update();
self.Draw();
break;
}
};

View File

@ -0,0 +1,172 @@
/**
* Creates an instance of the canvas. Also handles the configuration of the canvas.
* @constructor
* @param {HTML} document - The descriptor of the HTML.
*/
function GraphicsDevice(document) {
"use strict";
/*global Element*/
this.canvas = document.querySelector("canvas");
}
/**
* Gets the preferred back-buffer height.
* @name PreferredBackBufferHeight
* @function
* @memberOf GraphicsDevice
*/
GraphicsDevice.prototype.PreferredBackBufferHeight = function () {
"use strict";
return this.canvas.height;
};
/**
* Gets the preferred back-buffer width.
* @name PreferredBackBufferWidth
* @function
* @memberOf GraphicsDevice
*/
GraphicsDevice.prototype.PreferredBackBufferWidth = function () {
"use strict";
return this.canvas.width;
};
/**
* Specifies the default minimum back-buffer height (600).
* @name DefaultBackBufferHeight
* @function
* @memberOf GraphicsDevice
* @static
*/
GraphicsDevice.prototype.DefaultBackBufferHeight = function () {
"use strict";
return 600;
};
/**
* Specifies the default minimum back-buffer width (800).
* @name DefaultBackBufferWidth
* @function
* @memberOf GraphicsDevice
* @static
*/
GraphicsDevice.prototype.DefaultBackBufferWidth = function () {
"use strict";
return 800;
};
/**
* Toggles between full page and windowed mode.
* @name ToggleFullPage
* @function
* @memberOf GraphicsDevice
*/
GraphicsDevice.prototype.ToggleFullPage = function () {
"use strict";
var self = this,
canvas = self.canvas,
scaleX = 0,
scaleY = 0;
//Don't go to full page if full screen is activated
if (!self.IsFullScreen()) {
if (self.IsFullPage()) {
canvas.width = self.DefaultBackBufferWidth();
canvas.height = self.DefaultBackBufferHeight();
} else {
scaleX = window.innerWidth / canvas.width;
scaleY = window.innerHeight / canvas.height;
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.getContext("2d").scale(scaleX, scaleY);
}
}
};
/**
* Toggles between full screen and windowed mode.
* @name ToggleFullScreen
* @function
* @memberOf GraphicsDevice
*/
GraphicsDevice.prototype.ToggleFullScreen = function () {
"use strict";
/*global setTimeout*/
var self = this,
canvas = self.canvas,
scaleX = 0,
scaleY = 0;
if (!self.IsFullScreen()) {
//If canvas is full page turn it normal
if (self.IsFullPage()) {
self.ToggleFullPage();
}
if (canvas.requestFullScreen) {
canvas.requestFullScreen();
} else if (canvas.mozRequestFullScreen) {
canvas.mozRequestFullScreen();
} else if (canvas.webkitRequestFullScreen) {
canvas.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
scaleX = window.innerWidth / canvas.width;
canvas.width = window.innerWidth;
//For some reason (that I dunno), setTimeout is compulsory for the correct resizing
setTimeout(function () {
scaleY = window.innerHeight / canvas.height;
canvas.height = window.innerHeight;
canvas.getContext("2d").scale(scaleX, scaleY);
}, 150);
} else {
if (document.cancelFullScreen) {
document.cancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
canvas.width = self.DefaultBackBufferWidth();
canvas.height = self.DefaultBackBufferHeight();
}
};
/**
* Gets a value that indicates whether the device should start in full-page mode.
* @name IsFullPage
* @function
* @memberOf GraphicsDevice
*/
GraphicsDevice.prototype.IsFullPage = function () {
"use strict";
/*global window */
return (this.canvas.width === window.innerWidth && this.canvas.height === window.innerHeight);
};
/**
* Gets a value that indicates whether the device should start in full-screen mode.
* @name IsFullScreen
* @function
* @memberOf GraphicsDevice
*/
GraphicsDevice.prototype.IsFullScreen = function () {
"use strict";
/*global document */
return !((document.fullScreenElement && document.fullScreenElement !== null) || (!document.mozFullScreen && !document.webkitIsFullScreen));
};
/**
* Clear the canvas rectangle.
* @name Clear
* @function
* @memberOf GraphicsDevice
*/
GraphicsDevice.prototype.Clear = function () {
"use strict";
var canvas = this.canvas;
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
};

View File

@ -0,0 +1,153 @@
/**
* Allows retrieval of keystrokes from a keyboard input device.
* @global
*/
var Keyboard = {
keyDownList: [],
keyUpList: [],
keyPressList: [],
/**
* Add a key to the list of pressed down keys.
* @name addKeyDown
* @function
* @param {Event} event - This parameter represents a keyboard event.
* @memberOf Keyboard
* @static
*/
addKeyDown: function (event) {
"use strict";
var keyCode = event.keyCode,
indexOfKey = Keyboard.keyDownList.indexOf(keyCode);
if (indexOfKey === -1) {
Keyboard.removeKeyUp(keyCode);
Keyboard.keyDownList.push(keyCode);
}
event.preventDefault();
},
/**
* Add a key to the list of released keys.
* @name addKeyUp
* @function
* @param {Event} event - This parameter represents a keyboard event.
* @memberOf Keyboard
* @static
*/
addKeyUp: function (event) {
"use strict";
var keyCode = event.keyCode,
indexOfKey = Keyboard.keyUpList.indexOf(keyCode);
if (indexOfKey === -1) {
Keyboard.removeKeyDown(keyCode);
Keyboard.keyUpList.push(keyCode);
}
indexOfKey = Keyboard.keyPressList.indexOf(keyCode);
if (indexOfKey !== -1) {
Keyboard.keyPressList.splice(indexOfKey, 1);
} else {
Keyboard.keyPressList.push(keyCode);
}
event.preventDefault();
},
/**
* Remove a key of the list of pressed down keys.
* @name removeKeyDown
* @function
* @param {Number} key - The key code.
* @memberOf Keyboard
* @static
*/
removeKeyDown: function (key) {
"use strict";
var indexOfKey = Keyboard.keyDownList.indexOf(key);
if (indexOfKey !== -1) {
Keyboard.keyDownList.splice(indexOfKey, 1);
}
},
/**
* Remove a key of the list of released keys.
* @name removeKeyUp
* @function
* @param {Number} key - The key code.
* @memberOf Keyboard
* @static
*/
removeKeyUp: function (key) {
"use strict";
var indexOfKey = Keyboard.keyUpList.indexOf(key);
if (indexOfKey !== -1) {
Keyboard.keyUpList.splice(indexOfKey, 1);
}
},
/**
* Returns whether a specified key is currently being pressed.
* @name IsKeyDown
* @function
* @param {Keys} key - Enumerated value that specifies the key to query.
* @memberOf Keyboard
* @static
*/
IsKeyDown: function (key) {
"use strict";
var indexOfKey = Keyboard.keyDownList.indexOf(key);
if (indexOfKey !== -1) {
return true;
} else {
return false;
}
},
/**
* Returns whether a specified key is currently not pressed.
* @name IsKeyUp
* @function
* @param {Keys} key - Enumerated value that specifies the key to query.
* @memberOf Keyboard
* @static
*/
IsKeyUp: function (key) {
"use strict";
var indexOfKey = Keyboard.keyUpList.indexOf(key);
if (indexOfKey !== -1) {
Keyboard.removeKeyUp(key);
return true;
} else {
return false;
}
},
/**
* Returns whether a specified key was pressed and released.
* @name IsKeyPressed
* @function
* @param {Keys} key - Enumerated value that specifies the key to query.
* @memberOf Keyboard
* @static
*/
IsKeyPressed: function (key) {
"use strict";
var indexOfKey = Keyboard.keyPressList.indexOf(key);
if (indexOfKey !== -1) {
Keyboard.keyPressList.splice(indexOfKey, 1);
return true;
} else {
return false;
}
}
};

106
src/JS/XNA_Classes/Keys.js Normal file
View File

@ -0,0 +1,106 @@
/**
* Identifies a particular key on a keyboard.
* @readonly
* @enum {number}
*/
var Keys = Object.freeze({
backspace: 8,
tab: 9,
enter: 13,
shift: 16,
ctrl: 17,
alt: 18,
pause_break: 19,
caps_lock: 20,
escape: 27,
space: 32,
page_up: 33,
page_down: 34,
end: 35,
home: 36,
left_arrow: 37,
up_arrow: 38,
right_arrow: 39,
down_arrow: 40,
insert: 45,
supr: 46,
num0: 48,
num1: 49,
num2: 50,
num3: 51,
num4: 52,
num5: 53,
num6: 54,
num7: 55,
num8: 56,
num9: 57,
a: 65,
b: 66,
c: 67,
d: 68,
e: 69,
f: 70,
g: 71,
h: 72,
i: 73,
j: 74,
k: 75,
l: 76,
m: 77,
n: 78,
o: 79,
p: 80,
q: 81,
r: 82,
s: 83,
t: 84,
u: 85,
v: 86,
w: 87,
x: 88,
y: 89,
z: 90,
left_window_key: 91,
right_window_key: 92,
select_key: 93,
numpad_0: 96,
numpad_1: 97,
numpad_2: 98,
numpad_3: 99,
numpad_4: 100,
numpad_5: 101,
numpad_6: 102,
numpad_7: 103,
numpad_8: 104,
numpad_9: 105,
multiply: 106,
add: 107,
subtract: 109,
decimal_point: 110,
divide: 111,
f1: 112,
f2: 113,
f3: 114,
f4: 115,
f5: 116,
f6: 117,
f7: 118,
f8: 119,
f9: 120,
f10: 121,
f11: 122,
f12: 123,
num_lock: 144,
scroll_lock: 145,
semi_colon: 186,
equal_sign: 187,
comma: 188,
dash: 189,
period: 190,
forward_slash: 191,
grave_accent: 192,
open_bracket: 219,
back_slash: 220,
close_braket: 221,
single_quote: 222
});

124
src/JS/XNA_Classes/Mouse.js Normal file
View File

@ -0,0 +1,124 @@
/**
* Allows retrieval of position and button clicks from a mouse input device.
* @global
*/
var Mouse = {
X: 0,
Y: 0,
PreviousX: 0,
PreviousY: 0,
LeftButtonPressed: false,
MiddleButtonPressed: false,
RightButtonPressed: false,
LeftButtonClicked: false,
MiddleButtonClicked: false,
RightButtonClicked: false,
LeftButton: 0,
MiddleButton: 1,
RightButton: 2,
ScrollWheelValue: 0,
IsMoving: false,
IsDraggingSomething: false,
/**
* Determine which mouse button was pressed.
* @name mouseDownHandler
* @function
* @param {Event} event - This parameter represents a mouse event.
* @memberOf Mouse
* @static
*/
mouseDownHandler: function (event) {
"use strict";
switch (event.button) {
case 0:
this.LeftButtonPressed = true;
break;
case 1:
this.MiddleButtonPressed = true;
break;
case 2:
this.RightButtonPressed = true;
break;
}
},
/**
* Determine which mouse button was released.
* @name mouseUpHandler
* @function
* @param {Event} event - This parameter represents a mouse event.
* @memberOf Mouse
* @static
*/
mouseUpHandler: function (event) {
"use strict";
switch (event.button) {
case 0:
this.LeftButtonPressed = false;
this.LeftButtonClicked = true;
break;
case 1:
this.MiddleButtonPressed = false;
this.MiddleButtonClicked = true;
break;
case 2:
this.RightButtonPressed = false;
this.RightButtonClicked = true;
break;
}
},
/**
* Returns whether a specified mouse button was clicked (down and up).
* @name IsButtonClicked
* @function
* @param {Number} buttonCode - Enumerated value that specifies the button to query.
* @memberOf Mouse
* @static
*/
IsButtonClicked: function (buttonCode) {
"use strict";
switch (buttonCode) {
case 0:
if (this.LeftButtonClicked) {
this.LeftButtonClicked = false;
return true;
}
break;
case 1:
if (this.MiddleButtonClicked) {
this.MiddleButtonClicked = false;
return true;
}
break;
case 2:
if (this.RightButtonClicked) {
this.RightButtonClicked = false;
return true;
}
break;
default:
return false;
}
},
/**
* Increments or decrements the ScrollWheelValue property according to the mouse wheel event.
* @name mouseWheelHandler
* @function
* @param {Event} event - This parameter represents a mouse event.
* @memberOf Mouse
* @static
*/
mouseWheelHandler: function (event) {
"use strict";
/*global window*/
// cross-browser wheel delta
var e = window.event || event; // old IE support
this.ScrollWheelValue += Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
}
};

View File

@ -0,0 +1,49 @@
/**
* Defines a point in 2D space.
* @constructor
* @param {Number} x - The x-coordinate of the point.
* @param {Number} y - The y-coordinate of the point.
*/
function Point(x, y) {
"use strict";
this.X = x;
this.Y = y;
}
/**
* Returns the point (0,0).
* @name Zero
* @function
* @memberOf Point
* @static
*/
Point.Zero = function () {
"use strict";
return new Point(0, 0);
};
/**
* Returns the point (1,1).
* @name One
* @function
* @memberOf Point
* @static
*/
Point.One = function () {
"use strict";
return new Point(1, 1);
};
/**
* Check if the points are equal.
* @name Equals
* @function
* @param {Point} p1 - point 1.
* @param {Point} p2 - point 2.
* @memberOf Point
* @static
*/
Point.Equals = function (p1, p2) {
"use strict";
return (p1.X === p2.X && p1.Y === p2.Y);
};

View File

@ -0,0 +1,51 @@
/**
* The main entry point for the application.
*/
(function () {
"use strict";
/*global Game, Keyboard, Mouse, window*/
//Create the game object and start running it
var game = new Game(),
canvas = game.GraphicsDevice.canvas;
game.Run();
/***************************************************/
/*** Keyboard and Mouse listeners initialization ***/
/***************************************************/
//Add keyboard event listeners
window.addEventListener("keydown", Keyboard.addKeyDown, false);
window.addEventListener("keyup", Keyboard.addKeyUp, false);
//Add mouse event listeners
canvas.addEventListener("mousedown", Mouse.mouseDownHandler.bind(Mouse), false);
window.addEventListener("mouseup", Mouse.mouseUpHandler.bind(Mouse), false);
canvas.addEventListener("mousemove", function (event) {
//Find the new mouse's x and y position on the canvas
Mouse.X = event.pageX - canvas.offsetLeft;
Mouse.Y = event.pageY - canvas.offsetTop;
//If the mouse position changed then set the previous mouse's x and
//y position on the canvas
if (Mouse.PreviousX !== Mouse.X || Mouse.PreviousY !== Mouse.Y) {
Mouse.IsMoving = true;
Mouse.PreviousX = Mouse.X;
Mouse.PreviousY = Mouse.Y;
} else if (Mouse.IsMoving) {
Mouse.IsMoving = false;
}
}, false);
//The mouse wheel listener
canvas.addEventListener("wheel", Mouse.mouseWheelHandler.bind(Mouse), false);
//Disable the context menu when pressing right button of the mouse
canvas.addEventListener("contextmenu", function (e) {
if (e.button === 2) {
e.preventDefault();
return false;
}
}, false);
}());

View File

@ -0,0 +1,197 @@
/**
* Defines a rectangle.
* @constructor
* @param {Number} x - The x-coordinate of the rectangle.
* @param {Number} y - The y-coordinate of the rectangle.
* @param {Number} width - Width of the rectangle.
* @param {Number} height - Height of the rectangle.
*/
function Rectangle(x, y, width, height) {
"use strict";
this.Height = height;
this.Width = width;
this.X = x;
this.Y = y;
}
/**
* Gets the upper-left value of the Rectangle.
* @name Location
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.Location = function () {
"use strict";
/*global Point */
return new Point(this.X, this.Y);
};
/**
* Returns the y-coordinate of the top of the rectangle.
* @name Top
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.Top = function () {
"use strict";
return this.Y;
};
/**
* Returns the y-coordinate of the bottom of the rectangle.
* @name Bottom
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.Bottom = function () {
"use strict";
return this.Y + this.Height;
};
/**
* Returns the x-coordinate of the left side of the rectangle.
* @name Left
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.Left = function () {
"use strict";
return this.X;
};
/**
* Returns the x-coordinate of the right of the rectangle.
* @name Right
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.Right = function () {
"use strict";
return this.X + this.Width;
};
/**
* Gets the Point that specifies the center of the rectangle.
* @name Center
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.Center = function () {
"use strict";
/*global Point */
var self = this;
return new Point(self.X + (self.Width / 2), self.Y + (self.Height / 2));
};
/**
* Gets half of the width of the rectangle.
* @name HalfWidth
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.HalfWidth = function () {
"use strict";
return this.Width / 2;
};
/**
* Gets half of the height of the rectangle.
* @name HalfHeight
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.HalfHeight = function () {
"use strict";
return this.Height / 2;
};
/**
* Returns a Rectangle with all of its values set to zero.
* @name Empty
* @function
* @memberOf Rectangle
* @static
*/
Rectangle.Empty = function () {
"use strict";
return new Rectangle(0, 0, 0, 0);
};
/**
* Gets a value that indicates whether the Rectangle is empty.
* @name IsEmpty
* @function
* @memberOf Rectangle
*/
Rectangle.prototype.IsEmpty = function () {
"use strict";
return (this.Width <= 0 && this.Height <= 0);
};
/**
* Determines whether this Rectangle contains a specified Point.
* @name Contains
* @function
* @param {Point} point - The Point to evaluate.
* @memberOf Rectangle
*/
Rectangle.prototype.Contains = function (value) {
"use strict";
var self = this;
return (value.X >= self.X && value.X <= self.Right()) && (value.Y >= self.Y && value.Y <= self.Bottom());
};
/**
* Pushes the edges of the Rectangle out by the horizontal and vertical values specified.
* @name Inflate
* @function
* @param {Number} horizontalAmount - Value to push the sides out by.
* @param {Number} verticalAmount - Value to push the top and bottom out by.
* @memberOf Rectangle
*/
Rectangle.prototype.Inflate = function (horizontalAmount, verticalAmount) {
"use strict";
var self = this;
self.Width += horizontalAmount;
if (self.Width < 0) {
self.Width = 0;
}
self.Height += verticalAmount;
if (self.Height < 0) {
self.Height = 0;
}
};
/**
* Determines whether a specified Rectangle intersects with this Rectangle, and by how much.
* @name Intersects
* @function
* @param {Rectangle} value - The Rectangle to evaluate.
* @memberOf Rectangle
*/
Rectangle.prototype.Intersects = function (value) {
"use strict";
/*global Vector2*/
var self = this,
//Calculate the distance vector and the combined half widths and heights
distance = new Vector2(
self.Center().X - value.Center().X,
self.Center().Y - value.Center().Y
),
combinedHalfWidths = self.HalfWidth() + value.HalfWidth(),
combinedHalfHeights = self.HalfHeight() + value.HalfHeight();
//Check whether distance.X is less than the combined half widths
if (Math.abs(distance.X) < combinedHalfWidths) {
//An intersection might be occurring!
//Check whether distance.y is less than the combined half heights
if (Math.abs(distance.Y) < combinedHalfHeights) {
//An intersection has occurred! return the overlap vector
return new Vector2(combinedHalfWidths - Math.abs(distance.X),
combinedHalfHeights - Math.abs(distance.Y));
}
}
return false;
};

138
src/JS/XNA_Classes/Song.js Normal file
View File

@ -0,0 +1,138 @@
/**
* A song.
* @constructor
* @param {String} name - the path to the resource.
*/
function Song(name) {
"use strict";
/*global Audio*/
this.Name = name;
this.Audio = new Audio();
this.Audio.src = name;
this.Audio.loop = true;
this.Audio.muted = false;
this.Audio.volume = 0.8;
}
/**
* Gets the duration of the song.
* @name Duration
* @function
* @memberOf Song
*/
Song.prototype.Duration = function () {
"use strict";
return this.Audio.duration;
};
/**
* Gets or set the muted setting for the song.
* @name IsMuted
* @function
* @param {Boolean|Undefined} mute - The mute property (true, false or undefined)
* @memberOf Song
*/
Song.prototype.IsMuted = function (mute) {
"use strict";
if (typeof mute === "undefined") {
return this.Audio.muted;
}
this.Audio.muted = mute;
};
/**
* Gets or set the loop setting for the song.
* @name IsRepeating
* @function
* @param {Boolean|Undefined} loop - The loop property (true, false or undefined)
* @memberOf Song
*/
Song.prototype.IsRepeating = function (loop) {
"use strict";
if (typeof loop === "undefined") {
return this.Audio.loop;
}
this.Audio.loop = loop;
};
/**
* Gets the play position within the currently playing song.
* @name PlayPosition
* @function
* @memberOf Song
*/
Song.prototype.PlayPosition = function () {
"use strict";
return this.Audio.currentTime;
};
/**
* Gets or sets the media player volume.
* @name Volume
* @function
* @param {Number} volume - The loop volume.
* @memberOf Song
*/
Song.prototype.Volume = function (volume) {
"use strict";
var self = this;
if (typeof volume === "undefined") {
return self.Audio.volume;
}
if (volume < 0) {
self.Audio.volume = 0;
} else if (volume > 1) {
self.Audio.volume = 1;
} else {
self.Audio.volume = volume;
}
};
/**
* Plays the Song.
* @name Play
* @function
* @memberOf Song
*/
Song.prototype.Play = function () {
"use strict";
this.Audio.play();
};
/**
* Pauses the Song.
* @name Pause
* @function
* @memberOf Song
*/
Song.prototype.Pause = function () {
"use strict";
this.Audio.pause();
};
/**
* Resumes the Song.
* @name Resume
* @function
* @memberOf Song
*/
Song.prototype.Resume = function () {
"use strict";
this.Audio.play();
};
/**
* Stops the Song.
* @name Stop
* @function
* @memberOf Song
*/
Song.prototype.Stop = function () {
"use strict";
this.Audio.pause();
this.Audio.currentTime = 0.0;
};

View File

@ -0,0 +1,40 @@
/**
* A sound effect.
* @constructor
* @param {String} name - the path to the resource.
*/
function SoundEffect(name) {
"use strict";
/*global Audio*/
this.Name = name;
this.Audio = new Audio();
this.Audio.src = name;
this.Audio.loop = false;
this.Audio.muted = false;
this.Audio.volume = 0.85;
}
/**
* Plays the Sound Effect.
* @name Play
* @function
* @memberOf SoundEffect
*/
SoundEffect.prototype.Play = function () {
"use strict";
var self = this;
self.Audio.currentTime = 0.0;
self.Audio.play();
};
/**
* Gets the duration of the sound effect.
* @name Duration
* @function
* @memberOf SoundEffect
*/
SoundEffect.prototype.Duration = function () {
"use strict";
return this.Audio.duration;
};

View File

@ -0,0 +1,186 @@
/**
* Enables a group of sprites to be drawn using the same settings.
* @constructor
* @param {GraphicsDevice} graphicsDevice - The graphics device where sprites will be drawn.
*/
function SpriteBatch(graphicsDevice) {
"use strict";
this.ctx = graphicsDevice.canvas.getContext("2d");
}
/**
* Adds a sprite to a batch of sprites for rendering using the specified texture, position, and source rectangle.
* @name Draw
* @function
* @param {Texture2D} texture - A texture.
* @param {Vector2} position - The location (in screen coordinates) to draw the sprite.
* @param {Rectangle} sourceRectangle - A rectangle that specifies (in texels) the source texels from a texture.
* @param {Number} rotation - Specifies the angle (in radians) to rotate the sprite about its center.
* @param {Vector2} scale - Scale factor.
* @param {SpriteEffects} effects - Effects to apply.
* @memberOf SpriteBatch
*/
SpriteBatch.prototype.Draw = function (texture, position, sourceRectangle, rotation, scale, effects) {
"use strict";
/*global SpriteEffects*/
var self = this,
flipHorizontally = 1,
flipVertically = 1,
aspectRatio = texture.Width() / texture.Height(),
sourceAspectRatio = sourceRectangle.Width / sourceRectangle.Height,
textureWidth = texture.Width(),
posX = 0,
posY = 0;
//Save the context to restore later
self.ctx.save();
//Rotate the image if required
if (rotation !== 0) {
self.ctx.translate(Math.floor(position.X + texture.HalfWidth() * scale.X), Math.floor(position.Y + texture.HalfHeight() * scale.Y));
self.ctx.rotate(rotation * Math.PI / 180);
posX = -texture.HalfWidth() * scale.X;
posY = -texture.HalfHeight() * scale.Y;
} else {
posX = position.X;
posY = position.Y;
}
//Apply sprite effects if needed
if (effects === SpriteEffects.FlipHorizontally) {
flipHorizontally = -1;
} else if (effects === SpriteEffects.FlipVertically) {
flipVertically = -1;
}
//Scale the image
self.ctx.scale(scale.X * flipHorizontally, scale.Y * flipVertically);
if (aspectRatio !== sourceAspectRatio) {
textureWidth /= aspectRatio;
}
//Draw the image
self.ctx.drawImage(texture.Image,
sourceRectangle.X, sourceRectangle.Y,
sourceRectangle.Width, sourceRectangle.Height,
Math.floor(posX) * flipHorizontally / scale.X, Math.floor(posY) * flipVertically / scale.Y,
textureWidth * flipHorizontally, texture.Height() * flipVertically
);
//Restore the canvas context
self.ctx.restore();
};
/**
* Adds a string to a batch of sprites for rendering using the specified font, text, position, color and scale.
* @name DrawString
* @function
* @param {String} font - A string representing the font for displaying text (example: "normal bold 20px Helvetica").
* @param {String} text - A text string.
* @param {Vector2} position - The location (in screen coordinates) to draw the sprite.
* @param {String} color - A string representing the color (example: "#FF00F0").
* @param {Vector2} scale - Scale factor.
* @memberOf SpriteBatch
*/
SpriteBatch.prototype.DrawString = function (font, text, position, color, scale) {
"use strict";
var self = this;
//Save the context to restore later
self.ctx.save();
//Scale the image
self.ctx.scale(scale.X, scale.Y);
//Determine the font, color and baseline, and then draw the given text
self.ctx.font = font;
self.ctx.fillStyle = color;
self.ctx.textBaseline = "top";
self.ctx.fillText(text, position.X, position.Y);
//Restore the canvas context
self.ctx.restore();
};
/**
* Draw a given rectangle.
* @name DrawRectangle
* @function
* @param {Rectangle} rectangle - The rectangle to draw.
* @param {String} lineWidth - the width of the line to be drawn.
* @param {String} color - A string representing the color (example: "#FF00F0").
* @memberOf SpriteBatch
*/
SpriteBatch.prototype.DrawRectangle = function (rectangle, lineWidth, color) {
"use strict";
var self = this;
//If the line width is null or undefined set a default value
if (lineWidth === null || typeof lineWidth === "undefined") {
lineWidth = "1";
}
//If the color is null or undefined set a default color (black)
if (color === null || typeof color === "undefined") {
color = "#000000";
}
//Save the context to restore later
self.ctx.save();
//Set the line width and the line color
self.ctx.lineWidth = lineWidth;
self.ctx.strokeStyle = color;
//Draw the rectangle
self.ctx.strokeRect(
rectangle.X,
rectangle.Y,
rectangle.Width,
rectangle.Height
);
//Restore the canvas context
self.ctx.restore();
};
/**
* Draw a given segment.
* @name DrawSegment
* @function
* @param {Segment} segment - The segment to draw.
* @param {String} lineWidth - the width of the line to be drawn.
* @param {String} color - A string representing the color (example: "#FF00F0").
* @memberOf SpriteBatch
*/
SpriteBatch.prototype.DrawSegment = function (segment, lineWidth, color) {
"use strict";
var self = this;
//If the line width is null or undefined set a default value
if (lineWidth === null || typeof lineWidth === "undefined") {
lineWidth = "1";
}
//If the color is null or undefined set a default color (black)
if (color === null || typeof color === "undefined") {
color = "#000000";
}
//Save the context to restore later
self.ctx.save();
//Set the line width and the line color
self.ctx.lineWidth = lineWidth;
self.ctx.strokeStyle = color;
//Draw the segment
self.ctx.beginPath();
self.ctx.moveTo(segment.pointA.X, segment.pointA.Y);
self.ctx.lineTo(segment.pointB.X, segment.pointB.Y);
self.ctx.stroke();
//Restore the canvas context
self.ctx.restore();
};

View File

@ -0,0 +1,10 @@
/**
* Defines sprite mirroring options.
* @readonly
* @enum {number}
*/
var SpriteEffects = Object.freeze({
None: 0,
FlipHorizontally: 1,
FlipVertically: 2
});

View File

@ -0,0 +1,67 @@
/**
* Represents a 2D grid of texels.
* @constructor
* @param {String} name - The path to the resource.
*/
function Texture2D(name) {
"use strict";
/*global Rectangle, Image*/
this.Name = name;
this.Image = new Image();
this.Image.src = name;
}
/**
* Gets the width of the texture.
* @name Height
* @function
* @memberOf Texture2D
*/
Texture2D.prototype.Height = function () {
"use strict";
return this.Image.height;
};
/**
* Gets the height of the texture.
* @name Width
* @function
* @memberOf Texture2D
*/
Texture2D.prototype.Width = function () {
"use strict";
return this.Image.width;
};
/**
* Gets the bounds of the texture.
* @name Bounds
* @function
* @memberOf Texture2D
*/
Texture2D.prototype.Bounds = function () {
"use strict";
return new Rectangle(0, 0, this.Width(), this.Height());
};
/**
* Gets half of the width of the texture.
* @name HalfWidth
* @function
* @memberOf Texture2D
*/
Texture2D.prototype.HalfWidth = function () {
"use strict";
return this.Width() / 2;
};
/**
* Gets half of the height of the texture.
* @name HalfHeight
* @function
* @memberOf Texture2D
*/
Texture2D.prototype.HalfHeight = function () {
"use strict";
return this.Height() / 2;
};

View File

@ -0,0 +1,153 @@
/**
* Defines a vector with two components.
* @constructor
* @param {Number} x - Initial value for the x-component of the vector.
* @param {Number} y - Initial value for the y-component of the vector.
*/
function Vector2(x, y) {
"use strict";
this.X = x;
this.Y = y;
}
/**
* Returns a Vector2 with both of its components set to zero.
* @name Zero
* @function
* @memberOf Vector2
* @static
*/
Vector2.Zero = function () {
"use strict";
return new Vector2(0, 0);
};
/**
* Returns a Vector2 with both of its components set to one.
* @name One
* @function
* @memberOf Vector2
* @static
*/
Vector2.One = function () {
"use strict";
return new Vector2(1, 1);
};
/**
* Adds two vectors.
* @name Add
* @function
* @param {Vector2} value1 - Source vector 1
* @param {Vector2} value2 - Source vector 2
* @memberOf Vector2
* @static
*/
Vector2.Add = function (value1, value2) {
"use strict";
return new Vector2(value1.X + value2.X, value1.Y + value2.Y);
};
/**
* Substract two vectors.
* @name Substract
* @function
* @param {Vector2} value1 - Source vector 1
* @param {Vector2} value2 - Source vector 2
* @memberOf Vector2
* @static
*/
Vector2.Substract = function (value1, value2) {
"use strict";
return new Vector2(value1.X - value2.X, value1.Y - value2.Y);
};
/**
* Divides the components of a vector by a scalar value or the components of another vector.
* @name Divide
* @function
* @param {Vector2} value1 - Source vector 1
* @param {Vector2} value2 - A scalar value or a source vector 2
* @memberOf Vector2
* @static
*/
Vector2.Divide = function (value1, value2) {
"use strict";
if (typeof (value2) === "number") {
return new Vector2(value1.X / value2, value1.Y / value2);
} else {
return new Vector2(value1.X / value2.X, value1.Y / value2.Y);
}
};
/**
* Multiplies the components of a vector by a scalar value or the components of another vector.
* @name Multiply
* @function
* @param {Vector2} value1 - Source vector 1
* @param {Vector2} value2 - A scalar value or a source vector 2
* @memberOf Vector2
* @static
*/
Vector2.Multiply = function (value1, value2) {
"use strict";
if (typeof (value2) === "number") {
return new Vector2(value1.X * value2, value1.Y * value2);
} else {
return new Vector2(value1.X * value2.X, value1.Y * value2.Y);
}
};
/**
* Calculates the distance between two vectors.
* @name Distance
* @function
* @param {Vector2|Point} value1 - Source vector 1
* @param {Vector2|Point} value2 - Source vector 2
* @memberOf Vector2
* @static
*/
Vector2.Distance = function (value1, value2) {
"use strict";
return (Math.sqrt(Math.pow(value2.X - value1.X, 2) + Math.pow(value2.Y - value1.Y, 2)));
};
/**
* Calculates the length of the vector.
* @name Length
* @function
* @memberOf Vector2
*/
Vector2.prototype.Length = function () {
"use strict";
return (Math.sqrt(Math.pow(this.X, 2) + Math.pow(this.Y, 2)));
};
/**
* Turns the current vector into a unit vector. The result is a vector one unit
* in length pointing in the same direction as the original vector.
* @name Normalize
* @function
* @memberOf Vector2
*/
Vector2.prototype.Normalize = function () {
"use strict";
var self = this,
length = self.Length();
return (new Vector2(self.X / length, self.Y / length));
};
/**
* Check if the vectors are equal.
* @name Equals
* @function
* @param {Vector2} v1 - vector 1.
* @param {Vector2} v2 - vector 2.
* @memberOf Vector2
* @static
*/
Vector2.Equals = function (v1, v2) {
"use strict";
return (v1.X === v2.X && v1.Y === v2.Y);
};

View File

@ -0,0 +1,119 @@
/**
* Represents an animated sprite, which is composed of various frames.
* @constructor
* @param {Texture2D} texture - The texture image.
* @param {Vector2} scale - The scale of the image.
* @param {Rectangle} sourceRect - The image source rectangle.
* @param {Point} position - The sprite position in the canvas.
* @param {Boolean} isVisible - Determines if the sprite is visible or not.
* @param {Boolean} loop - Determines if the animation has to animate in loop or not (one time).
* @param {Boolean} pingPongLoop - Determines if the animation should run in reverse when reachs the last
* frame or not (reset to initial frame).
* @param {Number} millisecondsPerFrame - A number representing the milliseconds between each frame.
* @param {Number} numberOfFrames - The number of frames in the sprite sheet.
*/
function AnimatedSprite(texture, scale, sourceRect, position, isVisible, animationType, numberOfFrames, millisecondsPerFrame) {
"use strict";
/*global Sprite, AnimationTypes, setInterval, clearInterval*/
//Call the father constructor (super)
Sprite.call(this, texture, scale, sourceRect, position, isVisible);
this.AnimationType = animationType;
this.NumberOfFrames = numberOfFrames;
this.MillisecondsPerFrame = millisecondsPerFrame;
this.CurrentFrame = 0;
this.Forward = true; //to control the direction of the loop
this.Columns = Math.floor(texture.Width() / sourceRect.Width);
this.RunAnimation = true;
this.VerticalOffset = 0; //(optional) used when the animation sheet has different
//animations representing different states of the object
//which owns the sprite
this.interval = null;
}
//Create the AnimatedSprite.prototype object, which inherits from Sprite.prototype.
//Then stablish the "constructor" property to reference to AnimatedSprite
AnimatedSprite.prototype = Object.create(Sprite.prototype);
AnimatedSprite.prototype.constructor = AnimatedSprite;
/**
* Starts the update animation timer.
* @name StartAnimation
* @function
* @memberof AnimatedSprite
*/
AnimatedSprite.prototype.StartAnimation = function () {
"use strict";
var self = this;
self.interval = setInterval(self.UpdateAnimation.bind(self), self.MillisecondsPerFrame);
};
/**
* Stops the update animation timer.
* @name StopAnimation
* @function
* @memberof AnimatedSprite
*/
AnimatedSprite.prototype.StopAnimation = function () {
"use strict";
clearInterval(this.interval);
};
/**
* Update the animation depending on the number of frames
* @name UpdateAnimation
* @function
* @memberof AnimatedSprite
*/
AnimatedSprite.prototype.UpdateAnimation = function () {
"use strict";
var self = this,
sourceRect = self.SourceRect;
sourceRect.X = Math.floor(self.CurrentFrame % self.Columns) * sourceRect.Width;
sourceRect.Y = Math.floor(self.CurrentFrame / self.Columns) * sourceRect.Height;
if (self.RunAnimation) {
//Do different actions depending on the animation type
switch (self.AnimationType) {
case AnimationTypes.PlayOneTime:
//It the last frame has been reached, stop the run
if (self.CurrentFrame === self.NumberOfFrames - 1) {
self.RunAnimation = false;
}
break;
case AnimationTypes.Loop:
//If the last frame has been reached, reset to the initial frame
if (self.CurrentFrame === self.NumberOfFrames - 1) {
self.CurrentFrame = 0;
}
break;
case AnimationTypes.PingPongLoop:
//If the last frame has been reached, reverse the animation
if (self.CurrentFrame === self.NumberOfFrames - 1) {
self.Forward = false;
}
//If the first frame has been reached, set forward to true
if (self.CurrentFrame === 0) {
self.Forward = true;
}
break;
}
//Add 1 to currentFrame if forward is true, subtract 1 if it's false
if (self.Forward) {
self.CurrentFrame += 1;
} else {
self.CurrentFrame -= 1;
}
//Apply vertical offset
sourceRect.Y += sourceRect.Height * self.VerticalOffset;
}
};

View File

@ -0,0 +1,10 @@
/**
* Defines the animation types.
* @readonly
* @enum {number}
*/
var AnimationTypes = Object.freeze({
PlayOneTime: 0,
Loop: 1, //when the animation reaches the last frame then reset to the initial frame
PingPongLoop: 2 //when the animation reaches the last frame then reverse the animation
});

344
src/JS/XgameJS/Ball.js Normal file
View File

@ -0,0 +1,344 @@
/**
* Defines a Ball.
* @constructor
* @param {Sprite} sprite - The sprite that represents the ball.
* @param {Number} radius - The radius of the circle of the ball.
* @param {Point} position - The position of the ball.
* @param {Number} position - The position of the ball.
* @param {Boolean} bounce - Determines if the ball can bounce or not.
*/
function Ball(sprite, radius, position, index, bounce, rotate) {
"use strict";
/*global Vector2, Circle*/
this.Sprite = sprite;
this.Circle = new Circle(radius, position.X, position.Y);
//Physics properties
this.SpeedV = Vector2.Zero();
this.GroundFriction = 0.975;
this.BallBounceFriction = 0.85;
this.WallBounceFriction = 0.7;
this.MaxRotationSpeedTransmision = 25;
this.CurrentRotationSpeed = 0;
//Platform game properties
this.IsOnGround = false;
//Drag & Drop properties
this.IsDraggable = true;
this.IsBeenDragged = false;
//Other properties
this.RandomDir = [-0.1, 0.1];
this.Index = index;
this.IsBounceOn = bounce;
this.IsRotationOn = rotate;
}
/**
* Updates the ball.
* @name Update
* @function
* @param {Number} worldWidth - The width of the game world.
* @param {Number} worldHeight - The height of the game world.
* @param {Array} balls - Array of existing balls.
* @param {Boolean} isGravityOn - Determines if the gravity is activated or not.
* @param {GravityDirections} gravityDir - The gravity direction of the game world.
* @param {Number} gravityForce - The gravity force value.
* @memberOf Ball
*/
Ball.prototype.Update = function (worldWidth, worldHeight, balls, isGravityOn, gravityDir, gravityForce) {
"use strict";
/*global GravityDirections, Mouse, Point, hitTestPoint*/
var self = this,
randomDirImpulse = 0,
len = 0,
i = 0,
j = 0;
//Check if the mouse clicked a ball to drag it
if (self.Circle.Contains(new Point(Mouse.X, Mouse.Y)) && self.IsDraggable && Mouse.LeftButtonPressed && !Mouse.IsDraggingSomething) { //Si quitamos IsDraggingSom... ocurren cosas divertidas
//Assign the sprite to the dragSprite variable
self.IsBeenDragged = true;
Mouse.IsDraggingSomething = true;
self.CurrentRotationSpeed = 0;
self.SpeedV.X = 0;
self.SpeedV.Y = 0;
i = self.Index;
len = balls.length;
//push the dragSprite to the end of the sprites
//array so that it's displayed last
self.Index = balls.length - 1;
balls.push(self);
//Splice the dragSprite from its previous
//position in the sprites array
balls.splice(i, 1);
for (j = i; j < len - 1; j += 1) {
balls[j].Index -= 1;
}
}
//Update the Circle position with the mouse position
if (Mouse.IsMoving && self.IsBeenDragged) {
self.Circle.X = Mouse.X - self.Circle.Radius;
self.Circle.Y = Mouse.Y - self.Circle.Radius;
}
//If the mouse left button was released drop the ball
if (self.IsBeenDragged && !Mouse.LeftButtonPressed) {
self.IsBeenDragged = false;
Mouse.IsDraggingSomething = false;
}
//Apply gravity depending on the gravity direction
if (isGravityOn && !self.IsBeenDragged) {
//Random impulse when the balls are generated
if (!self.IsOnGround && self.SpeedV.X === 0 && self.SpeedV.Y === 0) {
randomDirImpulse = self.RandomDir[Math.floor(Math.random() * 2)];
}
switch (gravityDir) {
//Gravity down
case GravityDirections.G_DOWN:
self.SpeedV.Y += gravityForce;
self.SpeedV.X += randomDirImpulse;
if (self.Circle.Bottom() >= worldHeight) {
self.SpeedV.X *= self.GroundFriction;
self.IsOnGround = true;
}
break;
//Gravity up
case GravityDirections.G_UP:
self.SpeedV.Y -= gravityForce;
self.SpeedV.X += randomDirImpulse;
if (self.Circle.Top() <= 0) {
self.SpeedV.X *= self.GroundFriction;
self.IsOnGround = true;
}
break;
//Gravity left
case GravityDirections.G_LEFT:
self.SpeedV.X -= gravityForce;
self.SpeedV.Y += randomDirImpulse;
if (self.Circle.Left() <= 0) {
self.SpeedV.Y *= self.GroundFriction;
self.IsOnGround = true;
}
break;
//Gravity right
case GravityDirections.G_RIGHT:
self.SpeedV.X += gravityForce;
self.SpeedV.Y += randomDirImpulse;
if (self.Circle.Right() >= worldWidth) {
self.SpeedV.Y *= self.GroundFriction;
self.IsOnGround = true;
}
break;
}
}
//Move the ball if it isn't dragged
if (!self.IsBeenDragged) {
self.Circle.X += self.SpeedV.X;
self.Circle.Y += self.SpeedV.Y;
}
//Collision with balls
len = balls.length;
if (len > 1 && !self.IsBeenDragged) {
for (i = 0; i < len; i += 1) {
if (self.Index !== i) {
self.CollisionWithBall(balls[i], self.IsBounceOn, self.IsRotationOn);
}
}
}
//Screen boundaries
//Left
if (self.Circle.Left() < 0) {
if (self.IsBounceOn) {
self.SpeedV.X *= -self.WallBounceFriction;
}
self.Circle.X = 0;
}
//Up
if (self.Circle.Top() < 0) {
if (self.IsBounceOn) {
self.SpeedV.Y *= -self.WallBounceFriction;
}
self.Circle.Y = 0;
}
//Right
if (self.Circle.Right() > worldWidth) {
if (self.IsBounceOn) {
self.SpeedV.X *= -self.WallBounceFriction;
}
self.Circle.X = worldWidth - self.Circle.Diameter();
}
//Down
if (self.Circle.Bottom() > worldHeight) {
if (self.IsBounceOn) {
self.SpeedV.Y *= -self.WallBounceFriction;
}
self.Circle.Y = worldHeight - self.Circle.Diameter();
}
//Update the sprite
self.Sprite.Position.X = self.Circle.X;
self.Sprite.Position.Y = self.Circle.Y;
//Update the sprite rotation
self.Sprite.Rotation += self.CurrentRotationSpeed;
self.CurrentRotationSpeed *= self.GroundFriction;
};
/**
* Check if a ball collide with other ball. Besides, bounce and rotate the balls if needed.
* @name CollisionWithBall
* @function
* @param {Ball} ball - The ball which will be checked to find a collision.
* @memberOf Ball
*/
Ball.prototype.CollisionWithBall = function (ball) {
"use strict";
var self = this,
overlapV = self.Circle.IsInsideCircle(ball.Circle),
vector = null,
d = null,
angle = 0,
b1Magnitude = 0,
b2Magnitude = 0,
s = null;
//If the other ball is inside the other
if (overlapV !== false) {
self.Circle.X += overlapV.X;
self.Circle.Y += overlapV.Y;
return true;
}
//Check if this ball is inside the other
overlapV = self.Circle.Intersects(ball.Circle);
//If there is a collision with the other ball move it away of the other
if (overlapV !== false) {
vector = overlapV.Y; //the vector between the balls centers
d = vector.Normalize();
angle = Math.atan2(d.X, d.X) * 180 / Math.PI;
b1Magnitude = self.SpeedV.Length();
b2Magnitude = ball.SpeedV.Length();
//If rotation is activated then rotate the ball
if (self.IsRotationOn) {
if (
(angle >= 0 && angle <= 90 && self.SpeedV.X > 0) ||
(angle > 90 && angle <= 180 && self.SpeedV.X >= 0) ||
(angle < 0 && angle >= -90 && self.SpeedV.X <= 0) ||
(angle < -90 && angle >= -180 && self.SpeedV.X < 0)
) {
self.CurrentRotationSpeed = Math.min(Math.abs(b1Magnitude), self.MaxRotationSpeedTransmision);
ball.CurrentRotationSpeed = -Math.min(Math.abs(b2Magnitude), ball.MaxRotationSpeedTransmision);
} else {
self.CurrentRotationSpeed = -Math.min(Math.abs(b1Magnitude), self.MaxRotationSpeedTransmision);
ball.CurrentRotationSpeed = Math.min(Math.abs(b2Magnitude), ball.MaxRotationSpeedTransmision);
}
//Limit the rotation speeds
if (Math.abs(self.CurrentRotationSpeed) < 1) {
self.CurrentRotationSpeed = 0;
}
if (Math.abs(ball.CurrentRotationSpeed) < 1) {
ball.CurrentRotationSpeed = 0;
}
}
//Move circle 1 out of the collision by multiplying
//the overlap with the normalized vector and add it to
//ball 1's position
self.Circle.X += overlapV.X * d.X;
self.Circle.Y += overlapV.X * d.Y;
//Ocurren cosas diver al poner esto
//ball.Circle.X += overlapV.X * overlapV.Y[0];
//ball.Circle.Y += overlapV.X * overlapV.Y[1];
if (self.IsBounceOn) {
//Create a collision vector object to represent the bounce surface
//Find the bounce surface's X and Y properties
//(This represents the normal of the distance vector between the circles)
s = new Vector2(vector.Y, -vector.X);
//Bounce b1 off the surface
self.BounceOffSurface(ball, s);
}
return true;
}
return false;
};
/**
* Bounces the current ball with other ball given the virtual surface between them.
* @name BounceOffSurface
* @function
* @param {Ball} ball - The ball which will bounced.
* @param {Vector2} s - The surface to bounce off.
* @memberOf Ball
*/
Ball.prototype.BounceOffSurface = function (ball, s) {
"use strict";
//1. Calculate the collision surface's properties
var self = this,
//Find the surface vector's left normal
leftNormalV = new Vector2(s.Y, -s.X),
//s.lx = s.Y;
//s.ly = -s.X;
//Find its magnitude
sLength = s.Length(),
//Find its normalized/unit vector values
dV = s.Normalize(),
//2. Bounce the ball off the surface (s)
//Find the dot product between the object and the surface
dp1 = self.SpeedV.X * dV.X + self.SpeedV.Y * dV.Y,
//Project the object's velocity onto the collision surface
p1V = new Vector2(dp1 * dV.X, dp1 * dV.Y),
//Find the dot product of the object and the surface's left normal (s.lx and s.ly)
dp2 = self.SpeedV.X * (leftNormalV.X / sLength) + self.SpeedV.Y * (leftNormalV.Y / sLength),
//Project the object's velocity onto the surface's left normal
p2V = new Vector2(dp2 * (leftNormalV.X / sLength), dp2 * (leftNormalV.Y / sLength)),
bounceV = null;
//Reverse the projection on the surface's left normal
p2V.X *= -1;
p2V.Y *= -1;
//Add up the projections to create a new bounce vector
bounceV = new Vector2(p1V.X + p2V.X, p1V.Y + p2V.Y);
//Assign the bounce vector to the object's velocity
self.SpeedV.X = bounceV.X * self.BallBounceFriction;
self.SpeedV.Y = bounceV.Y * self.BallBounceFriction;
if (!ball.IsBeenDragged) {
ball.SpeedV.X = -bounceV.X * ball.BallBounceFriction;
ball.SpeedV.Y = -bounceV.Y * ball.BallBounceFriction;
}
};

150
src/JS/XgameJS/Camera.js Normal file
View File

@ -0,0 +1,150 @@
/**
* Defines the game camera.
* @constructor
* @param {Number} width - The width of the camera.
* @param {Number} height - The height of the camera.
* @param {Number} levelWidth - The width of the level.
* @param {Number} levelHeight - The height of the level.
* @param {Number} zoom - The zoom of the camera.
*/
function Camera(width, height, levelWidth, levelHeight, zoom) {
"use strict";
/*global Point, Vector2*/
this.Width = width;
this.Height = height;
this.LevelWidth = levelWidth;
this.LevelHeight = levelHeight;
this.Zoom = zoom;
this.Position = Point.Zero();
this.SpeedV = Vector2.Zero(); //For parallax scrolling
this.PreviousSpeedX = 0; //For parallax scrolling
//Camera constants
this.upLeftMarginPercentage = 0.3;
this.downRightMarginPercentage = 0.7;
this.MaxZoom = 2.5;
this.MinZoom = 1.0;
}
/**
* The camera's inner right scroll boundaries.
* @name RightInnerBoundary
* @function
* @memberOf Camera
*/
Camera.prototype.RightInnerBoundary = function () {
"use strict";
var self = this;
return self.Position.X + (self.Width * self.downRightMarginPercentage / self.Zoom);
};
/**
* The camera's inner left scroll boundaries.
* @name LeftInnerBoundary
* @function
* @memberOf Camera
*/
Camera.prototype.LeftInnerBoundary = function () {
"use strict";
var self = this;
return self.Position.X + (self.Width * self.upLeftMarginPercentage / self.Zoom);
};
/**
* The camera's inner top scroll boundaries.
* @name TopInnerBoundary
* @function
* @memberOf Camera
*/
Camera.prototype.TopInnerBoundary = function () {
"use strict";
var self = this;
return self.Position.Y + (self.Height * self.upLeftMarginPercentage / self.Zoom);
};
/**
* The camera's inner bottom scroll boundaries.
* @name BottomInnerBoundary
* @function
* @memberOf Camera
*/
Camera.prototype.BottomInnerBoundary = function () {
"use strict";
var self = this;
return self.Position.Y + (self.Height * self.downRightMarginPercentage / self.Zoom);
};
/**
* Increases the zoom by 0.1.
* @name IncreaseZoom
* @function
* @memberOf Camera
*/
Camera.prototype.IncreaseZoom = function () {
"use strict";
var self = this;
if (self.Zoom < self.MaxZoom) {
self.Zoom += 0.1;
}
};
/**
* Decreases the zoom by 0.1.
* @name DecreaseZoom
* @function
* @memberOf Camera
*/
Camera.prototype.DecreaseZoom = function () {
"use strict";
var self = this;
if (self.Zoom > self.MinZoom) {
self.Zoom -= 0.1;
}
};
/**
* Updates de camera depending on the player's position.
* @name Update
* @function
* @param {Player} player - the player of the game.
* @memberOf Camera
*/
Camera.prototype.Update = function (player) {
"use strict";
var self = this,
playerSprite = player.Sprite;
//Scroll the camera
if (playerSprite.Position.X < self.LeftInnerBoundary()) {
self.Position.X = Math.floor(playerSprite.Position.X - (self.Width * self.upLeftMarginPercentage / self.Zoom));
}
if (playerSprite.Position.X + playerSprite.Width() > self.RightInnerBoundary()) {
self.Position.X = Math.floor(playerSprite.Position.X + playerSprite.Width() - (self.Width * self.downRightMarginPercentage / self.Zoom));
}
if (playerSprite.Position.Y < self.TopInnerBoundary()) {
self.Position.Y = Math.floor(playerSprite.Position.Y - (self.Height * self.upLeftMarginPercentage / self.Zoom));
}
if (playerSprite.Position.Y + playerSprite.Height() > self.BottomInnerBoundary()) {
self.Position.Y = Math.floor(playerSprite.Position.Y + playerSprite.Height() - (self.Height * self.downRightMarginPercentage / self.Zoom));
}
//The camera's world boundaries
if (self.Position.X < 0) {
self.Position.X = 0;
}
if (self.Position.X * self.Zoom + self.Width > self.LevelWidth * self.Zoom) {
self.Position.X = (self.LevelWidth * self.Zoom - self.Width) / self.Zoom;
}
if (self.Position.Y < 0) {
self.Position.Y = 0;
}
if (self.Position.Y * self.Zoom + self.Height > (self.LevelHeight * self.Zoom)) {
self.Position.Y = (self.LevelHeight * self.Zoom - self.Height) / self.Zoom;
}
//Figure out the camera's velocity by subtracting its position in the
//previous frame from its position in this frame
self.SpeedV.X = self.Position.X - self.PreviousSpeedX;
};

300
src/JS/XgameJS/Circle.js Normal file
View File

@ -0,0 +1,300 @@
/**
* Defines a circle.
* @constructor
* @param {Number} radius - The radius of the circle.
* @param {Number} x - The x-coordinate of the circle.
* @param {Number} y - The y-coordinate of the circle.
*/
function Circle(radius, x, y) {
"use strict";
this.Radius = radius;
this.X = x;
this.Y = y;
}
/**
* Gets the diameter of the circle.
* @name Diameter
* @function
* @memberOf Circle
*/
Circle.prototype.Diameter = function () {
"use strict";
return this.Radius * 2;
};
/**
* Gets the upper-left value of the circle.
* @name Location
* @function
* @memberOf Circle
*/
Circle.prototype.Location = function () {
"use strict";
/*global Point */
return new Point(this.X, this.Y);
};
/**
* Returns the y-coordinate of the top of the circle.
* @name Top
* @function
* @memberOf Circle
*/
Circle.prototype.Top = function () {
"use strict";
return this.Y;
};
/**
* Returns the y-coordinate of the bottom of the circle.
* @name Bottom
* @function
* @memberOf Circle
*/
Circle.prototype.Bottom = function () {
"use strict";
return this.Y + this.Diameter();
};
/**
* Returns the x-coordinate of the left side of the circle.
* @name Left
* @function
* @memberOf Circle
*/
Circle.prototype.Left = function () {
"use strict";
return this.X;
};
/**
* Returns the x-coordinate of the right of the circle.
* @name Right
* @function
* @memberOf Circle
*/
Circle.prototype.Right = function () {
"use strict";
return this.X + this.Diameter();
};
/**
* Gets the Point that specifies the center of the circle.
* @name Center
* @function
* @memberOf Circle
*/
Circle.prototype.Center = function () {
"use strict";
var self = this;
//console.log(self.X);
return new Point(self.X + self.Radius, self.Y + self.Radius);
};
/**
* Determines whether this circle contains a specified Point.
* @name Contains
* @function
* @param {Point} point - The Point to evaluate.
* @memberOf Circle
*/
Circle.prototype.Contains = function (value) {
"use strict";
/*global Vector2*/
return (Vector2.Distance(this.Center(), value) <= this.Radius);
};
/**
* Pushes the edges of the circle out by the amount specified.
* @name Inflate
* @function
* @param {Number} amount - Value to push the radius out by.
* @memberOf Circle
*/
Circle.prototype.Inflate = function (amount) {
"use strict";
var self = this;
self.Radius += amount;
if (self.Radius < 0) {
self.Radius = 0;
}
};
/**
* Determines whether a specified Circle is inside this Circle, and by how much.
* @name IsInsideCircle
* @function
* @param {Circle} circle - The Circle to evaluate.
* @memberOf Circle
*/
Circle.prototype.IsInsideCircle = function (circle) {
"use strict";
var self = this,
centerA = self.Center(),
centerB = circle.Center(),
vector = null,
d = null,
surfacePoint = null,
distanceToSurface = 0;
//Check if circles have the same center
if (Point.Equals(centerA, centerB)) {
distanceToSurface = (self.Radius + circle.Radius);
return new Vector2(0, distanceToSurface);
//Check if self circle is inside the other circle
} else if (self.Radius < circle.Radius) {
if (Vector2.Distance(centerA, centerB) <= Math.abs(circle.Radius - self.Radius)) {
vector = new Vector2(centerA.X - centerB.X, centerA.Y - centerB.Y);
d = vector.Normalize();
surfacePoint = new Point((centerB.X + self.Radius) * d.X, (centerB.Y + self.Radius) * d.Y);
distanceToSurface = Vector2.Distance(centerA, surfacePoint) + self.Radius;
return new Vector2(distanceToSurface * d.X, distanceToSurface * d.Y);
}
}
return false;
};
/**
* Determines whether a specified Circle intersects with this Circle, and by how much.
* @name Intersects
* @function
* @param {Circle} value - The Circle to evaluate.
* @memberOf Circle
*/
Circle.prototype.Intersects = function (value) {
"use strict";
/*global Vector2 */
var self = this,
//Calculate the vector between the circles center points
vector = new Vector2(
self.Center().X - value.Center().X,
self.Center().Y - value.Center().Y
),
//Find the distance between the circles
magnitude = vector.Length(),
//Add together the circles combined radius
combinedRadius = self.Radius + value.Radius,
overlap = 0,
d = null;
//Figure out if there's a collision
if (magnitude < combinedRadius) {
//Yes, a collision is happening.
//Find the amount of overlap between the circles
overlap = combinedRadius - magnitude;
//Normalize the vector, these numbers tell us the direction of the collision.
//d = vector.Normalize();
//Return the overlap and the vector between the circles center points
return new Vector2(overlap, vector);
}
return false;
};
/**
* Determines whether a specified Segment intersects with this Circle, and by how much.
* @name IntersectsSegment
* @function
* @param {Segment} segment - The Segment to evaluate.
* @memberOf Circle
*/
Circle.prototype.IntersectsSegment = function (segment) {
"use strict";
/*global Vector2*/
var self = this,
pointA = new Point(segment.pointA.X - self.Radius, segment.pointA.Y - self.Radius),
pointB = new Point(segment.pointB.X - self.Radius, segment.pointB.Y - self.Radius),
// Calculate the euclidean distance between a & b
distance = Vector2.Distance(pointA, pointB),
// Compute the direction vector d from a to b
dir = new Vector2((pointB.X - pointA.X) / distance, (pointB.Y - pointA.Y) / distance),
// Now the line equation is x = dx*t + ax, y = dy*t + ay with 0 <= t <= 1.
// compute the value t of the closest point to the circle center (cx, cy)
t = (dir.X * (self.X - pointA.X)) + (dir.Y * (self.Y - pointA.Y)),
// compute the coordinates of the point e on line and closest to c
e = new Point((t * dir.X) + pointA.X, (t * dir.Y) + pointA.Y),
// Calculate the euclidean distance between c & e
eDistCtoE = Vector2.Distance(self, e);
Vector2.Add(e, self.Radius);
// test if the line intersects the circle
if (eDistCtoE < self.Radius) {
// compute distance from t to circle intersection point
var dt = Math.sqrt(Math.pow(self.Radius, 2) - Math.pow(eDistCtoE, 2));
// compute first intersection point
var f = new Point(((t - dt) * dir.X) + pointA.X, ((t - dt) * dir.Y) + pointA.Y);
// check if f lies on the line
f.onLine = (Vector2.Distance(pointA, f) + Vector2.Distance(f, pointB) === Vector2.Distance(pointA, pointB));
// compute second intersection point
var g = new Point(((t + dt) * dir.X) + pointA.X, ((t + dt) * dir.Y) + pointA.Y);
// check if g lies on the line
g.onLine = (Vector2.Distance(pointA, g) + Vector2.Distance(g, pointB) === Vector2.Distance(pointA, pointB));
Vector2.Add(f, self.Radius);
Vector2.Add(g, self.Radius);
//return {points: {intersection1:f, intersection2:g}, pointOnLine: e};
//console.log("Two intersections");
var circleCenter = self.Center(),
vectorAux1 = new Vector2(circleCenter.X - e.X, circleCenter.Y - e.Y),
magnitude1 = vectorAux1.Length(),
d = vectorAux1.Normalize(),
vectorAux3 = new Vector2(circleCenter.X - pointA.X - self.Radius, circleCenter.Y - pointA.Y - self.Radius),
magnitude3 = vectorAux3.Length(),
vectorAux4 = new Vector2(circleCenter.X - pointB.X - self.Radius, circleCenter.Y - pointB.Y - self.Radius),
magnitude4 = vectorAux4.Length(),
overlap = 1;
if (magnitude1 < self.Radius && (f.onLine || g.onLine)) {
var pOnLine = null;
if ((f.onLine && !g.onLine) || (!f.onLine && g.onLine)) {
if (f.onLine) {
pOnLine = f;
} else {
pOnLine = g;
}
var vectorAux2 = new Vector2(circleCenter.X - pOnLine.X, circleCenter.Y - pOnLine.Y),
magnitude2 = vectorAux2.Length();
d = vectorAux2.Normalize();
if (magnitude3 < self.Radius) {
overlap = (new Vector2(pOnLine.X - pointA.X - self.Radius, pOnLine.Y - pointA.Y - self.Radius)).Length();
} else if (magnitude4 < self.Radius) {
overlap = (new Vector2(pOnLine.X - pointB.X - self.Radius, pOnLine.Y - pointB.Y - self.Radius)).Length();
} else {
overlap = (self.Radius - magnitude1);
}
} else if (g.onLine && f.onLine) {
overlap = (self.Radius - magnitude1);
}
return new Vector2(overlap * d.X, overlap * d.Y);
}
}
/*else if (parseInt(eDistCtoE) === parseInt(self.Radius)) {
console.log("Only one intersection");
//return {points: false, pointOnLine: e};
return true;
}*/
return false;
};

108
src/JS/XgameJS/Enemy.js Normal file
View File

@ -0,0 +1,108 @@
/**
* Represents one enemy.
* @constructor
* @param {AnimatedSprite|Sprite} sprite - The enemys's sprite.
*/
function Enemy(sprite) {
"use strict";
/*globals Vector2, setInterval, AnimatedSprite, SpriteEffects*/
this.Sprite = sprite;
//Physics properties
this.SpeedV = Vector2.Zero();
this.Speed = 0;
//Platform game properties
this.IsOnGround = undefined;
//Enemy States
this.IDLE = 0;
this.MOVING = 1;
this.HITTED = 2;
//this.TURNING = 3;
//[...]
this.CurrentState = 0;
//Enemy attributtes
this.Life = 5;
//If the sprite is animated starts the sprite animation
if (this.Sprite instanceof AnimatedSprite) {
this.Sprite.StartAnimation();
}
//Change the enemy state every 2 seconds
setInterval(this.ChangeEnemyState.bind(this), 2000);
}
/**
* Updates de enemy.
* @name Update
* @function
* @param {Number} levelWidth - The width of the level.
* @param {Array} platforms - The platforms array.
* @param {Number} gravityForce - The gravity force.
* @memberOf Enemy
*/
Enemy.prototype.Update = function (levelWidth, platforms, gravityForce) {
"use strict";
var self = this,
enemySprite = self.Sprite,
bounds = self.Bounds();
//TODO: Add your enemy's update logic here. Change this function arguments as you need
//Screen boundaries
//Left
if (bounds.X < 0) {
self.SpeedV.X = 0;
enemySprite.Position.X = enemySprite.Position.X - bounds.Position.X;
}
//Up
if (bounds.Y < 0) {
self.SpeedV.Y = 0;
enemySprite.Position.Y = enemySprite.Position.Y - bounds.Position.Y;
}
//Right
if (bounds.X + bounds.Width > levelWidth) {
self.SpeedV.X = 0;
enemySprite.Position.X = levelWidth - (enemySprite.Right() - bounds.Right()) - bounds.Width;
}
};
/**
* Changes the enemy state randomly
* @name ChangeEnemysState
* @function
* @memberOf Enemy
*/
Enemy.prototype.ChangeEnemyState = function () {
"use strict";
/*globals SpriteEffects*/
var self = this,
enemySprite = self.Sprite;
//TODO: Change your enemy state logic here
};
/**
* The enemys's collision rectangle.
* @name Bounds
* @function
* @memberOf Enemy
*/
Enemy.prototype.Bounds = function () {
"use strict";
/*globals Rectangle*/
var self = this,
spriteBounds = self.Sprite.Bounds();
return new Rectangle(
spriteBounds.X + spriteBounds.HalfWidth() / 2,
spriteBounds.Y,
spriteBounds.HalfWidth(),
spriteBounds.Height
);
};

View File

@ -0,0 +1,13 @@
/**
* Defines the Game object states.
* @readonly
* @enum {number}
*/
var GameStates = Object.freeze({
Initializing: 0,
Loading: 1,
Playing: 2,
Paused: 3,
GameWin: 4,
GameOver: 5
});

View File

@ -0,0 +1,11 @@
/**
* Defines the gravity directions.
* @readonly
* @enum {number}
*/
var GravityDirections = Object.freeze({
"G_DOWN": 0,
"G_UP": 1,
"G_LEFT": 2,
"G_RIGHT": 3
});

View File

@ -0,0 +1,37 @@
/**
* Defines a pickable object.
* @constructor
* @param {Sprite|AnimatedSprite} sprite - The sprite of the object.
* @param {PickableObjectTypes} type - The object type.
*/
function PickableObject(sprite, type) {
"use strict";
/*globals AnimatedSprite*/
this.Sprite = sprite;
this.Type = type;
//If th sprite is animated starts the sprite animation
if (this.Sprite instanceof AnimatedSprite) {
this.Sprite.StartAnimation();
}
}
/**
* The collision rectangle of the pickable object.
* @name Update
* @function
* @memberOf PickableObject
*/
PickableObject.prototype.Bounds = function () {
"use strict";
/*globals Rectangle*/
var self = this,
spriteBounds = self.Sprite.Bounds();
return new Rectangle(
spriteBounds.X + spriteBounds.HalfWidth() / 2,
spriteBounds.Y + spriteBounds.HalfHeight() / 2,
spriteBounds.HalfWidth(),
spriteBounds.HalfHeight()
);
};

93
src/JS/XgameJS/Player.js Normal file
View File

@ -0,0 +1,93 @@
/**
* Represents the player.
* @constructor
* @param {AnimatedSprite|Sprite} sprite - The player's sprite.
*/
function Player(sprite) {
"use strict";
/*globals Vector2, AnimatedSprite*/
this.Sprite = sprite; //The player sprite
//Physics properties
this.SpeedV = Vector2.Zero();
this.AccelerationV = Vector2.Zero();
this.SpeedLimit = 4;
this.GroundFriction = 1;
//Platform game properties
this.IsOnGround = undefined;
this.JumpForce = -8;
//Player States
this.IDLE = 0;
this.MOVING = 3;
this.JUMPING = 4;
//this.CROUCHED = 4;
//[...]
this.CurrentState = 0;
this.Life = 10;
//If the sprite is animated starts the sprite animation
if (this.Sprite instanceof AnimatedSprite) {
this.Sprite.StartAnimation();
}
}
/**
* Updates de player.
* @name Update
* @function
* @param {Boolean} moveLeft - Tells if the player moved left or not.
* @param {Boolean} moveRight - Tells if the player moved right or not.
* @param {Boolean} jump - Tells if the player jumped or not.
* @param {Number} levelWidth - The width of the level.
* @param {Number} gravityForce - The gravity force.
* @memberOf Player
*/
Player.prototype.Update = function (moveLeft, moveRight, jump, levelWidth, gravityForce) {
"use strict";
/*globals SpriteEffects*/
var self = this,
playerSprite = self.Sprite,
bounds = self.Bounds();
//TODO: Add your player's update logic here. Change this function arguments as you need
//Screen boundaries
//Left
if (bounds.X < 0) {
self.SpeedV.X = 0;
playerSprite.Position.X = playerSprite.Position.X - bounds.X;
}
//Up
if (bounds.Y < 0) {
self.SpeedV.Y = 0;
playerSprite.Position.Y = playerSprite.Position.Y - bounds.Y;
}
//Right
if (bounds.X + bounds.Width > levelWidth) {
self.SpeedV.X = 0;
playerSprite.Position.X = levelWidth - (playerSprite.Right() - bounds.Right()) - bounds.Width;
}
};
/**
* The player's collision rectangle.
* @name Bounds
* @function
* @memberOf Player
*/
Player.prototype.Bounds = function () {
"use strict";
/*globals Rectangle*/
var self = this,
spriteBounds = self.Sprite.Bounds();
return new Rectangle(
spriteBounds.X + spriteBounds.HalfWidth() / 2,
spriteBounds.Y,
spriteBounds.HalfWidth(),
spriteBounds.Height
);
};

21
src/JS/XgameJS/Polygon.js Normal file
View File

@ -0,0 +1,21 @@
/**
* Defines a polygon.
* @constructor
* @param {Array} segments - An array with the segments that conform the polygon.
*/
function Polygon(segments) {
"use strict";
this.Segments = segments;
}
/**
* Gets the number of vertex of the polygon.
* @name NumberOfVertex
* @function
* @memberOf Polygon
*/
Polygon.prototype.NumberOfVertex = function () {
"use strict";
return this.Segments.length;
};

View File

@ -0,0 +1,31 @@
/**
* Represents a projectile.
* @constructor
* @param {Sprite} sprite - The sprite of the punch.
*/
function Projectile(sprite) {
"use strict";
/*globals Vector2*/
this.Sprite = sprite;
this.Speed = 6;
this.Power = 1;
this.SpeedV = Vector2.Zero();
}
/**
* Updates de projectile.
* @name Update
* @function
* @param {Sprite} playerSprite - The player's sprite.
* @param {Number} levelWidth - The width of the level.
* @memberOf Projectile
*/
Projectile.prototype.Update = function () {
"use strict";
/*globals SpriteEffects*/
var self = this,
projectileSprite = self.Sprite,
bounds = projectileSprite.Bounds();
//TODO: Add your projectile's update logic here. Change this function arguments as you need
};

39
src/JS/XgameJS/Segment.js Normal file
View File

@ -0,0 +1,39 @@
/**
* Represents a 2D segment, which is composed of two points.
* @constructor
* @param {Point} pointA - The A point of the segment.
* @param {Point} pointB - The B point of the segment.
*/
function Segment(pointA, pointB) {
"use strict";
/*global Vector2*/
this.pointA = pointA;
this.pointB = pointB;
}
/**
* Gets the distance of the segment.
* @name Distance
* @function
* @memberOf Segment
*/
Segment.prototype.Distance = function () {
"use strict";
var self = this;
return Math.sqrt(Math.pow((self.pointB.X - self.pointA.X), 2) + Math.pow((self.pointB.Y - self.pointA.Y), 2));
};
/**
* Gets the direction vector of the segment.
* @name DirectionVector
* @function
* @memberOf Segment
*/
Segment.prototype.DirectionVector = function () {
"use strict";
var self = this,
distance = self.Distance();
return new Vector2((self.pointB.X - self.pointA.X) / distance, (self.pointB.Y - self.pointA.Y) / distance);
};

145
src/JS/XgameJS/Sprite.js Normal file
View File

@ -0,0 +1,145 @@
/**
* Represents a sprite, which is composed of a Texture2D and other properties.
* @constructor
* @param {Texture2D} texture - The texture image.
* @param {Vector2} scale - The scale vector of the image.
* @param {Rectangle} sourceRect - The image source rectangle.
* @param {Point} position - The sprite position in the canvas.
* @param {Boolean} isVisible - Determines if the sprite is visible or not.
*/
function Sprite(texture, scale, sourceRect, position, isVisible) {
"use strict";
/*global SpriteEffects*/
this.Texture = texture;
this.Scale = scale;
this.SourceRect = sourceRect;
this.Position = position;
this.IsVisible = isVisible;
this.SpriteEffects = SpriteEffects.None;
this.Rotation = 0;
}
/**
* Gets the width of the sprite.
* @name Width
* @function
* @memberOf Sprite
*/
Sprite.prototype.Width = function () {
"use strict";
var self = this,
aspectRatio = self.Texture.Width() / self.Texture.Height(),
sourceAspectRatio = self.SourceRect.Width / self.SourceRect.Height;
if (aspectRatio !== sourceAspectRatio) {
return (self.Texture.Width() * self.Scale.X) / aspectRatio;
} else {
return self.Texture.Width() * self.Scale.X;
}
//return this.Texture.Width() * this.Scale.X;
};
/**
* Gets the height of the sprite.
* @name Height
* @function
* @memberOf Sprite
*/
Sprite.prototype.Height = function () {
"use strict";
return this.Texture.Height() * this.Scale.Y;
};
/**
* Gets half of the width of the texture.
* @name HalfWidth
* @function
* @memberOf Sprite
*/
Sprite.prototype.HalfWidth = function () {
"use strict";
return this.Width() / 2;
};
/**
* Gets half of the height of the texture.
* @name HalfHeight
* @function
* @memberOf Sprite
*/
Sprite.prototype.HalfHeight = function () {
"use strict";
return this.Height() / 2;
};
/**
* Gets the Point that specifies the center of the sprite.
* @name Center
* @function
* @memberOf Sprite
*/
Sprite.prototype.Center = function () {
"use strict";
/*global Point*/
var self = this;
return new Point(self.Position.X + self.HalfWidth(), self.Position.Y + self.HalfHeight());
};
/**
* Returns the y-coordinate of the top of the sprite.
* @name Top
* @function
* @memberOf Sprite
*/
Sprite.prototype.Top = function () {
"use strict";
return this.Position.Y;
};
/**
* Returns the y-coordinate of the bottom of the sprite.
* @name Bottom
* @function
* @memberOf Sprite
*/
Sprite.prototype.Bottom = function () {
"use strict";
return this.Position.Y + this.Height();
};
/**
* Returns the x-coordinate of the left side of the sprite.
* @name Left
* @function
* @memberOf Sprite
*/
Sprite.prototype.Left = function () {
"use strict";
return this.Position.X;
};
/**
* Returns the x-coordinate of the right side of the sprite.
* @name Right
* @function
* @memberOf Sprite
*/
Sprite.prototype.Right = function () {
"use strict";
return this.Position.X + this.Width();
};
/**
* Returns the rectangle bounds of the sprite.
* @name Bounds
* @function
* @memberOf Sprite
*/
Sprite.prototype.Bounds = function () {
"use strict";
/*global Rectangle*/
var self = this;
return new Rectangle(self.Position.X, self.Position.Y, self.Width(), self.Height());
};

View File

@ -0,0 +1,38 @@
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller
// fixes from Paul Irish and Tino Zijdel
// JSLint and JSHint fixes by Víctor Hernández Molpeceres
(function () {
"use strict";
/*global window, clearTimeout*/
var lastTime = 0,
vendors = ['ms', 'moz', 'webkit', 'o'],
x;
for (x = 0; x < vendors.length && !window.requestAnimationFrame; x += 1) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (callback, element) {
var currTime = new Date().getTime(),
timeToCall = Math.max(0, 16 - (currTime - lastTime)),
id = window.setTimeout(function () {
callback(currTime + timeToCall);
}, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}
}());