diff --git a/build.gradle b/build.gradle index c336103..8f083b0 100644 --- a/build.gradle +++ b/build.gradle @@ -46,6 +46,7 @@ project(":desktop") { compile project(":core") compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion" compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" + compile "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop" } } @@ -56,7 +57,9 @@ project(":core") { dependencies { compile "com.badlogicgames.gdx:gdx:$gdxVersion" + compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion" compile "net.dermetfan.libgdx-utils:libgdx-utils:0.13.4" + compile "net.dermetfan.libgdx-utils:libgdx-utils-box2d:0.13.4" } } diff --git a/core/src/com/me/brickbuster/entity/Ball.java b/core/src/com/me/brickbuster/entity/Ball.java index 662fc56..abf8041 100644 --- a/core/src/com/me/brickbuster/entity/Ball.java +++ b/core/src/com/me/brickbuster/entity/Ball.java @@ -6,19 +6,18 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; -import com.me.brickbuster.BrickBuster; -import com.me.brickbuster.Utils; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.CircleShape; +import com.badlogic.gdx.physics.box2d.FixtureDef; import com.me.brickbuster.state.PlayState; -import net.dermetfan.utils.Pair; -import java.util.Iterator; +public class Ball extends Entity implements PhysicsBody { -public class Ball extends Entity { - - public static final int RADIUS = 45; + public static final float RADIUS = 1.2f; public static final Color BALL_COLOR = Color.CHARTREUSE; - public static final float DEFAULT_SPEED = 1800; - public static final float BOOST_SPEED = 2200; + public static final float DEFAULT_SPEED = 45; + public static final float BOOST_SPEED = 55; public static final int BLOCKS_FOR_BOOST = 39; public Vector2 direction; @@ -26,16 +25,38 @@ public class Ball extends Entity { private boolean isStuck = true; private boolean isDead = false; + private Body body; + public Ball(PlayState state) { - super(state,BrickBuster.BOARD_WIDTH /2, state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS); + super(state,PlayState.BOARD_WIDTH/2, state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS); this.speed = state.bricks.size() > BLOCKS_FOR_BOOST? DEFAULT_SPEED : BOOST_SPEED; + + BodyDef ballBody = new BodyDef(); + ballBody.type = BodyDef.BodyType.DynamicBody; + ballBody.position.set(pos); + + CircleShape ballShape = new CircleShape(); + ballShape.setRadius(RADIUS); + + FixtureDef ballFixture = new FixtureDef(); + ballFixture.shape = ballShape; + ballFixture.restitution = 1f; + ballFixture.friction = 0f; + + body = state.world.createBody(ballBody); + body.createFixture(ballFixture); + body.setUserData(this); + + ballShape.dispose(); } @Override public void render(ShapeRenderer sr) { sr.begin(ShapeType.Filled); sr.setColor(BALL_COLOR); - sr.circle(pos.x, pos.y, RADIUS); + sr.circle(pos.x * PlayState.PIXEL_PER_METER, + pos.y * PlayState.PIXEL_PER_METER, + RADIUS * PlayState.PIXEL_PER_METER); sr.end(); } @@ -49,55 +70,60 @@ public class Ball extends Entity { } } - Vector2 new_pos = pos.cpy().add(direction.cpy().scl(speed * dt)); +// Vector2 new_pos = pos.cpy().add(direction.cpy().scl(speed * dt)); +// +// boolean brickCollision = false; +// Iterator brickIterator = state.bricks.iterator(); +// while (!brickCollision && brickIterator.hasNext()) { +// Brick brick = brickIterator.next(); +// Vector2[] vertices = brick.getVertices(); +// for(int i = 0; i < vertices.length; i++) { +// Vector2 v1 = vertices[i]; +// Vector2 v2 = vertices[i+1 < vertices.length? i+1 : 0]; +// Vector2 segment = v2.cpy().sub(v1); +// Vector2 nearest = Utils.nearestPoint(v1.cpy(), segment, new_pos.cpy()); +// +// if (nearest.dst(new_pos.x, new_pos.y) <= RADIUS) { +// if (brick.hit()) { +// brickIterator.remove(); +// } +// Utils.reflect(direction, segment.nor()); +// brickCollision = true; +// break; +// } +// } +// } +// +// if (new_pos.x + RADIUS > BrickBuster.BOARD_WIDTH || new_pos.x - RADIUS < 0) { +// Utils.reflect(direction, Utils.VERTICAL_EDGE); +// } else if (new_pos.y + RADIUS > BrickBuster.BOARD_HEIGHT) { +// Utils.reflect(direction, Utils.HORIZONTAL_EDGE); +// } else if (state.getShieldCount() > 0 +// && new_pos.y - RADIUS < PlayState.SHIELD_HEIGHT * state.getShieldCount()) { +// Utils.reflect(direction, Utils.HORIZONTAL_EDGE); +// state.removeShield(); +// } else if (new_pos.y + RADIUS < 0) { +// isDead = true; +// return; +// } else if (direction.y < 0 && new_pos.y <= state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS) { +// Pair paddle = state.paddle.getTopEdge(); +// Vector2 lineDir = paddle.getValue().sub(paddle.getKey()); +// Vector2 nearest = Utils.nearestPoint(paddle.getKey().cpy(), lineDir, new_pos.cpy()); +// +// if (nearest.dst(new_pos.x, new_pos.y) <= RADIUS) { +// paddleCollision(); +// if (state.paddle.isSticky()) { +// return; +// } +// } +// } +// +// pos.add(direction.cpy().scl(speed * dt)); + } - boolean brickCollision = false; - Iterator brickIterator = state.bricks.iterator(); - while (!brickCollision && brickIterator.hasNext()) { - Brick brick = brickIterator.next(); - Vector2[] vertices = brick.getVertices(); - for(int i = 0; i < vertices.length; i++) { - Vector2 v1 = vertices[i]; - Vector2 v2 = vertices[i+1 < vertices.length? i+1 : 0]; - Vector2 segment = v2.cpy().sub(v1); - Vector2 nearest = Utils.nearestPoint(v1.cpy(), segment, new_pos.cpy()); - - if (nearest.dst(new_pos.x, new_pos.y) <= RADIUS) { - if (brick.hit()) { - brickIterator.remove(); - } - Utils.reflect(direction, segment.nor()); - brickCollision = true; - break; - } - } - } - - if (new_pos.x + RADIUS > BrickBuster.BOARD_WIDTH || new_pos.x - RADIUS < 0) { - Utils.reflect(direction, Utils.VERTICAL_EDGE); - } else if (new_pos.y + RADIUS > BrickBuster.BOARD_HEIGHT) { - Utils.reflect(direction, Utils.HORIZONTAL_EDGE); - } else if (state.getShieldCount() > 0 - && new_pos.y - RADIUS < PlayState.SHIELD_HEIGHT * state.getShieldCount()) { - Utils.reflect(direction, Utils.HORIZONTAL_EDGE); - state.removeShield(); - } else if (new_pos.y + RADIUS < 0) { - isDead = true; - return; - } else if (direction.y < 0 && new_pos.y <= state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS) { - Pair paddle = state.paddle.getTopEdge(); - Vector2 lineDir = paddle.getValue().sub(paddle.getKey()); - Vector2 nearest = Utils.nearestPoint(paddle.getKey().cpy(), lineDir, new_pos.cpy()); - - if (nearest.dst(new_pos.x, new_pos.y) <= RADIUS) { - paddleCollision(); - if (state.paddle.isSticky()) { - return; - } - } - } - - pos.add(direction.cpy().scl(speed * dt)); + @Override + public Body getBody() { + return body; } public Vector2 paddleReflectAngle() { @@ -115,7 +141,12 @@ public class Ball extends Entity { // launch at random angle between 135 and 45 degrees float angle = MathUtils.random(MathUtils.PI/2) + MathUtils.PI/4; direction = new Vector2(MathUtils.cos(angle), MathUtils.sin(angle)); + } + //body.applyForceToCenter(new Vector2(0,Float.MAX_VALUE/2), true); + //body.setLinearVelocity(new Vector2(0,10000000)); + body.setLinearVelocity(direction.cpy().scl(speed)); + body.setBullet(true); isStuck = false; } diff --git a/core/src/com/me/brickbuster/entity/Brick.java b/core/src/com/me/brickbuster/entity/Brick.java index 504a569..98fb682 100644 --- a/core/src/com/me/brickbuster/entity/Brick.java +++ b/core/src/com/me/brickbuster/entity/Brick.java @@ -4,29 +4,35 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.FixtureDef; +import com.badlogic.gdx.physics.box2d.PolygonShape; import com.me.brickbuster.entity.powerup.PowerUpType; import com.me.brickbuster.state.PlayState; -public class Brick extends Entity { +public class Brick extends Entity implements PhysicsBody { public static final Color DEFAULT_COLOR = Color.FOREST; - public static final int BRICK_WIDTH = 200; - public static final int BRICK_HEIGHT = 100; + public static final float BRICK_WIDTH = 5f; + public static final float BRICK_HEIGHT = 2.5f; private PowerUpType powerUpType; private Color color; private Vector2[] vertices; - public Brick(PlayState state, PowerUpType powerUpType, int x, int y) { + private Body body; + + public Brick(PlayState state, PowerUpType powerUpType, float x, float y) { this(state, powerUpType, true, x, y); } - public Brick(PlayState state, PowerUpType powerUpType, boolean hidePowerup, int x, int y) { + public Brick(PlayState state, PowerUpType powerUpType, boolean hidePowerup, float x, float y) { this(state, powerUpType, DEFAULT_COLOR, hidePowerup, x, y); } - public Brick(PlayState state, PowerUpType powerUpType, Color color, boolean hidePowerUp, int x, int y) { + public Brick(PlayState state, PowerUpType powerUpType, Color color, boolean hidePowerUp, float x, float y) { super(state, x, y); this.powerUpType = powerUpType; this.color = powerUpType != null && !hidePowerUp? powerUpType.getColor() : color; @@ -36,13 +42,34 @@ public class Brick extends Entity { new Vector2(x + BRICK_WIDTH, y + BRICK_HEIGHT), new Vector2(x, y + BRICK_HEIGHT) }; + + BodyDef brickBody = new BodyDef(); + brickBody.type = BodyDef.BodyType.StaticBody; + brickBody.position.set(pos.cpy()); + + PolygonShape brickShape = new PolygonShape(); + brickShape.setAsBox(BRICK_WIDTH/2, BRICK_HEIGHT/2, + new Vector2(BRICK_WIDTH/2,BRICK_HEIGHT/2), 0); + + FixtureDef brickFixture = new FixtureDef(); + brickFixture.shape = brickShape; + brickFixture.friction = 0f; + + body = state.world.createBody(brickBody); + body.createFixture(brickFixture); + body.setUserData(this); + + brickShape.dispose(); } @Override public void render(ShapeRenderer sr) { sr.begin(ShapeType.Filled); sr.setColor(color); - sr.rect(getX(), getY(), BRICK_WIDTH, BRICK_HEIGHT); + sr.rect(getX()*PlayState.PIXEL_PER_METER, + getY()*PlayState.PIXEL_PER_METER, + BRICK_WIDTH*PlayState.PIXEL_PER_METER, + BRICK_HEIGHT*PlayState.PIXEL_PER_METER); sr.end(); } @@ -50,6 +77,11 @@ public class Brick extends Entity { public void update(float dt) { } + @Override + public Body getBody() { + return body; + } + public boolean hit() { if (state.bricks.size()-1 <= Ball.BLOCKS_FOR_BOOST) { for (Ball ball : state.balls) { diff --git a/core/src/com/me/brickbuster/entity/Paddle.java b/core/src/com/me/brickbuster/entity/Paddle.java index 65b12fb..05e8bf1 100644 --- a/core/src/com/me/brickbuster/entity/Paddle.java +++ b/core/src/com/me/brickbuster/entity/Paddle.java @@ -6,31 +6,58 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Vector2; -import com.me.brickbuster.BrickBuster; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.EdgeShape; +import com.badlogic.gdx.physics.box2d.FixtureDef; import com.me.brickbuster.state.PlayState; import net.dermetfan.utils.Pair; -public class Paddle extends Entity { +public class Paddle extends Entity implements PhysicsBody { public static final Color STICKY_COLOR = Color.GRAY; public static final Color PADDLE_COLOR = Color.BLACK; - public static final int DEFAULT_WIDTH = 300; - public static final int PADDLE_HEIGHT = 30; - public static final int PADDLE_Y = 50; - public static final int PADDLE_SPEED = 1500; - private int width = DEFAULT_WIDTH; + public static final float DEFAULT_WIDTH = 7.5f; + public static final float PADDLE_HEIGHT = 0.75f; + public static final float PADDLE_Y = 1.25f; + public static final float PADDLE_SPEED = 40f; + + private float width = DEFAULT_WIDTH; private boolean sticky = false; + private Body body; + public Paddle(PlayState brickBuster) { - super(brickBuster, BrickBuster.BOARD_WIDTH / 2, PADDLE_Y); + super(brickBuster, PlayState.BOARD_WIDTH/2, PADDLE_Y); + + BodyDef paddleBody = new BodyDef(); + paddleBody.type = BodyDef.BodyType.KinematicBody; + paddleBody.position.set(pos); + + EdgeShape paddleShape = new EdgeShape(); + paddleShape.set(new Vector2(-DEFAULT_WIDTH/2,PADDLE_HEIGHT), + new Vector2(DEFAULT_WIDTH/2, PADDLE_HEIGHT)); + + FixtureDef paddleFixture = new FixtureDef(); + paddleFixture.shape = paddleShape; + paddleFixture.isSensor = true; + + body = state.world.createBody(paddleBody); + body.createFixture(paddleFixture); + body.setUserData(this); + + paddleShape.dispose(); } @Override public void render(ShapeRenderer sr) { sr.begin(ShapeType.Filled); sr.setColor(sticky? STICKY_COLOR : PADDLE_COLOR); - sr.rect(getX() - width/2, getY(), width, PADDLE_HEIGHT); + sr.rect((getX() - width/2) * PlayState.PIXEL_PER_METER, + getY() * PlayState.PIXEL_PER_METER, + width * PlayState.PIXEL_PER_METER, + PADDLE_HEIGHT * PlayState.PIXEL_PER_METER); sr.end(); } @@ -50,8 +77,8 @@ public class Paddle extends Entity { } } if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { - if (pos.x + width/2 + PADDLE_SPEED * dt > BrickBuster.BOARD_WIDTH) { - setX(BrickBuster.BOARD_WIDTH - width/2); + if (pos.x + width/2 + PADDLE_SPEED * dt > PlayState.BOARD_WIDTH) { + setX(PlayState.BOARD_WIDTH - width/2); return; } pos.x = pos.x + PADDLE_SPEED * dt; @@ -64,6 +91,11 @@ public class Paddle extends Entity { } } + @Override + public Body getBody() { + return body; + } + public Pair getTopEdge() { return new Pair( new Vector2(pos.x - width/2, pos.y + PADDLE_HEIGHT), @@ -71,11 +103,11 @@ public class Paddle extends Entity { ); } - public int getWidth() { + public float getWidth() { return width; } - public void setWidth(int width) { + public void setWidth(float width) { this.width = width; } diff --git a/core/src/com/me/brickbuster/entity/PhysicsBody.java b/core/src/com/me/brickbuster/entity/PhysicsBody.java new file mode 100644 index 0000000..bab3c0a --- /dev/null +++ b/core/src/com/me/brickbuster/entity/PhysicsBody.java @@ -0,0 +1,11 @@ +package com.me.brickbuster.entity; + +import com.badlogic.gdx.physics.box2d.Body; + +public interface PhysicsBody { + + Body getBody(); + + //public void handleCollission(Entity other); + +} diff --git a/core/src/com/me/brickbuster/entity/powerup/PowerUp.java b/core/src/com/me/brickbuster/entity/powerup/PowerUp.java index ac1aaba..b98d672 100644 --- a/core/src/com/me/brickbuster/entity/powerup/PowerUp.java +++ b/core/src/com/me/brickbuster/entity/powerup/PowerUp.java @@ -4,29 +4,55 @@ import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.Body; +import com.badlogic.gdx.physics.box2d.BodyDef; +import com.badlogic.gdx.physics.box2d.CircleShape; +import com.badlogic.gdx.physics.box2d.FixtureDef; import com.me.brickbuster.Utils; import com.me.brickbuster.entity.Entity; +import com.me.brickbuster.entity.PhysicsBody; import com.me.brickbuster.state.PlayState; import net.dermetfan.utils.Pair; -public abstract class PowerUp extends Entity { +public abstract class PowerUp extends Entity implements PhysicsBody { - public static final int RADIUS = 45; - public static final int FALL_SPEED = 600; + public static final float RADIUS = 1.2f; + public static final float FALL_SPEED = 15f; private Color color; private boolean isCaught; + private Body body; + public PowerUp(PlayState state, Vector2 pos, Color color) { super(state, pos); this.color = color; + + BodyDef ballBody = new BodyDef(); + ballBody.type = BodyDef.BodyType.DynamicBody; + ballBody.position.set(pos); + + CircleShape ballShape = new CircleShape(); + ballShape.setRadius(RADIUS); + + FixtureDef ballFixture = new FixtureDef(); + ballFixture.shape = ballShape; + ballFixture.isSensor = true; + + body = state.world.createBody(ballBody); + body.createFixture(ballFixture); + body.setUserData(this); + + ballShape.dispose(); } @Override public void render(ShapeRenderer sr) { sr.begin(ShapeType.Filled); sr.setColor(color); - sr.circle(getX(), getY(), RADIUS); + sr.circle(getX() * PlayState.PIXEL_PER_METER, + getY() * PlayState.PIXEL_PER_METER, + RADIUS * PlayState.PIXEL_PER_METER); sr.end(); } @@ -48,6 +74,11 @@ public abstract class PowerUp extends Entity { } } + @Override + public Body getBody() { + return body; + } + public abstract void activate(); public boolean isCaught() { diff --git a/core/src/com/me/brickbuster/state/PlayState.java b/core/src/com/me/brickbuster/state/PlayState.java index ba58657..af2d2e9 100644 --- a/core/src/com/me/brickbuster/state/PlayState.java +++ b/core/src/com/me/brickbuster/state/PlayState.java @@ -4,6 +4,8 @@ import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.math.MathUtils; +import com.badlogic.gdx.math.Vector2; +import com.badlogic.gdx.physics.box2d.*; import com.me.brickbuster.BrickBuster; import com.me.brickbuster.entity.Ball; import com.me.brickbuster.entity.Brick; @@ -14,12 +16,30 @@ import java.util.*; public class PlayState extends State { - public static final int SHIELD_HEIGHT = 30; + public static final float PIXEL_PER_METER = 40f; // Board dimension: 54x96 meters + public static final float BOARD_WIDTH = 54f; + public static final float BOARD_HEIGHT = 96f; + public static final float EDGE_PADDING = .125f; + + + public static final float SHIELD_HEIGHT = 0.75f; public static final float POWERUP_CHANCE = 0.15f; public static final int COLUMNS = 9; public static final int ROWS = 8; + public static final Vector2 lowerLeftCorner = + new Vector2(EDGE_PADDING,EDGE_PADDING); + public static final Vector2 lowerRightCorner = + new Vector2(BrickBuster.BOARD_WIDTH/PIXEL_PER_METER-EDGE_PADDING,EDGE_PADDING); + public static final Vector2 upperRightCorner = + new Vector2(BrickBuster.BOARD_WIDTH/PIXEL_PER_METER-EDGE_PADDING, BrickBuster.BOARD_HEIGHT/PIXEL_PER_METER-EDGE_PADDING); + public static final Vector2 upperLeftCorner = + new Vector2(EDGE_PADDING, BrickBuster.BOARD_HEIGHT/PIXEL_PER_METER-EDGE_PADDING); + + public World world; + public Body playArea; + public List powerUps; public Paddle paddle; public List balls; @@ -28,28 +48,54 @@ public class PlayState extends State { private int shieldCount = 0; private float updateTime = 0f; + private final Box2DDebugRenderer debugRenderer; + public PlayState(BrickBuster game) { super(game); + debugRenderer = new Box2DDebugRenderer(); } @Override public void setup() { + // Initialize a world with no gravity + world = new World(new Vector2(), false); + + // define a playArea body with position set to 0 + BodyDef playAreaDef = new BodyDef(); + playAreaDef.position.set(new Vector2()); + EdgeShape screenEdge = new EdgeShape(); + + playArea = world.createBody(playAreaDef); + // Right edge + screenEdge.set(lowerRightCorner, upperRightCorner); + playArea.createFixture(screenEdge, 0f); + // Top edge + screenEdge.set(upperRightCorner, upperLeftCorner); + playArea.createFixture(screenEdge, 0f); + // Left edge + screenEdge.set(upperLeftCorner, lowerLeftCorner); + playArea.createFixture(screenEdge, 0f); + // Bottom edge + screenEdge.set(lowerLeftCorner, lowerRightCorner); + playArea.createFixture(screenEdge, 0f); + screenEdge.dispose(); + powerUps = new ArrayList(); paddle = new Paddle(this); - int brick_padding = (BrickBuster.BOARD_WIDTH - COLUMNS * Brick.BRICK_WIDTH) / (COLUMNS + 1); + float brick_padding = ((BrickBuster.BOARD_WIDTH/PIXEL_PER_METER) - COLUMNS * Brick.BRICK_WIDTH) / (COLUMNS + 1); bricks = new ArrayList(); for (int col = 0; col < COLUMNS; col++) { for (int row = 0; row < ROWS; row++) { - int x = brick_padding + (col * (Brick.BRICK_WIDTH + brick_padding)); - int y = brick_padding + Brick.BRICK_HEIGHT + (row * (Brick.BRICK_HEIGHT + brick_padding)); + float x = brick_padding + (col * (Brick.BRICK_WIDTH + brick_padding)); + float y = brick_padding + Brick.BRICK_HEIGHT + (row * (Brick.BRICK_HEIGHT + brick_padding)); PowerUpType powerUpType = null; if (MathUtils.randomBoolean(POWERUP_CHANCE)) { powerUpType = PowerUpType.getWeightedRandom(); } - bricks.add(new Brick(this, powerUpType, x, BrickBuster.BOARD_HEIGHT - y)); + bricks.add(new Brick(this, powerUpType, x, BrickBuster.BOARD_HEIGHT/PIXEL_PER_METER - y)); } } @@ -84,11 +130,15 @@ public class PlayState extends State { game.font.draw(game.sb, String.format("FPS: %d Update: %.2f ms Render: %.2f ms", Gdx.graphics.getFramesPerSecond(), updateTime/1000000f, renderTime/1000000f), 10, BrickBuster.BOARD_HEIGHT-10); game.sb.end(); + + debugRenderer.render(world, game.cam.combined.cpy().scl(PIXEL_PER_METER)); } @Override public void update(float dt) { long start = System.nanoTime(); + world.step(dt, 6, 2); + paddle.update(dt); for (Iterator it = balls.iterator(); it.hasNext();) {