isometric projection
等角投影制作egret伪3D游戏
2015/9/3 by DKZ thx. May
最近在制作一款类似cubejump的游戏伪3D游戏,接下来cubex3的手机版也要想要使用等角投影制作。
感谢剑龙写的egret版本的等角投影库,我简单研究了下原理,可能下面的笔记会有错误,具体请参考《Flash ActionScript 3.0 动画高级教程》
简单的说等角变换是将三维世界的点变化成为二维平面上的坐标来确定对象的位置,在游戏中实现伪3D效果
原理
三维空间点p(px,py,pz)沿y轴旋转angleY沿x轴旋转angleX得到二维平面上点(x,y)和深度z
x=pxcos(angleY)-pzsin(angleY)
tempz=pzcos(angleY)+pxsin(angleY)
y=pycos(angleX)-tempzsin(angleX)
z=tempzcos(angleX)+pysin(angleX)
等角变换angleY=45°,angleX=-30°带入消去tempz再乘2的平方根(变为2等角,w=h*2)
最终化简为:
x=px-pz
y=py1.2247+(px+pz)0.5
z=(px+pz)0.886-y0.707
二维变三维将py设为0可计算px,pz
px=y+x*0.5
py=0
pz=y-x*0.5
使用
可以前往egretInit获得这个库
其中主要包括
Point3D.ts
三维空间点类
IsoUtils.ts
换算坐标类
isoToScreen(p3d:Point3D):egret.Point
三维到二维
XYZToXY(x,y,z)
三维到二维
screenToIso(p2d:egret.Point):Point3D
二维到三维
IsoObject.ts
等角投影对象类,所有显示对象都要扩展这个类
_px:number
_py:number
_pz:number
_position:Point3D
三维坐标和三维点
_width:number
_height:number
显示对象宽和高用于碰撞检测或显示对象排布
_walkable:boolean = false
_vx:number = 0
_vy:number = 0
_vz:number = 0
三维空间中三个方向的运动速度
updateScreenPosition():void
调用IsoUtils计算并更新二维平面中的位置
setPosition(x,y,z):void
设置三维空间中位置
get depth()
获得深度
update(p:number = 1):void
更新位置(用在frame loop中)
IsoWorld.ts
等角投影世界
_floor:egret.DisplayObjectContainer
地面容器(不参与深度排序)
_world:egret.DisplayObjectContainer
世界容器(参与深度排序)
_objects:IsoObject[] = []
等角变换对象数组
addChildToWorld(child:IsoObject):void
添加一个等角变换对象到世界中
removeChildFromWorld(child:IsoObject):void
从世界删除一个等角变换对象
addChildToFloor(child:IsoObject):void
添加一个等角变换对象到地板中
removeChildFromFloor(child:IsoObject):void
从地板删除一个等角变换对象
sort():void
对等角变换世界排序
BitmapTile.ts
等角投影位图 extends IsoObject
设计师注意位图使用二等角长宽比1:2(或根据需要定制此类)
其他还有几个扩展IsoObject的类可以用作参考