注:本系列教程全部翻译完之后可能会以PDF的形式发布。
如果有什么错误可以到http://blog.csdn.net/kakashi8841留言或EMAIL:[email protected]给我。
jME版本 :jME_2.0.1_Stable
开发工具:MyEclipse8.5
开发环境:Window7/Vista
在这个向导中,我们将通过冲突检测(Collision Detection,也叫碰撞检测,碰撞检查,冲突检查等)保证我们呆在一个fence。我将通过为Collision Detection增加一个新的接口来实现。这种方式,我们有几种不同的Collision Detection系统。像反弹(bounce)墙和冲撞(crash)墙。
而最后,我不是会巫术的猴子(mojomonkey),所以这将和其它向导不同。
首先,我们增加一个接口去知道我们需要注意哪里。所以我们需要知道player和我们寻找的目标。而Collision Detector需要知道下一步发生什么。我们也准备必要的例子用于产生更好的效果。
我们先创建一个类:CollisionDetection,里面有2个方法:
public CollisionDetection(
Vehicle player, Node target, int nextMove){
this.player = player;
this.target = target;
this.nextMove = nextMove;
this.zExtent = ((BoundingBox)(player.getWorldBound())).zExtent;
createParticles();
}
public CollisionDetection(
Vehicle player, Spatial target, int nextMove){
this.player = player;
this.target = (Node) target;
this.nextMove = nextMove;
this.zExtent = ((BoundingBox)(player.getWorldBound())).zExtent;
createParticles();
}
nextMove现在只有2种类型:
public static final int MOVE_BOUNCE_OFF = 0;
public static final int MOVE_STOP = 1;
所以你现在可以输入这个如果你想要vehicle撞在fence后反弹的话:
增加一个类变量:
private CollisionDetection bounce;
在initGame(buildPlayer和buildEnvironment方法后)中加入:
bounce = new CollisionDetection(
player, walls, CollisionDetection. MOVE_BOUNCE_OFF
);
你现在看到那里有个node(walls)还没有被定义。我将在之后再做。因为你将一个新的bounce墙放入游戏中所需要做的就是,将墙(fence)attach到Node walls。
增加一个类变量:
private Node walls;
然后像这样:
private void buildEnvironment() {
//这将是所有walls的主要结点
walls = new Node("bouncing walls");
scene.attachChild(walls);
fence = new ForceFieldFence("forceFieldFence");
//我们将手工做一些调整去让它更好适应terrain
//首先我们将实体“模型”放大
fence.setLocalScale(5);
//现在,让我们移动fence到terrain的高度并有一点陷入它里面
fence.setLocalTranslation(
new Vector3f(25,tb.getHeight(25,25)+10,25)
);
//这里我们将它(fence)attach到walls Node
walls.attachChild(fence);
}
这是我创建的一个小的detection system。它在游戏中将vehicle弹回。而另一个detection直接停止vehicle。
//这里处理你所有的冲突
public void processCollisions(){
if(nextMove == MOVE_STOP){
if(player.hasCollision(target,false)){
if(
player.getFrontwheel()
.hasCollision(target, false)
){
player.setMaxSpeed(0);
player.setMinSpeed(15);
}else if(
player.getBackwheel()
.hasCollision(target, false)
){
player.setMaxSpeed(25);
player.setMinSpeed(0);
}
}else{
player.setMaxSpeed(25);
player.setMinSpeed(15);
}
}else if(nextMove == MOVE_BOUNCE_OFF){
if(player.hasCollision(target,false))
if(
player.getFrontwheel()
.hasCollision(target, false)
){
player.setVelocity(
-Math.abs(player.getVelocity())
);
particleGeom.setLocalTranslation(
player.getFrontwheel()
.getLocalTranslation().x,
player.getFrontwheel()
.getLocalTranslation().y*0.0025f,
zExtent
);
particleGeom.forceRespawn();
}else if(
player.getBackwheel()
.hasCollision(target, false)
){
player.setVelocity(
Math.abs(player.getVelocity())
);
particleGeom.setLocalTranslation(
player.getFrontwheel()
.getLocalTranslation().x,
player.getFrontwheel()
.getLocalTranslation().y*0.0025f,
-zExtent
);
particleGeom.forceRespawn();
}
}
}
上面的particleGeom为类变量:
private ParticleSystem particleGeom;
为了有一个好的冲突,你需要火花。我们将使用ParticleSystem创建这些。我尝试几次得出这些数字让它看起来更好。
private void createParticles() {
particleGeom = ParticleFactory.buildParticles("collsion", 300);
particleGeom.addInfluence(
SimpleParticleInfluenceFactory
.createBasicGravity(
new Vector3f(0, -0.01f, 0), true
)
);
particleGeom.setEmissionDirection(
new Vector3f(0.0f, 1.0f, 0.0f)
);
particleGeom.setMaximumAngle(360f * FastMath.DEG_TO_RAD);
particleGeom.setMinimumLifeTime(2000.0f);
particleGeom.setMaximumLifeTime(4000.0f);
particleGeom.setInitialVelocity(.004f);
particleGeom.recreate(FastMath.nextRandomInt(6, 20));
particleGeom.setStartSize(.05f);
particleGeom.setEndSize(.02f);
particleGeom.setStartColor(
new ColorRGBA(1.0f, 0.796875f, 0.1992f, 1.0f)
);
particleGeom.setEndColor(
new ColorRGBA(1.0f, 1.0f, 0.5976f, 1.0f)
);
particleGeom.getParticleController().setRepeatType(
Controller.RT_CLAMP
);
BlendState as = (BlendState) particleGeom.getRenderState(
RenderState.StateType.Blend
);
if (as == null) {
as = DisplaySystem.getDisplaySystem().getRenderer()
.createBlendState();
as.setBlendEnabled(true);
as.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
as.setTestEnabled(true);
as.setTestFunction(BlendState.TestFunction.GreaterThan);
particleGeom.setRenderState(as);
particleGeom.updateRenderState();
}
as.setDestinationFunction(BlendState.DestinationFunction.One);
TextureState ts = DisplaySystem.getDisplaySystem()
.getRenderer().createTextureState();
ts.setTexture(
TextureManager.loadTexture(
CollisionDetection.class.getClassLoader().getResource(
"res/flaresmall.jpg"
),
Texture.MinificationFilter.BilinearNearestMipMap,
Texture.MagnificationFilter.Bilinear
)
);
particleGeom.setRenderState(ts);
player.attachChild(particleGeom);
particleGeom.updateRenderState();
}