gpt4 book ai didi

java - JBullet NullPointer 在单独线程中进行步骤模拟

转载 作者:太空宇宙 更新时间:2023-11-04 14:53:38 26 4
gpt4 key购买 nike

我的游戏中有一个设置,其中物理在单独的线程中更新,其实现如下

物理处理器(物理线程)

public class PhysicsProcessor extends Runnable {
private DynamicsWorld world;

public PhysicsProcessor() {
/* basic dynamics world setup with dvbt broadphase :P */
}

public synchronized getDynamicsWorld() { return world; }

@Override
public void run() {
/* update time */

//update phyics
getDynamicsWorld().stepSimulation(/* delta time */);
}
}

主线程中的对象创建示例

myPhysicsProcessor.getDynamicsWorld.addRigidBody(/* some rigid body created here */);

问题是,当游戏运行时,我偶尔会在“stepSimulation”的单独线程中遇到空指针异常,这是由 dbvt Broadphase 中的 setAabb 引起的。

有人对我可以采取哪些措施来防止此异常或如何解决此异常有任何建议吗?

最佳答案

从表面上看,你可以让这个世界最终。那么这将向您展示同步访问是徒劳的:

public class PhysicsProcessor extends Runnable {
private final DynamicsWorld world;

public synchronized DynamicsWorld getDynamicsWorld() { return world; } //why sync? it can't change
}

您会看到,当您执行以下操作时: myPhysicsProcessor.getDynamicsWorld().addRigidBody(...) 同步会在 getDynamicsWorld() 返回后停止。因此 addRigidBody(...) 在安全同步上下文之外被调用。

不,您想要做的是确保它始终同步块(synchronized block)内使用:

@Override
public void run() {
//update physics
synchronized(this) {
world.stepSimulation(/* delta time */);
}
}

public void addBody(/*args here*/) {
synchronized(this) {
world.addRigidBody(/*args here*/);
}
}

现在这对于一种方法来说是可以的,但是如果您发现自己想要以这种方式在运行器外部执行许多 DynamicsWorld 方法,或者只是想要另一种选择,那么这个方法不需要同步:

public interface IWorldRunable {    
void run(DynamicsWorld world);
}

public class PhysicsProcessor extends Runnable {
private final DynamicsWorld world;
private final ConcurrentLinkedQueue<IWorldRunable> worldRunables = ConcurrentLinkedQueue<IWorldRunable>();

public PhysicsProcessor() {
/* basic dynamics world setup with dvbt broadphase :P */
}

@Override
public void run() {
/* update time */

//run runables on world
for(IWorldRunable runable : worldRunables)
runable.run(world);

//clear runables
worldRunables.clear();

//update phyics
world.stepSimulation(/* delta time */);
}

public void do(IWorldRunable runnable) {
worldRunables.add(runnable);
}
}

然后你可以这样做,添加一个正文:

myPhysicsProcessor.do(new IWorldRunable(){      
@Override
public void run(DynamicsWorld world){
world.addRigidBody(...);
}
});

它将在同一线程上的下一个 stepSimulation 之前执行,因此无需担心线程。

关于java - JBullet NullPointer 在单独线程中进行步骤模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23481191/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com