方向鍵可以控制車輛移動,
空白鍵停止。
車輛的材質還有反光效果。

demo
知之者不如好之者,好之者不如樂之者
package
{
import com.adobe.utils.AGALMiniAssembler;
import com.adobe.utils.PerspectiveMatrix3D;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DRenderMode;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.display3D.VertexBuffer3D;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.textures.Texture;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.net.URLRequest;
import flash.display.Loader;
import MonitorKit;
/**
* ...Flash 3D API(Molehill) 貼圖範例
* @author Max
*/
public class Flash3D_Texture extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
private var vertexBuffer:VertexBuffer3D;
private var indexBuffer:IndexBuffer3D;
private var perspection:PerspectiveMatrix3D;
private var modelProjection:Matrix3D;
private var modelView:Matrix3D;
private var texture:Texture;
private var loaderObj:Loader;
private var shaderpg3d:Program3D;
public function Flash3D_Texture()
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
private function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE, onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
private function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
initTexture();
}
private function initTexture():void
{
loaderObj = new Loader();
loaderObj.contentLoaderInfo.addEventListener(Event.COMPLETE,
onLoaderBmpComple);
loaderObj.load(new URLRequest("pic.jpg"));
}
private function onLoaderBmpComple(event:Event):void
{
var tmploaderBmp:Bitmap = event.target.content as Bitmap;
texture = con3D.createTexture( 256, 256,
Context3DTextureFormat.BGRA, false);
texture.uploadFromBitmapData(tmploaderBmp.bitmapData,0);
initMesh();
}
private function initMesh():void
{
var vertexShader:Array =["dp4 op.x, va0, vc0",
"dp4 op.y, va0, vc1",
"dp4 op.z, va0, vc2",
"dp4 op.w, va0, vc3",
"mov v0, va1.xyzw"];
var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler();
vertexAssembler.assemble(flash.display3D.Context3DProgramType.VERTEX,
vertexShader.join("\n"));
var fragmentShader:Array =["mov ft0, v0\n",
"tex ft1, ft0, fs1 <2d,clamp,linear>\n",
"mov oc, ft1\n"];
var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler();
fragmentAssembler.assemble(flash.display3D.Context3DProgramType.FRAGMENT,
fragmentShader.join("\n"));
shaderpg3d = con3D.createProgram();
shaderpg3d.upload(vertexAssembler.agalcode, fragmentAssembler.agalcode);
indexBuffer = con3D.createIndexBuffer(6);
indexBuffer.uploadFromVector(Vector.([0, 1, 2, 0, 2, 3]), 0, 6);
vertexBuffer = con3D.createVertexBuffer(4, 4);
vertexBuffer.uploadFromVector(Vector.([-1.0, 1.0,0.0,1.0,
-1.0,-1.0,0.0,0.0,
1.0,-1.0,1.0,0.0,
1.0, 1.0,1.0,1.0]),0,4);
con3D.setVertexBufferAt( 0, vertexBuffer, 0,
Context3DVertexBufferFormat.FLOAT_2);
con3D.setVertexBufferAt( 1, vertexBuffer, 2,
Context3DVertexBufferFormat.FLOAT_2);
con3D.setTextureAt(1, texture);
addEventListener(Event.ENTER_FRAME, on3DRender);
stage.addEventListener(Event.RESIZE, onResizeStage);
onResizeStage();
}
private function drawMesh():void
{
con3D.setProgram(shaderpg3d);
modelView = new Matrix3D();
modelView.identity();
modelView.position = new Vector3D(0, 0, 2, 1);
modelView.appendScale(1, -1, 1);
perspection = new PerspectiveMatrix3D();
perspection.identity();
perspection.perspectiveLH(5.5, 4, 1, 100);
modelProjection = new Matrix3D();
modelProjection.identity();
modelProjection.position = new Vector3D(0, 0, 0, 1);
modelProjection.appendRotation(stage.mouseX/4,
new Vector3D(0, 1, 0, 1),null);
modelProjection.append(modelView);
modelProjection.append(perspection);
con3D.setCulling("none");
con3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,
0,modelProjection,true);
con3D.drawTriangles(indexBuffer, 0, 2);
}
private function onResizeStage(event:Event=null):void
{
con3D.configureBackBuffer(stage.stageWidth, stage.stageHeight,2,true);
sta3D.viewPort = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
on3DRender();
}
private function on3DRender(event:Event=null):void
{
con3D.clear(0.0, 0.0, 0.5, 1.0);
drawMesh();
con3D.present();
}
}
}

package
{
import com.adobe.utils.AGALMiniAssembler;
import com.adobe.utils.PerspectiveMatrix3D;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
public class Flash3D_DrawMesh extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
private var indexBuffer:IndexBuffer3D;
private var perspection:PerspectiveMatrix3D;
private var modelProjection:Matrix3D;
private var modelView:Matrix3D;
private var ro:Number = 5;
public function Flash3D_DrawMesh()
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
public function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.frameRate = 30;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE,onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
public function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
initMesh();
addEventListener(Event.ENTER_FRAME,on3DRender);
stage.addEventListener(Event.RESIZE,onResizeStage);
onResizeStage();
}
public function onResizeStage(event:Event = null):void
{
con3D.configureBackBuffer(stage.stageWidth,stage.stageHeight,2,true);
sta3D.viewPort = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
on3DRender();
}
public function initMesh():void
{
var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler();
vertexAssembler.assemble(Context3DProgramType.VERTEX,"m44 op,va0,vc \n"+
"mov v0,va1");
var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler();
fragmentAssembler.assemble(Context3DProgramType.FRAGMENT,"mov oc,v0");
var vertexBuffer:VertexBuffer3D = con3D.createVertexBuffer(4,6);
vertexBuffer.uploadFromVector(Vector.([-1, 1,0,1,0,0,
-1,-1,0,1,1,0,
1,-1,0,1,0,1,
1, 1,0,1,0,0]),0,4);
con3D.setVertexBufferAt(0,vertexBuffer,0,
Context3DVertexBufferFormat.FLOAT_3);
con3D.setVertexBufferAt(1,vertexBuffer,3,
Context3DVertexBufferFormat.FLOAT_3);
indexBuffer= con3D.createIndexBuffer(6);
indexBuffer.uploadFromVector(Vector.([0,1,2,0,2,3]),0,6);
var program:Program3D = con3D.createProgram();
program.upload(vertexAssembler.agalcode,fragmentAssembler.agalcode);
con3D.setProgram(program);
modelView = new Matrix3D();
modelView.identity();
perspection = new PerspectiveMatrix3D();
perspection.identity();
perspection.perspectiveLH(5.5, 4, 1, 10000);
modelProjection = new Matrix3D();
}
private function drawMesh():void
{
modelView.position = new Vector3D(0,0,1.5,1);
modelView.appendRotation(ro,Vector3D.Z_AXIS, null);
modelProjection.identity();
modelProjection.append(modelView);
modelProjection.append(perspection);
con3D.setCulling("front");
con3D.setProgramConstantsFromMatrix( Context3DProgramType.VERTEX,
0,modelProjection,true);
con3D.drawTriangles(indexBuffer,0,2);
}
private function on3DRender(event:Event=null):void
{
con3D.clear(0.0, 0.0, 0.5, 1.0);
drawMesh();
con3D.present();
}
}
}


package
{
import com.adobe.utils.AGALMiniAssembler;
import com.adobe.utils.PerspectiveMatrix3D;
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DProgramType;
import flash.display3D.Context3DRenderMode;
import flash.display3D.Context3DTextureFormat;
import flash.display3D.Context3DVertexBufferFormat;
import flash.display3D.IndexBuffer3D;
import flash.display3D.Program3D;
import flash.display3D.VertexBuffer3D;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Rectangle;
import flash.geom.Vector3D;
public class Flash3D_DrawTriangle extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
private var vertexBuffer:VertexBuffer3D;
private var indexBuffer:IndexBuffer3D;
private var modelView:Matrix3D;
private var modelProjection:Matrix3D;
private var perspection:PerspectiveMatrix3D;
private var ro:Number = 5;
private var pos:Vector3D;
public function Flash3D_DrawTriangle()
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
public function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.frameRate = 30;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE, onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
public function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
initMesh();
addEventListener(Event.ENTER_FRAME, on3DRender);
stage.addEventListener(Event.RESIZE, onResizeStage);
onResizeStage();
}
public function onResizeStage(event:Event = null):void
{
con3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 2, true);
sta3D.viewPort = new Rectangle(0,0,stage.stageWidth, stage.stageHeight);
on3DRender();
}
public function initMesh():void
{
var vertexAssembler:AGALMiniAssembler = new AGALMiniAssembler();
vertexAssembler.assemble(Context3DProgramType.VERTEX,"m44 op,va0,vc0 \n"+
"mov v0,va1");
var fragmentAssembler:AGALMiniAssembler = new AGALMiniAssembler();
fragmentAssembler.assemble(Context3DProgramType.FRAGMENT,"mov oc,v0");
vertexBuffer = con3D.createVertexBuffer(3,6);
vertexBuffer.uploadFromVector(Vector.([ 0, 1,0,1,0,0,
-1,-1,0,0,1,0,
1,-1,0,0,0,1,]),0, 3);
con3D.setVertexBufferAt(0,vertexBuffer,0,
Context3DVertexBufferFormat.FLOAT_3);
con3D.setVertexBufferAt(1,vertexBuffer,3,
Context3DVertexBufferFormat.FLOAT_3);
indexBuffer = con3D.createIndexBuffer(3);
indexBuffer.uploadFromVector(Vector.([0,1,2]),0,3);
var program:Program3D = con3D.createProgram();
program.upload(vertexAssembler.agalcode,fragmentAssembler.agalcode);
con3D.setProgram(program);
modelView = new Matrix3D();
modelView.identity();
pos = new Vector3D(0,0,2,1);
perspection = new PerspectiveMatrix3D();
perspection.identity();
perspection.perspectiveLH(2.8,2,1,10000);
}
public function DrawMesh():void
{
modelView.position = pos;
modelView.appendRotation(ro,Vector3D.Y_AXIS, null);
modelProjection = new Matrix3D();
modelProjection.identity();
modelProjection.append(modelView);
modelProjection.append(perspection);
con3D.setCulling("none");
con3D.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX,
0,modelProjection,true);
con3D.drawTriangles(indexBuffer,0,-1);
}
public function on3DRender(event:Event):void
{
con3D.clear(0.0, 0.0, 0.5, 1.0);
DrawMesh();
con3D.present();
}
}
}


package
{
import flash.display.Sprite;
import flash.display.Stage3D;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display3D.Context3D;
import flash.display3D.Context3DRenderMode;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Rectangle;
import MonitorKit;
/**
* ...Flash 3D Framework
* @author Max
*/
public class Flash3D_Framework extends Sprite
{
private var sta3D:Stage3D;
private var con3D:Context3D;
public function Flash3D_Framework():void
{
addEventListener(Event.ADDED_TO_STAGE, onAddtoStage);
}
public function onAddtoStage(event:Event):void
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
sta3D = stage.stage3Ds[0];
sta3D.addEventListener(Event.CONTEXT3D_CREATE, onCreateContext3D);
sta3D.requestContext3D(Context3DRenderMode.AUTO);
// 設定FPS
var FPS:MonitorKit = new MonitorKit(MonitorKit.MKMODE_TL);
addChild(FPS);
}
public function onCreateContext3D(event:Event):void
{
con3D = sta3D.context3D;
con3D.enableErrorChecking = true;
addEventListener(Event.ENTER_FRAME, on3DRender);
stage.addEventListener(Event.RESIZE, onResizeStage);
onResizeStage();
}
public function onResizeStage(event:Event = null):void
{
// 設定背景緩衝
con3D.configureBackBuffer(stage.stageWidth, stage.stageHeight, 2, true);
// 讓成像大小等於stage的大小
sta3D.viewPort = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight);
on3DRender();
}
// 3D渲染
public function on3DRender(event:Event = null):void
{
// 設定3D背景色(rgba)
con3D.clear(0.0, 0.0, 0.5, 1.0);
// ...
// 要繪製3D的處理可以加在這...
// ...
con3D.present();
}
}
}

global pDirPhyz -- 物理引擎
global pTimeStep -- 影響時間
global pSubSteps -- 計算動力係數
global resSphere -- 球的模型資源
global modSphere -- 球的模型
global resBox -- 方塊的模型資源
global modBox -- 方塊模型
global resFloor -- 地板模型資源
global modFloor -- 地板模型
on startmovie
--W3D
member("Scene3D").resetworld()
-------------------------------------
--建立球體模型
resSphere = member("Scene3D").newModelResource("SphereRes",#sphere,#front)
resSphere.radius = 10
resSphere.resolution = 6
modSphere = member("Scene3D").newModel("SphereRes")
modSphere.resource = resSphere
modSphere.transform.position = vector(50,100,-20)
modSphere.addmodifier(#meshdeform)
-------------------------------------
--建立方塊模型
resBox = member("Scene3D").newModelResource("BoxRes",#Box,#front)
resBox.height = 5
resBox.width = 100
resBox.length = 100
resBox.lengthVertices = 5
resBox.widthVertices = 5
resBox.heightVertices = 2
modBox = member("Scene3D").newModel("BoxRes")
modBox.resource = resBox
modBox.transform.position = vector(20,0,-20)
modBox.transform.rotation = vector(10,10,20)
modBox.addmodifier(#meshdeform)
-----------------------------------------
--建立地板模型
resFloor = member("Scene3D").newModelResource("FloorRes",#Box,#front)
resFloor.height = 5
resFloor.width = 200
resFloor.length = 200
resFloor.lengthVertices = 5
resFloor.widthVertices = 5
resFloor.heightVertices = 2
modFloor = member("Scene3D").newModel("FloorRes")
modFloor.resource = resFloor
modFloor.transform.position = vector(0,-70,0)
modFloor.transform.rotation = vector(0,0,0)
modFloor.addmodifier(#meshdeform)
------------------------------------------
--物理引擎
pDirPhyz = member("physX")
pTimeStep = 0.2
pSubSteps = 10
--初始引擎
pDirPhyz.Init(member("Scene3D"), vector(1,1,1),#equal, pTimeStep, pSubSteps )
pDirPhyz.gravity = vector(0,-9.8,0)
pDirPhyz.contacttolerance = 0.2
pDirPhyz.friction = 0.2
pDirPhyz.lineardamping = 0.4
pDirPhyz.angulardamping = 0.4
pDirPhyz.restitution = 0.9
--引擎套用到球模型
rb_ball=pDirPhyz.createRigidBody(modSphere.name,modSphere.name,#sphere,#dynamic)
rb_ball.mass = 100
--引擎套用到方塊模型
rb_box=pDirPhyz.createRigidBody(modBox.name,modBox.name,#Box,#static )
rb_box.mass = 100
--引擎套用到地板模型
rb_floor=pDirPhyz.createRigidBody(modFloor.name,modFloor.name,#Box,#static )
rb_floor.mass = 100
end
on endSprite me
if (pDirPhyz.isInitialized = 1) then
pDirPhyz.destroy()
end if
end
global pDirPhyz -- 物理引擎
global pTimeStep -- 影響時間
global pSubSteps -- 計算動力係數
on exitFrame
pDirPhyz.simulate()
go to the frame
end

