{"id":432,"date":"2009-10-29T11:09:12","date_gmt":"2009-10-29T18:09:12","guid":{"rendered":"https:\/\/actionsnippet.com\/?p=2342"},"modified":"2009-10-29T11:09:12","modified_gmt":"2009-10-29T18:09:12","slug":"bitmapdata-frame-animation-w-circular-linked-list","status":"publish","type":"post","link":"https:\/\/actionsnippet.com\/?p=432","title":{"rendered":"BitmapData Frame Animation (w\/ linked list)"},"content":{"rendered":"<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\n&#x5B;SWF(width = 100, height = 100)]\r\nvar circle:Shape = new Shape();\r\nwith(circle.graphics) beginFill(0x000000), drawCircle(20,20,20);\r\n\r\nvar currFrame:Frame;\r\n\r\n\/\/ populate the linked list\r\ngenerateAnimation();\r\n\r\nvar canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0x000000);\r\naddChild(new Bitmap(canvas));\r\nvar loc:Point = new Point(20, 20);\r\n\r\naddEventListener(Event.ENTER_FRAME, onLoop);\r\nfunction onLoop(evt:Event):void {\r\n\t\/\/ clear the canvas\r\n\tcanvas.fillRect(canvas.rect, 0x000000);\r\n\t\/\/ draw the current frame\r\n\tcanvas.copyPixels(currFrame.bitmap, currFrame.bitmap.rect, loc, null, null, true);\r\n\t\/\/ get the next frame of the animation\r\n\tcurrFrame = currFrame.next;\r\n}\r\n\r\n\/\/ generate and capture 40 bitmaps by altering the colorTransform of the circle shape\r\nfunction generateAnimation():void{\r\n\tvar channel:uint = 0;\r\n\tvar ct:ColorTransform = new ColorTransform();\r\n\tvar increase:Boolean = true;\r\n\tvar firstFrame:Frame;\r\n    var pFrame:Frame;\r\n\tfor (var i:int = 0; i&lt;40; i++){\r\n\t\tif (increase){\r\n\t\t   channel += 10;\r\n\t\t   if (channel == 200){\r\n\t\t\t  increase = false;   \r\n\t\t   }\r\n\t\t}else{\r\n\t\t   channel -= 10;\r\n\t\t}\r\n\t\tct.color = channel &lt;&lt; 16 | channel &lt;&lt; 8 | channel;\r\n\t\tcircle.transform.colorTransform = ct;\r\n\t\t\/\/ populate linked list\r\n\t\tcurrFrame = capture(circle); \r\n\t\tif (pFrame){\r\n\t\t   pFrame.next = currFrame;\r\n\t\t}\r\n\t\tif (i == 0){\r\n\t\t   firstFrame = currFrame;\r\n\t\t}\r\n\t\tpFrame = currFrame;\r\n\t}\r\n\t\/\/ close the list\r\n\tcurrFrame.next = firstFrame;\r\n\tcurrFrame = firstFrame;\r\n}\r\n\r\n\/\/ create the Frame instance and draw the circle to it\r\n\/\/ preserving the colorTransform information\r\nfunction capture(target:Shape):Frame{\r\n\tvar frame:Frame = new Frame();\r\n\tframe.bitmap = new BitmapData(target.width, target.height, true, 0x00000000);\r\n\tframe.bitmap.draw(target, null, target.transform.colorTransform);\r\n\treturn frame;\r\n}\r\n<\/pre>\n<p><i>Requires this little Frame class<\/i><\/p>\n<pre class=\"brush: as3; title: ; notranslate\" title=\"\">\r\npackage {\r\n\timport flash.display.*;\r\n\tfinal public class Frame{\r\n\t\tpublic var bitmap:BitmapData;\r\n\t\tpublic var next:Frame;\r\n\t}\r\n}\r\n<\/pre>\n<p>This is a small test I did today to see how easy it would be to use a circular linked list to loop an animation of bitmaps. I did this because I was thinking about using some animated sprites in conjunction with Utils3D.projectVectors() to do an orthographic 3D demo with lots of animating sprites. In the past I&#8217;ve had up to 7,000 animated sprites running nicely using arrays and copyPixels&#8230; figured it would be interesting to try and do the same with a circular linked list.<\/p>\n<p>When compiled, this test simply draws a circle that fades from black to gray and back again&#8230; Pretty boring, but I threw it up over at wonderfl anyway&#8230; <a href=\"http:\/\/wonderfl.net\/code\/ae847e08b60443b14443c7a50dcf91d3f292be83\" target=\"blank\">check it out<\/a>.<\/p>\n<p>I recently saw a few tweets (forget who from) about using the final keyword on linked list nodes&#8230; haven&#8217;t tested it myself but it&#8217;s supposed to be faster&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#x5B;SWF(width = 100, height = 100)] var circle:Shape = new Shape(); with(circle.graphics) beginFill(0x000000), drawCircle(20,20,20); var currFrame:Frame; \/\/ populate the linked list generateAnimation(); var canvas:BitmapData = new BitmapData(stage.stageWidth,stage.stageHeight,false, 0x000000); addChild(new Bitmap(canvas)); var loc:Point = new Point(20, 20); addEventListener(Event.ENTER_FRAME, onLoop); function onLoop(evt:Event):void { \/\/ clear the canvas canvas.fillRect(canvas.rect, 0x000000); \/\/ draw the current frame canvas.copyPixels(currFrame.bitmap, currFrame.bitmap.rect, loc, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[24,140,94,13,25],"tags":[3,14,4],"class_list":["post-432","post","type-post","status-publish","format-standard","hentry","category-bitmapdata","category-data-structures","category-misc","category-motion","category-pixel-manipulation","tag-actionscript","tag-as3","tag-flash"],"_links":{"self":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/432","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=432"}],"version-history":[{"count":0,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=\/wp\/v2\/posts\/432\/revisions"}],"wp:attachment":[{"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=432"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=432"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/actionsnippet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=432"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}