前回のトランジション効果をちょっといじってフォトスライドショーのようなものを。
連番jpgをLoaderでリアルタイムに読み込むのだが、Loader.load()が重いのかload中に一瞬止まってしまう。
なのでカメラやコンテナはアニメーションさせなかった。カメラをぐりぐり回してると一瞬止まる瞬間がわかるだろう。
あと回線によっては切り替わるタイミングが波紋が広がるときになったり戻ったり。
サイズのある画像だとなかなか切り替わらなかったりするかも。
ネットから連番jpgを持ってくるにあたってきれいな画像を探してて、こちらのまとめブログさんから無断でいただくことにしました。ありがとう。
package { import alternativa.engine3d.core.Object3D; import alternativa.engine3d.materials.TextureMaterial; import alternativa.engine3d.resources.BitmapTextureResource; import flash.display.BitmapData; import flash.display.Loader; import flash.events.Event; import flash.events.IOErrorEvent; import flash.geom.Point; import flash.net.URLRequest; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.easing.Expo; import org.libspark.betweenas3.tweens.ITween; /** * ... * @author */ [SWF(width="550",height="400")] public class Main extends AlBasicView { private const texWidth:uint = 1280; private const texHeight:uint = 960; private const texLength:uint = 2048; private const RAD:Number = Math.PI / 180; private const BASE_URL:String = "http://blog-imgs-29-origin.fc2.com/o/n/l/onlinegameinside/2009326000"; private const division:uint = 20; // private var firstTween:ITween; private var roundTween1:ITween; private var roundTween2:ITween; private var numPicture:uint = 1; private var setMaterialFlag:Boolean = false; private var prepareMaterialFlag:Boolean = false; private var changedMaterialCount:uint = division * division; private var materialList:Vector.<TextureMaterial>; private var loaderA:Loader; private var loaderB:Loader; // public function Main():void { stage.frameRate = 30; camera.view.backgroundColor = 0x333333; var controller:RoundCameraController = new RoundCameraController(camera, stage); controller.setCameraAt(1000, -70, 90); // materialList = new Vector.<TextureMaterial>(2); loaderA = new Loader(); loaderB = new Loader(); // var sourceBd:BitmapData = new BitmapData(texWidth, texHeight, false, 0xDDDDDD); //init var resizedBd:BitmapData = resizeBitmapData(sourceBd); var perW:Number = texWidth / texLength; //max u coordinate of texture var perH:Number = texHeight / texLength; var material1:TextureMaterial = new TextureMaterial(new BitmapTextureResource(resizedBd)); var material2:TextureMaterial = new TextureMaterial(new BitmapTextureResource(resizedBd)); materialList[0] = material1; materialList[1] = material2; // var container:Object3D = new Object3D(); container.rotationX = RAD * 90; scene.addChild(container); // var parallel:Array = new Array(division * division * 2); //for parallel tween var parallelR1:Array = new Array(division * division * 2); var parallelR2:Array = new Array(division * division * 2); // var tipW:uint = texWidth / division; //plane width var tipH:uint = texHeight / division; var dU:Number = perW / division; //plane texture width var dV:Number = perH / division; var baseX:Number = (-texWidth + tipW) / 2; //min x coordinate of plane var baseY:Number = (texHeight - tipH) / 2; var uStart:Number; var uEnd:Number; var vStart:Number; var vEnd:Number; for (var i:int = 0; i < division; i++){ uStart = i * dU; uEnd = (i + 1) * dU; for (var j:int = 0; j < division; j++){ var tip:Plane = new Plane(tipW, tipH, 1, 1, false, material2); var tip2:Plane = new Plane(tipW, tipH, 1, 1, false, material2); tip2.rotationY = 180 * RAD; tip.addChild(tip2); vStart = j * dV; vEnd = (j + 1) * dV; tip.setUV(uStart, uEnd, vStart, vEnd); tip2.setUV(perW - uEnd, perW - uStart, vStart, vEnd); tip.x = baseX + i * tipW; tip.y = baseY - j * tipH; container.addChild(tip); // var ii:int = (division >> 1) - i; var jj:int = (division >> 1) - j; var delay:Number = Math.sqrt(ii * ii + jj * jj) * 0.1; //determin delay from distance var delay2:Number = 0.1 * division - delay; var num:uint = (i * division + j) << 1; parallel[num] = BetweenAS3.delay(BetweenAS3.from(tip, {z: 3000}, 0.2, Expo.easeOut), delay * 2); parallel[uint(num + 1)] = BetweenAS3.delay(BetweenAS3.from(tip, {rotationY: 540 * RAD}, 1), delay * 2 + 1); parallelR1[num] = BetweenAS3.delay(BetweenAS3.tween(tip, {rotationY: 720 * RAD}, {rotationY: 0 * RAD}, 0.6), delay2/2); parallelR1[uint(num + 1)] = BetweenAS3.delay(BetweenAS3.func(setUV, [tip, tip2]), delay2/2 + 0.3); parallelR2[num] = BetweenAS3.delay(BetweenAS3.tween(tip, {rotationY: 0 * RAD}, {rotationY: 720 * RAD}, 0.6), delay); parallelR2[uint(num + 1)] = BetweenAS3.delay(BetweenAS3.func(setUV, [tip, tip2]), delay + 0.3); } } firstTween = BetweenAS3.parallelTweens(parallel); firstTween.onComplete = play1; roundTween1 = BetweenAS3.delay(BetweenAS3.parallelTweens(parallelR1), 2); roundTween1.onComplete = play2; roundTween2 = BetweenAS3.parallelTweens(parallelR2); roundTween2.onComplete = play1; // request(); } override public function onContextCreate(e:Event):void { super.onContextCreate(e); firstTween.play(); } private function play1():void { loadPrepare(); roundTween1.play(); } private function play2():void { loadPrepare(); roundTween2.play(); } private function setUV(tip:Plane, tip2:Plane):void { if (setMaterialFlag){ tip.getSurface(0).material = materialList[1]; tip2.getSurface(0).material = materialList[1]; changedMaterialCount++; } } // private function loadPrepare():void { if (changedMaterialCount == division * division){ setMaterialFlag = false; changedMaterialCount = 0; loadInit(); } if (prepareMaterialFlag){ prepareMaterialFlag = false; setMaterialFlag = true; } } private function loadInit():void { var numS:String; if (numPicture == 89 || numPicture == 218){ numPicture++; } if (numPicture >= 100){ numS = String(numPicture); } else if (numPicture >= 10){ numS = "0" + String(numPicture); } else { numS = "00" + String(numPicture); } numPicture++; if (numPicture == 220){ numPicture = 1; } loaderA.contentLoaderInfo.addEventListener(Event.COMPLETE, onAcomplete); loaderA.load(new URLRequest(BASE_URL + numS + ".jpg")); } private function onAcomplete(e:Event):void { loaderB.contentLoaderInfo.addEventListener(Event.COMPLETE, onBcomplete); loaderB.loadBytes(loaderA.contentLoaderInfo.bytes); } private function onBcomplete(e:Event):void { var bd:BitmapData = new BitmapData(loaderB.width, loaderB.height, false); bd.draw(loaderB); var resizedBd:BitmapData = resizeBitmapData(bd); var resource:BitmapTextureResource = new BitmapTextureResource(resizedBd); resource.upload(context3D); var material:TextureMaterial = new TextureMaterial(resource); material.useDiffuseAlphaChannel = true; materialList.push(material); materialList.shift().diffuseMap.dispose(); prepareMaterialFlag = true; } //utility private function resizeBitmapData(data:BitmapData):BitmapData { var bd:BitmapData = new BitmapData(texLength, texLength, true, 0x0); bd.copyPixels(data, data.rect, new Point(texWidth / 2 - data.width / 2, texHeight / 2 - data.height / 2)); return bd; } } }
今回はコードの説明はなし。
前回と変わった点はローダー周りと、uvの動的書き換えをしていないのと、片面のみのPlaneを二枚表裏に貼り付けてる点。
いろんな試行錯誤の結果だったりする。
Author:9ballsyn
ActionScriptについて
最近はMolehill