MetaballsFiled Under: actionscript
Recenently I’ve developed this Magma Effect:
This effect is using so-called metaballs (or blobbies), which are pretty hard to code using math. What you see up there is a cheap trick, however it works and looks sexy ![]()
Magma Effect was achieved using red balls simulated by Box2DFlashAS3 engine, which in my oppinion is the best avaible physics engine for ActionScript 3.0.
First step is to create a sprite with red circle inside. This is a base of your metaball. You can see what’s behind the scene of Magma Effect here (single click launches ShadowBox, don’t open it in new tab).
It doesn’t look much like magma, right? This is why the balls are blurred in the next step. To do this you have to apply the BlurFilter to the sprite which contains all the balls (or each ball independently). It’s important to use medium or even high quality (third argument of BlurFilter class constructor). Low quality makes the metaballs look like squares. According to Help blurX and blurY values that are power of 2 are optimized to render more quickly, so I recommend you to use value of 32 or 64. Blurred balls should look something like this.
Last step is to draw the container into BitmapData object and use the BitmapData.threshold function. You can read how exactly this function works in tutorial on sepiroth.it. After this operation your shiny new metaballs are ready to use.
Here is simple example:
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.filters.BlurFilter; import flash.filters.BitmapFilterQuality; import flash.geom.Point; import flash.geom.Rectangle; [SWF(width = 300, height = 200, framerate = 31)] public class Metaballs extends Sprite { public var container:Sprite = new Sprite(); public var bitmap:Bitmap; public var bitmapData:BitmapData; public function Metaballs():void { for (var i:uint = 0; i < 10; i++) { var radius:uint = Math.round(Math.random() * 30 + 10); var circle:Sprite = getRedCircle(radius); circle.x = Math.random() * stage.stageWidth; circle.y = Math.random() * stage.stageHeight; container.addChild(circle); } container.filters = [new BlurFilter(32, 32, BitmapFilterQuality.MEDIUM)]; //draw to bitmap: bitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false); bitmap = new Bitmap(bitmapData.clone()); bitmapData.draw(container); var bounds:Rectangle = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); var zeroPoint:Point = new Point(0, 0); bitmap.bitmapData.threshold(bitmapData, bounds, zeroPoint, "<=", 0x00ee00, 0xFFFF0000, 0x0000FF00, false) addChild(bitmap); } private function getRedCircle(radius:Number):Sprite { var circle:Sprite = new Sprite(); circle.graphics.beginFill(0xff0000); circle.graphics.drawCircle(0, 0, radius); circle.graphics.endFill(); return circle; } } }
- Read More
- szataniol
- 24 Jul 2008 8:54 PM
- Comments (4)