drawTrianglesを使用して画像を自由変形する
画像を自由変形するエフェクトを作成しました。
Flash Player10の機能のdrawTrianglesを使いました。
実行結果はwonderflにアップしています。
wonderfl build flash online | 面白法人カヤック
今は10×10の点の位置を指定して、
画像を変形させています。
点の位置指定は適当な式を入れて変形しています。
もっと思いどおりに変形できればいいんだけど・・・。
ソースは一応載せておきます。
package { import __AS3__.vec.Vector; import flash.display.Bitmap; import flash.display.Graphics; import flash.display.Sprite; [SWF(width=800, height=600, backgroundColor=0xAADDFF)] public class Main03 extends Sprite { [Embed(source="images/school.jpg")] private var P1:Class; private var image:Bitmap = new P1(); private var bendImage:Sprite = new Sprite(); public function Main03() { bendImage.x = 50; bendImage.y = 50; addChild(bendImage); createBendImage(); } private function createBendImage():void { var vertices:Vector.<Number> = new Vector.<Number>(); var indices:Vector.<int> = new Vector.<int>(); var uvtData:Vector.<Number> = new Vector.<Number>(); for (var xx:int=0; xx<10; xx++) { for (var yy:int=0; yy<10; yy++) { vertices[vertices.length] = xx*50-(5-yy)*(5-yy)*5*(xx<5? 1 : -1); vertices[vertices.length] = yy*50; uvtData[uvtData.length] = xx/10; uvtData[uvtData.length] = yy/10; } } for (var i:int=0; i<10-1; i++) { for (var j:int=0; j<10-1; j++) { indices.push(i*10+j, i*10+j+1, (i+1)*10+j); indices.push(i*10+j+1, (i+1)*10+1+j, (i+1)*10+j); } } const g:Graphics = bendImage.graphics; g.beginBitmapFill(image.bitmapData); g.drawTriangles(vertices, indices, uvtData); g.endFill(); } } }
爆発エフェクト
爆発のエフェクトを作成しました。
爆発のエフェクトの作成手順は、
-
- 円が飛び散るだけのアニメーションを作成する。
- その円にBlurFilterをかける。
- 円のBlendModeをADDに設定する。
です。
実行結果は、wonderflに上げました。
wonderfl build flash online | 面白法人カヤック
ソースは以下に掲載します。
package { import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.MouseEvent; [SWF(width=800, height=600, backgroundColor=0xAADDFF)] public class Main04 extends Sprite { public function Main04() { stage.addEventListener(MouseEvent.CLICK, onClick); } private function onClick(event:MouseEvent):void { var burst:Burst = new Burst(); burst.x = event.stageX - burst.width/2; burst.y = event.stageY - burst.height/2; addChild(burst); burst.addEventListener(BurstEvent.COMPLETE, onFinishBurst); } private function onFinishBurst(event:BurstEvent):void { removeChild(event.currentTarget as DisplayObject); } } } import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.Graphics; import flash.filters.BlurFilter; import flash.events.Event; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.display.BlendMode; class Burst extends Bitmap { private var particleDesign:Sprite = new Sprite(); private var particleList:Array = []; public function Burst() { var tempBmp:BitmapData = new BitmapData(200, 200, true, 0x00000000); super(tempBmp); // パーティクルのデザインを作成する createParticleDesign(); // パーティクルを作成する createParticle(); addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function createParticleDesign():void { // 円を描く const g:Graphics = particleDesign.graphics; g.beginFill(0xFF8022, 0.5); g.drawCircle(0, 0, 10); g.endFill(); // ぼかし効果を適用する particleDesign.filters = [new BlurFilter(10, 10, 1)]; } private function createParticle():void { for (var i:int=0; i<50; i++) { var x:int = bitmapData.width/2; var y:int = bitmapData.height/2; var v:Number = Math.random()*5; var angle:uint = Math.random()*360; var ax:Number = 0; var ay:Number = 0; var enagy:Number = 1; var particle:Particle = new Particle(x, y, v, angle, ax, ay, enagy); particleList[particleList.length] = particle; } if (particleList.length <= 0) { removeEventListener(Event.ENTER_FRAME, onEnterFrame); dispatchEvent(new BurstEvent(BurstEvent.COMPLETE)); } } private function onEnterFrame(event:Event):void { bitmapData.colorTransform(bitmapData.rect, new ColorTransform(1, 1, 1, 1, 0, 0, 0, -32)); for (var i:int=particleList.length-1; i>-1; i--) { var particle:Particle = Particle(particleList[i]); particle.move(); var mat:Matrix = new Matrix(); mat.translate(particle.x, particle.y); bitmapData.draw(particleDesign, mat, new ColorTransform(1, 1, 1, particle.enagy), BlendMode.ADD); if (particle.enagy < 0.01) { particleList.splice(i, 1); } } } } class BurstEvent extends Event { public static const COMPLETE:String = "complete"; public function BurstEvent(type:String) { super(type); } } class Particle { public var x:Number; public var y:Number; private var vx:Number; private var vy:Number; private var ax:Number; private var ay:Number public var enagy:Number; public function Particle(x:int, y:int, v:Number, angle:uint, ax:Number, ay:Number, enagy:Number) { this.x = x; this.y = y; this.vx = Math.cos(angle*Math.PI/180) * v; this.vy = Math.sin(angle*Math.PI/180) * v; this.ax = ax; this.ay = ay; this.enagy = enagy; } public function move():void { x += vx; y += vy; vx += ax; vy += ay; enagy *= 0.9; } }
あけましておめでとうございます!!!
あけましておめでとうございます。
正月は、プログラムもしないで、
ゴロゴロしていました。
今になって、
もっとプログラムしておくべきだったと思い返しています・・・。
ではでは、
今年もよろしくお願いします。
右クリックのメニューを作成するContextMenuクラス
こんなクラスがあったんですね。
右クリックのメニューは変更できないと思っていました。
しかも、Spriteごとに設定できるようで使い勝手もよさそうです。
問題点は、Flashの右クリックのメニューは表示されるところかな?
右クリックのメニューを変更したソースを載せておきます。
右クリックすると、テスト1・テスト2・テスト3という項目が増えています。
package { import flash.display.Sprite; import flash.ui.ContextMenu; import flash.ui.ContextMenuItem; [SWF(width=800, height=600, backgroundColor=0xAADDFF)] public class Main04 extends Sprite { public function Main04() { var menu:ContextMenu = new ContextMenu(); menu.customItems.push(new ContextMenuItem("テスト1")); menu.customItems.push(new ContextMenuItem("テスト2")); menu.customItems.push(new ContextMenuItem("テスト3")); menu.hideBuiltInItems(); contextMenu = menu; } } }
気になったサイト
wonderfl build flash online | 面白法人カヤック
オンラインでSWFを生成できるサイト。
ソースもWeb上で編集できます。
コミュニティー的なもので、
他人が作成したSWFやソースを見ることができ、
それを改良したものを作ったりとかして、
コミュニケーションをとれるらしい。
大変いいサイトだよwww
登録していても、損はないと思いましたw
BitmapDataで残像エフェクト
BitmapDataを使って残像エフェクトを作成しました。
やり方は簡単。
残像エフェクトを適用したいオブジェクトを
BitmapDataにdrawしていくだけ。
それだけだと、
残像が消えないので、1つ処理を加えます。
BitmapDataクラスのcolorTransformメソッドを使って、
現在drawされているものを半透明にする。
afterBitmapData.colorTransform(afterBitmapData.rect, new ColorTransform(1, 1, 1, 1, 0, 0, 0, -16)); var mat:Matrix = new Matrix(); mat.translate(character.x, character.y); afterBitmapData.draw(character, mat);
こんな感じですね^^
次にdrawするものは、半透明にならないので、
残像を作るにはぴったりのメソッドだと思いました。
一応、ソースコード載せておきます。
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.PixelSnapping; import flash.display.Sprite; import flash.events.Event; import flash.geom.ColorTransform; import flash.geom.Matrix; [SWF(width=800, height=600, backgroundColor=0xAADDFF)] public class Main17 extends Sprite { private var afterBitmapData:BitmapData = new BitmapData(800, 600, true, 0x00FFFFFF); private var afterImage:Bitmap = new Bitmap(afterBitmapData, PixelSnapping.AUTO, true); private var character:Character = new Character(); public function Main17() { addChild(afterImage); character.x = 200; character.y = 200; addChild(character); addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function onEnterFrame(event:Event):void { character.move(); afterBitmapData.colorTransform(afterBitmapData.rect, new ColorTransform(1, 1, 1, 1, 0, 0, 0, -16)); var mat:Matrix = new Matrix(); mat.translate(character.x, character.y); afterBitmapData.draw(character, mat); } } } import flash.display.Sprite; import flash.events.Event; class Character extends Sprite { private var isStage:Boolean = false; private var vx:Number = 5; private var vy:Number = 5; public function Character() { graphics.beginFill(0x0000FF); graphics.drawCircle(0, 0, 50); graphics.endFill(); graphics.beginFill(0x00FF00); graphics.drawCircle(0, 0, 20); graphics.endFill(); addEventListener(Event.ADDED_TO_STAGE, onAddedStage); } public function move():void { x += vx; y += vy; if (isStage) { if (x < 0+width/2 || x > stage.stageWidth-width/2) { vx *= -1; } if (y < 0+height/2 || y > stage.stageHeight-height/2) { vy *= -1; } } } private function onAddedStage(event:Event):void { isStage = true; } }
気になった記事
かなり前の記事だけど・・・。
パーリンノイズを使った焼けるエフェクト - PHP,MySQL,Flex,JSな日々+イラストとか
パーリンノイズを使用して、
画面が焼けおちていくのを実装しているようです。
閾値を上げていくことで、画面を透明化するアルゴリズムは、
すごいと思いました。
これを使えば、いろいろなエフェクト作成できるかもしれません。
画面遷移のエフェクトにかなり有効的だと思いました。