小行星 libGDX 余弦和正弦旋转方程,以错误的角度发射子弹
Asteroids libGDX cosine and sine rotation equations, shooting bullets at wrong angle
我为 Android 设备制作了一个小行星游戏,但我无法注意到玩家站在一个方向,但在另一个稍微偏移的方向发射子弹。我查看了代码,只有当玩家加速和旋转时才会发生。不是当玩家只是旋转时。我希望这段代码足以告诉你一些关于它给我的建议。
玩家在正确的方向旋转,而子弹不是。我尝试将更新功能按不同的顺序排列,但这也无济于事。我看不出问题是什么,因为在射击玩家时 class 每次都会用玩家的弧度创建一颗子弹。所以我认为这与发射子弹时弧度没有更新有关。
private void initForces() {
maxSpeed = 300;
acceleration = 200;
friction = 10;
}
private void initRotationSpeed() {
// Radians are used to determine the angle the player points in
radians = MathUtils.PI / 2;
rotationSpeed = 3;
}
public void shoot() {
final int MAX_BULLETS = 4;
if (bullets.size() == MAX_BULLETS || isHit()) return;
bullets.add(new Bullet(x, y, radians));
}
public void update(float dt) {
if (updateCheckIfPlayerHit(dt)) {
return;
}
updateCheckExtraLives();
// Forces
updateAcceleration(dt);
updateRotationSpeed(dt);
updateTurning(dt);
updateFriction(dt);
// Set shape
setShape();
// Screen wrap
wrap();
}
private void updateTurning(float dt) {
// Turning: Tilt the screen to left or right to rotate the ship
final float ROTATION_SENSITIVITY = 3;
if (left || Gdx.input.getAccelerometerX() > ROTATION_SENSITIVITY) {
radians += rotationSpeed * dt;
}
else if (right || Gdx.input.getAccelerometerX() < -ROTATION_SENSITIVITY) {
radians -= rotationSpeed * dt;
}
}
private void updateRotationSpeed(float dt) {
x += dx * dt;
y += dy * dt;
}
private void updateAcceleration(float dt) {
// Accelerating
if (up || Gdx.input.isTouched() && Gdx.input.getX() > 0 && Gdx.input.getX() < Gdx.graphics.getWidth() / 2) {
dx += MathUtils.cos(radians) * acceleration * dt;
dy += MathUtils.sin(radians) * acceleration * dt;
}
}
private void updateFriction(float dt) {
// Friction
float vector = (float)Math.sqrt(dx * dx + dy * dy);
if (vector > 0) {
dx -= (dx / vector) * friction * dt;
dy -= (dy / vector) * friction * dt;
}
if (vector > maxSpeed) {
dx = (dx / vector) * maxSpeed;
dy = (dy / vector) * maxSpeed;
}
}
Bullet.java
package com.mygdx.entities;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
public class Bullet extends SpaceObject {
private float lifeTime;
private float lifeTimer;
private boolean remove;
Bullet(float x, float y, float radians) {
this.x = x;
this.y = y;
this.radians = radians;
float speed = 350;
dx = MathUtils.cos(radians) * speed;
dy = MathUtils.sin(radians) * speed;
width = height = 2;
lifeTimer = 0;
lifeTime = 1;
}
public boolean shouldRemove() {
return remove;
}
public void update(float dt) {
updateRotationSpeed(dt);
wrap();
updateLifeTime(dt);
}
private void updateRotationSpeed(float dt) {
x += dx * dt;
y += dy * dt;
}
private void updateLifeTime(float dt) {
// How long time the bullet is supposed to live
lifeTimer += dt;
if (lifeTimer > lifeTime) {
remove = true;
}
}
public void draw(ShapeRenderer shapeRenderer) {
shapeRenderer.setColor(1, 1, 1, 1);
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.circle(x - width / 2, y - height / 2, width / 2);
shapeRenderer.end();
}
}
与玩家一起射击的代码是:
if (Gdx.input.justTouched() &&
Gdx.input.getX() > Gdx.graphics.getWidth() / 2 &&
Gdx.input.getX() < Gdx.graphics.getWidth()) {
player.shoot();
}
我的问题的答案是我忘记了一点数学知识。所以在 Bullet 构造函数中,我没有玩家在 x 或 y 方向上的速度,所以我在玩家 class 中创建了两个静态变量,并在更新旋转速度函数中将它们设置为等于玩家的 dx 和 dy .这两个变量都是浮点数。
private void updateRotationSpeed(float dt) {
x += dx * dt;
y += dy * dt;
dxStatic = dx;
dyStatic = dy;
}
public static float getPlayerDeltaX() {
return dxStatic;
}
public static float getPlayerDeltaY() {
return dyStatic;
}
在 Bullet 的构造函数中 class 我需要添加:
Bullet(float x, float y, float radians) {
this.x = x;
this.y = y;
this.radians = radians;
float speed = 350;
dx = speed * MathUtils.cos(radians) + Player.getPlayerDeltaX();
dy = speed * MathUtils.sin(radians) + Player.getPlayerDeltaY();
width = height = 2;
lifeTimer = 0;
lifeTime = 1;
}
所以这就是导致子弹向稍微不同的方向移动的原因。
编辑:
或者您可以只向 Bullet 构造函数添加一些浮点变量并接收玩家的 dx 和 dy,因为每次在玩家 class 内都会创建一颗子弹。就我而言,至少是这样。那可能是一个更好的选择。
Bullet(float x, float y, float playerDeltaX, float playerDeltaY, float radians) {
this.x = x;
this.y = y;
this.radians = radians;
float speed = 350;
dx = speed * MathUtils.cos(radians) + playerDeltaX;
dy = speed * MathUtils.sin(radians) + playerDeltaY;
width = height = 2;
lifeTimer = 0;
lifeTime = 1;
}
我为 Android 设备制作了一个小行星游戏,但我无法注意到玩家站在一个方向,但在另一个稍微偏移的方向发射子弹。我查看了代码,只有当玩家加速和旋转时才会发生。不是当玩家只是旋转时。我希望这段代码足以告诉你一些关于它给我的建议。
玩家在正确的方向旋转,而子弹不是。我尝试将更新功能按不同的顺序排列,但这也无济于事。我看不出问题是什么,因为在射击玩家时 class 每次都会用玩家的弧度创建一颗子弹。所以我认为这与发射子弹时弧度没有更新有关。
private void initForces() {
maxSpeed = 300;
acceleration = 200;
friction = 10;
}
private void initRotationSpeed() {
// Radians are used to determine the angle the player points in
radians = MathUtils.PI / 2;
rotationSpeed = 3;
}
public void shoot() {
final int MAX_BULLETS = 4;
if (bullets.size() == MAX_BULLETS || isHit()) return;
bullets.add(new Bullet(x, y, radians));
}
public void update(float dt) {
if (updateCheckIfPlayerHit(dt)) {
return;
}
updateCheckExtraLives();
// Forces
updateAcceleration(dt);
updateRotationSpeed(dt);
updateTurning(dt);
updateFriction(dt);
// Set shape
setShape();
// Screen wrap
wrap();
}
private void updateTurning(float dt) {
// Turning: Tilt the screen to left or right to rotate the ship
final float ROTATION_SENSITIVITY = 3;
if (left || Gdx.input.getAccelerometerX() > ROTATION_SENSITIVITY) {
radians += rotationSpeed * dt;
}
else if (right || Gdx.input.getAccelerometerX() < -ROTATION_SENSITIVITY) {
radians -= rotationSpeed * dt;
}
}
private void updateRotationSpeed(float dt) {
x += dx * dt;
y += dy * dt;
}
private void updateAcceleration(float dt) {
// Accelerating
if (up || Gdx.input.isTouched() && Gdx.input.getX() > 0 && Gdx.input.getX() < Gdx.graphics.getWidth() / 2) {
dx += MathUtils.cos(radians) * acceleration * dt;
dy += MathUtils.sin(radians) * acceleration * dt;
}
}
private void updateFriction(float dt) {
// Friction
float vector = (float)Math.sqrt(dx * dx + dy * dy);
if (vector > 0) {
dx -= (dx / vector) * friction * dt;
dy -= (dy / vector) * friction * dt;
}
if (vector > maxSpeed) {
dx = (dx / vector) * maxSpeed;
dy = (dy / vector) * maxSpeed;
}
}
Bullet.java
package com.mygdx.entities;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.math.MathUtils;
public class Bullet extends SpaceObject {
private float lifeTime;
private float lifeTimer;
private boolean remove;
Bullet(float x, float y, float radians) {
this.x = x;
this.y = y;
this.radians = radians;
float speed = 350;
dx = MathUtils.cos(radians) * speed;
dy = MathUtils.sin(radians) * speed;
width = height = 2;
lifeTimer = 0;
lifeTime = 1;
}
public boolean shouldRemove() {
return remove;
}
public void update(float dt) {
updateRotationSpeed(dt);
wrap();
updateLifeTime(dt);
}
private void updateRotationSpeed(float dt) {
x += dx * dt;
y += dy * dt;
}
private void updateLifeTime(float dt) {
// How long time the bullet is supposed to live
lifeTimer += dt;
if (lifeTimer > lifeTime) {
remove = true;
}
}
public void draw(ShapeRenderer shapeRenderer) {
shapeRenderer.setColor(1, 1, 1, 1);
shapeRenderer.begin(ShapeRenderer.ShapeType.Line);
shapeRenderer.circle(x - width / 2, y - height / 2, width / 2);
shapeRenderer.end();
}
}
与玩家一起射击的代码是:
if (Gdx.input.justTouched() &&
Gdx.input.getX() > Gdx.graphics.getWidth() / 2 &&
Gdx.input.getX() < Gdx.graphics.getWidth()) {
player.shoot();
}
我的问题的答案是我忘记了一点数学知识。所以在 Bullet 构造函数中,我没有玩家在 x 或 y 方向上的速度,所以我在玩家 class 中创建了两个静态变量,并在更新旋转速度函数中将它们设置为等于玩家的 dx 和 dy .这两个变量都是浮点数。
private void updateRotationSpeed(float dt) {
x += dx * dt;
y += dy * dt;
dxStatic = dx;
dyStatic = dy;
}
public static float getPlayerDeltaX() {
return dxStatic;
}
public static float getPlayerDeltaY() {
return dyStatic;
}
在 Bullet 的构造函数中 class 我需要添加:
Bullet(float x, float y, float radians) {
this.x = x;
this.y = y;
this.radians = radians;
float speed = 350;
dx = speed * MathUtils.cos(radians) + Player.getPlayerDeltaX();
dy = speed * MathUtils.sin(radians) + Player.getPlayerDeltaY();
width = height = 2;
lifeTimer = 0;
lifeTime = 1;
}
所以这就是导致子弹向稍微不同的方向移动的原因。
编辑: 或者您可以只向 Bullet 构造函数添加一些浮点变量并接收玩家的 dx 和 dy,因为每次在玩家 class 内都会创建一颗子弹。就我而言,至少是这样。那可能是一个更好的选择。
Bullet(float x, float y, float playerDeltaX, float playerDeltaY, float radians) {
this.x = x;
this.y = y;
this.radians = radians;
float speed = 350;
dx = speed * MathUtils.cos(radians) + playerDeltaX;
dy = speed * MathUtils.sin(radians) + playerDeltaY;
width = height = 2;
lifeTimer = 0;
lifeTime = 1;
}