gpt4 book ai didi

android - 当相机以其为中心时,Box2D 主体滞后/跳跃

转载 作者:行者123 更新时间:2023-11-30 02:18:55 27 4
gpt4 key购买 nike

我试图将相机位置设置为 body 的位置,但是当我这样做时, body 会跳得非常明显。您可以使用调试渲染器看到这一点,但我的代码中附加了一个 Sprite 。跳跃总是朝着 Sprite 前进的方向。我有一个固定的插值时间步长,我将 Sprite 位置更新为每帧 box2d 主体的当前和最后位置的插值。然后将相机设置到插值位置。

import java.util.Random;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Input.Orientation;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.JointEdge;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.TimeUtils;
import com.badlogic.gdx.utils.viewport.FitViewport;

public class GameScreen implements Screen {
private static learnGame game;
private static OrthographicCamera camera;
private static FitViewport viewport;
private static Random rand;
private static BitmapFont font;
private static Vector3 touch;
private static double frameTime;
private static double accumulator;
private static float animTime = 0f;
private static float step = 1f / 60f;
private static boolean killBody;
private static Buttons buttons;

public static Player tom;
public static InputMultiplexer multiplexer;
public static Bodies world;
public static boolean paused;
private static Sprite tomSprite = new Sprite(new Texture(Gdx.files.internal("chars/bob.png")));

public GameScreen(learnGame learngame) {
GameScreen.game = learngame;
multiplexer = new InputMultiplexer();
Gdx.input.setInputProcessor(multiplexer);
camera = new OrthographicCamera();
viewport = new FitViewport(40, 22.5f, camera);
buttons = new Buttons(game, multiplexer, viewport); //HUD stuff
world = new Bodies(viewport, multiplexer); //creates a box2d world
tom = new Player(world.box2d, 10, 15, 1f, multiplexer); //creates a body with a CircleShape with a radius of 1. Catches user input to apply forces to the body
Assets.loadSprites();
world.box2d.getBodies(world.bodies);
font = new BitmapFont();

touch = new Vector3();
rand = new Random();
}

@Override
public void render(float delta) {

Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

learnGame.batch.setProjectionMatrix(camera.combined);
frameTime = 0;

if (!paused) {

frameTime = Math.min(Gdx.graphics.getRawDeltaTime(), 0.25);
accumulator += frameTime;

tom.update(); //here I apply forces to the body that I attach a camera to
generalUpdate(delta, touch, camera);
updatePositions(); //get previous positions for interpolation

while (accumulator >= step) {
world.box2d.step(step, 6, 2);
accumulator -= step;
interpolate((float) (accumulator / step));

}
world.box2d.clearForces();

learnGame.batch.begin();

if (tom.getBody().isActive()) {
tomSprite.setSize(tom.getHeight(), tom.getHeight());
tomSprite.setOriginCenter();
tomSprite.setRotation(Assets.tom.angle);//this doesn't work right but not the point.
tomSprite.setPosition(Assets.tom.pos.x, Assets.tom.pos.y);
tomSprite.draw(learnGame.batch);
}

learnGame.batch.end();

cameraUpdate(); //update the camera to the same position as the sprite

} else { //else pause the game
learnGame.batch.begin();
learnGame.batch.draw(Assets.pauset, viewport.getCamera().position.x
- (viewport.getCamera().viewportWidth / 2), viewport.getCamera().position.y
- (viewport.getCamera().viewportHeight / 2), viewport.getWorldWidth(), viewport.getWorldHeight());
learnGame.batch.end();
if (Gdx.input.isKeyJustPressed(Keys.SPACE) || Gdx.input.justTouched()) {
paused = false;

}

}
//destroy fixtures and bodies outside of the world step
for (Fixture fixture : Bodies.fixturesToDestroy) {
if (Bodies.destroyJoint == true) {
world.box2d.destroyJoint(Bodies.joint);
Bodies.joint = null;
Bodies.destroyJoint = false;
}
fixture.getBody().destroyFixture(fixture);
Bodies.fixturesToDestroy.removeValue(fixture, true);
}

for (Body body : Bodies.bodiesToDestroy) {
world.box2d.destroyBody(body);
body.setActive(false);
Bodies.bodiesToDestroy.removeValue(body, true);
}

}

@Override
public void show() {
Assets.firstSound.play();

}

@Override
public void resize(int width, int height) {

viewport.update(width, height, true);
Assets.reloadFont();

}

@Override
public void pause() {
paused = true;
}

@Override
public void resume() {
}

@Override
public void hide() {
paused = true;

}

@Override
public void dispose() {
Bodies.box2d.dispose();
Bodies.debugRenderer.dispose();
Buttons.stage.dispose();
Assets.cFrame.getTexture().dispose();
Assets.firstSound.dispose();
System.out.println("disposed");
}

public void generalUpdate(float delta, Vector3 touch, OrthographicCamera camera) {
if (Gdx.input.isKeyPressed(Keys.PAGE_UP)) {
camera.zoom -= 2f * Gdx.graphics.getDeltaTime();
;
} else if (Gdx.input.isKeyPressed(Keys.PAGE_DOWN)) {
camera.zoom += 2f * Gdx.graphics.getDeltaTime();
}
}

public static void cameraUpdate() {
camera.position.set(Assets.tom.pos, 0);
System.out.println("cam:" + Assets.tom.pos.x);
camera.update();
}

public static void kill() {
world.box2d.dispose();
world.debugRenderer.dispose();
Assets.cFrame.getTexture().dispose();
}

public void updatePositions() {
for (MySprite name : Assets.spriteList) {
name.prevPos = name.body.getTransform().getPosition();
name.prevAngle = name.body.getTransform().getRotation();
}

}

public void interpolate(float alpha) {
for (MySprite name : Assets.spriteList) {
name.pos.x = (name.body.getTransform().getPosition().x) * alpha + name.prevPos.x * (1.0f - alpha);
name.pos.y = (name.body.getTransform().getPosition().y) * alpha + name.prevPos.y * (1.0f - alpha);
name.angle = (name.body.getTransform().getRotation() * alpha + name.prevAngle * (1.0f - alpha));
}
}
}

我已经在相机不移动的情况下测试了我的插值实现,它似乎工作正常。我已经能够在我的桌面和我的 android 上测试这个。 Sprite 在我的 android 上“跳”得更多,但它发生在两个设备上。不确定我哪里出错了,非常感谢您提供一些意见!

最佳答案

我知道这是一个老问题,但我今天刚刚解决了我的问题。

我已经实现了固定的时间步长和插值,但我的 body 滞后、抖动和跳跃,就像没有明天一样。

请对您的相机运动执行以下操作:

  1. 使用 body 的插值位置,而不是原始 body 位置。
  2. 使用 camera.position.slerp(x, y, z, alpha) 进行平滑移动。 (您需要对变量进行一些尝试。

一个非常简单的例子:

static Vector3 desiredPosition;
static {
desiredPosition = new Vector3(0, 0, 0);
}
public static moveCam(Player player, Camera camera){
desiredPosition.x = player.interpolatedPos.x;
desiredPosition.y = player.interpolatedPos.y;
camera.slerp(desiredPosition, Gdx.graphics.getDeltaTime * 5);
camera.update();
}

并在您的渲染中执行以下操作

render(float delta){
moveCam(player, camera);
}

(即时位置设置导致我移动的物体抖动)

因为这个错误,我想放弃我的项目。但我设法做到了。我希望它能帮助那里的人。

€dit:猜测为什么会发生跳跃的 body :插值位置与相机不同步(设置位置然后更新世界(现在插值位置与相机偏移),然后绘制)但我不确定这一点。

关于android - 当相机以其为中心时,Box2D 主体滞后/跳跃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28886621/

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