我正在使用opengl-es在android中制作游戏,使用多个线程:
class World{
protected static final AtomicInteger entityLock = new AtomicInteger();
private GameEntity entities[];
public World(){
// populate game world with entities
// executed on main thread
addEntity(new GameEntity("tank"));
addEntity(new GameEntity("rifleman"));
addEntity(new GameEntity("rifleman"));
}
void update(){
synchronized(entityLock){
for(int i = 0;i<entities.length;i++){
// move entity to new position
// executed on PhysThread
entities[i].updatePosition();
}
}
if(entity.isDead(){
// remove entity. Enter sync block inside removeEntity() method
removeEntity(entity);
}
}
void draw(GL10 gl){
synchronized(entityLock){
for(int i = 0;i<entites.length;i++){
// draw models
// executed on GLThread
Vector3 entityPosition = entities[i].getPosition();
gl.glTranslatef(entityPosition.x, entityPosition.y, entityPosition.z);
entities[i].draw();
}
}
}
public void addEntity(GameEntity entity){
synchronized(entityLock){
// arrays stuff
}
}
public void removeEntity(GameEntity entity){
synchronized(entityLock){
// arrays stuff
}
}
}
class MyRenderer implements GLSurfaceView.Renderer{
World world;
public MyRenderer(World world){
this.world = world;
}
public void onDrawFrame(GL10 gl) {
// executed on GLThread
world.draw(gl);
}
}
class PhysThreadRunnable implements Runnable{
private long tickRate = 30;
private World world;
private PhysThreadRunnable(World world){
this.world = world;
}
protected void setTickRate(long tickRate){
this.tickRate = tickRate;
}
public void run() {
while(true){
try {
// executed on PhysThread
world.update();
Thread.sleep(1000/tickRate);
} catch (InterruptedException e) {
return;
}
}
}
}
MyActivity extends Activity{
@Override
public void onCreate(Bundle savedInstanceState) {
World world = new World();
// sets up the game world, populates it with entities
// set up GLSurfaceView (simplified)
setContentView(R.layout.main);
GLSurfaceView mGLView = findViewById(R.id.myGLSurfaceView);
mGLView.setRenderer(new MyRenderer(world));
// start phys thread
PhysThreadRunnable physThreadRunnable = new PhysThreadRunnable(world);
Thread physThread = new Thread(physThreadRunnable);
physThread.start();
}
}
我有一个问题,有时(但不是每次)当我开始游戏时,PhysThread 卡住等待释放锁(即当我去调试并暂停线程时,它只是坐在synchronized(entityLock)
里面update()
真正奇怪的是,一段时间后(2 秒到 1 分钟之间),PhysThread 将被解除阻塞,游戏将继续进行,而任何一个线程都不会在线程循环的多次迭代中被锁定。(即游戏运行良好)
编辑:我在示例中添加了一些额外的东西,以防万一这是问题的原因。基本上,更新和绘制实体数组而不是单个实体