ボールの動作にはAPEパッケージを使用しています。
TransparentBall.as (メインクラス)package { import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.geom.Rectangle; import flash.filters.DisplacementMapFilter; import org.cove.ape.APEngine; import org.cove.ape.CircleParticle; import org.cove.ape.Group; import org.cove.ape.Vector; [SWF(width='550',height='400',backgroundColor='0x0',frameRate='40')] public class TransparentBall extends Sprite{ [Embed(source="bg_grid.png")] private var IMG:Class; private const WIDTH:Number = stage.stageWidth; private const HEIGHT:Number = stage.stageHeight; private var wall:Wall; private var objGroup:Group = new Group(); private var objAry:Array = new Array(); private var sprAry:Array = new Array(); private var bmpAry:Array = new Array(); private var background:Bitmap; private static const RADIUS:int = 80;//must be tuned public function TransparentBall(){ background = new IMG(); addChild(background); APEInit(); addEventListener(Event.ENTER_FRAME, run); stage.addEventListener(MouseEvent.MOUSE_DOWN, createBall); } private function createBall(e:MouseEvent):void{ var xPos:Number = mouseX; var yPos:Number = mouseY; //for near-walls if (xPos < RADIUS){ xPos = RADIUS; } else if (xPos > WIDTH - RADIUS){ xPos = WIDTH - RADIUS; } if (yPos < RADIUS){ yPos = RADIUS; } else if (yPos > HEIGHT - RADIUS){ yPos = HEIGHT - RADIUS; } var c:CircleParticle = new CircleParticle(xPos,yPos,RADIUS*1.05,false,1,0.6,0.1); c.setStyle(0,0x0,0,0x0,0); objGroup.addParticle(c); objAry.push(c); var spr:Sprite = new Sprite(); spr.x = c.px; spr.y = c.py; sprAry.push(spr); addChild(spr); var fMap:Bitmap = new Bitmap(); fMap.bitmapData = new BitmapData(2*RADIUS,2*RADIUS); fMap.bitmapData.copyPixels(background.bitmapData, new Rectangle(spr.x-fMap.width/2,spr.y-fMap.height/2,fMap.width,fMap.height),new Point(0,0)); fMap.x = -fMap.bitmapData.width/2; fMap.y = -fMap.bitmapData.height/2; spr.addChild(fMap); bmpAry.push(fMap); var lens:BitmapData = createMap(RADIUS); var dispFilter:DisplacementMapFilter = new DisplacementMapFilter( lens,new Point(0,0),BitmapDataChannel.RED,BitmapDataChannel.BLUE,RADIUS,RADIUS); fMap.filters = [dispFilter]; } //from "http://yamasv.blog92.fc2.com/blog-entry-100.html" private function createMap(r:int):BitmapData{ var diameter:int = 2*r; var bmp:BitmapData = new BitmapData(diameter, diameter, false, 0x808080); for(var j:int = 0; j < diameter; j++){ for(var i:int = 0; i < diameter; i++){ var ii:int = i - r; var jj:int = j - r; var distance:Number = Math.sqrt(ii*ii+jj*jj); if(distance < r){ var v:Number = r*Math.asin(distance/r); var theta:Number = Math.abs(Math.atan((j-r)/(i-r))); var offsetR:int = (i > r) ? (v-distance)*Math.cos (theta) : -1*(v-distance)*Math.cos(theta); var offsetB:int = (j > r) ? (v-distance)*Math.sin(theta) : -1*(v-distance)* Math.sin(theta); var colR:int = 128 + offsetR; var colB:int = 128 + offsetB; bmp.setPixel(i, j, (colR << 16) + colB); } } } return bmp; } private function APEInit():void{ var wallThickness:Number = 100; APEngine.init(0.25); APEngine.container = this; APEngine.addMasslessForce(new Vector(0,5)); wall= new Wall(WIDTH,HEIGHT,wallThickness); wall.addCollidable(objGroup); objGroup.collideInternal = true; APEngine.addGroup(wall); APEngine.addGroup(objGroup); } private function run(e:Event):void{ chase(); APEngine.step(); APEngine.paint(); } private function chase():void{ var iMax:int = sprAry.length; for (var i:int=0; i<iMax; i++){ var bmp:BitmapData = bmpAry[i].bitmapData; var rect:Rectangle = new Rectangle(objAry[i].px-bmp.width/2,objAry[i].py-bmp.height/2,bmp.width,bmp.height); bmpAry[i].bitmapData.copyPixels(background.bitmapData,rect,new Point(0,0)); sprAry[i].x = objAry[i].px; sprAry[i].y = objAry[i].py; } } } }Wall.as (ステージ下左右の壁)
package{ import org.cove.ape.RectangleParticle; import org.cove.ape.Group; public class Wall extends Group{ private var rL:RectangleParticle; private var rR:RectangleParticle; //private var rT:RectangleParticle; private var rB:RectangleParticle; public function Wall(stageWidth:Number,stageHeight:Number,wallThickness:Number){ rL = new RectangleParticle(-wallThickness/2,stageHeight/2,stageHeight,wallThickness,Math.PI/2,true); addParticle(rL); rR = new RectangleParticle(stageWidth+wallThickness/2,stageHeight/2,stageHeight,wallThickness,Math.PI/2,true); addParticle(rR); //rT = new RectangleParticle(stageWidth/2,-wallThickness/2,stageWidth,wallThickness,0,true); //addParticle(rT); rB = new RectangleParticle(stageWidth/2,stageHeight+wallThickness/2,stageWidth,wallThickness,0,true); addParticle(rB); } } }Powered by blog Boreal Kiss 2008.