【发布时间】:2026-02-13 20:55:02
【问题描述】:
从图像中您可以看到,在左边开火的球在后面开火,与计算出的轨迹不符。我使用来自 SO question 的方程绘制球轨迹,将其修改为考虑到每秒 30 帧的 box2d 步骤。这确实计算了一个有效的轨迹,但它与球的实际轨迹不匹配,球的轨迹较小。我正在对球施加一个 box2d 力,这也有一个密度集和一个形状。形状半径因球的种类而异。我在触地事件中设置开始速度。
public class ProjectileEquation {
public float gravity;
public Vector2 startVelocity = new Vector2();
public Vector2 startPoint = new Vector2();
public Vector2 gravityVec = new Vector2(0,-10f);
public float getX(float n) {
return startVelocity.x * (n * 1/30f) + startPoint.x;
}
public float getY(float n) {
float t = 1/30f * n;
return 0.5f * gravity * t * t + startVelocity.y * t + startPoint.y;
}
}
@Override
public void draw(SpriteBatch batch, float parentAlpha) {
float t = 0f;
float width = this.getWidth();
float height = this.getHeight();
float timeSeparation = this.timeSeparation;
for (int i = 0; i < trajectoryPointCount; i+=timeSeparation) {
//projectileEquation.getTrajectoryPoint(this.getX(), this.getY(), i);
float x = this.getX() + projectileEquation.getX(i);
float y = this.getY() + projectileEquation.getY(i);
batch.setColor(this.getColor());
if(trajectorySprite != null) batch.draw(trajectorySprite, x, y, width, height);
// t += timeSeparation;
}
}
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
if(button==1 || world.showingDialog)return false;
touchPos.set(x, y);
float angle = touchPos.sub(playerCannon.position).angle();
if(angle > 270 ) {
angle = 0;
}
else if(angle >70) {
angle = 70;
}
playerCannon.setAngle(angle);
world.trajPath.controller.angle = angle;
float radians = (float) angle * MathUtils.degreesToRadians;
float ballSpeed = touchPos.sub(playerCannon.position).len()*12;
world.trajPath.projectileEquation.startVelocity.x = (float) (Math.cos(radians) * ballSpeed);
world.trajPath.projectileEquation.startVelocity.y = (float) (Math.sin(radians) * ballSpeed);
return true;
}
public CannonBall(float x, float y, float width, float height, float damage, World world, Cannon cannonOwner) {
super(x, y, width, height, damage, world);
active = false;
shape = new CircleShape();
shape.setRadius(width/2);
FixtureDef fd = new FixtureDef();
fd.shape = shape;
fd.density = 4.5f;
if(cannonOwner.isEnemy) { //Enemy cannon balls cannot hit other enemy cannons just the player
fd.filter.groupIndex = -16;
}
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(this.position);
body = world.createBody(bodyDef);
body.createFixture(fd);
body.setUserData(this);
body.setBullet(true);
this.cannonOwner = cannonOwner;
this.hitByBall = null;
this.particleEffect = null;
}
private CannonBall createCannonBall(float radians, float ballSpeed, float radius, float damage)
{
CannonBall cannonBall = new CannonBall(CannonEnd().x, CannonEnd().y, radius * ballSizeMultiplier, radius * ballSizeMultiplier, damage, this.world, this);
cannonBall.velocity.x = (float) (Math.cos(radians) * ballSpeed);
//cannonBall.velocity.x = (float) ((Math.sqrt(10) * Math.sqrt(29) *
// Math.sqrt((Math.tan(cannon.angle)*Math.tan(cannon.angle))+1)) / Math.sqrt(2 * Math.tan(cannon.angle) - (2 * 10 * 2)/29))* -1f;
cannonBall.velocity.y = (float) (Math.sin(radians) * ballSpeed);
cannonBall.active = true;
//cannonBall.body.applyLinearImpulse(cannonBall.velocity, cannonBall.position);
cannonBall.body.applyForce(cannonBall.velocity, cannonBall.position );
return cannonBall;
}
trajPath = new TrajectoryActor(-10f);
trajPath.setX(playerCannon.CannonEnd().x);
trajPath.setY(playerCannon.CannonEnd().y);
trajPath.setWidth(10f);
trajPath.setHeight(10f);
stage.addActor(trajPath);
【问题讨论】:
-
看看这里。这可能是采用轨迹的更好方法:*.com/a/18702564/1464294
-
我也尝试过这种方法,我认为有些东西与 box2d 不匹配。我在那篇文章中读到,只要起始速度相同,那么无论质量或密度如何,轨迹都应该是正确的,但我的情况不匹配,所以有些事情是不对的。球的半径会改变距离,难道这些方程式没有考虑到这一点?
-
您正在比较两条轨迹。您已经向我们展示了一条轨迹的代码。你如何计算另一个?你确定初始速度和重力是一样的吗?
-
两者都在 touchDown 事件中使用上述方法,使用角度和球速以及一些触发。当改变形状半径时,发射球的轨迹会发生变化,而不是轨迹预测,那么方程是否需要考虑这一点?
-
你确定初始速度和重力是一样的吗?你在哪里设置
gravity?
标签: android box2d libgdx physics