具有固定步进发动机的Andengine微滞后

时间:2015-11-17 16:33:43

标签: android andengine game-physics

我的问题是,当我使用有限FPS引擎时,我的游戏有微滞后,因为增量时间太不一致了。
我在这里描述了这个问题:Andengine PhysicsHandler makes player look laggy

现在我使用固定步进引擎来获得一致的增量时间,但现在它的滞后更多 也许我在游戏设计上犯了一些错误。

以下是代码:

对于固定步进引擎,我使用以下行:

@Override
public Engine onCreateEngine(EngineOptions pEngineOptions) 
{
    return new FixedStepEngine(pEngineOptions, 60);
}

对于我正在使用这两个类的玩家(Blocks是游戏网格):

public abstract class ActorObject extends AnimatedSprite {

// ===========================================================
// Constants
// ===========================================================

// ===========================================================
// Fields
// ===========================================================

public PhysicsHandler mPhysicsHandler;
public Camera camera;


// ===========================================================
// Constructors
// ===========================================================

public ActorObject(final float pX, final float pY, final ITiledTextureRegion pTiledTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager, Camera camera) {
    super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager);
    this.mPhysicsHandler = new PhysicsHandler(this);
    this.camera=camera;
    this.registerUpdateHandler(this.mPhysicsHandler);

    //updater=new Updater(this.camera,this);


    this.registerUpdateHandler(new IUpdateHandler() {
        @Override
        public void onUpdate(final float pSecondsElapsed) {
            onMove(pSecondsElapsed);    
      }
        @Override
        public void reset() {
            // TODO Auto-generated method stub

        }});

}

public  void onMove(float pSecondsElapsed){};

}

public class Player extends ActorObject {

// ===========================================================
// Constants
// ===========================================================

// ===========================================================
// Fields
// ===========================================================
public int direction;
public int desDirection;
public boolean canmove_vert;
public boolean canmove_hor;

Blocks[][] block;
boolean final_goal=false;
GameScene gm;
Rectangle rects;
Rectangle rects2;
VertexBufferObjectManager pVertexBufferObjectManager;
private int lastX;
private int lastY;
// ===========================================================
// Constructors
// ===========================================================
public Player(final float pX, final float pY, final VertexBufferObjectManager pVertexBufferObjectManager, Blocks[][] block2, int i, int p,final Camera camera,final GameScene gm) {
    super(pX, pY, ResourcesManager.getInstance().player_region, pVertexBufferObjectManager,camera); 
    block=block2;   
    this.pVertexBufferObjectManager=pVertexBufferObjectManager;
    this.gm=gm;
    rects=new Rectangle(this.getX(),this.getY(),78,78,ResourcesManager.getInstance().vbom);
    rects2=new Rectangle(this.getX(),this.getY(),2f,2f,ResourcesManager.getInstance().vbom);
    canmove_hor=false;
    canmove_vert=false;
    direction=Globals.RIGHT;
    setCullingEnabled(true);

    final long[] PLAYER_ANIMATE = new long[] { 130, 130, 130,130, 130, 130,130, 130, 130,130, 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,130,130 };     
 //   animate(PLAYER_ANIMATE, 0, 21, true);    
}

// ===========================================================
// Methods
// ===========================================================
public Rectangle getBounds(){
    return rects;
}
public Rectangle getSmallBounds(){
    return rects2;
}

public void setDirection(int dir){
    direction=dir;
}
@Override
public void onMove(final float sec){
    rects.setX(this.getX());
    rects.setY(this.getY());
    rects2.setPosition(this.getX(), this.getY());

    for(int i=0;i<Globals.OFFSETX;i++){
        for(int p=0;p<Globals.OFFSETY;p++){
            if(this.getBounds().collidesWith(block[i][p].getBounds())){

                this.mPhysicsHandler.setVelocity(0, 0);
                this.loadLastPos();
            }
            else if(this.getSmallBounds().collidesWith(block[i][p].getSmallBounds())){
            switch(desDirection){
            case Globals.LEFT:
                if(block[i][p].links_frei){
                direction=Globals.LEFT;
                desDirection=Globals.NICHTS;
                this.setPosition(block[i][p].x, block[i][p].y);
                this.mPhysicsHandler.setVelocityY(0);
                this.mPhysicsHandler.setVelocityX(-150);
                this.setRotation(270);
                }
                break;
            case Globals.RIGHT:
                if(block[i][p].rechts_frei){
                direction=Globals.RIGHT;
                desDirection=Globals.NICHTS;
                this.setPosition(block[i][p].x+1, block[i][p].y+1);
                this.mPhysicsHandler.setVelocityY(0);
                this.mPhysicsHandler.setVelocityX(150);
                this.setRotation(90);
                }
                break;
            case Globals.UP:
                if(block[i][p].oben_frei){
                direction=Globals.UP;
                desDirection=Globals.NICHTS;
                this.setPosition(block[i][p].x+1, block[i][p].y+1);
                this.mPhysicsHandler.setVelocityY(-150);
                this.mPhysicsHandler.setVelocityX(0);
                this.setRotation(0);
                }
                break;
            case Globals.DOWN:
                if(block[i][p].unten_frei){
                direction=Globals.DOWN;
                desDirection=Globals.NICHTS;
                this.setPosition(block[i][p].x+1, block[i][p].y+1);
                this.mPhysicsHandler.setVelocityY(150);
                this.mPhysicsHandler.setVelocityX(0);
                this.setRotation(180);
                }
                break;
            }

            }

            }
    }
        this.saveLastPos();


}//end onmove

public void saveLastPos(){
    lastX=(int) this.getX();
    lastY=(int) this.getY();
}

public void loadLastPos() {
    this.setX((float)lastX);
    this.setY((float)lastY);

}

我没有使用Physics Box 2d扩展名。
有人有解决方案吗?

1 个答案:

答案 0 :(得分:2)

尝试使用以下引擎。这是我在所有Andengine项目中使用的自定义引擎,它允许以设定的步数/速率进行流畅的游戏,而不会跳过,并且比其他引擎更容易预测。

public class FixedStepMaxFPSEngine extends Engine {

    // ===========================================================
    // Constants
    // ===========================================================

    // ===========================================================
    // Fields
    // ===========================================================

    private final long mStepLength;
    private long mSecondsElapsedAccumulator;
    private final UpdateHandlerList mConstantUpdateHandlers = new UpdateHandlerList(8);

    // ===========================================================
    // Constructors
    // ===========================================================

    /**
     * Create a new Fixed Step Max FPS engine.
     * @param pEngineOptions {@link EngineOptions} Engine options to use.
     * @param pStepsPerSecond {@link integer} How many updates a second?
     */
    public FixedStepMaxFPSEngine(EngineOptions pEngineOptions, final int pStepsPerSecond) {
        super(pEngineOptions);
        this.mStepLength = TimeConstants.NANOSECONDS_PER_SECOND / pStepsPerSecond;
    }

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    // ===========================================================
    // Methods for/from SuperClass/Interfaces
    // ===========================================================

    @Override
    public void onUpdate(final long pNanosecondsElapsed) throws InterruptedException {
        this.mSecondsElapsedAccumulator += pNanosecondsElapsed;
        final long stepLength = this.mStepLength;
        while(this.mSecondsElapsedAccumulator >= stepLength) {
            final float pSecondsElapsed = stepLength * TimeConstants.SECONDS_PER_NANOSECOND;
            this.onConstantUpdateUpdateHandlers(pSecondsElapsed);
            this.mSecondsElapsedAccumulator -= stepLength;
        }
        super.onUpdate(pNanosecondsElapsed);
    }

    protected void onConstantUpdateUpdateHandlers(final float pSecondsElapsed) {
        this.mConstantUpdateHandlers.onUpdate(pSecondsElapsed);
    }

    /**
     * Register an {@link IUpdateHandler} to be updated using our constant game speed.
     * @param pUpdateHandler {@link IUpdateHandler} to update.
     * @see FixedStepMaxFPSEngine
     */
    public void registerConstantUpdateHandler(final IUpdateHandler pUpdateHandler) {
        this.mConstantUpdateHandlers.add(pUpdateHandler);
    }

    /**
     * Unregister a {@link IUpdateHandler} from being updated using our constant game speed.
     * @param pUpdateHandler {@link IUpdateHandler} to unregister.
     */
    public void unregisterConstantUpdateHandler(final IUpdateHandler pUpdateHandler) {
        this.mConstantUpdateHandlers.remove(pUpdateHandler);
    }

    /**
     * Clear all {@link IUpdateHandler} registered for constant game speed updates.
     */
    public void clearConstantUpdateHandlers() {
        this.mConstantUpdateHandlers.clear();
    }

    // ===========================================================
    // Methods
    // ===========================================================

    // ===========================================================
    // Inner and Anonymous Classes
    // ===========================================================
}