收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 4079|回复: 10

[AS3] flash cs4的3d旋转和深度问题

[复制链接]
发表于 2009-12-13 17:20:32 | 显示全部楼层 |阅读模式
比如说,有四个物体排成一圈,绕着圆心旋转,视觉上应该是离你越近的,就盖在离你远的物体上面。可实际上却是,深度越大的就盖在深度越小的物体上面。怎么才能即时的调整深度呢?

我做了两个例子:

第一个例子: 对象a里边包括b1、b2、b3、b4共四个对象,让a不断的改变rotation的值,也就是绕着y轴旋转,就会出现上述的问题。

第二个例子:对象a里边包括b1、b2、b3、b4共四个对象,不断的计算b1~b4的坐标,也能达到绕着y轴旋转的效果,仍然有上述问题。 接着,根据b1~b4的z值,不断的调整深度,但是问题解决了没有不知道,因为对象重叠的时候,就会闪烁了。

麻烦大家帮我看看,谢谢

temp.rar

16.73 KB, 下载次数: 302

发表于 2009-12-13 17:35:26 | 显示全部楼层
这是一个AS2 时经常有朋友问的问题
一般是通过坐标判断设置深度,  AS3是通过Z轴排序

我用PV3D实现这样的效果
  1. package
  2. {
  3.         import flash.events.Event;
  4.         import flash.net.URLLoader;
  5.         import flash.net.URLRequest;
  6.         import org.papervision3d.events.InteractiveScene3DEvent;
  7.         import org.papervision3d.materials.BitmapFileMaterial;
  8.         import org.papervision3d.objects.DisplayObject3D;
  9.         import org.papervision3d.objects.primitives.Plane;
  10.         import org.papervision3d.view.BasicView;
  11.         import gs.TweenLite;
  12.         /**
  13.          * ...
  14.          * @author FLASH023
  15.          */
  16.         [SWF(width = "550", height = "400", backgroundColor = "0xffffff", frameRate = "30")]
  17.         public class Main extends BasicView
  18.         {
  19.                 private var display3d:DisplayObject3D;
  20.                 private var total:uint;
  21.                 public function Main():void {
  22.                         super(550, 400, false, true);
  23.                         init();
  24.                         startRendering ();
  25.                 }
  26.                 private function init():void {
  27.                         var _loader:URLLoader = new URLLoader;
  28.                         _loader.addEventListener (Event.COMPLETE, xmlComplete);
  29.                         _loader.load (new URLRequest ("xml/data.xml"));
  30.                         display3d = new DisplayObject3D();
  31.                         scene.addChild (display3d);
  32.                 }
  33.                 private function xmlComplete(_evt:Event):void {
  34.                         var _xml:XML = XML(_evt.target.data);
  35.                         total = _xml.ping.length();
  36.                         for each(var _node:XML in _xml.ping) {
  37.                                 showImage(_node);
  38.                         }
  39.                 }
  40.                 private function showImage(_node:XML):void {
  41.                         var _plane:Plane = new Plane(new BitmapFileMaterial(_node.thumbs), 300, 200);
  42.                         _plane.material.doubleSided = true;       
  43.                         _plane.material.interactive = true;
  44.                         _plane.rotationY = display3d.numChildren / total * 360;
  45.                         _plane.moveBackward (400);
  46.                         _plane.addEventListener (InteractiveScene3DEvent.OBJECT_CLICK, onClick );
  47.                         display3d .addChild (_plane);
  48.                 }
  49.                 private function onClick(_evt:InteractiveScene3DEvent):void {
  50.                         var _plane:Plane = _evt.target as Plane;
  51.                 }
  52.                 override protected function onRenderTick(_evt:Event = null):void {
  53.                         display3d.rotationY --;
  54.                         super.onRenderTick ();
  55.                 }
  56.                
  57.         }
  58.        
  59. }
复制代码

PV3D_test.rar

287.97 KB, 下载次数: 299

回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-12-13 18:01:27 | 显示全部楼层
谢谢斑竹!有空真要好好研究一下pv3d。

在第二个例子里边,
private var depthes:Array = new Array(); //新建了一个数组
。。。
var imageItem:Object = {obj:mc, depth:mc.z};
depthes.push(imageItem); //将对象和深度保存进数组
。。。
depthes.sortOn("depth", Array.NUMERIC); //然后根据深度重排数组
for(var i:int=0; i<len; i++) {
        container.setChildIndex(depthes[i].obj, i); //重新定义深度
}

这个方法不知道哪里出错了呢? 重叠的时候就一直在闪烁
回复 支持 反对

使用道具 举报

发表于 2009-12-13 21:03:14 | 显示全部楼层
楼上都解决了~~我路过~~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-12-13 22:13:40 | 显示全部楼层
原帖由 [i]dreamy5190 于 2009-12-13 21:03 发表
楼上都解决了~~我路过~~


引用巴士大叔的名言:未解决!

2楼斑竹给的是不同的做法,是pv3d的。

3楼是我自己的做法,但是有bug,望高手指点指点
回复 支持 反对

使用道具 举报

发表于 2009-12-14 10:41:30 | 显示全部楼层
第一个的
  1. package  {
  2.         import flash.events.Event;
  3.         import flash.display.MovieClip;
  4.         import flash.display.*;
  5.         import flash.geom.*;
  6.        
  7.         public class rotateOne extends MovieClip {
  8.                 private var radius:uint = 200;
  9.                 private var len   :uint;
  10.                 private var imageItem:Array;
  11.                
  12.                 public function rotateOne():void {
  13.                         len  = container.numChildren;
  14.                         imageItem = new Array();
  15.                         for(var i:int=0; i<len; i++) {
  16.                                 var mc:MovieClip = container.getChildAt(i) as MovieClip;
  17.                                 var rot:uint = (360 / len) * i;
  18.                                 mc.x = radius * Math.sin(rot * Math.PI/180);
  19.                                 mc.z = radius * Math.cos(rot * Math.PI/180);
  20.                                 mc.rotationY = rot;
  21.                                 imageItem.push(mc);
  22.                         }
  23.                         stage.addEventListener(Event.ENTER_FRAME, handleTick);
  24.                 }
  25.                
  26.                 private function handleTick(evt:Event = null):void {
  27.                         container.rotationY += 1;
  28.                         sortShapes();
  29.                 }
  30.                
  31.                 private function depthSort(objA:DisplayObject, objB:DisplayObject):int {
  32.                     var posA:Vector3D = objA.transform.matrix3D.position;
  33.                         posA = container.transform.matrix3D.deltaTransformVector(posA);
  34.                         var posB:Vector3D = objB.transform.matrix3D.position;
  35.                         posB = container.transform.matrix3D.deltaTransformVector(posB);
  36.                         return posB.z - posA.z;
  37.                 }
  38.                
  39.                 private function sortShapes():void {
  40.                      imageItem.sort(depthSort);
  41.                          for(var i:int = 0; i < len; i++) {
  42.                              container.setChildIndex(imageItem[i] as MovieClip, i);
  43.                         }
  44.            }
  45.         }
  46. }
复制代码

第一个的情况,你是容器旋转,你要注意,每个容器都有自己独立的内部的一个3为坐标系,所以你要把它转为绝对的三维坐标系,也就是root的三维

第二个的
  1. package  {
  2.         import flash.events.Event;
  3.         import flash.display.MovieClip;
  4.         import flash.display.Sprite;
  5.        
  6.         public class rotateTwo extends MovieClip {
  7.                 private var rotations:Array = new Array();
  8.                 private var radius   :uint = 200;
  9.                 private var images   :Array = new Array();
  10.                 private var depthes  :Array = new Array();
  11.                 private var len      :uint  = 0;
  12.                
  13.                 public function rotateTwo():void {
  14.                         len  = container.numChildren;
  15.                         for(var i:int=0; i<len; i++) {
  16.                                 var mc:MovieClip = container.getChildAt(i) as MovieClip;
  17.                                 var rot:uint = (360 / len) * i;
  18.                                 mc.x = radius * Math.sin(rot * Math.PI/180);
  19.                                 mc.z = radius * Math.cos(rot * Math.PI/180);
  20.                                 images.push(mc);
  21.                                 rotations.push(rot);
  22.                         }
  23.                    stage.addEventListener(Event.ENTER_FRAME, handleTick);
  24.                 }
  25.                
  26.                 private function handleTick(evt:Event = null):void {
  27.                         for(var i:int=0; i<len; i++) {
  28.                                 rotations[i] += 1;
  29.                                 images[i].x = radius * Math.sin(rotations[i] * Math.PI/180);
  30.                                 images[i].z = radius * Math.cos(rotations[i] * Math.PI/180);
  31.                                 images[i].rotationY = rotations[i];
  32.                         }
  33.                         sortIndex();
  34.                 }
  35.                
  36.                 private function sortIndex():void {
  37.                         images.sortOn("z", Array.NUMERIC|Array.DESCENDING);
  38.                         for(var i:int=0; i<len; i++) {
  39.                                 container.addChildAt(images[i], i);
  40.                                 rotations[i] = images[i].rotationY;
  41.                         }
  42.                 }
  43.         }
  44. }
复制代码

第二个的问题就是对Z轴进行判断,你说的出现闪烁的情况,就说明你那个记录角度的数组,与与图片的数组,不是相对应的,有可能让a图应用b的角度,等会又是b图应用c的角度,就这样出现了闪烁现象,因为你只是对图片进行了深度排序,而之前的记录角度的那个数组,没有进行相应的改变,所以在sortIndex里,重新定义与之对应的角度就可以避免闪烁

评分

参与人数 1威望 +2 收起 理由
flash023 + 2 ^_^

查看全部评分

回复 支持 反对

使用道具 举报

发表于 2009-12-14 12:16:28 | 显示全部楼层
过路学习一下,是绝对坐标的问题?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-12-15 09:24:34 | 显示全部楼层
谢谢flash023,你提供的例子终于调试出来了,原来flashdevelop的class路径没有设置好。

还有libins,赶紧来学习领会一下。。。

谢谢!
回复 支持 反对

使用道具 举报

发表于 2009-12-15 09:42:18 | 显示全部楼层
我也是才开始学PV3D 感觉真的很有趣

在这里要感谢风飞扬老师的帮助
回复 支持 反对

使用道具 举报

发表于 2009-12-15 09:56:23 | 显示全部楼层
PV3D
回复 支持 反对

使用道具 举报

发表于 2009-12-15 09:59:00 | 显示全部楼层
papervision3d
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备12001430号 )  

GMT+8, 2020-3-28 23:10 , Processed in 0.140270 second(s), 11 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表