Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当子弹出现在屏幕上时,libgdx播放器加速_Java_Android_Libgdx_Sprite - Fatal编程技术网

Java 当子弹出现在屏幕上时,libgdx播放器加速

Java 当子弹出现在屏幕上时,libgdx播放器加速,java,android,libgdx,sprite,Java,Android,Libgdx,Sprite,我在libgdx中创建的一个游戏遇到了一个非常奇怪的问题。当我的玩家发射子弹时,他(毫不犹豫地)加速 起初,我认为这可能是因为我在创建子弹时,以某种方式传递了对玩家位置的引用,而不是创建一个新位置,但我一遍又一遍地扫描代码,我不认为这是导致它的原因 我相信这可能与delta计时的处理方式有关,因为在低规格设备上这种行为被夸大了: -在我的台式计算机上作为LWJGLAP应用程序运行时,问题要么不明显,要么根本没有发生 -在1.4Ghz的四核平板电脑上,这个问题是显而易见的,但尽管令人讨厌,但它并不

我在libgdx中创建的一个游戏遇到了一个非常奇怪的问题。当我的玩家发射子弹时,他(毫不犹豫地)加速

起初,我认为这可能是因为我在创建子弹时,以某种方式传递了对玩家位置的引用,而不是创建一个新位置,但我一遍又一遍地扫描代码,我不认为这是导致它的原因

我相信这可能与delta计时的处理方式有关,因为在低规格设备上这种行为被夸大了:

-在我的台式计算机上作为LWJGLAP应用程序运行时,问题要么不明显,要么根本没有发生 -在1.4Ghz的四核平板电脑上,这个问题是显而易见的,但尽管令人讨厌,但它并不影响游戏的工作流程 -在单芯1Ghz手机上,这个问题非常明显,以至于玩家通常会比屏幕上的子弹快很多(偶尔会从他不应该的矩形中掉下来)

我的GameScreen.render类如下所示:

@Override
public void render(float delta) 
{
    if((!(this.isPaused)&&(!(this.renderInProgress))))
    {
        this.renderInProgress = true;
        Gdx.gl.glClearColor(0.35f, 0.15f, 0.1f, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
               //update players with delta passed in
        controllerPlayer.update(delta);
               //update bullets with delta passed in
        for(Bullet b:world.getLevel().getBullets())
        {
            b.getController().update(delta);
        }
        world.getLevel().updateObjectStateTimes(delta);
        rendererWorld.render();
        rendererOverlay.render();
        this.renderInProgress = false;
    }
 }
    // Processing the input - setting the states of Bob
    processInput();

    // If Bob is grounded then reset the state to IDLE 
    if (grounded && bob.getState().equals(State.JUMPING)) 
    {
        bob.setState(State.IDLE);
    }

    // Setting initial vertical acceleration 
    bob.getAcceleration().y = GRAVITY;

    // Convert acceleration to frame time
    bob.getAcceleration().mul(delta);

    // apply acceleration to change velocity
    bob.getVelocity().add(bob.getAcceleration().x, bob.getAcceleration().y);

    // checking collisions with the surrounding blocks depending on Bob's velocity
    checkCollisions(delta);

    // apply damping to halt Bob nicely 
    bob.getVelocity().x *= DAMP;

    // ensure terminal velocity is not exceeded
    if (bob.getVelocity().x > MAX_VEL) {
        bob.getVelocity().x = MAX_VEL;
    }
    if (bob.getVelocity().x < -MAX_VEL) {
        bob.getVelocity().x = -MAX_VEL;
    }

    // simply updates the state time
    bob.update(delta);
controllerPlayer如下所示:

@Override
public void render(float delta) 
{
    if((!(this.isPaused)&&(!(this.renderInProgress))))
    {
        this.renderInProgress = true;
        Gdx.gl.glClearColor(0.35f, 0.15f, 0.1f, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
               //update players with delta passed in
        controllerPlayer.update(delta);
               //update bullets with delta passed in
        for(Bullet b:world.getLevel().getBullets())
        {
            b.getController().update(delta);
        }
        world.getLevel().updateObjectStateTimes(delta);
        rendererWorld.render();
        rendererOverlay.render();
        this.renderInProgress = false;
    }
 }
    // Processing the input - setting the states of Bob
    processInput();

    // If Bob is grounded then reset the state to IDLE 
    if (grounded && bob.getState().equals(State.JUMPING)) 
    {
        bob.setState(State.IDLE);
    }

    // Setting initial vertical acceleration 
    bob.getAcceleration().y = GRAVITY;

    // Convert acceleration to frame time
    bob.getAcceleration().mul(delta);

    // apply acceleration to change velocity
    bob.getVelocity().add(bob.getAcceleration().x, bob.getAcceleration().y);

    // checking collisions with the surrounding blocks depending on Bob's velocity
    checkCollisions(delta);

    // apply damping to halt Bob nicely 
    bob.getVelocity().x *= DAMP;

    // ensure terminal velocity is not exceeded
    if (bob.getVelocity().x > MAX_VEL) {
        bob.getVelocity().x = MAX_VEL;
    }
    if (bob.getVelocity().x < -MAX_VEL) {
        bob.getVelocity().x = -MAX_VEL;
    }

    // simply updates the state time
    bob.update(delta);
这里是创建项目符号的地方:

        this.fireReleased();

        if(world.getLevel().getBullets().size() < Bob.MAX_BULLETS)
        {
            Bullet b = bullPool.obtain();
            Rectangle bobRect = rectPool.obtain();
            bobRect.set(bobRect.set(bob.getBounds().x, bob.getBounds().y, bob.getBounds().width, bob.getBounds().height));

            Vector2 bobCent = new Vector2();
            bobRect.getCenter(bobCent);

            this.sndFire.play(0.4f);
            if(bob.isFacingLeft())
            {               
                b.set(bobCent, DIRECTION.LEFT, world);
                world.getLevel().addBullet(b);
            }
            else
            {
                b.set(bobCent, DIRECTION.RIGHT, world);
                world.getLevel().addBullet(b);
            }
        }
this.fireReleased();
if(world.getLevel().get子弹头().size()
根据要求,我上传了一个示例项目,其速度为0

从不动到右转

delta = 0.5;   
bobv = (velocity=0 + (20 * delta)) * 0.9
bobpixels = 9 * delta
bulletv = 10 * delta
bulletpixels = bulletv
仍然在进行,现在我们达到了最大速度(15)

仍然向右行驶,已经达到最大速度,不能再快了

delta = 0.5;
bobv = (velocity=15 + (20 * delta)) * 0.9
bobpixels = 15 * delta
bulletv = 10 * delta
bulletpixels = bulletv
仍然正常,德尔塔下降

delta = 0.1;
bobv = (velocity=15 + (20 * delta)) * 0.9
bobpixels = 15 * delta
bulletv = 10 * delta
bulletpixels = bulletv
德尔塔仍在正常运行,下降幅度更大

delta = 0.01;
bobv = (velocity=15 + (20 * delta)) * 0.9
bobpixels = 13.68  * delta
bulletv = 10 * delta
bulletpixels = bulletv
所以,如果我找到了你所有的数学(像我说的那样集中这些东西),看起来你没事,除非增量足够小,以至于bob不能保持“15”的速度。在第一部分中,bob加速并达到子弹速度的1.5倍,但在最后,当delta下降时,比率看起来变成了1.368:1。问题是你如何试图加速鲍勃达到他的最高速度

解决这一切。先把你所有的bob velocity代码都撕下来。删除所有加速逻辑。让bob以固定的速度开始,并确保问题已解决。我建议定义一个全局基本速度,例如10米/秒。让bullet和bob达到这个速度,然后乘以他们的百分比。鲍勃是全球速度*1.5f,子弹是全球速度*1.0f

渲染时,将对象速度乘以增量,以计算自上一帧以来它们移动了多少像素。在您看到最大问题的设备上进行测试。一旦一切正常,添加加速代码。我们需要记录我们鲍勃在同一个方向上走了多久。您需要bob具备:

int direction = 0; // -1 for left, 0 for still, 1 for right
float timeInSameDirection = 0f;
final float timeToTopSpeed = 100f; //find the number that works for you
final topSpeed = Globals.topSpeed * 1.5f;
现在,当您更新bob时,您将执行以下操作:

if(currentDirection == direction) {
    timeInSameDirection += delta;
} else {
    timeInSameDirection = delta;
    direction = currentDirection;
}

float speed = 0;
// are we moving
if(direction != 0) {
    Interpolation interpolation = Interpolation.linear;
    float accelRatio = timeInSameDirection/timeToTopSpeed;
    accelRatio = accelRatio > 1 ? 1 : accelRatio;
    float speed = interpolation.apply(0, topSpeed, accelRatio);
    speed = direction == -1 ? -speed : speed;
}
很酷的一点是,你可以改变插值,你会得到一个完全不同的感觉,bobs加速度(顺便说一句,这有时被称为tweening)。只需再多做一点工作,您就可以通过跟踪TopSpeedCachedCurrentDirection和TimePents减速来增加减速


注意,鲍勃的最高速度是15。这是米每秒或其他一些游戏世界的速度。这与像素不同,因为每帧显示的增量与上一帧的增量不完全相同,我们需要将bob的世界速度转换为每帧像素。基本上
pixelsMoved=速度*数值常数*增量将数值常数调整到所需的像素/米比率。

因此,首先:您的代码非常混乱。您的BobController类(我认为它确实不需要与Bob分离,尽管这不是一个真正的问题,只是看起来毫无意义)做得太多了。我肯定会把两件事放在另一个类中,那就是输入和冲突检测。尽量避免在碰撞检测过程中更新Bob的位置,这样会使其变得杂乱无章,难以找到

很抱歉这么多人谈论这个问题,现在谈谈问题本身。注意你的子弹的速度是10,鲍勃的最大速度是15。这意味着他应该能够加速超越他们。但是为什么他不以每秒60帧的速度这样做呢

运动的一部分,它不依赖于
delta
何时应为
DAMP
。在60 FPS时,它将速度降低60倍;每秒20帧,仅20次。这意味着在高FPS时,
MAX_VEL
根本无法达到。最终,鲍勃达到了一个速度,在这个速度下,他的每一帧加速度等于阻尼从他身上带走的速度。如果我们假设固定FPS为60,这意味着他每帧加速
加速度*delta
=20*(1/60)=0.33。当这个加速度把他带到3.33的水平速度时,阻尼也带走了0.33-达到平衡。所以实际的最大速度是3,而不是15。在较低的FPS速率下,该值较高

因此,修复它的第一部分很简单-将
MAX_VEL
更改为3

这是一个显著的改进,但是Bob在较低的帧速率下仍然要快一点。这是因为在施加加速度后,但在施加阻尼和最大水平之前,他的位置在
checkCollisions()
中更新。
private static final float DAMP = 10f;
private static final float MAX_VEL = 3f;

(...)

public void update(float delta) {

    (...)

    // apply damping to halt Bob nicely 
    float decel = DAMP*delta;
    if (Math.abs(bob.getVelocity().x) < decel) {
        bob.getVelocity().x = 0;
    } else {
        bob.getVelocity().x -= decel*(bob.getVelocity().x < 0 ? -1 : 1);
    }

    (...)

    // checking collisions with the surrounding blocks depending on Bob's velocity
    checkCollisions(delta);

    // simply updates the state time
    bob.update(delta);
}