在前面两节中你在空间位置是成不变我们直是让舞台上物体来回移动并没有用到摄像机这个概念在有些时候我们只需要让物体运动但是随着你对3D深入你会发现那些并不足够当我们讨论3D空间时候摄像机理论上代表3D中个点我们从这个点去观看这个空间为什么要使用摄像机呢?我们希望能够透过个镜头看到其他所有舞台上物体其实里摄像机只不过是组数值来表示你摄像机在3D空间参数(比如位置)想象下你在广阔撒哈拉沙漠里越野又或者你朋友小P走向在你身旁你朋友小P慢慢走向你并最终到达离你很近位置几下来你们可以交谈了但是如果小P站在原地不动而是你走向他身旁那么对于地面来说小P是不动而你(摄像机)是移动在这里你眼睛就充当了我们摄像机看看下面两个动画文件再对比下左边是小P走向你右边是你走向小P
移动物体和移动摄像机
你会发现对于你眼睛来说你可以并不走动只要把小P和周围切物体都移动到你面前也会达到同样效果但是哪种可行呢?下面我们做两个动画来介绍说明如何在我们3D使用摄像机动画效果如下左面是移动我们小P右边是移动我们摄像机
对比移动小P和移动你摄像机
制作步骤:
1. 和以前样定义原点设置焦距创建舞台
//originisthecenteroftheviewpoin3dspace
//everythingscalearoundthispo
//theselinesofcodewillsht3dspaceorigothecenter
varorigin=Object;
origin.x=stage.stageWidth/2;
origin.y=stage.stageHeight/2-70;
//focallengthofviewer'scamera
varfocal_length=400;
2. 下面我们定义个摄像机物体它具有3D空间xyz并且我们给它个移动方向和在z方向移动速度
//upcamera
varcamera=Object;
camera.x=0;
camera.y=0;
camera.z=0;
camera.direction=1;
camera.speed_z=6;
3. 创建个小球在舞台上
//createasphere
//gotolibrary,rightclickonSphere,chooselinkage
//andcheckExportforActionscript
for(vari=0;i<1;i)
{
varsphere=Sphere;
sphere.x_3d=-30;
sphere.y_3d=80;
sphere.z_3d=600;
//addallthesphereestothesceneobject
scene.addChild(sphere);
}
4. 接下来我们开始写运动循环每次执行开始我们要把摄像机位置在z方向移动定量如果摄像机离小球很近了话那么让摄像机回来
//movethesphereesbackandforth
functionrun(e:Event)
{
//hereweoffthecamerapositionbyitsmovingspeedtimesthedirection
camera.zcamera.speed_z*camera.direction;
(camera.z>600) //thecameraistooclootheball
{
camera.z=600;
camera.direction=-1; //movecamerabackward
}
(camera.z<0) //thecameraistoocloothescreen
{
camera.z=0;
camera.direction=1;
}
//loopthroughalltheobjectsonthescene
for(vari=0;i<scene.numChildren;i)
{
//calculatethescalewhattheobjectshouldbe
varscale=focal_length/(focal_length+scene.getChildAt(i).z_3d-camera.z);
scene.getChildAt(i).x=(scene.getChildAt(i).x_3d-camera.x)*scale;
scene.getChildAt(i).y=(scene.getChildAt(i).y_3d-camera.x)*scale;
//properlyscaletheobjecttolook3d
scene.getChildAt(i).scaleX=scene.getChildAt(i).scaleY=scale;
}
}
5. 计算出小球离摄像机x距离y距离和z距离然后得出小球缩放比率最后把小球缩放并移动到相应位置That's it! 不要忘记添加循环执行事件
this.addEventListener(Event.ENTER_FRAME,run);
注意:
你需要考虑让摄像机z指不能小于-1乘焦距如果z小于这个值那么公式scale = focal_length/(focal_length+z)得出缩放比率会是负数那么物体就会开始向后运动
个简单赛车小游戏制作
下面我们运用摄像机概念来制作个简单赛车小游戏游戏里你可以使用上下左右键控制赛车COOL!那么我们开始
简单赛车游戏键盘WASD控制
1. 定义原点设置焦距创建舞台
//originisthecenteroftheviewpoin3dspace
//everythingscalearoundthispo
//theselinesofcodewillsht3dspaceorigothecenter
varorigin=Object;
origin.x=stage.stageWidth/2;
origin.y=stage.stageHeight/2;
//nowcreateasceneobjecttoholdallthespheres
varscene=Sprite;
this.addChild(scene);
scene.x=origin.x;
scene.y=origin.y;
//focallengthofviewer'scamera
varfocal_length=400;
2. 下面我们定义个摄像机物体它具有3D空间xyz并且我们给它在z方向移动速度
//upcamera
varcamera=Object;
camera.x=0;
camera.y=-40; //makethecameraoffthegroundalittlebit
camera.z=0;
camera.speed_z=0; //yourdrivingspeed
3. 创建两个个场景个用来盛放所有赛车另外个盛放放有路边轮胎然后把它们添加到舞台上
vartires=Sprite; //thisspriteholdsallthetires
varcars=Sprite; //thisspriteholdsallthecars
vartxt_speed=TextField; //yourdashboard
txt_speed.x=20;
txt_speed.y=20;
//nowaddthemtothescreen
scene.addChild(tires);
scene.addChild(cars);
this.addChild(txt_speed);
4. 定义些赛车运动状态变量
//nowherearethevariablesdeterminethecar'smovingstate
varmove_left=false;
varmove_right=false;
varspeed_up=false;
varbrake=false;
5. 那么接下来我们创建40个轮胎并且把前20个放在路左边后20个放在路右边这样我们给赛道画出个轮廓
//nowcreate40tires,20ontheleftand10ontheright
for(vari=0;i<40;i)
{
vartire=Tire;
(i<20)
{
tire.x_3d=-400;
tire.z_3d=i*500;
}
{
tire.x_3d=400;
tire.z_3d=(i-20)*500;
}
tire.y_3d=40;
tires.addChild(tire);
}
6. 创建8个赛车给它们相应xyz位置(注意要赛车放在赛道上设置它们x范围在-230到230的间)给他们区别起始z位置和速度最后把它们添加到舞台上
//create8opponentcars
for(varj=0;j<8;j)
{
varcar=Car;
car.x_3d=Math.random*(-230-230)+230; //givethemrandomxposition
car.y_3d=-30;
car.z_3d=-800+(8-j)*400; //givethemspeed
car.speed_z=(8-j)*15;
cars.addChild(car);
}
7. 接下来我们要写个每次我们执行这个首先把赛车在z方向移动定量(赛车相对地面是运动)然后计算比率把赛车移动到相应位置并且缩放我把它命名updateCar还是运用摄像机理论分别计算出摄像机和小车xyz距离然后把小车缩放和移动注意小车如果离摄像机太远或者被甩到摄像机后面话我们可以让它不在屏幕上显示
//foreachoftherunningcycle,thewofunctionsarecalled
functionupdateCar(car)
{
varx=car.x_3d-camera.x; //calculatethexdistancebetweenyourcameraandcar
vary=car.y_3d-camera.y; //samewecanydistance
varz=car.z_3d-camera.z; //andzdistance
(z<0||z>10000) //caristoofarorleftbehind
car.visible=false; //thendonotdrawit
car.visible=true;
car.z_3dcar.speed_z; //movethecar
z=car.z_3d-camera.z; //recaculatethezdistance
varscale=focal_length/(focal_length+z); //caculatethescalewhatthecarshouldbe
car.x=x*scale;
car.y=y*scale;
car.scaleX=car.scaleY=scale; //scaleittoapropersize
}
8. 轮胎更新updateTire和赛车更新类似区别是轮胎相对地面是静止所以这里我们不改变它们xyz值只有在轮胎已经到了摄像机后面(轮胎z小于摄像机z)我们把这个轮胎重新定位到摄像机前非常远地方
functionupdateTire(tire)
{
varx=tire.x_3d-camera.x;
vary=tire.y_3d-camera.y;
varz=tire.z_3d-camera.z;
(z<0)
{
tire.z_3d10000; //thetireisleftbehind,thenoffit
z=tire.z_3d-camera.z;
}
varscale=focal_length/(focal_length+z);
tire.x=x*scale;
tire.y=y*scale;
tire.scaleX=tire.scaleY=scale;
}
9. 下步run执行首先把我们摄像头沿z方向移动然后我们前面写updateCar和updateTire刷新所有赛车和轮胎位置和大小
//hereisthefunctionloop
functionrun(e:Event)
{
camera.zcamera.speed_z; //firstmoveyourcamera
for(vari=0;i<cars.numChildren;i) //updateallthecars
{
updateCar(cars.getChildAt(i));
}
for(varj=0;j<tires.numChildren;j) //andthetiresontheside
{
updateTire(tires.getChildAt(j));
}
txt_speed.text=(camera.speed_z)+"MPH"; //showyourspeed
txt_speed.TextFormat(TextFormat("Verdana",16,0x444444,true));
}
10. 下面是键盘响应事件我写了些注释在里不过我相信你应该很快就能看懂就不打算详细解说了实现功能是当按下左键你赛车左移;按下上键赛车开始加速(当然极速是需要你来定义了)等等
//keyboardfunctions
functionkey_down(e:KeyboardEvent):void
{
(e.keyCode37) //leftkey
move_left=true;
(e.keyCode39) //rightkey
move_right=true;
(e.keyCode38) //upkey
speed_up=true;
(e.keyCode40) //downkey
brake=true;
}
functionkey_up(e:KeyboardEvent):void
{
(e.keyCode37)
move_left=false;
(e.keyCode39)
move_right=false;
(e.keyCode38)
speed_up=false;
(e.keyCode40)
brake=false;
}
functionkeyboard_response(e:Event):void
{
(move_left)
{
//movethecameratotheleft,rememberherethefastyougo,thefastyoursteer
camera.x-=camera.speed_z/6;
(camera.x<-300)camera.x=-300; //limityourcarsoitwon'tgoofftheroad
}
(move_right)
{
camera.xcamera.speed_z/6;
(camera.x>300)camera.x=300; //limityourcarsoitwon'tgoofftheroad
}
(speed_up)
{
camera.speed_z.2; //accelerate
//limitthecarspeedinarange
(camera.speed_z<0)camera.speed_z=0;
(camera.speed_z>120)camera.speed_z=120;
}
{
camera.speed_z*=.99; //youdon'thitthethrottle,itwillstopsoon
}
(brake)
{
camera.speed_z-=.3; //slowdown
(camera.speed_z<0)camera.speed_z=0;
}
}
11. 最后添加循环执行和键盘响应事件如果没问题话现在发布运行成功了!
//nowinitializeallthenecessaryeventlistenersandwearedone
this.addEventListener(Event.ENTER_FRAME,run);
this.addEventListener(Event.ENTER_FRAME,keyboard_response);
stage.addEventListener(KeyboardEvent.KEY_DOWN,key_down);
stage.addEventListener(KeyboardEvent.KEY_UP,key_up);
stage.stageFocusRect=false;
stage.focus=scene;
注意:
当你在循环个中所有对象时你可能会遇到想要删除个对象情况(可能你需要把这个对象从这个删除然后添加到另外个中)那么在这个删除过程中你要非常小心在你执行删除操作后长度会改变那么你如果循环使用长度作为max话会造成掠过对现在在原删除对象所在位置对象操作
种解决办法就是在循环的前定义个变量然后再执行for循环
varlength=objects.numChildren;
个简单Particle 例子
这是最后个使用摄像机基本概念例子你可以使用键盘上下左右键移动摄像机按下W键加速前进按下S键减速例子源文件已经放在下载中压缩文件里我就不再把代码粘贴上来了尝试改变星星数量星星很多话移动你摄像机你应该会看到个很长星带(题外话:我在我电脑里运行2000个星星就有些慢了Dual Core 2.0GHZ如果你有更强大CPU话那你看到星空要比我漂亮多)
3D星空简单Particle WASD移动摄像机K键加速L键减速
目前为止我们直在讨论3D场景设置后面我会陆续介绍如何使用代码实现3D物体绘制不过我想在那的前我们还是多看几个3D场景例子加深你印象那么请不要失去耐心最终你所关心内容这里定会有介绍
相关文章:
Flash和3D编程探秘( 7)- 3D物体框架
Flash和3D编程探秘( 6)- 全方位旋转摄像机
Flash和3D编程探秘()- Flash和3D空间
Flash和3D编程探秘( 5)- 摄像机旋转和移动
Flash和3D编程探秘( 4)- 摄像机旋转基础知识
Flash和3D编程探秘( 3)- 摄像机(Camera)
作者:YangZhou
出处:http://yangzhou1030.cnblogs.com/
感谢:Yunqing
最新评论