/* * Petri Leskinen * leskinen[dot]petri[at]luukku[dot]com * Espoo, Finland * 3.3 2008 */ package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.Stage; import flash.events.Event; import flash.events.MouseEvent; import flash.events.TimerEvent; import flash.filters.ColorMatrixFilter; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.utils.Timer; public class Metaballs extends Sprite { private var _sprite:Sprite; private var myTimer:Timer; private var balls:Array; private var renderedImage:Bitmap; private var renderedBmp:BitmapData; private var ballImage:BitmapData; private var lightPoint:Point = new Point(); function Metaballs() { // some background this.graphics.beginFill(0x104050,1.0); this.graphics.drawRect(0.0, 0.0, stage.stageWidth, stage.stageHeight); // 500.0, 500.0); // initializing the balls with some random location to start with balls = new Array; for (var i:int=0; i<12; i++) { // here a ball has just a position and size balls[i]= new Object(); balls[i]= { x: 100+300*Math.random(), y: 200+100*Math.random(), size: 1.0-0.05*i } ; } // create a Bitmap of one ball ballImage = regerateBallImage(150,150); // 'renderedImage' is what we see in the player renderedImage = new Bitmap; this.addChild(renderedImage); upDate(); // adding some animation myTimer = new Timer(1000/20); myTimer.addEventListener(TimerEvent.TIMER, newPhase); myTimer.start(); // ... and interactivity stage.addEventListener(MouseEvent.MOUSE_MOVE, followLight); } private function newPhase(e:Event):void { // timer animation var sina:Number; var cosa:Number; var po:Point = new Point(); // animation by rotating the balls for (var i:int =0; i0.0) { // lightAngle, in fact the cosine of the angle between surface normal and light direction, // values between -1.0 ... 1.0 // lightAngle = xx*lightSrc.x + yy*lightSrc.y + Math.sqrt(zz)*lightSrc.z; lightAngle *= (lightAngle>0.0) ? lightAngle*lightAngle : 0.0; // rendered pixel, alpha by sphere's z-component, color mixed by light angle pxl = (Math.floor(zz*0xFF)<<24) | (Math.floor(0xFF*lightAngle*lightAngle)<<16) | (Math.floor(0xFF*lightAngle)<<8) | 0x40-0x3F*lightAngle; } else { pxl = 0x0; } bmp.setPixel32(x,y,pxl); } } return bmp; } } }