[转] [Flash/Flex] 运用Flare3D来实现Flash 3D的推箱子游戏原型-纹理
[转] [Flash/Flex] 使用Flare3D来实现Flash 3D的推箱子游戏原型---纹理
http://bbs.9ria.com/thread-74032-1-1.html
我们继续来学习 使用Flare3D来实现Flash 3D的推箱子游戏原型(Flash 3D Sokoban prototype ), 现在我将应用一些纹理(textures)到我的游戏元素中.
下面的脚本显示出三个有趣的Flare3D特点:
*在一个立方体上应用纹理
*只在一个立方体的某些面上应用纹理
*在同一个立方体上应用不同的材料,然后在它们上使用过滤器(filters)
下面是源码:
结果是这样的
http://www.emanueleferonato.com/2011/02/16/flash-3d-sokoban-prototype-with-flare3d-textures/
使用左,右和向上箭头键移动游戏体(player) 。正如你所看到的,游戏体(player)和箱子目标(crate goals)没有质感,而且当箱子在箱子目标上时,箱子并不改变纹理。这是因为我计划给这些元素添加新的功能。
下载源代码
http://bbs.9ria.com/thread-74032-1-1.html
我们继续来学习 使用Flare3D来实现Flash 3D的推箱子游戏原型(Flash 3D Sokoban prototype ), 现在我将应用一些纹理(textures)到我的游戏元素中.
下面的脚本显示出三个有趣的Flare3D特点:
*在一个立方体上应用纹理
*只在一个立方体的某些面上应用纹理
*在同一个立方体上应用不同的材料,然后在它们上使用过滤器(filters)
下面是源码:
package { // required flash classes import flash.display.Sprite; import flash.events.Event; import flash.display.BitmapData; import flash.display.BlendMode; import flash.filters.* // required flare3d classes import flare.basic.*; import flare.materials.*; import flare.primitives.*; import flare.system.*; import flare.utils.*; import flare.core.*; public class Main extends Sprite { private const CUBESIZE:Number=10; // sokobal demo level and player position private var levels:Array=[[1,1,1,1,0,0,0,0],[1,0,0,1,1,1,1,1],[1,0,2,0,0,3,0,1],[1,0,3,0,0,2,4,1],[1,1,1,0,0,1,1,1],[0,0,1,1,1,1,0,0]]; private var playerCol:uint; private var playerRow:uint; private var playerRotation:Number=0; private var playerAngle:Number=0; private var playerMovement:Number=0; private var dRow:int; private var dCol:int; // flare3d variables private var scene:Scene3D;// scene3D is the canvas of the flare3d environment private var player:Cube;// cube primitive representing the player private var movingCrate:Cube;// cube primitive representing the moving crate // bitmap datas private var crateBitmap:BitmapData=new BitmapData(256,256); private var cratetopBitmap:BitmapData=new BitmapData(256,256); private var floorBitmap:BitmapData=new BitmapData(256,256); private var wallBitmap:BitmapData=new BitmapData(256,256); // textures private var crateTexture:Texture3D; private var cratetopTexture:Texture3D; private var floorTexture:Texture3D=new Texture3D("",floorBitmap); private var wallTexture:Texture3D; // materials private var floorMaterial:TextureMaterial=new TextureMaterial("",floorTexture); private var goalMaterial:ShadedColorMaterial=new ShadedColorMaterial("",0x000000,0x00ff00); private var playerMaterial:ShadedColorMaterial=new ShadedColorMaterial("",0x000000,0x0000ff); // multi materials private var wallMaterial:MultiMaterial = new MultiMaterial(); private var crateMaterial:MultiMaterial = new MultiMaterial(); private var cratetopMaterial:MultiMaterial = new MultiMaterial(); public function Main() { floorBitmap.draw(new floorPic(256,256)); // wallBitmap.draw(new wallPic(256,256)); wallTexture=new Texture3D("",wallBitmap); wallMaterial.setTextureChannel(0,wallTexture); wallMaterial.setShadedColorChannel(1); wallMaterial.setBlendMode(BlendMode.MULTIPLY); // crateBitmap.draw(new cratePic(256,256)); crateTexture=new Texture3D("",crateBitmap); crateMaterial.setTextureChannel(0,crateTexture); crateMaterial.setShadedColorChannel(1); crateMaterial.setBlendMode(BlendMode.MULTIPLY); // cratetopBitmap.draw(new cratetopPic(256,256)); cratetopTexture=new Texture3D("",cratetopBitmap); cratetopMaterial.setTextureChannel(0,cratetopTexture); cratetopMaterial.setShadedColorChannel(1); cratetopMaterial.setBlendMode(BlendMode.MULTIPLY); // scene setup scene=new Viewer3D(this,"",0,0); // level construction var cube:Cube; for (var i:uint=0; i<6; i++) { for (var j:uint=0; j<8; j++) { switch (levels[i][j]) { case 0 : cube=new Cube("",CUBESIZE,CUBESIZE/2,CUBESIZE,1,floorMaterial); cube.setPosition(CUBESIZE*j,0,CUBESIZE*i); scene.addChild(cube); break; case 1 : cube=new Cube("",CUBESIZE,CUBESIZE/2,CUBESIZE,1,floorMaterial); cube.setPosition(CUBESIZE*j,0,CUBESIZE*i); scene.addChild(cube); cube=new Cube("",CUBESIZE,CUBESIZE,CUBESIZE,1,wallMaterial); cube.setPosition(CUBESIZE*j,CUBESIZE*3/4,CUBESIZE*i); scene.addChild(cube); break; case 2 : cube=new Cube("",CUBESIZE,CUBESIZE/2,CUBESIZE,1,goalMaterial); cube.setPosition(CUBESIZE*j,0,CUBESIZE*i); scene.addChild(cube); break; case 3 : cube=new Cube("",CUBESIZE,CUBESIZE/2,CUBESIZE,1,floorMaterial); cube.setPosition(CUBESIZE*j,0,CUBESIZE*i); scene.addChild(cube); cube=new Cube("crate_"+i+"_"+j,CUBESIZE,CUBESIZE,CUBESIZE,1,crateMaterial); cube.setPosition(CUBESIZE*j,CUBESIZE*3/4,CUBESIZE*i); scene.addChild(cube); // top of the crate var polyVec:Vector.<Poly3D>=cube.polys; polyVec[4].material=cratetopMaterial; polyVec[5].material=cratetopMaterial; break; case 4 : cube=new Cube("",CUBESIZE,CUBESIZE/2,CUBESIZE,1,floorMaterial); cube.setPosition(CUBESIZE*j,0,CUBESIZE*i); scene.addChild(cube); player=new Cube("player",CUBESIZE,CUBESIZE,CUBESIZE,1,playerMaterial); player.setPosition(CUBESIZE*j,CUBESIZE*3/4,CUBESIZE*i); scene.addChild(player); playerCol=j; playerRow=i; break; } } } // listener to handle the 3D engine scene.addEventListener(Scene3D.UPDATE_EVENT,updateEvent); } private function updateEvent(e:Event):void { var currentRotation:Number=0; // we have to determine the difference between current row and column // and the new row and column according to player heading switch (playerAngle) { case 0 : dRow=0; dCol=-1; break; case 90 : dRow=1; dCol=0; break; case 180 : dRow=0; dCol=1; break; case 270 : dRow=-1; dCol=0; break; } if (playerRotation==0&&playerMovement==0) { // look how does flare3D listens for key pressed if (Input3D.keyDown(Input3D.RIGHT)) { playerRotation=9; playerAngle+=90; } if (Input3D.keyDown(Input3D.LEFT)) { playerRotation=-9; playerAngle-=90; } if (Input3D.keyDown(Input3D.UP)) { movingCrate=null; if (levels[playerRow+dRow][playerCol+dCol]==0||levels[playerRow+dRow][playerCol+dCol]==2) { // the player can move playerMovement=- CUBESIZE/10; } else { if (levels[playerRow+dRow][playerCol+dCol]==3||levels[playerRow+dRow][playerCol+dCol]==5) { if (levels[playerRow+2*dRow][playerCol+2*dCol]==0||levels[playerRow+2*dRow][playerCol+2*dCol]==2) { // the player can move and can push a crate movingCrate=scene.getChildByName("crate_"+(playerRow+dRow)+"_"+(playerCol+dCol))as Cube; playerMovement=- CUBESIZE/10; } } } } if (playerAngle<0) { playerAngle+=360; } if (playerAngle==360) { playerAngle=0; } } else { if (playerRotation) { // this is how flare3D rotates an object player.rotateY(playerRotation); if (Math.abs(Math.round(player.getRotation().y))%90==0) { playerRotation=0; } } if (playerMovement) { // this is how flare3D moves an object player.translateX(playerMovement); if (movingCrate) { switch (playerAngle) { case 0 : movingCrate.translateX(playerMovement); break; case 90 : movingCrate.translateZ(-playerMovement); break; case 180 : movingCrate.translateX(-playerMovement); break; case 270 : movingCrate.translateZ(playerMovement); break; } } // we need this to know if the player stopped on the destination tile if ((playerAngle%180==0&&(Math.round(player.getPosition().x*10)/10)%CUBESIZE==0)||(playerAngle%180!=0&&(Math.round(player.getPosition().z*10)/10)%CUBESIZE==0)) { playerMovement=0; levels[playerRow+dRow][playerCol+dCol]+=4; levels[playerRow][playerCol]-=4; if (movingCrate) { levels[playerRow+2*dRow][playerCol+2*dCol]+=3; if (levels[playerRow+2*dRow][playerCol+2*dCol]==5) { // crate on goal } else { // crate not on goal } levels[playerRow+dRow][playerCol+dCol]-=3; movingCrate.name="crate_"+(playerRow+2*dRow)+"_"+(playerCol+2*dCol); } playerCol+=dCol; playerRow+=dRow; } } } // camera management Pivot3DUtils.setPositionWithReference(scene.camera,CUBESIZE*3,CUBESIZE*6,0,player,0.1); Pivot3DUtils.lookAtWithReference(scene.camera,-CUBESIZE*2,-CUBESIZE*3,0,player); } } }
结果是这样的
http://www.emanueleferonato.com/2011/02/16/flash-3d-sokoban-prototype-with-flare3d-textures/
使用左,右和向上箭头键移动游戏体(player) 。正如你所看到的,游戏体(player)和箱子目标(crate goals)没有质感,而且当箱子在箱子目标上时,箱子并不改变纹理。这是因为我计划给这些元素添加新的功能。
下载源代码