[转] [Flash/Flex] 使用Flare3D来实现Flash 3D的推箱子游戏原型---纹理

[url]http://bbs.9ria.com/thread-74032-1-1.html[/url]

我们继续来学习 使用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);
}
}
}

结果是这样的

[url]http://www.emanueleferonato.com/2011/02/16/flash-3d-sokoban-prototype-with-flare3d-textures/[/url]

使用左,右和向上箭头键移动游戏体(player) 。正如你所看到的,游戏体(player)和箱子目标(crate goals)没有质感,而且当箱子在箱子目标上时,箱子并不改变纹理。这是因为我计划给这些元素添加新的功能。

下载源代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值