{"id":966,"date":"2013-01-14T20:32:04","date_gmt":"2013-01-15T01:32:04","guid":{"rendered":"http:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/?p=966"},"modified":"2013-01-14T20:32:04","modified_gmt":"2013-01-15T01:32:04","slug":"play-external-swf-movieclip-from-haxenme","status":"publish","type":"post","link":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/01\/play-external-swf-movieclip-from-haxenme\/","title":{"rendered":"Play External SWF MovieClip from Haxe\/NME"},"content":{"rendered":"<p>To tease with some exciting news, <em><a href=\"http:\/\/rocketshipgames.com\/games\/goldleader\/\">Gold Leader<\/a><\/em> has been picked up for a sponsorship!<\/p>\n<p>On an immediate coding topic though,\u00a0this has meant dealing with something I&#8217;d been dreading: Incorporating the sponsor&#8217;s splash screen. \u00a0As expected they gave me an FLA and compiled SWF. \u00a0Fortunately it turned out to be just a simple movie, no buttons to hook up or anything. \u00a0Quite typically for Haxe\/NME\/ActionScript, making this work turned out to be not muchcode, but kind of a pain to figure out.<\/p>\n<p>NME, along with the SWF library, does now include some cross-platform support for playing SWFs. \u00a0Josh Granick has notes <a href=\"http:\/\/www.joshuagranick.com\/blog\/2012\/01\/24\/embedding-swfs-makes-nme-meme-friendly\/\">here<\/a>, although be sure to read the comments as the API has been updated since that post (I don&#8217;t see a particularly better update post). \u00a0However, as far as I can tell, at the moment this only supports the graphics. \u00a0It wouldn&#8217;t play the sound effect associated with my movie and threw an error trying to decode it (something like &#8220;Unknown sub-tag SoundStreamHead2,&#8221; where the latter begins the encoded sound chunk in the SWF).<\/p>\n<p>I really only care about playing the SWF in Flash though, so happily instead I can just have Flash load and play the movie. \u00a0First off, the movie gets included in the compiled program SWF as a binary asset. \u00a0Simply copy the movie SWF into your assets folder, include with the assets command in your .nmml as usual, and NME will assume it&#8217;s a binary asset.<\/p>\n<p>The code to then play that movie clip looks something like this:<\/p>\n<pre>import nme.display.Sprite;\r\n\r\nimport nme.Assets;\r\nimport nme.Lib;\r\n\r\nimport nme.display.Loader;\r\nimport nme.display.MovieClip;\r\nimport nme.events.Event;\r\n\r\nclass Main extends Sprite {\r\n\r\npublic function new () {\r\n\r\n  super ();\r\n\r\n  var bytes = Assets.getBytes(\"assets\/splash.swf\");\r\n  trace(\"Bytes \" + bytes.length);\r\n\r\n  var loader:Loader = new Loader();\r\n  loader.loadBytes(bytes);\r\n\r\n  loader.contentLoaderInfo.addEventListener\r\n    (Event.COMPLETE,\r\n     function (_) {\r\n       var mc:MovieClip = cast(loader.content, MovieClip);\r\n       trace(\"Frames: \" + mc.totalFrames);\r\n       mc.addFrameScript(mc.totalFrames-1,\r\n                         function():Void {\r\n                           trace(\"Done.\");\r\n                           mc.stop();\r\n                           removeChild(mc);\r\n                         });\r\n       addChild(mc);\r\n     });\r\n\r\n    \/\/ end main\r\n  }\r\n\r\n  \/\/ end Main\r\n}<\/pre>\n<p>Note that you could skip the dynamic cast to MovieClip and simply add the loader object to the stage\/parent directly. However, I need the movie object itself so I can detect when it has stopped and move on to the actual game.<\/p>\n<p>That last point is itself somewhat interesting. Utterly shockingly, ActionScript3 has an event for absolutely everything except movie clips completing. Seemingly it&#8217;s just not there, doesn&#8217;t exist&#8230; This blew my mind.<\/p>\n<p>What most people do is add a function to the <code>ENTER_FRAME<\/code> event that checks every frame to see whether or not the current frame is the last frame, and throw another event or set a property if so. \u00a0However, Flash internally can associate a script with each frame, to be executed as it plays. \u00a0The\u00a0seemingly <a href=\"http:\/\/www.kirupa.com\/forum\/showthread.php?223798-ActionScript-3-Tip-of-the-Day&amp;p=2098268#post2098268\">undocumented function <code>MovieClip.addFrameScript()<\/code><\/a> allows you to add a function to particular frames of the movie. \u00a0In general you&#8217;d have to be careful about blowing away other code, but here I don&#8217;t have that problem&#8212;there&#8217;s nothing there, and I just want to bail. \u00a0So, I add a function to the last frame of the movie to do some housekeeping, and we&#8217;re all set!<\/p>\n<p>Like I said, this is all fairly simple in the code, but I haven&#8217;t seen anybody spell out how to make this work, so hopefully this will be of use.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To tease with some exciting news, Gold Leader has been picked up for a sponsorship! On an immediate coding topic though,\u00a0this has meant dealing with something I&#8217;d been dreading: Incorporating the sponsor&#8217;s splash screen. \u00a0As expected they gave me an FLA and compiled SWF. \u00a0Fortunately it turned out to be just a simple movie, no &hellip; <a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2013\/01\/play-external-swf-movieclip-from-haxenme\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58],"tags":[69,82,277],"class_list":["post-966","post","type-post","status-publish","format-standard","hentry","category-code","tag-flash","tag-haxe","tag-videogames"],"_links":{"self":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/966","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/comments?post=966"}],"version-history":[{"count":2,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/966\/revisions"}],"predecessor-version":[{"id":968,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/966\/revisions\/968"}],"wp:attachment":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/media?parent=966"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/categories?post=966"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/tags?post=966"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}