In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

flash on 2012-6-26

WonderShmup
@by Hasufel 2010 for Wonderfl
A two nights exercise with Vectors, SetPixels, and Particles
Who said Flash shmups can't be played on netbooks?
Get Adobe Flash player
by sakurashibe121 26 Jun 2012

    Talk

    Hasufel at 27 Jun 2012 04:13
    original here: http://wonderfl.net/c/lZjB
    Embed
/**
 * Copyright sakurashibe121 ( http://wonderfl.net/user/sakurashibe121 )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/A7VN
 */

package {

    //*********************************************************************************
    //WonderShmup
    //@by Hasufel 2010 for Wonderfl
    //A two nights exercise with Vectors, SetPixels, and Particles
    //Who said Flash shmups can't be played on netbooks?
    //**********************************************************************************

    import flash.display.StageQuality;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.geom.Rectangle;
    import flash.geom.Point;
    import flash.geom.Matrix;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.filters.BlurFilter;
    import flash.utils.ByteArray;
    import flash.utils.Timer;
    import flash.utils.getTimer;

[SWF(width="465", height="465", frameRate="60", backgroundColor="0")]
    
        
    public class WonderShmup extends Sprite {

        private const stageH:int = stage.stageHeight;
        private const stageW:int = stage.stageWidth;
        private const stageH2:int = Math.round(stage.stageHeight/2);
        private const stageW2:int = Math.round(stage.stageWidth/2);

        private const point:Point = new Point();
        private const stageRect:Rectangle = new Rectangle(0, 0, stageW, stageH);
        private const blurFilter:BlurFilter = new BlurFilter(2,2,2);
        
        private const graphicsData:Array = ["47494638396108000800a20700ff0077ffeeffff77ccffaaeeff2288ff55aaffbbffffffff21f90401000007002c000000000800080000031b780aa03b218c064c102218000b2185d47de164611a955d8dc33809003b",
        "4749463839611e002200c41700170d11690710ff0825785b6a8a0506b29da9503441f20204a90404ff0853c7030b627f1dfdb31ffdcf67e7e4eaa8c459fde292fdaa00482d2d0e0504715556dfffa0af9a9cffffff00000000000000000000000000000000000000000000000021f90401000017002c000000001e0022000005ffe0258e24c94465aaae17d334282ba70c04c5737e0d4531e8bac262f103ca0405c763a030b2048bca63d174aa128be9e2604d21b0890335d0dd39060884a26008b87906271b900020d80800d250040e1c07750a090a047a0105007206097507150b8602040671460681750f610b7a0401967e8d010081850001a74e070209a0ac696d079f4e15020288b300040501b30b40800fb78888030003a9040b017d2c0602c3adc90e89d004cb9439ac0fc38e8d0a9e43b42bb7acb7dd15a9090208015ad8866a260d02070a8ce8ea0ab7ee53d879762168c0a0450308f77c1460d72a553f5f0007f009800002418309253aa856ed409a350ef81c9b38b0e0887b8600731850e9c3d78166bd5001984900410a010a0e2824700ccd4c043d41ad0c5033852f003e1cdc99c99469019e12779131ba03d346640e70cea9464991221616285c983041828583162950207b216c0e0923244ca861030283b271ad4888801606dc32222c18bc2816f088080c4e184e1101c78c10003b",
        "4749463839610c000c00d52500ffeed1ffd2a2fffaf2ffde92ffc879ff9c48ffecbcf79e94ffecbbfd8f1ffd901fff9146ffa248ff9847ffa028f96015ffd644f67440ffc581fff1b6ffef6fff9b49f77742fe6d2bfff9a7ffb134ffc436ffe280ff8b1bff9e23ffc883f97b1cfff88ff94e21ffa24dfff1a3fa9f94ffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021f90401000025002c000000000c000c0000064ec01281502a1a87c5c1c068549604088380099502262300f39a0d803001a617eca16c24ccf25904d154986c3723e32830e7f54687b360eaf9160a09114c8183070f1f244c888a2521174c45902541003b",
        "4749463839611c001f00b30f0000204a615f5a1038634882ad39383168a1cea1a19c205784f1f0ef91c1ef810100b9e9ffd95700101119f99a00ffffff21f9040100000f002c000000001c001f000004fff0c949a73135eb8dd0fe5b401001684ec47110e73924c9d082c1b02c43396b42a10e821de5f238000201c0e141dc5d084098604068b60297802021d80ab006dd29d0d126545c3242bc39148e8063215198179270dfe60520001804090b750b09040c7d00311b5d037d045f1d6502230040411a07830b00770871716b6f9b4b19036e744606a0a0aba83e3212050f03b5a08e49080aa0498e71b53205c1036f1771490abbc771c6c2b3c404755f234901ca710ad5d43d05d1945b726eaac9c9ae3e778adf70027d029fb80c0e0e0cbd00089400ecd57049ee53062490883000e41e1c3f221e30cb87e0408e5eb86a1c30b80ac0031628183aacd885d929831841351870e72685428b2b7cdcc3f0014a8c376c92088b115243a75b35a1807a03221f800bec28e4331614c497060dd848088054cb097695323ccad702d406ab192200003b",
        "47494638396120010800a20700133d4cffffffa1c4c953939cd9e7e975a9b036818cffffff21f90401000007002c00000000200108000003ff780aa0cecdadf8983c906278f95bddf549918689540a92a6c77616acb9ebbc9e7879e7328cb6b14a6b97f1b14c9b5f271048319b24a653fa784231d6e915d0e43a91de2ae38a9d41c3def082ba66b7b56636d79dde76cff771595d8757c9586473824f5f7c597f7e895182040c8e0b8e0090189294938f2592299b0f9d91999e6094959824a4958e049093aa9aa1a5a6b19796af41a5a7b098a6bb96b3b6a8bab5b947a410b4c22ebb30c6c3bf0b02d10225d229d33818d300d7d9d1d6de0fd3e0dde3d960dcdd2de8e6e20ddbdbdcefefd0e5f2f1d524e5e6f90cf7fdeeda02d29b812f9cb57ffcf2d52b086f5cc36febf6855bf770410106172d622c7111d640460c1d3f7a54d69144488e1b1f7cacb072e44a904146a69429f2a4c61936618e14d2f2254d943b7f7ad4d932e54d95463522bd05a1e8ce094f7f2235997483c8010cb02e18c07546d7075cb56e0d5b422c09b25bb3a6308be12b58b560dd02d03ad71dd6ba71d78271db166e5bbe7d3ba01dbb16ebd7ba78ffb29dcb97710bb38ce50e3e5b16b063ca82175b26726b428f2336446c083dc408891da34fdfd0f142f50f032ab0a50ef103888f989cc174ee8cba8810d1b26978a66dba02f0e3c8932b5fcebcb9f3e7c991409f4ebdbaf5ebd80f2400003b",
        "89504e470d0a1a0a0000000d49484452000000c50000001408060000003d5af97a0000001974455874536f6674776172650041646f626520496d616765526561647971c9653c000013c04944415478daec5b7b505bd799ff842424814002832060236ce2103bc452b2f1b38945124749274db0773be974d31acffee3c8bb19c7bbd9064fb3637bdb9d3871da2493d9c86e6767f0a6d95d3c6983dbb513e44d034e629be0c4c2c131606383c104842d090448e8b9dfb92f9d7bb97af8d1e9ccce9e993be29efb7dbff3fb1ee7792f8ab6b6b67700c001c9e2c46b1b88cb2b9c8c8192790baf3e4a662b2763a16476e03547c9d4e3b5052f2b25c7970ebcdc9c5e1fcc2f529e0739d94e902f6578eda2743a38f916192cb9d2c1fdb6e3d58cd760169c3215deb7526e726592f3c720d77e7b0ab96abc367297958a118de1e6f45b53f0968b395f7ec0c9dab2f063a698dc0c26a9df83d7f82de2c89521cebfc4374ebbddceb4a1c04e9178fd959f275b79f6c7b0a8cafcb02408feb77fb9cf3037c7e6f7fd2b57c1231beca453bcc0ebbeb8f365f7c17ffbb565c2c3727f78831dfe62e5aa1df8fc4d7cf63821387c65a8a1e76c3778c6c78197e30bb609a5656544070c0623e308d415841043c4f39e7b57c077bff73409c256ac9f935a8bf2bb4f7c7a7cd789cf8e0bf8685b07cad64bb1e40a91e77fef59b182e7f416eaf5a5e294a950beada7b9c9158d4603a6b272283418a06e8585e839b1ad6d121bdf999cf43b2ef6f7c3c5fe3ef4eb18f031a231885fabd08e3befaa6530a4bc795e58d72ee3c7f696f7deb561ec32fa918f09d66d49e7871bc15cf7e07a58f7d07a920bbb6f0547ae10df625c193d92771aadf639ec180754e4a1279c141c1c1d274256aa536c3cd7db67180e249dddd9d3473a0519995ea0742de74692896e2c258321b891dcd66028b4ff50ebefe15c5f7f4a829e8b68185e1f7dfe053c665bef78ac7e3d31faad9fec492621cdd3f3e559d09794373eb466d52cd6cb8e7233b1a48e3e22c6a0b152f2c1f225feb6fef1383cb87a95e3e927ec79c8c9899c3ae538652ae1b83c3779e139180eb01c3e415b9f6978ca816d03b6cdd8fadaae97df39edee761c3afc87cc18c416f42bea38785fd16df3bc52f1f145b2f3e314e645fd865023f27c0979ca8dec84c3ead1b171db979c7f3361123fdd0e6eb2319ec089142fc2a5f35c1f3cb7e5c7fb5d2e572be9141d65e6e5b6fea1ab8ce0b7fe103f25f3656357ef30cec3c9597912b186c726cc8bca4bad58ef3eb0ebf9fafec1ab22999a6a66a43d3f1b9afbe417cd1fc0c8f835c9cc9ebabcdfd10dbe10389e79623dc1dc965c0b88f57fd3d609d5d58b1de8e8c9ad7bdede29c5098146d099817c11c664965cf872a4b30fbca19cc62d1b3710ddce549cd29518a864b965537e7df8382c666d7d0d6f57bb7b2f39481ddca01d72f6f3bc52f121becbc68f93386efecfa96e78aa7eb503eb77a7a0e0709dfa5aa4970e93f8e97670cbe897f190c09d786330af74a16d6a3cca3cecf5325dd3ca0ff8b37391c6b63e2f80b64c04f2c9b911d85c5eba654a5bf602911fb83603539c4c49611ebf5e7be1e8e98bf0cda452d0cfd3a861f3a3f7c1cabb2a99bf4999989c818eaf07e1b79f9f13f03fe81e83bae51e0776b8c33f7cf5501b3312493890b2fbbf3e83b71ddf6b423937cab5d0cfe6547a416726b708680c1aeb9f7e580fcbab4cc23dda0c83e33e86d3f19ee45682f861f1d7838dd8d6496ceb40261cb93d05eab5ffe74bcfd4d3dc48c13af162d7e387a35dfda2f67b86bd60331632fbb2df7f3524d2ffabefdc03b67baba1d4903fcf8e6fae4cc0e90bcca0d72d677f34470da9fccbfb6e4a1bcde847525ce72730b180e4c5bc4e81365663ace7e5533a4ce2a7dbc14d2e36c427ce235f307e22e5cce82c3c854b5ba653184a2b605acfcea15d3ee687dfb86c3c79d98fcfaa989bc5257970f9da2cf3f7d14b514c6ed882cf984ed18789cfcbdd6366c8b967e6a24def9f9f8519ae3e3f57093fddb41c9694e4efc5db579ffad7537e52ff87bf5d53fdfd07eff9495189c9f1e6c70302e9dff5f888210ec4653a058f4f9769bc7e76f402bcb269b9039dee464c61b915ce35083a415d21d01834564ca965b641a8dbcef13162bb56bcb6dcb7eccec67ff930b9ecfbed3753987c40381dc884235b38799a1b5f504fc1ff8d1c566fde70ffa9a383c935d7d5a08a9fc56d5d3e9d80f5b4a51cbeff6035d9f3bc86188314066f473dfa972c779d69ec97f52febbb327ca6cbe847e61ee97edc3b61c6586c452e0724505b8ff5f9e6e9a4c3247eba1ddce46283fe6937996b6d3da353227de2e5f63ab36957b83f39b50fe042ada6484d668b8d9f8eab206c6057533f7db2141c47aec14c240164b9766238644060e6d4a32f6440397694322f647ab7bbdb136df0e91601b09ce1f9b506ec10babd8fff668c5dea70b8784f02b9aded47e5cb3f1a56dace8eb38bc14fbdcc4f03df3eff4bca9222155cf2b123c4573300fb4f4fd99e7ba0703bca08cbad98d6883aac5d517dae0883c64aa8b4a23ae4e3e7f654edc8096cf72d6b3c7629c83cebc341653a1cb79084cb849376294571131240ac679c8e284475bac202e6d0432a5b52c2d4f7337ea4ea693bc8a44afbfc467847f5e5f8ac38a31f85e5ef80021ebd1b1cf84cda291cef5f56cfd3498719d3ea6f0b37a98d18d7d564801981d279facc4c515688ebb6a224c0384e273510abc6a0349c9cbe039f61121626a04c3fd7bdeeee859663234a46ee042eb5d62d8a904e61b9040b193966c75d49923a0e034134a8c8983c49a8229bf5c4ab745b925d40f363cb4a6d67c36aa1e6ecf53031a09eb9a1f41c6bc2e0fc460d97a6d8c1f503dcd6ad188b385076f2f123da9d64350a98785054c22a14901137cc61844458a062f9caf30a35db6b8b1a8ff99253f1a54018562c885ba59c389c4f48474a71c4eb446e2df3b871ab6782d5f664c8c81f6f3b7b7522fc7566c67fe45875777e69b56126ca2d592612f82cfc06b6fb86ccb12e73148bed364bdbca9237fa0eebc33919fd487284c4e3121b370be2fd80b517885d2fb9469486193d7baa87fe4399cc98c02c8da2a9629335373ec6c88939bec6dc6edcff8d0a3cb93868e772fbe04ab27588b8d94ea14be0b8b428395384bdb00eae5b8f4d18c8311253b76929394c9873ae5ba8d97f8c7414d2298284c4c0c6b393183ce3c2e40b02fd209b645aa25f9c5c39a82fc0e39f2ff58331d5f87961b0bc20578405aa1132b17163e72251fdbeb573b0f9f4629889b14e791d971afb0a469a3000ec12826e5f4f3046388c0bf3b09836e8ba2427f71203c8cb4b38fd636fea9961852168db57c7b4dfc2b42ff10da943deef4c47731c27bc7a78f7ca02f0cc6178385f6daaf043992ee444ff0db67de742ebba2586c6631e76ba2749b8f9abf96de62be3066cb761dd82e986b627a7ea994ef9f9d24ea9fde97827e72dc8e8479223bfb8c00e1eef7e1b847d0b461cacbd8c7d8e77c77039636467c7c7968cc3d95859e6d868c972e17aaad8a02eee1362ba6c636c3c715dffc1096f3ee02f9b3746c157b0a9e60aff5e04127f8aabadad6df76dc4aabf4d38ed8944e2966ddef7bb5337c5896fff567cc3e9afbe45fddbe2c75bc5f95360de2a0ed155a132597f34fff25a5de3c7d3154caf31a982b0b7fc34fccdc843ccfda3fa51f8fb929e83dcdbe8377fe5bd7bfbe1a92ae11929bceebd5a1fea76316f8337b75c84fff0d7b03d31270a87aafe38f9e4a03de53c71a4da55ff75a8f893a6b107843ac203c04b8c04d415d5dfabf5921761cfbce7af71f0edd07cb1be91af27bc00ba40fd2b48898575ed329cac97c205679e1f5d2bd42994a7d975a904275da1db3f522df60dd70e205f511df1d98e921e589be761de14635b9d441fc0de896def1d8fea9a88cea95913ccc4551939102c97cbc5bc58531d48c0cd14a91d340eb101f348c8052a6f8c3ff3581b084f525e36b9418fb6f1714e87f9d7c60178d638b0076ddf2d139bf6a6b195b6af43451971b818ef417fed92e60ae243992ab8d76eb7efe4f714cc3b3bb32e08460e238c3be3cfe62ac0c89deead2ff000f58940f3e38557b777c4d84e711e4c50a20c0ab22bf3bcfca711a0c5ad8151382154c16c426540438ccf4ed8fda926e939858ad2412d25f550be7e0f1ab5fc3214dbce4758e77c99a8808f828146ba7dbd5a8c218745d7d19f5178133ad1b3425544d8f0d2f52f1b4fc332b537dd67234e5e5eec1bb6d80b46a13d6a267e628faf71b8aac865966927d1679db43cdeef7cafd4d58a49e7e03ef1101dca4fe092e2cbb009de9dae15ea2e268a61038cd6df206ff8b97f25f0be4de747e668d838c4f89f8fc36ca2b77126ae865e858991cd534449279f3c1f293664131bad3a6d6c408ffb67a332eb18b7df9fefdb15508ec272b47799da07a5cae041ee138fce64a672dff758b4be5d9f2992209fe156db84a0458a203ca0f10c519dc26d5605866af541b32fa16320425000260df779041b44b2a61f9462f6c44cb04a35ba15715f4de1ff8dfde83c13654cb58a392e7333331855afe6f6563b66ede36fe4b99cff603863fbe7d07a087109d596a8853a9547d03172f2fcbd1c96293f3b4e683f69d78dedcae13c8ccf521ec9f2f2f9b8753229c4cf30407b7f641c686a0dd70ae13914ad83bf5376edc70ed08eb8a26fc2f0be33d57746c8adfa09ddd09b57738a1a88dfd9f7113ae1c56cb6bc11a7dda8059b2937b31f39df745b0b0296d138732206c7b193934185975baf625616cdd8e6f66c6293af4e1b1b406ec073bb43c90e56e9628c9dff61bcb6f0a772d81906a598c24c8101814afdfc46ef4f4c90d556aba4baf5c1bc89ed5f29e69f1d57c7034c12bf9e6377bf08aec925faa8618e6bc68d1dcd12f7ec4547fbf1b9e8b8eec5b8eb150f14348e6a2ba0924f1208802e1eed46593f3e17f1d370ab4052f73ad85bf0b97587aeabe9df7392cb1c1fce62492c76efcf60f0bf3258141fb2cc7b6958512ce27467c243640f678b235b50af100359a911d79153259b6a68ed58aec936cc1fe5e180733271273c92e8dd8eb8db287e566e866825be9669e35b664cd1e9e6f98094ac79a37c691e739693d18f1cb6f3bbbaa1fd1f29eab8ad307bdac4737824ce7cded1aa51c1f64ab52c66c71abd4fb0ff0ae0ac131fd88239f321dad949d9bf751274b6505e9180bd2c112076b8d3c50631daa94f98406ef12b740a0304a14ac629aba78708985352dd7c7fced5edd7f2e7770ad354000e15daddcc9329703ea21e6a3aa7e1d7703ae888ad8455a19efd2fc65c3b21f9e5a9d5a32a367caeb34215357aae0a0e11e39c0c2f9c30687e9a59f6a48eaf3b04f69dcf4cb90c4fabfa1c6e6ded3c5ea531e63b004883b59b743c7e008a285496cbea4a20dc694eeb66af1059679638d2d28cbe69267a06ec145574a7c03a7c36873638ff3271c6f6dffaf5801c9847d7a00aaece7a1d2f465d932843ecb4fa950567aeaab0d3473dbbd097ccdb6a7e49c7fbb43fd76cd0690b808fd2d270806437e940b674be1415e465d2917d54663f02fb0eaca5163cfb2fe44739fe2a2a063e30cc0499fda606f1aaf26431dbebd45e9b425324e4cc17913af37da1de53e857fecb65e34c8eced249f2855a5e2f9ff1906f565ab3c9977485de9d75dc9bebb34de5160915799100e44f0589b3a59f72bb8db140f7324dc032ab2e48aeb5c3ccebf00eb35e70d29b7747869ae2852648ca15409f612d686241b32616628691195501c4725450413540b0aaa7463b3a2bec07cc9cc3cd9441da39d648b338283bee0a0f5580bea8c1a715bfd22f0cb38e37ebe7638d6b6ae17a226a135e08613079be34a792d9513045bd0791539b1c27298eb494cc5eb56142b3efd072e77167ee3bf5f696d5a32e6b7da4a7a9bfd82a3cfe36af0e4a264e36a13e1948fa72546a985e508381a9e163655125a2c9cf1f389f9aa9266a27984f3dc8fb8aed197d49f12ac74e91979bd98fe41e7de347fe0757283d8dd7f22a44504bfc42fba055267525984ecc995dc12233c39f3d2aac80aff0c29cb0d1f131501b29922fc6a900c91777d6f99245a718ac54066dc5f9c94e51383e249cdbca8d7a3591d13702c6e4a8ac8bb1fb896a6e2d37bed43e5e76c1f55cddf5aefdde852b21aa29a0d475c0bfea2e9600e706d140ef19a6ed6a7a7f416fc07cf3ebb0bd396ccfb9d4dfd370ddbc16622a5d1233472c5f2d5aa316647494064721c3546f5a4e99707409dcccceb26b7a2326995ab24ea6fcb613edb863596cb431585821846a3ad70a9a2b27c9c6fa056d4efab6a53e2d1cef015d24e0446c376267f4255dca71dd5eaccbc68fc2bdd31c1c6ad497263b85221e859231e1c0c64af3a731b99cd96bf57535919c49e450294ae5a62889e702503c76e3f99255a7209bea923ceab38319c6889614baadf9b39e378c79c94e11f30770f602f7220a032cf603e16e172cc060e614575894256650e8e4932731ed8398ef2ac4bda3cc494daec5dec2bf7e2183098d1b55b24b58515b6c7b6dd85e53e9987baffaaee4fe2281c2114e3e2ca727fb2d4614e2d35e885fbb427e0f739c3a5371ca081720b33b5b0cb89e2ea67d2dc1c27b67e1b5dec605c545a0c8e532320f47ff708d253636508f332d54864641a1a79ecb6d09263d3c7fc27ddba21bf125274b0e51147999fd28dca38fa0dbd5bd5011b0f0b18e7b3d108d470f22073fc90732532c92c1e462b813f5a16cf86493b2ac06720c38eb2be71f3927c24188fb4621364196d9d1e76e2a5f32740a273adb8497f4bf9e521d9f0e2229271a289577564a63b486d9541fb87ccab515139ef9ef3c6d61722c8bc722d80103fcb165f3e235f6666963971157da16cac99ff2acb1bf8a6d9925f21d3c3719ac5485ff4c82b4d59605a74cc5c9cfbc72be16f96d8dbd136d688a9cff94c898a518e8fb0fa3c3cc712c396235e7e617408e522de7d3c352fe37e24b221b19e8227fdab2f0a36003a3d77f92fe4fcc83c2736c0b6da3753b64ecdf8932ad8c8dc3b051a5d119f04a76c0d929ec07d1216e3946f88fdf74be480af9cf3bf833957aea6f3f7fecfaffe5a68b95fa18e3ffa24fab41fc7f3eee340376d6c56e9f7ffef4bf020c00362b5c228de1cf660000000049454e44ae426082"];
        private const backgroundBmd:BitmapData = new BitmapData(stageW,stageH,true,0x0FFFFFF);
        private const bmd:BitmapData = new BitmapData(stageW,stageH,true,0x00FFFFFF);
        private const bmdShip:BitmapData = new BitmapData(stageW,stageH,true,0x00FFFFFF);
        private const shipBmd:BitmapData = new BitmapData(stageW,stageH,true,0x00FFFFFF);
        private const shipBmp:BitmapData = new BitmapData(30,34,true,0x00FFFFFF);
        private const shipRect:Rectangle = new Rectangle(0, 0, 30, 34);
        private const ennemyBmd:BitmapData = new BitmapData(stageW,stageH,true,0x00FFFFFF);
        private const effectsBmd:BitmapData = new BitmapData(stageW,stageH,true,0x00FFFFFF);
        private const ennemyBmp:BitmapData = new BitmapData(28,31,true,0x00FFFFFF);
        private const ennemyRect:Rectangle = new Rectangle(0, 0, 28, 31);
        private const shipBulBmp:BitmapData = new BitmapData(12,12,true,0x00FFFFFF);
        private const shipBulRect:Rectangle = new Rectangle(0, 0, 12, 12);
        private const bulBmp:BitmapData = new BitmapData(8,8,true,0x00FFFFFF);
        private const bulRect:Rectangle = new Rectangle(0, 0, 8, 8);
        private const fontBmp:BitmapData = new BitmapData(288,8,true,0x00FFFFFF);
        private const infosBmd:BitmapData = new BitmapData(stageW,stageH,true,0x00FFFFFF);
        private const titleScreenBmp:BitmapData = new BitmapData(197,19,true,0x00FFFFFF);
        private const titleScreenRect:Rectangle = new Rectangle(0, 0, 197, 20);

        private const starsCols:Array = [0xffffffff,0xffffcdff,0xffbebebe,0xffc7c7c7,0xffaaaaaa];
        private const stagesDescription:Array = [[3,0,"testing ground"],[10,0,"warm up"],[30,0,"you will slalom"],[3,1,"wtf shields"],[10,1,"round and round"],[20,1,"life aint easy"],[40,1,"dodge this human"]];
        private const starsNum:int = 100; //can be pushed up to 10000 on a 1ghz cpu without slowdown
        private const spd:int = 10; //speed of player bullets in pixels/move
        private const bulletFrequence:int = 70; //frequency of bullets in ms

        private const kd:Object = {37:goLeft,39:goRight,38:goUp,40:goDown,32:goFire};
        private const ko:Object = {37:unlockHorizontal,39:unlockHorizontal,38:unlockVertical,40:unlockVertical,32:unlockFire};

        private const friction:Number = .9; //friction of ship
        
        private var stars:Vector.<Particle> = new Vector.<Particle>(starsNum, true);
        private var ennemyBullets:Vector.<Particle>;
        private var shipBullets:Vector.<Particle>;
        private var impactParticles:Vector.<Particle>;
        private var ennemies:Vector.<Particle>;

        private var angle:int;
        private var lockVertical:Boolean;
        private var keyVertical:int;
        private var lockHorizontal:Boolean;
        private var keyHorizontal:int;
        private var lockFire:Boolean;
        private var bulletTimer:uint;
        private var titleTimer:uint;
        private var titleDisplay:int;
        private var titleBlinkDelay:int = 1000;
        private var stageInfosTimer:uint;
        private var stageTimer:uint;
        private var stageTimeBonus:int;
        private var stageInfosDelay:int = 3000;
        private var gameFinishedTimer:uint;
        private var gameFinishedDelay:int = 10000;

        private var currentStage:int;
        private var score:int;
        private var shipVx:Number;
        private var shipVy:Number;
        private var shipX:Number;
        private var shipY:Number;
        private var shipLife:int;
        private var shipVel:int = 3;

        private var loader:Loader;
        private var assetsMemoryBank:Array = [];
        private var assetsNum:int = 0;
    
        public function WonderShmup() {
             Wonderfl.capture_delay(20);
            setProps(stage, {quality:StageQuality.LOW,scaleMode:StageScaleMode.NO_SCALE,align:StageAlign.TOP_LEFT});
            var blackBg:Bitmap = new Bitmap(new BitmapData(465,465,false,0x000000));
            addChild(blackBg);
            prepareAsset(0);
        }

        private function prepareAsset(n:int):void{
            var bytes:ByteArray = new ByteArray();
            var data1:Array=graphicsData[n>>0].split("");
            var data2:Array=[];
            var d1l:int = data1.length;
            for (var i:int=0;i<d1l;i+=2){
                data2.push("0x"+data1[i>>0]+data1[(i+1)>>0]);
            }
            var d2l:int = data2.length;
            for (var j:int=0;j<d2l;++j){
                bytes[j>>0] = data2[j>>0];
            }
            loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE,assetsLoaded);
            loader.loadBytes(bytes);
        }

        private function assetsLoaded(event:Event):void {
            assetsMemoryBank.push(loader.content);
            assetsNum++;
            if (assetsNum<graphicsData.length) {prepareAsset(assetsNum);}
            else {initGame();}
        }

        private function initGame():void{
            //prepare bitmapdatas
            bulBmp.draw(assetsMemoryBank[0].bitmapData,new Matrix());
            shipBmp.draw(assetsMemoryBank[1].bitmapData,new Matrix());
            shipBulBmp.draw(assetsMemoryBank[2].bitmapData,new Matrix());
            ennemyBmp.draw(assetsMemoryBank[3].bitmapData,new Matrix());
            fontBmp.draw(assetsMemoryBank[4].bitmapData,new Matrix());
            titleScreenBmp.draw(assetsMemoryBank[5].bitmapData,new Matrix());
            //stars/background layer
            addChild(new Bitmap(backgroundBmd)) as Bitmap;
            //ship layer
            addChild(new Bitmap(shipBmd)) as Bitmap;
            //ennemies layer
            addChild(new Bitmap(ennemyBmd)) as Bitmap;
            //effects layer
            addChild(new Bitmap(effectsBmd)) as Bitmap;
            //ennemy bullets layer
            addChild(new Bitmap(bmd)) as Bitmap;
            //ship bullets layer
            addChild(new Bitmap(bmdShip)) as Bitmap;
            //infos layer
            addChild(new Bitmap(infosBmd)) as Bitmap;
            //prepare stars/background
            for (var i:int=0;i<starsNum;++i){
                createStar(randomNumber(0,stageW),randomNumber(0,stageH),0,randomNumber(1,5),i);
            }
            titleScreen();
        }

        private function titleScreen():void{
            titleTimer = getTimer();
            titleDisplay = 1;
            currentStage = -1;
            shipLife = 10;
            score = 0;
            stageTimeBonus = 0;
            stage.addEventListener(MouseEvent.CLICK,startGame);
            addEventListener(Event.ENTER_FRAME,titleLoop);
        }

        private function backToTitleScreen(e:Event):void{
            removeEventListener(Event.ENTER_FRAME,gameLoop);
            stage.removeEventListener(MouseEvent.CLICK, backToTitleScreen);
            clearGameStage();
            titleScreen();
        }

        private function titleLoop(e:Event):void{
            infosBmd.lock();
            infosBmd.fillRect(stageRect,0x00000000);
            infosBmd.copyPixels(titleScreenBmp,titleScreenRect,new Point(Math.round(stageW2-titleScreenBmp.width/2),30));
            var z:BitmapData = displayText("dodge da bullet human");
            var zRect:Rectangle = new Rectangle(0, 0, z.width, z.height);
            infosBmd.copyPixels(z,zRect,new Point(Math.round(stageW2-z.width/2),50));
            if (titleDisplay == 1){
                var a:BitmapData = displayText("click to start");
                var aRect:Rectangle = new Rectangle(0, 0, a.width, a.height);
                infosBmd.copyPixels(a,aRect,new Point(Math.round(stageW2-a.width/2),Math.round(stageH2-a.height/2)));
                a.dispose();
            }
            if (getTimer() - titleTimer > titleBlinkDelay){
                titleTimer = getTimer();
                titleDisplay = -titleDisplay;
            }
            var b:BitmapData = displayText("arrows to move space to fire");
            var bRect:Rectangle = new Rectangle(0, 0, b.width, b.height);
            infosBmd.copyPixels(b,bRect,new Point(Math.round(stageW2-b.width/2),stageH-b.height-1));
            b.dispose();
            infosBmd.unlock();
            starsScroll();
        }

        private function startGame(e:Event):void{
            stage.removeEventListener(MouseEvent.CLICK, startGame);
            removeEventListener(Event.ENTER_FRAME,titleLoop);
            nextStage();
        }

        private function stageInfosLoop(e:Event):void{
            if (getTimer() - stageInfosTimer > stageInfosDelay){
                removeEventListener(Event.ENTER_FRAME,stageInfosLoop);
                initKeys();
                addEventListener(Event.ENTER_FRAME,gameLoop);
            }
            else {
            infosBmd.lock();
            infosBmd.fillRect(stageRect,0x00000000);
            
                var textInfos:Array = ["stage " + (currentStage+1), stagesDescription[currentStage][2], stagesDescription[currentStage][0] + " targets to destroy", "targets shield is " + (stagesDescription[currentStage][1] == 0 ? "inactive" : "active"), "get ready"];
                for (var i:int=0;i<textInfos.length;++i){
                    if (i == 0 && stageTimeBonus>0){
                        var z:BitmapData = displayText("time bonus " + stageTimeBonus + " points");
                        var zRect:Rectangle = new Rectangle(0, 0, z.width, z.height);
                        infosBmd.copyPixels(z,zRect,new Point(Math.round(stageW2-z.width/2),Math.round(stageH2-z.height/2)-120));
                        z.dispose();
                    }
                    var a:BitmapData = displayText(textInfos[i>>0]);
                    var aRect:Rectangle = new Rectangle(0, 0, a.width, a.height);
                    infosBmd.copyPixels(a,aRect,new Point(Math.round(stageW2-a.width/2),Math.round(stageH2-a.height/2)-100+30*i));
                    a.dispose();
                }
            infosBmd.unlock();
            starsScroll();
            }
        }

        private function gameFinishedLoop(e:Event):void{
            infosBmd.lock();
            infosBmd.fillRect(stageRect,0x00000000);
            if (getTimer() - gameFinishedTimer > gameFinishedDelay){
                removeEventListener(Event.ENTER_FRAME,gameFinishedLoop);
                clearGameStage();
                titleScreen();
            }
            else {
                var textInfos:Array = ["congratulations", "your score is " + score, " ", "wondershmup", "a game by hasufel", "for wonderfl community", " ", "thank you for playing", "thank you for sharing", "dodge da bullet human"];
                for (var i:int=0;i<textInfos.length;++i){
                    var a:BitmapData = displayText(textInfos[i>>0]);
                    var aRect:Rectangle = new Rectangle(0, 0, a.width, a.height);
                    infosBmd.copyPixels(a,aRect,new Point(Math.round(stageW2-a.width/2),Math.round(stageH2-a.height/2)-140+30*i));
                }
            }
            infosBmd.unlock();
            starsScroll();
        }

        private function nextStage():void{
            removeKeys();
            removeEventListener(Event.ENTER_FRAME,gameLoop);
            //time bonus calculation
            if (currentStage>-1){
                stageTimeBonus = getTimer()-stageTimer<30000?Math.abs(Math.round((30000-(getTimer()-stageTimer))/100)):0;
                score+=stageTimeBonus;
            }
            initShip();
            clearGameStage();
            currentStage++;
            if (currentStage>stagesDescription.length-1){gameFinishedTimer = getTimer(); addEventListener(Event.ENTER_FRAME,gameFinishedLoop);}
            else {
            //prepare ennemies
            for (var i:int=0;i<stagesDescription[currentStage>>0][0];++i){
                createParticle(randomNumber(0,stageW-31),0,0,randomNumber(1,3),4);
            }
            stageInfosTimer = getTimer();
            addEventListener(Event.ENTER_FRAME,stageInfosLoop);
            }
        }

        private function clearGameStage():void{
            var layers:Array = [effectsBmd,bmdShip,shipBmd,ennemyBmd,bmd];
            for (var i:int;i<layers.length;++i){
                layers[i>>0].lock();
                layers[i>>0].fillRect(stageRect, 0x00000000);
                layers[i>>0].unlock();
            }
            ennemyBullets = new Vector.<Particle>();
            shipBullets = new Vector.<Particle>();
            impactParticles = new Vector.<Particle>();
            ennemies = new Vector.<Particle>();
        }

        private function initShip():void{
            shipVx = 0;
            shipVy = 0;
            shipX = stageW2;
            shipY = stageH-40;
        }

        private function gameLoop(e:Event):void{
            starsScroll();
            //ennemies
            var g:int = ennemies.length;
            if (g==0 && shipLife){nextStage();return;}
            if (stagesDescription[currentStage>>0][1]){
                ennemyBmd.applyFilter(ennemyBmd,stageRect,new Point(0,0),blurFilter);
            }
            ennemyBmd.lock();
            if (stagesDescription[currentStage>>0][1]==0){ennemyBmd.fillRect(stageRect,0x00000000);}
            var R:Number = .2;
            while(g--) {
                var l:Particle=ennemies[g>>0];
                l.clock = (++l.clock)%200;
                l.x = (.5 + R*Math.cos(l.clock*Math.PI/100*3))*stageW;
                l.y = (.5 + R*Math.sin(l.clock*Math.PI/100*2))*stageH2;
                ennemyBmd.copyPixels(ennemyBmp,ennemyRect,new Point(l.x,l.y), null, null, true); //mergealpha false in default
                var dx:int = (shipX+15) - (l.x+10);
                var dy:int = shipY - (l.y+20);
                var d:Number = Math.sqrt(dx * dx + dy * dy);
                if (shipLife && d < 160 && getTimer() - l.t > bulletFrequence/3) {l.t = getTimer(); d/=3; createParticle(l.x+10,l.y+20,dx/d,dy/d,2);}
                if (l.x>stageW || l.x<0 || l.y>stageH){
                    l.y = -30;
                    l.x = randomNumber(1,stageW-30);
                    l.vy = randomNumber(1,3);
                }
                if (l.y>0 && l.y<stageH-31 && testVector(bmdShip.getVector(new Rectangle(l.x,l.y,28,28)))){
                    l.power--;
                    if (l.power==0){particlesExplosion(ennemyBmp,5,l.x,l.y,5); ennemies.splice(g,1); score+=100;}
                }
            }
            ennemyBmd.unlock();

            //player fires
            if (lockFire && (getTimer() - bulletTimer > bulletFrequence)){
                bulletTimer = getTimer();
                createParticle(shipX+9,shipY,0,-spd*2,1);
            }
            var q:int = shipBullets.length;
            if (q){
            bmdShip.lock();
            bmdShip.fillRect(stageRect, 0x00000000);
            while(q--) {
                var s:Particle=shipBullets[q>>0];
                //if bullet hits something remove it
                if (s.y>0 && testVector(ennemyBmd.getVector(new Rectangle(s.x,s.y,12,12)))){
                    shipBullets.splice(q,1);
                }
                else {
                    s.x+=s.vx;
                    s.y+=s.vy;
                    point.x = s.x;
                    point.y = s.y;
                    bmdShip.copyPixels(shipBulBmp,shipBulRect,point);
                    if (s.x>stageW || s.x<0 || s.y>stageH || s.y<-12){shipBullets.splice(q,1);}
                }
            }
            bmdShip.unlock();
            }
            

            //ship handling
            if (shipLife) {
                shipX+=shipVx;
                shipY+=shipVy;
                if (shipX+30>stageW){shipVx = 0; shipX=stageW-31;}
                if (shipX<0){shipVx = 0; shipX=1;}
                
                if (shipY+35>stageH){shipVy = 0; shipY=stageH-35;}
                if (shipY<0){shipVy = 0; shipY=1;}

                
                if (!lockHorizontal){
                    if (shipVx>-.1 && shipVx<.1){
                        shipVx = 0;
                    }
                    else {
                        shipVx*=friction;
                    }
                }
                if (!lockVertical){
                    if (shipVy>-.1 && shipVy<.1){
                        shipVy = 0;
                    }
                    else {
                        shipVy*=friction;
                    }
                }
                shipBmd.applyFilter(shipBmd,stageRect,new Point(0,0),blurFilter);
                shipBmd.lock();
                shipBmd.copyPixels(shipBmp,shipRect,new Point(shipX,shipY)); //mergealpha false in default will help us create effect of ship's thrusters. User will notice from time to time black "square" around ship tho.
                shipBmd.unlock();

                //hit ennemy bullets
                if (testVector(bmd.getVector(new Rectangle(shipX+14,shipY+2,2,2)))){
                    particlesExplosion(bulBmp,5,shipX+14,shipY,2);
                    shipLife--;
                }
                //hit ennemy ship
                if (testVector(ennemyBmd.getVector(new Rectangle(shipX+14,shipY+2,2,2)))){
                    shipLife--;
                }
                if (shipLife<=0){playerDies();return;}
            }

            
            var f:int = impactParticles.length;
            effectsBmd.lock();
            effectsBmd.fillRect(stageRect, 0x00000000);
            while(f--) {
                var n:Particle=impactParticles[f>>0];
                n.x+=n.vx;
                n.y+=n.vy;
                n.vx*=.95;
                n.vy*=.95;
                effectsBmd.setPixel32(n.x,n.y,n.col);
                if (n.vx+n.vy>-.1 && n.vx+n.vy<.1){impactParticles.splice(f,1);}
            }
            effectsBmd.unlock();
            
            var o:int = ennemyBullets.length;
            bmd.lock();
            bmd.fillRect(stageRect, 0x00000000);
            while(o--) {
                var p:Particle=ennemyBullets[o>>0];
                p.x+=p.vx;
                p.y+=p.vy;
                point.x = p.x;
                point.y = p.y;
                bmd.copyPixels(bulBmp,bulRect,point,null,null,true);
                if (p.x>stageW || p.x<0 || p.y>stageH || p.y<0){ennemyBullets.splice(o,1);}
            }
            bmd.unlock();
            displayInfos();
            
        }
        
        private function starsScroll():void{
            //background stars
            var r:int = starsNum;
            backgroundBmd.lock();
            backgroundBmd.fillRect(stageRect,0x00000000);
            while(r--) {
                var v:Particle=stars[r>>0];
                v.y+=v.vy;
                backgroundBmd.setPixel32(v.x,v.y,v.c);
                if (v.y>stageH){v.y=0;v.x=randomNumber(0,stageW);}
            }
            backgroundBmd.unlock();
        }

        private function displayInfos():void{
            var a:BitmapData = displayText("energy "+shipLife);
            var aRect:Rectangle = new Rectangle(0, 0, a.width, a.height);
            if(ennemies){var b:BitmapData = displayText(ennemies.length + " targets remaining");}
            var bRect:Rectangle = new Rectangle(0, 0, b.width, b.height);
            var c:BitmapData = displayText("stage " + (currentStage+1));
            var cRect:Rectangle = new Rectangle(0, 0, c.width, c.height);
            var d:BitmapData = displayText("score " + score);
            var dRect:Rectangle = new Rectangle(0, 0, d.width, d.height);

            infosBmd.lock();
            infosBmd.fillRect(stageRect,0x00000000);
            infosBmd.copyPixels(a,aRect,new Point(0,stageH-a.height));
            infosBmd.copyPixels(b,bRect,new Point(Math.round(stageW2 - b.width/2),0));
            infosBmd.copyPixels(c,cRect,new Point(Math.round(stageW - c.width),stageH-c.height));
            infosBmd.copyPixels(d,dRect,new Point(0,stageH-d.height*2));
            if (shipLife==0){
                var z:BitmapData = displayText("game over");
                var zRect:Rectangle = new Rectangle(0, 0, z.width, z.height);
                infosBmd.copyPixels(z,zRect,new Point(Math.round(stageW2-z.width/2),Math.round(stageH2-z.height/2)-10));
                var y:BitmapData = displayText("click to continue");
                var yRect:Rectangle = new Rectangle(0, 0, y.width, y.height);
                infosBmd.copyPixels(y,yRect,new Point(Math.round(stageW2-y.width/2),Math.round(stageH2-y.height/2)+10));
            }
            infosBmd.unlock();
        }

        private function playerDies():void{
            removeKeys();
            shipLife=0;
            shipBmd.fillRect(stageRect,0x00000000);
            particlesExplosion(shipBmp,5,shipX,shipY,5);
            stage.addEventListener(MouseEvent.CLICK,backToTitleScreen);
        }

        private function testVector(a:Vector.<uint>):Boolean{
            var i:uint = a.length;
            while(i--) {if (a[i]){return true;}}
            return false;
        }

        private function particlesExplosion(bd:BitmapData,t:int,xx:int,yy:int,r:int):void{
            var a:Vector.<uint> = bd.getVector(new Rectangle(0,0,bd.width,bd.height));
            var i:uint = a.length;
            while(i--) {
                var pval:int = a[int(i)];
                var aa:int = pval >> 24;
                if (aa < 100) {
                    var dx:int = xx;
                    var dy:int = yy;
                    var px:int = int(i % bd.width)+dx;
                    var py:int = int(i / bd.height)+dy;
                    angle=Math.round(Math.random()*360);
                    createParticle(px,py,Math.cos(angle/180*Math.PI)*Math.random()*r,Math.sin(angle/180*Math.PI)*Math.random()*r,t,pval);
                }
            }
        }

        private function initKeys():void{
            lockVertical = false;
            keyVertical = 0;
            lockHorizontal = false;
            keyHorizontal = 0;
            lockFire = false;
            bulletTimer = getTimer();
            stageTimer = getTimer();
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
        }

        private function removeKeys():void{
            lockFire=false;
            stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
        }
        
        private function goLeft():void {
            if (!lockHorizontal || keyHorizontal != 37){keyHorizontal = 37; lockHorizontal = true; shipVx = -shipVel;}
        }
        
        private function goRight():void {
            if (!lockHorizontal || keyHorizontal != 39){keyHorizontal = 39; lockHorizontal = true; shipVx = shipVel;}
        }

        private function goUp():void {
            if (!lockVertical || keyVertical != 38){keyVertical = 38; lockVertical = true; shipVy = -shipVel;}
        }
        
        private function goDown():void {
            if (!lockVertical|| keyVertical != 40){keyVertical = 40; lockVertical = true; shipVy = shipVel;}
        }

        private function goFire():void {
            if (!lockFire){lockFire = true;}
        }

        private function unlockVertical():void {
            lockVertical = false;
        }

        private function unlockHorizontal():void {
            lockHorizontal = false;
        }

        private function unlockFire():void {
            lockFire = false;
        }

        private function keyDownHandler(e:KeyboardEvent):void {
            var a:int = e.keyCode;
            if (kd[a>>0]) {kd[a>>0]();} 
            //39 is right
            //37 is left
            //40 is down
            //38 is up
            //32 is space
        }

        private function keyUpHandler(e:KeyboardEvent):void {
            var a:int = e.keyCode;
            if (ko[a>>0]) {ko[a>>0]();}
        }

        private function displayText(s:String):BitmapData{
            var dictionnary:Object = {a:0,b:1,c:2,d:3,e:4,f:5,g:6,h:7,i:8,j:9,k:10,l:11,m:12,n:13,o:14,p:15,q:16,r:17,s:18,t:19,u:20,v:21,w:22,x:23,y:24,z:25,0:26,1:27,2:28,3:29,4:30,5:31,6:32,7:33,8:34,9:35};
            var dt:Array = s.split("");
            var dl:int = dt.length;
            var tBmd:BitmapData = new BitmapData(dl*8,8,true,0x00000000);
            tBmd.lock();
            for (var i:int=0;i<dl;++i){
                if (dt[i]== " "){}
                else {
                    tBmd.copyPixels(fontBmp,new Rectangle(dictionnary[dt[i>>0]]*8, 0, 8,8),new Point(i*8,0));                }
            }
            tBmd.unlock();
            return (tBmd);
        }

        private function createParticle(xx:Number,yy:Number,vx:Number,vy:Number,t:int,col:uint=0):void {
            var p:Particle=new Particle();
            setProps(p, {x:xx,y:yy,vx:vx,vy:vy});
            if (t==1){shipBullets.push(p);}
            else if (t==2){ennemyBullets.push(p);}
            else if (t==4){setProps(p, {t:getTimer(),power:2,clock:randomNumber(0,200)}); ennemies.push(p);}
            else if (t==5){p.col = col; impactParticles.push(p);}
        }

        private function createStar(xx:Number,yy:Number,vx:Number,vy:Number,num:int):void {
            var p:Particle=new Particle();
            setProps(p, {x:xx,y:yy,vx:vx,vy:vy,c:starsCols[randomNumber(0,4)]});
            stars[num>>0] = p;
        }

        private function setProps(o:*,p:Object):void {
            for (var k:String in p) {o[k]=p[k];}
        }
        
        private function randomNumber(low:int, high:int):int{
            return Math.round(Math.random() * (high - low) + low);
        }

    }
}

class Particle {
    public var x:Number;
    public var y:Number;
    public var vx:Number;
    public var vy:Number;
    public var c:uint;
    public var t:uint;
    public var power:int;
    public var clock:int=0;
    public var col:uint;
}