Libgdx 三角函数错误的角度
Libgdx Trigonometry Wrong Angle
我正在构建像 Counter Strike 2D 这样的自上而下射击游戏,速度有问题:
public class Player extends Entity {
private float moveSpeed;
private float turnSpeed;
private float maxSpeed;
private float moveFriction;
private float turnFriction;
private Texture tex;
private Sprite sprite;
private ArrayList<Bullet> bullets;
public Player() {
moveSpeed = 15 / Game.PPM;
turnSpeed = 400 / Game.PPM;
maxSpeed = 300 / Game.PPM;
moveFriction = 5 / Game.PPM;
turnFriction = 10 / Game.PPM;
tex = new Texture(Gdx.files.internal("ingame/TempPlayer.png"));
sprite = new Sprite(tex);
bodyDef = new BodyDef();
bodyDef.position.set(Game.cam.position.x / Game.PPM, Game.cam.position.y / Game.PPM);
bodyDef.type = BodyType.DynamicBody;
body = Game.world.createBody(bodyDef);
shape = new PolygonShape();
shape.setAsBox(sprite.getWidth() / 2 / Game.PPM, sprite.getHeight() / 4 / Game.PPM);
fixDef = new FixtureDef();
fixDef.shape = shape;
body.createFixture(fixDef);
shape.setAsBox(sprite.getWidth() / 10 / Game.PPM, sprite.getHeight() / 5 / Game.PPM, new Vector2(sprite.getWidth() / 2 / Game.PPM, sprite.getHeight() / 3 / Game.PPM), 0 / Game.PPM);
fixDef.shape = shape;
body.createFixture(fixDef);
bullets = new ArrayList<Bullet>();
}
public void update(float dt) {
sprite.setCenter(body.getPosition().x * Game.PPM, body.getPosition().y * Game.PPM);
sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
// FRICTON
if (body.getLinearVelocity().x > 0) {
body.setLinearVelocity(body.getLinearVelocity().x - moveFriction, body.getLinearVelocity().y);
} else if (body.getLinearVelocity().x < 0) {
body.setLinearVelocity(body.getLinearVelocity().x + moveFriction, body.getLinearVelocity().y);
}
if (body.getLinearVelocity().y > 0) {
body.setLinearVelocity(body.getLinearVelocity().x, body.getLinearVelocity().y - moveFriction);
} else if (body.getLinearVelocity().y < 0) {
body.setLinearVelocity(body.getLinearVelocity().x, body.getLinearVelocity().y + moveFriction);
}
if (body.getAngularVelocity() > 0) {
body.setAngularVelocity(body.getAngularVelocity() - turnFriction);
} else if (body.getAngularVelocity() < 0) {
body.setAngularVelocity(body.getAngularVelocity() + turnFriction);
}
// MAX SPEED
if (body.getLinearVelocity().x > maxSpeed) {
body.setLinearVelocity(maxSpeed, body.getLinearVelocity().y);
} else if (body.getLinearVelocity().x < -maxSpeed) {
body.setLinearVelocity(-maxSpeed, body.getLinearVelocity().y);
}
if (body.getLinearVelocity().y > maxSpeed) {
body.setLinearVelocity(body.getLinearVelocity().x, maxSpeed);
} else if (body.getLinearVelocity().y < -maxSpeed) {
body.setLinearVelocity(body.getLinearVelocity().x, -maxSpeed);
}
// PLAYER MOVEMENT
if (body.getAngle() >= 360) {
body.setTransform(body.getPosition().x, body.getPosition().y, 0);
}
float xVel = -(MathUtils.sin(body.getAngle()) * moveSpeed);
float yVel = MathUtils.cos(body.getAngle()) * moveSpeed;
if (Gdx.input.isKeyPressed(Keys.LEFT)) {
body.setAngularVelocity(turnSpeed);
} else if (Gdx.input.isKeyPressed(Keys.RIGHT)) {
body.setAngularVelocity(-turnSpeed);
} else {
body.setAngularVelocity(0);
}
if (Gdx.input.isKeyPressed(Keys.UP)) {
body.setLinearVelocity(body.getLinearVelocity().x + xVel, body.getLinearVelocity().y + yVel);
} else if (Gdx.input.isKeyPressed(Keys.DOWN)) {
body.setLinearVelocity(body.getLinearVelocity().x - xVel, body.getLinearVelocity().y - yVel);
}
if (Gdx.input.isKeyJustPressed(Keys.SPACE)) {
bullets.add(new Bullet(body.getPosition().x, body.getPosition().y, body.getAngle()));
}
// CAMERA MOVEMENT
Game.b2dCam.position.set(body.getPosition().x, body.getPosition().y, 0);
Game.cam.position.set(body.getPosition().x * Game.PPM, body.getPosition().y * Game.PPM, 0);
for (int i = 0; i < bullets.size(); i++) {
bullets.get(i).update(dt);
}
}
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(Game.cam.combined);
sprite.draw(sb);
for (int i = 0; i < bullets.size(); i++) {
bullets.get(i).render(sb);
}
}
public void dispose() {
tex.dispose();
shape.dispose();
}
在这部分代码中,我试图转到我正在寻找的地方,它应该像这样工作
float xVel = MathUtils.cos(body.getAngle()) * moveSpeed;
float yVel = MathUtils.sin(body.getAngle()) * moveSpeed;
if (Gdx.input.isKeyPressed(Keys.LEFT)) {
body.setAngularVelocity(turnSpeed);
} else if (Gdx.input.isKeyPressed(Keys.RIGHT)) {
body.setAngularVelocity(-turnSpeed);
} else {
body.setAngularVelocity(0);
}
if (Gdx.input.isKeyPressed(Keys.UP)) {
body.setLinearVelocity(body.getLinearVelocity().x + xVel, body.getLinearVelocity().y + yVel);
} else if (Gdx.input.isKeyPressed(Keys.DOWN)) {
body.setLinearVelocity(body.getLinearVelocity().x - xVel, body.getLinearVelocity().y - yVel);
}
但是当我这样做时,当我尝试前进时角色会向侧面移动
İ如果我更改 cos 和 sin 的位置,它可以正常工作,但不应该
float xVel = -(MathUtils.sin(body.getAngle()) * moveSpeed);
float yVel = MathUtils.sin(body.getAngle()) * moveSpeed;
可能的原因仅仅是因为您的播放器纹理(png/jpg 本身)可能没有指向右侧,这被认为是 0 度角。
如果是这种情况,最简单的解决方案是编辑纹理,使播放器指向右侧。
你的所有代码看起来都很好,除了这个:
// PLAYER MOVEMENT
if (body.getAngle() >= 360) {
body.setTransform(body.getPosition().x, body.getPosition().y, 0);
}
你在哪里比较弧度和度数。无论如何,如果子句不是必需的,Box2D 已经将角度值限制在 0 和 2*PI 之间。
我正在构建像 Counter Strike 2D 这样的自上而下射击游戏,速度有问题:
public class Player extends Entity {
private float moveSpeed;
private float turnSpeed;
private float maxSpeed;
private float moveFriction;
private float turnFriction;
private Texture tex;
private Sprite sprite;
private ArrayList<Bullet> bullets;
public Player() {
moveSpeed = 15 / Game.PPM;
turnSpeed = 400 / Game.PPM;
maxSpeed = 300 / Game.PPM;
moveFriction = 5 / Game.PPM;
turnFriction = 10 / Game.PPM;
tex = new Texture(Gdx.files.internal("ingame/TempPlayer.png"));
sprite = new Sprite(tex);
bodyDef = new BodyDef();
bodyDef.position.set(Game.cam.position.x / Game.PPM, Game.cam.position.y / Game.PPM);
bodyDef.type = BodyType.DynamicBody;
body = Game.world.createBody(bodyDef);
shape = new PolygonShape();
shape.setAsBox(sprite.getWidth() / 2 / Game.PPM, sprite.getHeight() / 4 / Game.PPM);
fixDef = new FixtureDef();
fixDef.shape = shape;
body.createFixture(fixDef);
shape.setAsBox(sprite.getWidth() / 10 / Game.PPM, sprite.getHeight() / 5 / Game.PPM, new Vector2(sprite.getWidth() / 2 / Game.PPM, sprite.getHeight() / 3 / Game.PPM), 0 / Game.PPM);
fixDef.shape = shape;
body.createFixture(fixDef);
bullets = new ArrayList<Bullet>();
}
public void update(float dt) {
sprite.setCenter(body.getPosition().x * Game.PPM, body.getPosition().y * Game.PPM);
sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
// FRICTON
if (body.getLinearVelocity().x > 0) {
body.setLinearVelocity(body.getLinearVelocity().x - moveFriction, body.getLinearVelocity().y);
} else if (body.getLinearVelocity().x < 0) {
body.setLinearVelocity(body.getLinearVelocity().x + moveFriction, body.getLinearVelocity().y);
}
if (body.getLinearVelocity().y > 0) {
body.setLinearVelocity(body.getLinearVelocity().x, body.getLinearVelocity().y - moveFriction);
} else if (body.getLinearVelocity().y < 0) {
body.setLinearVelocity(body.getLinearVelocity().x, body.getLinearVelocity().y + moveFriction);
}
if (body.getAngularVelocity() > 0) {
body.setAngularVelocity(body.getAngularVelocity() - turnFriction);
} else if (body.getAngularVelocity() < 0) {
body.setAngularVelocity(body.getAngularVelocity() + turnFriction);
}
// MAX SPEED
if (body.getLinearVelocity().x > maxSpeed) {
body.setLinearVelocity(maxSpeed, body.getLinearVelocity().y);
} else if (body.getLinearVelocity().x < -maxSpeed) {
body.setLinearVelocity(-maxSpeed, body.getLinearVelocity().y);
}
if (body.getLinearVelocity().y > maxSpeed) {
body.setLinearVelocity(body.getLinearVelocity().x, maxSpeed);
} else if (body.getLinearVelocity().y < -maxSpeed) {
body.setLinearVelocity(body.getLinearVelocity().x, -maxSpeed);
}
// PLAYER MOVEMENT
if (body.getAngle() >= 360) {
body.setTransform(body.getPosition().x, body.getPosition().y, 0);
}
float xVel = -(MathUtils.sin(body.getAngle()) * moveSpeed);
float yVel = MathUtils.cos(body.getAngle()) * moveSpeed;
if (Gdx.input.isKeyPressed(Keys.LEFT)) {
body.setAngularVelocity(turnSpeed);
} else if (Gdx.input.isKeyPressed(Keys.RIGHT)) {
body.setAngularVelocity(-turnSpeed);
} else {
body.setAngularVelocity(0);
}
if (Gdx.input.isKeyPressed(Keys.UP)) {
body.setLinearVelocity(body.getLinearVelocity().x + xVel, body.getLinearVelocity().y + yVel);
} else if (Gdx.input.isKeyPressed(Keys.DOWN)) {
body.setLinearVelocity(body.getLinearVelocity().x - xVel, body.getLinearVelocity().y - yVel);
}
if (Gdx.input.isKeyJustPressed(Keys.SPACE)) {
bullets.add(new Bullet(body.getPosition().x, body.getPosition().y, body.getAngle()));
}
// CAMERA MOVEMENT
Game.b2dCam.position.set(body.getPosition().x, body.getPosition().y, 0);
Game.cam.position.set(body.getPosition().x * Game.PPM, body.getPosition().y * Game.PPM, 0);
for (int i = 0; i < bullets.size(); i++) {
bullets.get(i).update(dt);
}
}
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(Game.cam.combined);
sprite.draw(sb);
for (int i = 0; i < bullets.size(); i++) {
bullets.get(i).render(sb);
}
}
public void dispose() {
tex.dispose();
shape.dispose();
}
在这部分代码中,我试图转到我正在寻找的地方,它应该像这样工作
float xVel = MathUtils.cos(body.getAngle()) * moveSpeed;
float yVel = MathUtils.sin(body.getAngle()) * moveSpeed;
if (Gdx.input.isKeyPressed(Keys.LEFT)) {
body.setAngularVelocity(turnSpeed);
} else if (Gdx.input.isKeyPressed(Keys.RIGHT)) {
body.setAngularVelocity(-turnSpeed);
} else {
body.setAngularVelocity(0);
}
if (Gdx.input.isKeyPressed(Keys.UP)) {
body.setLinearVelocity(body.getLinearVelocity().x + xVel, body.getLinearVelocity().y + yVel);
} else if (Gdx.input.isKeyPressed(Keys.DOWN)) {
body.setLinearVelocity(body.getLinearVelocity().x - xVel, body.getLinearVelocity().y - yVel);
}
但是当我这样做时,当我尝试前进时角色会向侧面移动
İ如果我更改 cos 和 sin 的位置,它可以正常工作,但不应该
float xVel = -(MathUtils.sin(body.getAngle()) * moveSpeed);
float yVel = MathUtils.sin(body.getAngle()) * moveSpeed;
可能的原因仅仅是因为您的播放器纹理(png/jpg 本身)可能没有指向右侧,这被认为是 0 度角。
如果是这种情况,最简单的解决方案是编辑纹理,使播放器指向右侧。
你的所有代码看起来都很好,除了这个:
// PLAYER MOVEMENT
if (body.getAngle() >= 360) {
body.setTransform(body.getPosition().x, body.getPosition().y, 0);
}
你在哪里比较弧度和度数。无论如何,如果子句不是必需的,Box2D 已经将角度值限制在 0 和 2*PI 之间。