我一直在使用box2d,但遇到一个问题,当我尝试将其放置在屏幕的右下角时,我的身体未设置为正确的y坐标。
我正在尝试将y坐标设置为0,以使主体直接与屏幕底部对齐。但是,身体的一半悬挂在屏幕上。即使我打印出人体的位置,它也表示y为0。
我将每米的像素设置为screenHeight / 80,对于我正在使用的当前设备,结果约为25 PPM。我不确定我的缩放是否会导致某些奇怪的事情发生。
代码:
public class GameScreen extends ScreenAdapter {
Controller game;
public World world;
public Body ball;
public Body block;
public Box2DDebugRenderer box2DDebugRenderer;
private Matrix4 cameraBox2D;
public MyGestureListener myGestureListener;
//x-axis length for top/bottom bar
private float goalWidth;
//pixels per meter
public float PPM;
//y-axis height for back bar
private float goalHeight;
private float goalPostThickness;
//Screen height and width
private float screenWidth;
private float screenHeight;
//How far down/up posts are from edge of screen
private float goalPostTopOffset;
private float goalPostBottomOffset;
//Center x,y of cannon
private float cannonOriginX; //Variables used for starting poisition of balls
private float cannonOriginY;
//Center x,y of ball
float ballX;
float ballY;
//Velocity of ball
public float velocity = 50;
public int colorCode = 1;
//Tracks users drag y coord
public float panLocation = 0;
//Velocity of block once the user releases
public float flingVelocity;
//Changes to true when the block is released
public boolean isReleased = false;
public GameScreen (Controller game){
this.game = game;
}
@Override
public void show(){
myGestureListener = new MyGestureListener(game, this);
cameraBox2D = new Matrix4(game.cam.combined);
screenWidth = game.getScreenWidth();
screenHeight = game.getScreenHeight();
//PPM = screenHeight / 80f;
PPM = screenHeight / 80f;
goalPostTopOffset = screenHeight/7;
goalPostBottomOffset = goalPostTopOffset * 3;
goalHeight = screenHeight - (goalPostTopOffset + goalPostBottomOffset);
goalWidth = screenWidth / 6;
goalPostThickness = screenWidth / 75;
cannonOriginX = goalWidth / 2; //Variables used for starting position of balls
cannonOriginY = (goalPostThickness*5) / 2;
ballX = 0 + cannonOriginX;
ballY = (goalPostBottomOffset - (goalPostBottomOffset / 4)) + cannonOriginY;
world = new World(new Vector2(0, 0f), true);
box2DDebugRenderer = new Box2DDebugRenderer();
//Creates animated ball
ball = createBall();
//Sets radius, density, etc.
setBallProperties(ball);
//Creates block that stops balls
block = createBlock();
//Sets properties
setBlockProperties(block);
}
@Override
public void render(float delta){
//Logic
world.step(1/60f, 6, 2);
//Draw
game.cam.update();
Gdx.gl.glClearColor(32/255f, 32/255f, 32/255f, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
box2DDebugRenderer.render(world, game.cam.combined.scl(PPM));
game.shape.setProjectionMatrix(game.cam.combined);
Gdx.input.setInputProcessor(new GestureDetector(myGestureListener));
System.out.println(block.getPosition().y);
System.out.println(block.getPosition().x);
drawNonAnimated();
drawAnimated();
//show()
cameraBox2D = game.cam.combined.cpy(); //Copy the main camera
cameraBox2D.scl(PPM); //Scale the camera projection to the ratio you're using for Box2D
//render()
box2DDebugRenderer.render(world, cameraBox2D);
}
@Override
public void hide(){
}
//draws stationary objects such as goal posts
public void drawNonAnimated(){
//Cannon platform
game.shape.setColor(1, 1, 1, 1);
game.shape.begin(ShapeRenderer.ShapeType.Filled);
game.shape.rect(0, (goalPostBottomOffset - (goalPostBottomOffset / 4))/PPM, goalWidth/PPM, (goalPostThickness*2)/PPM);
game.shape.end();
//Cannon
game.shape.setColor(1, 1, 1, 1);
game.shape.begin(ShapeRenderer.ShapeType.Filled);
game.shape.rect(0, (goalPostBottomOffset - (goalPostBottomOffset / 4))/PPM, cannonOriginX/PPM,
cannonOriginY/PPM, goalWidth/PPM, (goalPostThickness*5)/PPM, 1, 1, 45);
game.shape.end();
}
public void drawAnimated(){
//FOR BALL
velocity--;
ball.setLinearVelocity(new Vector2(35,velocity));
Vector2 pos = ball.getPosition();
if (pos.x >= screenWidth/PPM){
ball.setTransform(new Vector2(ballX/PPM, ballY/PPM), 0);
//Changing color of ball each loop
if (colorCode == 3){
colorCode = 1;
}
else{
colorCode++;
}
//max 75 min 50
velocity = randInt(50, 75);
}
attachCircleShape(pos);
blockerMovement();
}
public void blockerMovement(){
//FOR BLOCKER RECTANGLE ANIMATION
Vector2 pos = block.getPosition();
float boundaryLocation = (goalPostBottomOffset - (goalPostBottomOffset / 4))/PPM;
//attachBlockerShape(pos);
panLocation = myGestureListener.getPanLocation();
if (isReleased == true){
//Get the velocity as the block is released
//to determine the speed it will continue to go after release
block.setLinearVelocity(0, flingVelocity);
flingVelocity -= 3;
}
else if (myGestureListener.getCheckRelease()|| panLocation/PPM >= boundaryLocation && !isReleased) {
flingVelocity = myGestureListener.speed;
isReleased = true;
System.out.println("SPEED: " + flingVelocity);
}
else if (myGestureListener.isPaning) {
block.setTransform(new Vector2((screenWidth - goalPostThickness) / PPM, panLocation / PPM), 0);
}
}
//Creates animated ball
public Body createBall(){
Body bBody;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.DynamicBody;
def.position.set(ballX/PPM,ballY/PPM);
def.fixedRotation = true;
bBody = world.createBody(def);
return bBody;
}
//Sets radius, density, etc.
public void setBallProperties(Body body){
float gbt = screenWidth / 75; //Goal post thickness
float ballRadius = (gbt * 1.5f) / PPM;
// Create a circle shape and set its radius to 6
CircleShape circle = new CircleShape();
circle.setRadius(ballRadius);
// Create a fixture definition to apply our shape to
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = circle;
fixtureDef.density = 3.5f;
fixtureDef.friction = 0.4f;
fixtureDef.restitution = 0.6f; // Make it bounce a little bit
// Create our fixture and attach it to the body
Fixture fixture = ball.createFixture(fixtureDef);
circle.dispose();
}
public Body createBlock(){
Body bBody;
BodyDef def = new BodyDef();
def.type = BodyDef.BodyType.DynamicBody;
def.position.set((screenWidth - goalPostThickness)/PPM,0);
def.fixedRotation = true;
bBody = world.createBody(def);
return bBody;
}
//Sets radius, density, etc.
public void setBlockProperties(Body body){
float gbt = screenWidth / 75; //Goal post thickness
// Create a circle shape and set its radius to 6
PolygonShape square = new PolygonShape();
square.setAsBox(goalPostThickness/PPM, (goalWidth/2)/PPM);
// Create a fixture definition to apply our shape to
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = square;
fixtureDef.density = 3.5f;
fixtureDef.friction = 0.4f;
fixtureDef.restitution = 0.6f; // Make it bounce a little bit
// Create our fixture and attach it to the body
Fixture fixture = block.createFixture(fixtureDef);
square.dispose();
}
public static int randInt(int min, int max) {
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
public void attachBlockerShape(Vector2 pos){
game.shape.setColor(1, 1, 1, 1);
game.shape.begin(ShapeRenderer.ShapeType.Filled);
game.shape.rect(pos.x, pos.y, goalPostThickness/PPM, (goalWidth/2)/PPM);
game.shape.end();
}
//Attaching a regular libgdx shape to the position of box2d shape
public void attachCircleShape(Vector2 pos){
//Color of ball changes each loop
if (colorCode == 1){
//Blue
game.circle.setColor(66/255f, 134/255f, 244/255f, 0);
}
else if (colorCode == 2){
//Pink
game.circle.setColor(244/255f, 66/255f, 116/255f, 0);
}
else if (colorCode == 3){
game.circle.setColor(244/255f, 116/255f, 66/255f, 0);
}
game.circle.begin(ShapeRenderer.ShapeType.Filled);
game.circle.circle(pos.x*PPM, pos.y*PPM, goalPostThickness * 1.5f);
game.circle.end();
game.cam.update();
}
@Override public void dispose(){
box2DDebugRenderer.dispose();
world.dispose();
}
}
答案 0 :(得分:0)
如果使用Box2d 0,0创建一个Body,则在Body的中心,而libgdx在左下角将其设置为0,0。
因此,如果您使用Box2d创建实体,并且希望0,0位于左下角,则必须将实体在x上移动一半的宽度,在y上移动一半的高度:
public Body createBody(float x, float y, float width, float height){
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
//Move the body so if x and y are 0 the bottom left corner of the body is on position 0,0
bodyDef.position.x = x + width / 2;
bodyDef.position.y = y + height / 2;
PolygonShape polygonShape = new PolygonShape();
polygonShape.setAsBox(width / 2, height / 2);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = polygonShape;
Body body = world.createBody(bodyDef);
body.createFixture(fixtureDef);
polygonShape.dispose();
return body;
}