Andengine 微滞后与 Fixed step 引擎
Andengine micro lags with Fixed step engine
我的问题是当我使用 Limited FPS 引擎时我的游戏有轻微的滞后,因为增量时间太不一致。
我在这里描述了这个问题:
现在我使用 Fixed step 引擎来获得一致的增量时间,但现在它更滞后了。
可能是我游戏设计出了问题
代码如下:
对于 Fixed step 引擎,我使用此行:
@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 扩展。
有人对此有解决方案吗?
尝试使用以下引擎。这是我在所有 Andengine 项目中使用的自定义引擎,它允许在一组 step/rate 中流畅地玩游戏而不会跳过,而且它比其他引擎更可预测。
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
// ===========================================================
}
我的问题是当我使用 Limited FPS 引擎时我的游戏有轻微的滞后,因为增量时间太不一致。
我在这里描述了这个问题:
现在我使用 Fixed step 引擎来获得一致的增量时间,但现在它更滞后了。
可能是我游戏设计出了问题
代码如下:
对于 Fixed step 引擎,我使用此行:
@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 扩展。
有人对此有解决方案吗?
尝试使用以下引擎。这是我在所有 Andengine 项目中使用的自定义引擎,它允许在一组 step/rate 中流畅地玩游戏而不会跳过,而且它比其他引擎更可预测。
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
// ===========================================================
}