我正在研究什么是我的主要项目,它是一个自上而下的2d太空射击游戏。我正在使用Box2D动态主体和Libgdx库。
在我释放数学技能之前,这似乎是一个好主意!
我对机芯有问题,基本上我想要的是W加速,A和D旋转,S减速或制动,如果这是空间思考。
现在第一个障碍是试图通过按W来让船朝着它面向的方向移动,成功!现在无论你面对什么样的方式,W都会让你朝着这个方向前进。
现在出现了问题,我按下W并且我的船开始通过施加冲动加速,好,现在当我按下A或D旋转身体并在握住W时改变角度时,它只是继续向那个方向飞行除非我释放W并压制。现在这确实改变了方向但是我必须坐下来等待,这取决于冲击速度以抵消当前速度并实际开始直接加速。
我真正希望它做的是用W加速,任何时候我按A和D,它应该计算新的标题并开始去那里,但我似乎无法搞清楚。这是我的代码:
输入处理器(播放器):
public void update(float delta) {
currentShip.shipAngle = currentShip.getBody().getAngle();
// move the ship
currentShip.getBody().applyForceToCenter(currentShip.getVelocity(), true);
// Turn the ship
currentShip.getBody().applyTorque(currentShip.steeringTorque, true);
}
@Override
public boolean keyDown(int keycode) {
switch (keycode) {
case Keys.D:
if (currentShip.getEngine() != null) {
currentShip.steeringTorque = -1f;
break;
} else {
System.out.println("No engine fitted!");
break;
}
case Keys.A:
if (currentShip.getEngine() != null) {
currentShip.steeringTorque = 1f;
break;
} else {
System.out.println("No engine fitted!");
break;
}
case Keys.W:
if (currentShip.getEngine() != null) {
currentShip.velocity.x = MathUtils
.cos(currentShip.shipAngle)
* currentShip.getEngine().getAccelleration().x;
currentShip.velocity.y = MathUtils
.sin(currentShip.shipAngle)
* currentShip.getEngine().getAccelleration().x;
break;
} else {
System.out.println("No engine fitted!");
break;
}
case Keys.S:
if (currentShip.getEngine() != null) {
break;
} else {
System.out.println("No engine fitted!");
break;
}
case Keys.B:
currentShip.shipAngle = 0;
currentShip.getBody().setLinearVelocity(0, 0);
break;
case Keys.SPACE:
if (currentShip.getEngine() != null) {
System.out.println("Already have an engine fitted!");
break;
} else {
Ship.addModule(new Engine(new Vector2(10, 10f), 10));
System.out.println("Engine fitted!");
break;
}
}
return false;
}
我不认为这是相关的,但这是引擎类:
public class Engine extends Module{
public Vector2 accelleration = new Vector2();
public Vector2 decelleration = new Vector2();
public float maxSpeed;
/**
*
* @param accelleration - The max accelleration this engine can supply
* @param maxSpeed - The max terminal velocity that this engine can have
*/
public Engine(Vector2 accelleration, float maxSpeed){
this.accelleration = accelleration;
this.maxSpeed = maxSpeed;
}
public Vector2 getAccelleration() {
return accelleration;
}
public void setAccelleration(Vector2 accelleration) {
this.accelleration = accelleration;
}
public void setMaxSpeed(float maxSpeed) {
this.maxSpeed = maxSpeed;
}
}
这是我的船的Box2D属性:
this.width = 70;
this.height = 30;
// Setup ships model
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(position);
body = world.createBody(bodyDef);
chassis.setAsBox(width / GameScreen.WORLD_TO_BOX_WIDTH, height / GameScreen.WORLD_TO_BOX_HEIGHT);
fixtureDef.shape = chassis;
fixtureDef.friction = 0.225f;
fixtureDef.density = 0.85f;
fixture = body.createFixture(fixtureDef);
sprite = new Sprite(new Texture(Gdx.files.internal("img/TestShip.png")));
body.setUserData(sprite);
chassis.dispose();
tl; dr我按A或D时需要计算新角度,然后在不释放W键的情况下改变船舶移动的方向。
答案 0 :(得分:2)
当您按下A / W键时,您将直接设置身体的速度。我认为你应该向它施加力量,使它朝着你想要的方向前进。这是一个物理模拟,如果你想将它限制在你的身体可以行进的最大速度,你应该只是直接设置速度。或者当你希望身体只沿某个方向移动时(例如导弹)重新分配速度(速度)。
我也玩二维空间模拟。其中一个,我正在创造一个朝着用户想要的方向移动的导弹。在这种情况下,他们通过将手指放在屏幕上来做这件事(这是一款iPad游戏)。
至少有两种方法可以做到这一点。
他们的行动和工作方式都有权衡。最大的折衷是当你从一个地方移动到另一个地方时,在(1)中,你将永远向前移动,这看起来正如人们在想到太空船(向前移动)时所想到的那样。您也可以尝试将其用于车辆控制,但是您必须取消侧面作用力(我做过)或者运动有点时髦且难以控制。
在(2)中,身体转向面向它朝向的方向,这更像是我感觉人们朝着某个位置移动的方式。此外,(2)允许你在拍摄时让身体向后移动等。所以它对角色控制器更有用。
在这两种情况下,我发现这样做的简单方法是有一个“点”,你希望角色向前移动,并将扭矩和推力施加到身体上以使其朝向该点移动。我有两种不同类型的字符(c ++类),一种像(1)一样移动,另一种像(2)一样移动。
我在post中给出了(2)的部分答案 有一个完整的代码库(C ++)和位于here的演示视频。它位于Cocos2d-x中,但代码评论很好,网站上有帖子显示类的结构等。
这有用吗?