Away3D基础教程(六):支持双面交互的PlaneGeometry
看了老外的一篇文章,现在将文章中的实例转过来与大家分享,此例中巧妙的运用两个Mesh对象创建了支持双面交互的PlaneGeometry,其实原理就是将PlaneGeometry放到两个Mesh里去,做反面的那个Mesh设置back.rotationY = 180即可,文章里将这种支持双面交互的PlaneGeometry封装成了DoubleSidedPlane3D类,使用起来也非常简单。大家也可以自己扩展这个类来实现更多的动能,比如点击正面的时候和点击反面的时候做出不同的处理。效果如下:
Main.as 代码
package { import flash.display.Sprite; import flash.display.StageScaleMode; import flash.display.StageAlign; import flash.events.MouseEvent; import flash.system.System; import flash.events.Event; import flash.geom.Vector3D; import flash.display.BitmapData; import flash.text.TextField; import flash.ui.Mouse; import flash.ui.MouseCursor; import away3d.Away3D; import away3d.containers.View3D; import away3d.containers.Scene3D; import away3d.cameras.Camera3D; import away3d.containers.ObjectContainer3D; import away3d.materials.TextureMaterial; import away3d.textures.BitmapTexture; import away3d.materials.ColorMaterial; import away3d.utils.Cast; import away3d.events.MouseEvent3D; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.tweens.ITween; import org.libspark.betweenas3.events.TweenEvent; import org.libspark.betweenas3.easing.*; import DoubleSidedPlane3D; import flash.text.TextFieldAutoSize; [SWF(backgroundColor="#FFFFFF", width="512", height="512", frameRate="60")] public class Main extends Sprite { [Embed(source="assets/back.jpg")] private var Background:Class; [Embed(source="assets/image0.jpg")] private var Image0:Class; [Embed(source="assets/image1.jpg")] private var Image1:Class; [Embed(source="assets/image2.jpg")] private var Image2:Class; [Embed(source="assets/image3.jpg")] private var Image3:Class; [Embed(source="assets/image4.jpg")] private var Image4:Class; private var view:View3D; private var scene:Scene3D; private var camera:Camera3D; private var container:ObjectContainer3D; private static var cameraDepth:uint = 1000; private static var cameraHeight:int = 0; private static var max:uint = 5; private var planes:Array; private static var pwidth:uint = 256; private static var pheight:uint = 128; private var angle:Number = 0; private static var center:Vector3D = new Vector3D(); private var htmlText:TextField; public function Main() { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; System.pauseForGCIfCollectionImminent(1); init(); } private function init():void { view = new View3D(); scene = view.scene; camera = view.camera; addChild(view); setup(); initialize(); htmlText = new TextField(); htmlText.autoSize = TextFieldAutoSize.LEFT; htmlText.selectable = false; htmlText.textColor = 0xa3a3a3; htmlText.htmlText = '交流QQ:781444988\n交流地址:<a href="http://www.cnblogs.com/njflash/" target="_blank">http://www.cnblogs.com/njflash/ </a>'; addChild(htmlText); htmlText.x = 10; htmlText.y = 30; addEventListener(Event.ENTER_FRAME, render, false, 0, true); } private function setup():void { view.backgroundColor = 0xFFFFFF; view.antiAlias = 4; view.width = 512; view.height = 512; view.background = Cast.bitmapTexture(Background); camera.x = 0; camera.y = cameraHeight; camera.z = - cameraDepth; } private function initialize():void { container = new ObjectContainer3D(); scene.addChild(container); var Images:Array = [Image0, Image1, Image2, Image3, Image4]; var colors:Array = [0xF5F5F5, 0x3366CC, 0x339900, 0xFF9900, 0xCC0066]; planes = new Array(); for (var n:uint = 0; n < max; n++) { var bitmapData:BitmapData = Cast.bitmapData(Images[n]); var texture:BitmapTexture = new BitmapTexture(bitmapData); var frontmaterial:TextureMaterial = new TextureMaterial(texture); var backmaterial:ColorMaterial = new ColorMaterial(colors[n]); var plane:DoubleSidedPlane3D = new DoubleSidedPlane3D(frontmaterial, backmaterial, pwidth, pheight, 10, 4, false); plane.x = 0; plane.y = 140*(n - 2); plane.z = 0; plane.extra = {id: n}; container.addChild(plane); plane.front.mouseEnabled = true; plane.front.addEventListener(MouseEvent3D.CLICK, click, false, 0, true); plane.front.addEventListener(MouseEvent3D.MOUSE_OVER, rollOver, false, 0, true); plane.front.addEventListener(MouseEvent3D.MOUSE_OUT, rollOut, false, 0, true); plane.back.mouseEnabled = true; plane.back.addEventListener(MouseEvent3D.CLICK, click, false, 0, true); plane.back.addEventListener(MouseEvent3D.MOUSE_OVER, rollOver, false, 0, true); plane.back.addEventListener(MouseEvent3D.MOUSE_OUT, rollOut, false, 0, true); planes.push(plane); } } private function render(evt:Event):void { angle += 0.5; container.rotationY = angle; camera.lookAt(center); view.render(); } private function click(evt:MouseEvent3D):void { enable(false); var plane:DoubleSidedPlane3D = DoubleSidedPlane3D(evt.target.parent); transit(plane.extra.id); } private function rollOver(vet:MouseEvent3D):void { Mouse.cursor = MouseCursor.BUTTON; } private function rollOut(vet:MouseEvent3D):void { Mouse.cursor = MouseCursor.AUTO; } private function transit(id:uint):void { var fadeouttweens:Array = new Array(); var fadeintweens:Array = new Array(); var offset:int = 2 - Math.abs(2 - id); for (var n:uint = 0; n < max; n++) { var direction:int = (n == id) ? 0 : (n < id) ? - 1 : 1; var plane:DoubleSidedPlane3D = planes[n]; var fadeout:ITween = BetweenAS3.delay(BetweenAS3.parallel( BetweenAS3.to(plane, {y: 140*(n - 2) + 120*direction}, 1, Quad.easeIn), BetweenAS3.to(plane, {rotationY: 180}, 1, Quad.easeIn), BetweenAS3.delay(BetweenAS3.to(plane, {alpha: 0, visible: 0}, 0.4, Linear.easeNone), 0.6) ), 0.2*(4 - Math.abs(n - id) - offset)); fadeouttweens.push(fadeout); var fadein:ITween = BetweenAS3.delay(BetweenAS3.parallel( BetweenAS3.to(plane, {alpha: 1, visible: 1}, 0.4, Linear.easeNone), BetweenAS3.to(plane, {y: 140*(n - 2)}, 1, Quad.easeOut), BetweenAS3.tween(plane, {rotationY: 0}, {rotationY: -180}, 1, Quad.easeOut) ), 0.2*Math.abs(n - id)); fadeintweens.push(fadein); } var itween:ITween = BetweenAS3.serial( BetweenAS3.parallelTweens(fadeouttweens), BetweenAS3.delay(BetweenAS3.parallelTweens(fadeintweens), 0.4) ); itween.addEventListener(TweenEvent.COMPLETE, complete, false, 0, true); itween.play(); } private function complete(evt:TweenEvent):void { evt.target.removeEventListener(TweenEvent.COMPLETE, complete); enable(true); } private function enable(useful:Boolean):void { for (var n:uint = 0; n < max; n++) { var plane:DoubleSidedPlane3D = planes[n]; plane.front.mouseEnabled = useful; plane.back.mouseEnabled = useful; } } } }
DoubleSidedPlane3D.as 代码
package{ import away3d.containers.ObjectContainer3D; import away3d.entities.Mesh; import away3d.primitives.PlaneGeometry; import away3d.materials.TextureMaterial; import away3d.materials.ColorMaterial; public class DoubleSidedPlane3D extends ObjectContainer3D { public var front:Mesh; public var back:Mesh; private var _geometry:PlaneGeometry; private var _frontmaterial:TextureMaterial; private var _backmaterial:ColorMaterial; private var _alpha:Number = 1; public function DoubleSidedPlane3D(frontmaterial:TextureMaterial, backmaterial:ColorMaterial, width:Number = 100, height:Number = 100, segmentsW:uint = 1, segmentsH:uint = 1, yUp:Boolean = true) { _geometry = new PlaneGeometry(width, height, segmentsW, segmentsH, yUp, false); _frontmaterial = frontmaterial; _backmaterial = backmaterial; init(); } private function init():void { front = new Mesh(_geometry, _frontmaterial); back = new Mesh(_geometry, _backmaterial); addChild(front); addChild(back); back.rotationY = 180; } public function get alpha():Number { return _alpha; } public function set alpha(value:Number):void { _alpha = value; _frontmaterial.alpha = _alpha; _backmaterial.alpha = _alpha; } } }