Compare commits
3 Commits
fe2c68d39a
...
e4000998cc
Author | SHA1 | Date | |
---|---|---|---|
e4000998cc | |||
92201411b9 | |||
0994289c7e |
@ -46,6 +46,7 @@ project(":desktop") {
|
|||||||
compile project(":core")
|
compile project(":core")
|
||||||
compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
|
compile "com.badlogicgames.gdx:gdx-backend-lwjgl:$gdxVersion"
|
||||||
compile "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
|
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 {
|
dependencies {
|
||||||
compile "com.badlogicgames.gdx:gdx:$gdxVersion"
|
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:0.13.4"
|
||||||
|
compile "net.dermetfan.libgdx-utils:libgdx-utils-box2d:0.13.4"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,102 +6,108 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.me.brickbuster.BrickBuster;
|
import com.badlogic.gdx.physics.box2d.Body;
|
||||||
import com.me.brickbuster.Utils;
|
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.physics.CollisionListener;
|
||||||
|
import com.me.brickbuster.physics.PhysicsBody;
|
||||||
import com.me.brickbuster.state.PlayState;
|
import com.me.brickbuster.state.PlayState;
|
||||||
import net.dermetfan.utils.Pair;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
public class Ball extends Entity implements PhysicsBody, CollisionListener {
|
||||||
|
|
||||||
public class Ball extends Entity {
|
public static final float RADIUS = 1.2f;
|
||||||
|
|
||||||
public static final int RADIUS = 45;
|
|
||||||
public static final Color BALL_COLOR = Color.CHARTREUSE;
|
public static final Color BALL_COLOR = Color.CHARTREUSE;
|
||||||
public static final float DEFAULT_SPEED = 1800;
|
public static final float DEFAULT_SPEED = 45;
|
||||||
public static final float BOOST_SPEED = 2200;
|
public static final float BOOST_SPEED = 55;
|
||||||
public static final int BLOCKS_FOR_BOOST = 39;
|
public static final int BLOCKS_FOR_BOOST = 39;
|
||||||
|
|
||||||
public Vector2 direction;
|
|
||||||
private float speed;
|
private float speed;
|
||||||
private boolean isStuck = true;
|
private boolean isStuck = true;
|
||||||
private boolean isDead = false;
|
private boolean touchedPaddle = false;
|
||||||
|
|
||||||
|
private Body body;
|
||||||
|
|
||||||
public Ball(PlayState state) {
|
public Ball(PlayState state) {
|
||||||
super(state,BrickBuster.BOARD_WIDTH /2, state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS);
|
super(state, state.paddle.getX(), state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS);
|
||||||
this.speed = state.bricks.size() > BLOCKS_FOR_BOOST? DEFAULT_SPEED : BOOST_SPEED;
|
this.speed = state.bricks.size() > BLOCKS_FOR_BOOST? DEFAULT_SPEED : BOOST_SPEED;
|
||||||
|
createBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ShapeRenderer sr) {
|
public void render(ShapeRenderer sr) {
|
||||||
sr.begin(ShapeType.Filled);
|
sr.begin(ShapeType.Filled);
|
||||||
sr.setColor(BALL_COLOR);
|
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();
|
sr.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dt) {
|
public void update(float dt) {
|
||||||
if (isStuck || isDead) {
|
if (isStuck || deleted) {
|
||||||
if (!isDead && Gdx.input.justTouched()) {
|
if (!deleted && Gdx.input.justTouched()) {
|
||||||
launch();
|
launch();
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (touchedPaddle) {
|
||||||
Vector2 new_pos = pos.cpy().add(direction.cpy().scl(speed * dt));
|
|
||||||
|
|
||||||
boolean brickCollision = false;
|
|
||||||
Iterator<Brick> 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<Vector2, Vector2> 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();
|
paddleCollision();
|
||||||
if (state.paddle.isSticky()) {
|
touchedPaddle = false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getY() + RADIUS < 0) {
|
||||||
|
deleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.setLinearVelocity(body.getLinearVelocity().nor().scl(speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Body getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createBody() {
|
||||||
|
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 beginContact(Entity contacted) {
|
||||||
|
if (contacted instanceof Shield) {
|
||||||
|
contacted.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contacted instanceof Paddle && !isStuck) {
|
||||||
|
touchedPaddle = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pos.add(direction.cpy().scl(speed * dt));
|
@Override
|
||||||
|
public void endContact(Entity contacted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 paddleReflectAngle() {
|
public Vector2 paddleReflectAngle() {
|
||||||
int trim = (int) (state.paddle.getWidth() * 0.10);
|
float trim = state.paddle.getWidth() * 0.10f;
|
||||||
float rel = MathUtils.clamp((pos.x - state.paddle.getX()) + (state.paddle.getWidth()/2),
|
float rel = MathUtils.clamp((pos.x - state.paddle.getX()) + (state.paddle.getWidth()/2),
|
||||||
trim, state.paddle.getWidth()-trim);
|
trim, state.paddle.getWidth()-trim);
|
||||||
float newAngle = MathUtils.PI - (MathUtils.PI * (rel / state.paddle.getWidth()));
|
float newAngle = MathUtils.PI - (MathUtils.PI * (rel / state.paddle.getWidth()));
|
||||||
@ -109,23 +115,43 @@ public class Ball extends Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void launch() {
|
public void launch() {
|
||||||
|
Vector2 direction;
|
||||||
if (state.paddle.isSticky()) {
|
if (state.paddle.isSticky()) {
|
||||||
direction = paddleReflectAngle();
|
direction = paddleReflectAngle();
|
||||||
} else {
|
} else {
|
||||||
// launch at random angle between 135 and 45 degrees
|
// launch at random angle between 135 and 45 degrees
|
||||||
float angle = MathUtils.random(MathUtils.PI/2) + MathUtils.PI/4;
|
float angle = MathUtils.random(MathUtils.PI/2) + MathUtils.PI/4;
|
||||||
direction = new Vector2(MathUtils.cos(angle), MathUtils.sin(angle));
|
direction = new Vector2(MathUtils.cos(angle), MathUtils.sin(angle));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
body.setLinearVelocity(direction.scl(speed));
|
||||||
isStuck = false;
|
isStuck = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void paddleCollision() {
|
public void paddleCollision() {
|
||||||
if (state.paddle.isSticky()) {
|
if (state.paddle.isSticky()) {
|
||||||
isStuck = true;
|
isStuck = true;
|
||||||
pos.y = state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS;
|
body.setLinearVelocity(new Vector2());
|
||||||
|
setY(state.paddle.getY() + Paddle.PADDLE_HEIGHT + RADIUS);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
direction = paddleReflectAngle();
|
body.setLinearVelocity(paddleReflectAngle().scl(speed));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setX(float x) {
|
||||||
|
super.setX(x);
|
||||||
|
Vector2 bodyPos = body.getPosition();
|
||||||
|
bodyPos.x = x;
|
||||||
|
body.setTransform(bodyPos, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setY(float y) {
|
||||||
|
super.setY(y);
|
||||||
|
Vector2 bodyPos = body.getPosition();
|
||||||
|
bodyPos.y = y;
|
||||||
|
body.setTransform(bodyPos, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSpeed(float speed) {
|
public void setSpeed(float speed) {
|
||||||
@ -136,15 +162,4 @@ public class Ball extends Entity {
|
|||||||
return isStuck;
|
return isStuck;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDead() {
|
|
||||||
return isDead;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDirection(Vector2 direction) {
|
|
||||||
this.direction = direction;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStuck(boolean stuck) {
|
|
||||||
isStuck = stuck;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,50 +4,96 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
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.entity.powerup.PowerUpType;
|
||||||
|
import com.me.brickbuster.physics.CollisionListener;
|
||||||
|
import com.me.brickbuster.physics.PhysicsBody;
|
||||||
import com.me.brickbuster.state.PlayState;
|
import com.me.brickbuster.state.PlayState;
|
||||||
|
|
||||||
public class Brick extends Entity {
|
public class Brick extends Entity implements PhysicsBody, CollisionListener {
|
||||||
|
|
||||||
public static final Color DEFAULT_COLOR = Color.FOREST;
|
public static final Color DEFAULT_COLOR = Color.FOREST;
|
||||||
public static final int BRICK_WIDTH = 200;
|
public static final float BRICK_WIDTH = 5f;
|
||||||
public static final int BRICK_HEIGHT = 100;
|
public static final float BRICK_HEIGHT = 2.5f;
|
||||||
|
|
||||||
private PowerUpType powerUpType;
|
private PowerUpType powerUpType;
|
||||||
private Color color;
|
private Color color;
|
||||||
|
|
||||||
private Vector2[] vertices;
|
private Body body;
|
||||||
|
private boolean hitByBall = false;
|
||||||
|
|
||||||
public Brick(PlayState state, PowerUpType powerUpType, int x, int y) {
|
public Brick(PlayState state, PowerUpType powerUpType, float x, float y) {
|
||||||
this(state, powerUpType, true, x, 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);
|
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);
|
super(state, x, y);
|
||||||
this.powerUpType = powerUpType;
|
this.powerUpType = powerUpType;
|
||||||
this.color = powerUpType != null && !hidePowerUp? powerUpType.getColor() : color;
|
this.color = powerUpType != null && !hidePowerUp? powerUpType.getColor() : color;
|
||||||
this.vertices = new Vector2[] {
|
createBody();
|
||||||
new Vector2(x, y),
|
|
||||||
new Vector2(x + BRICK_WIDTH, y),
|
|
||||||
new Vector2(x + BRICK_WIDTH, y + BRICK_HEIGHT),
|
|
||||||
new Vector2(x, y + BRICK_HEIGHT)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ShapeRenderer sr) {
|
public void render(ShapeRenderer sr) {
|
||||||
sr.begin(ShapeType.Filled);
|
sr.begin(ShapeType.Filled);
|
||||||
sr.setColor(color);
|
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();
|
sr.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dt) {
|
public void update(float dt) {
|
||||||
|
if (hitByBall) {
|
||||||
|
hit();
|
||||||
|
hitByBall = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Body getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createBody() {
|
||||||
|
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 beginContact(Entity contacted) {
|
||||||
|
if (contacted instanceof Ball) {
|
||||||
|
hitByBall = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endContact(Entity contacted) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hit() {
|
public boolean hit() {
|
||||||
@ -60,11 +106,9 @@ public class Brick extends Entity {
|
|||||||
if (powerUpType != null) {
|
if (powerUpType != null) {
|
||||||
state.powerUps.add(powerUpType.createInstance(state, this));
|
state.powerUps.add(powerUpType.createInstance(state, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleted = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2[] getVertices() {
|
|
||||||
return vertices;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ public abstract class Entity {
|
|||||||
|
|
||||||
protected PlayState state;
|
protected PlayState state;
|
||||||
protected Vector2 pos;
|
protected Vector2 pos;
|
||||||
|
protected boolean deleted = false;
|
||||||
|
|
||||||
public Entity(PlayState state, Vector2 pos) {
|
public Entity(PlayState state, Vector2 pos) {
|
||||||
this(state, pos.x, pos.y);
|
this(state, pos.x, pos.y);
|
||||||
@ -46,4 +47,12 @@ public abstract class Entity {
|
|||||||
pos.y = y;
|
pos.y = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
this.deleted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDeleted() {
|
||||||
|
return deleted;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,31 +6,43 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
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.physics.CollisionListener;
|
||||||
|
import com.me.brickbuster.physics.PhysicsBody;
|
||||||
import com.me.brickbuster.state.PlayState;
|
import com.me.brickbuster.state.PlayState;
|
||||||
import net.dermetfan.utils.Pair;
|
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 STICKY_COLOR = Color.GRAY;
|
||||||
public static final Color PADDLE_COLOR = Color.BLACK;
|
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 boolean sticky = false;
|
||||||
|
|
||||||
|
private Body body;
|
||||||
|
|
||||||
public Paddle(PlayState brickBuster) {
|
public Paddle(PlayState brickBuster) {
|
||||||
super(brickBuster, BrickBuster.BOARD_WIDTH / 2, PADDLE_Y);
|
super(brickBuster, PlayState.BOARD_WIDTH/2, PADDLE_Y);
|
||||||
|
createBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ShapeRenderer sr) {
|
public void render(ShapeRenderer sr) {
|
||||||
sr.begin(ShapeType.Filled);
|
sr.begin(ShapeType.Filled);
|
||||||
sr.setColor(sticky? STICKY_COLOR : PADDLE_COLOR);
|
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();
|
sr.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +53,7 @@ public class Paddle extends Entity {
|
|||||||
setX(width/2);
|
setX(width/2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos.x = pos.x - PADDLE_SPEED * dt;
|
setX(pos.x - PADDLE_SPEED * dt);
|
||||||
|
|
||||||
for (Ball ball : state.balls) {
|
for (Ball ball : state.balls) {
|
||||||
if (ball.isStuck()) {
|
if (ball.isStuck()) {
|
||||||
@ -50,11 +62,11 @@ public class Paddle extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
|
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
|
||||||
if (pos.x + width/2 + PADDLE_SPEED * dt > BrickBuster.BOARD_WIDTH) {
|
if (pos.x + width/2 + PADDLE_SPEED * dt > PlayState.BOARD_WIDTH) {
|
||||||
setX(BrickBuster.BOARD_WIDTH - width/2);
|
setX(PlayState.BOARD_WIDTH - width/2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos.x = pos.x + PADDLE_SPEED * dt;
|
setX(pos.x + PADDLE_SPEED * dt);
|
||||||
|
|
||||||
for (Ball ball : state.balls) {
|
for (Ball ball : state.balls) {
|
||||||
if (ball.isStuck()) {
|
if (ball.isStuck()) {
|
||||||
@ -64,19 +76,59 @@ public class Paddle extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Vector2, Vector2> getTopEdge() {
|
@Override
|
||||||
return new Pair<Vector2, Vector2>(
|
public void createBody() {
|
||||||
new Vector2(pos.x - width/2, pos.y + PADDLE_HEIGHT),
|
BodyDef paddleBody = new BodyDef();
|
||||||
new Vector2(pos.x + width/2, pos.y + PADDLE_HEIGHT)
|
paddleBody.type = BodyDef.BodyType.KinematicBody;
|
||||||
);
|
paddleBody.position.set(pos);
|
||||||
|
|
||||||
|
EdgeShape paddleShape = new EdgeShape();
|
||||||
|
paddleShape.set(new Vector2(-width/2, PADDLE_HEIGHT),
|
||||||
|
new Vector2(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();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWidth() {
|
@Override
|
||||||
|
public Body getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setX(float x) {
|
||||||
|
super.setX(x);
|
||||||
|
Vector2 bodyPos = body.getPosition();
|
||||||
|
bodyPos.x = x;
|
||||||
|
body.setTransform(bodyPos, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setY(float y) {
|
||||||
|
super.setY(y);
|
||||||
|
Vector2 bodyPos = body.getPosition();
|
||||||
|
bodyPos.y = y;
|
||||||
|
body.setTransform(bodyPos, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWidth(int width) {
|
public void setWidth(float width) {
|
||||||
|
if (this.width == width) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
state.world.destroyBody(body);
|
||||||
this.width = width;
|
this.width = width;
|
||||||
|
createBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSticky() {
|
public boolean isSticky() {
|
||||||
|
67
core/src/com/me/brickbuster/entity/Shield.java
Normal file
67
core/src/com/me/brickbuster/entity/Shield.java
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
package com.me.brickbuster.entity;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
|
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.physics.PhysicsBody;
|
||||||
|
import com.me.brickbuster.state.PlayState;
|
||||||
|
|
||||||
|
public class Shield extends Entity implements PhysicsBody {
|
||||||
|
|
||||||
|
public static final float SHIELD_HEIGHT = 0.75f;
|
||||||
|
|
||||||
|
private Body body;
|
||||||
|
|
||||||
|
public Shield(PlayState state) {
|
||||||
|
super(state, 0, state.getShieldCount() * SHIELD_HEIGHT);
|
||||||
|
createBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(ShapeRenderer sr) {
|
||||||
|
sr.begin(ShapeRenderer.ShapeType.Filled);
|
||||||
|
sr.setColor(PowerUpType.SHIELD.getColor());
|
||||||
|
sr.rect(0, pos.y * PlayState.PIXEL_PER_METER,
|
||||||
|
PlayState.BOARD_WIDTH * PlayState.PIXEL_PER_METER,
|
||||||
|
SHIELD_HEIGHT * PlayState.PIXEL_PER_METER);
|
||||||
|
sr.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dt) {
|
||||||
|
if (deleted) {
|
||||||
|
state.removeShield(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createBody() {
|
||||||
|
BodyDef brickBody = new BodyDef();
|
||||||
|
brickBody.type = BodyDef.BodyType.StaticBody;
|
||||||
|
brickBody.position.set(pos.cpy());
|
||||||
|
|
||||||
|
PolygonShape brickShape = new PolygonShape();
|
||||||
|
brickShape.setAsBox(PlayState.BOARD_WIDTH/2, SHIELD_HEIGHT/2,
|
||||||
|
new Vector2(PlayState.BOARD_WIDTH/2,SHIELD_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 Body getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.math.MathUtils;
|
import com.badlogic.gdx.math.MathUtils;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.me.brickbuster.entity.Ball;
|
import com.me.brickbuster.entity.Ball;
|
||||||
|
import com.me.brickbuster.entity.Paddle;
|
||||||
import com.me.brickbuster.state.PlayState;
|
import com.me.brickbuster.state.PlayState;
|
||||||
|
|
||||||
public class MultiBallPowerUp extends PowerUp {
|
public class MultiBallPowerUp extends PowerUp {
|
||||||
@ -19,10 +20,7 @@ public class MultiBallPowerUp extends PowerUp {
|
|||||||
public void activate() {
|
public void activate() {
|
||||||
for (int x = 0; x < 2; x++) {
|
for (int x = 0; x < 2; x++) {
|
||||||
Ball ball = new Ball(state);
|
Ball ball = new Ball(state);
|
||||||
ball.setPos(pos.cpy());
|
ball.launch();
|
||||||
float angle = MathUtils.random(MathUtils.PI*2);
|
|
||||||
ball.setDirection(new Vector2(MathUtils.cos(angle), MathUtils.sin(angle)));
|
|
||||||
ball.setStuck(false);
|
|
||||||
state.balls.add(ball);
|
state.balls.add(ball);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,53 +4,93 @@ import com.badlogic.gdx.graphics.Color;
|
|||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
|
||||||
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
|
||||||
import com.badlogic.gdx.math.Vector2;
|
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.Utils;
|
||||||
import com.me.brickbuster.entity.Entity;
|
import com.me.brickbuster.entity.Entity;
|
||||||
|
import com.me.brickbuster.entity.Paddle;
|
||||||
|
import com.me.brickbuster.physics.CollisionListener;
|
||||||
|
import com.me.brickbuster.physics.PhysicsBody;
|
||||||
import com.me.brickbuster.state.PlayState;
|
import com.me.brickbuster.state.PlayState;
|
||||||
import net.dermetfan.utils.Pair;
|
import net.dermetfan.utils.Pair;
|
||||||
|
|
||||||
public abstract class PowerUp extends Entity {
|
public abstract class PowerUp extends Entity implements PhysicsBody, CollisionListener {
|
||||||
|
|
||||||
public static final int RADIUS = 45;
|
public static final float RADIUS = 1.2f;
|
||||||
public static final int FALL_SPEED = 600;
|
public static final float FALL_SPEED = 15f;
|
||||||
|
|
||||||
private Color color;
|
private Color color;
|
||||||
private boolean isCaught;
|
private boolean isCaught;
|
||||||
|
|
||||||
|
private Body body;
|
||||||
|
|
||||||
public PowerUp(PlayState state, Vector2 pos, Color color) {
|
public PowerUp(PlayState state, Vector2 pos, Color color) {
|
||||||
super(state, pos);
|
super(state, pos);
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
createBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(ShapeRenderer sr) {
|
public void render(ShapeRenderer sr) {
|
||||||
sr.begin(ShapeType.Filled);
|
sr.begin(ShapeType.Filled);
|
||||||
sr.setColor(color);
|
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();
|
sr.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dt) {
|
public void update(float dt) {
|
||||||
setY(getY() - FALL_SPEED * dt);
|
if (isCaught) {
|
||||||
|
|
||||||
Pair<Vector2, Vector2> paddle = state.paddle.getTopEdge();
|
|
||||||
Vector2 lineDir = paddle.getValue().sub(paddle.getKey());
|
|
||||||
Vector2 nearest = Utils.nearestPoint(paddle.getKey().cpy(), lineDir, getPos().cpy());
|
|
||||||
|
|
||||||
if (nearest.dst(getX(), getY()) <= RADIUS) {
|
|
||||||
activate();
|
activate();
|
||||||
isCaught = true;
|
delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getY() + RADIUS < 0) {
|
if (getY() + RADIUS < 0) {
|
||||||
|
delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Body getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createBody() {
|
||||||
|
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);
|
||||||
|
|
||||||
|
body.setLinearVelocity(0f, -FALL_SPEED);
|
||||||
|
|
||||||
|
ballShape.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginContact(Entity contacted) {
|
||||||
|
if (contacted instanceof Paddle) {
|
||||||
isCaught = true;
|
isCaught = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endContact(Entity contacted) {}
|
||||||
|
|
||||||
public abstract void activate();
|
public abstract void activate();
|
||||||
|
|
||||||
public boolean isCaught() {
|
|
||||||
return isCaught;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.me.brickbuster.physics;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.physics.box2d.Contact;
|
||||||
|
import com.badlogic.gdx.physics.box2d.ContactImpulse;
|
||||||
|
import com.badlogic.gdx.physics.box2d.ContactListener;
|
||||||
|
import com.badlogic.gdx.physics.box2d.Manifold;
|
||||||
|
import com.me.brickbuster.entity.Entity;
|
||||||
|
|
||||||
|
public class Box2dContactListener implements ContactListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginContact(Contact contact) {
|
||||||
|
Object userDataA = contact.getFixtureA().getBody().getUserData();
|
||||||
|
Object userDataB = contact.getFixtureB().getBody().getUserData();
|
||||||
|
|
||||||
|
if (userDataA == null || userDataB == null ||
|
||||||
|
!(userDataA instanceof Entity) || !(userDataB instanceof Entity)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userDataA instanceof CollisionListener) {
|
||||||
|
((CollisionListener) userDataA).beginContact((Entity) userDataB);
|
||||||
|
}
|
||||||
|
if (userDataB instanceof CollisionListener) {
|
||||||
|
((CollisionListener) userDataB).beginContact((Entity) userDataA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endContact(Contact contact) {
|
||||||
|
Object userDataA = contact.getFixtureA().getBody().getUserData();
|
||||||
|
Object userDataB = contact.getFixtureB().getBody().getUserData();
|
||||||
|
|
||||||
|
if (userDataA == null || userDataB == null ||
|
||||||
|
!(userDataA instanceof Entity) || !(userDataB instanceof Entity)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userDataA instanceof CollisionListener) {
|
||||||
|
((CollisionListener) userDataA).endContact((Entity) userDataB);
|
||||||
|
}
|
||||||
|
if (userDataB instanceof CollisionListener) {
|
||||||
|
((CollisionListener) userDataB).endContact((Entity) userDataA);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preSolve(Contact contact, Manifold oldManifold) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postSolve(Contact contact, ContactImpulse impulse) {}
|
||||||
|
|
||||||
|
}
|
11
core/src/com/me/brickbuster/physics/CollisionListener.java
Normal file
11
core/src/com/me/brickbuster/physics/CollisionListener.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.me.brickbuster.physics;
|
||||||
|
|
||||||
|
import com.me.brickbuster.entity.Entity;
|
||||||
|
|
||||||
|
public interface CollisionListener {
|
||||||
|
|
||||||
|
void beginContact(Entity contacted);
|
||||||
|
|
||||||
|
void endContact(Entity contacted);
|
||||||
|
|
||||||
|
}
|
11
core/src/com/me/brickbuster/physics/PhysicsBody.java
Normal file
11
core/src/com/me/brickbuster/physics/PhysicsBody.java
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package com.me.brickbuster.physics;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.physics.box2d.Body;
|
||||||
|
|
||||||
|
public interface PhysicsBody {
|
||||||
|
|
||||||
|
void createBody();
|
||||||
|
|
||||||
|
Body getBody();
|
||||||
|
|
||||||
|
}
|
@ -2,63 +2,125 @@ package com.me.brickbuster.state;
|
|||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
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.MathUtils;
|
||||||
|
import com.badlogic.gdx.math.Vector2;
|
||||||
|
import com.badlogic.gdx.physics.box2d.*;
|
||||||
|
import com.badlogic.gdx.utils.Array;
|
||||||
import com.me.brickbuster.BrickBuster;
|
import com.me.brickbuster.BrickBuster;
|
||||||
import com.me.brickbuster.entity.Ball;
|
import com.me.brickbuster.entity.*;
|
||||||
import com.me.brickbuster.entity.Brick;
|
import com.me.brickbuster.entity.powerup.PowerUp;
|
||||||
import com.me.brickbuster.entity.Paddle;
|
import com.me.brickbuster.entity.powerup.PowerUpType;
|
||||||
import com.me.brickbuster.entity.powerup.*;
|
import com.me.brickbuster.physics.Box2dContactListener;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PlayState extends State {
|
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 POWERUP_CHANCE = 0.15f;
|
public static final float POWERUP_CHANCE = 0.15f;
|
||||||
|
|
||||||
public static final int COLUMNS = 9;
|
public static final int COLUMNS = 9;
|
||||||
public static final int ROWS = 8;
|
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 Array<Body> bodies;
|
||||||
|
|
||||||
public List<PowerUp> powerUps;
|
public List<PowerUp> powerUps;
|
||||||
public Paddle paddle;
|
public Paddle paddle;
|
||||||
public List<Ball> balls;
|
public List<Ball> balls;
|
||||||
public List<Brick> bricks;
|
public List<Brick> bricks;
|
||||||
|
public List<Shield> shields;
|
||||||
|
|
||||||
private int shieldCount = 0;
|
|
||||||
private float updateTime = 0f;
|
private float updateTime = 0f;
|
||||||
|
|
||||||
|
private final Box2DDebugRenderer debugRenderer;
|
||||||
|
|
||||||
public PlayState(BrickBuster game) {
|
public PlayState(BrickBuster game) {
|
||||||
super(game);
|
super(game);
|
||||||
|
debugRenderer = new Box2DDebugRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
// Initialize a world with no gravity
|
||||||
|
world = new World(new Vector2(), false);
|
||||||
|
world.setContactListener(new Box2dContactListener());
|
||||||
|
|
||||||
|
// define a playArea body with position set to 0
|
||||||
|
BodyDef playAreaDef = new BodyDef();
|
||||||
|
playAreaDef.type = BodyDef.BodyType.StaticBody;
|
||||||
|
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<PowerUp>();
|
powerUps = new ArrayList<PowerUp>();
|
||||||
paddle = new Paddle(this);
|
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<Brick>();
|
bricks = new ArrayList<Brick>();
|
||||||
for (int col = 0; col < COLUMNS; col++) {
|
for (int col = 0; col < COLUMNS; col++) {
|
||||||
for (int row = 0; row < ROWS; row++) {
|
for (int row = 0; row < ROWS; row++) {
|
||||||
int x = brick_padding + (col * (Brick.BRICK_WIDTH + brick_padding));
|
float x = brick_padding + (col * (Brick.BRICK_WIDTH + brick_padding));
|
||||||
int y = brick_padding + Brick.BRICK_HEIGHT + (row * (Brick.BRICK_HEIGHT + brick_padding));
|
float y = brick_padding + Brick.BRICK_HEIGHT + (row * (Brick.BRICK_HEIGHT + brick_padding));
|
||||||
|
|
||||||
PowerUpType powerUpType = null;
|
PowerUpType powerUpType = null;
|
||||||
if (MathUtils.randomBoolean(POWERUP_CHANCE)) {
|
if (MathUtils.randomBoolean(POWERUP_CHANCE)) {
|
||||||
powerUpType = PowerUpType.getWeightedRandom();
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
balls = new ArrayList<Ball>();
|
balls = new ArrayList<Ball>();
|
||||||
balls.add(new Ball(this));
|
balls.add(new Ball(this));
|
||||||
|
|
||||||
|
shields = new ArrayList<Shield>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render() {
|
public void render() {
|
||||||
|
Array<Body> bodies = new Array<Body>();
|
||||||
|
world.getBodies(bodies);
|
||||||
|
for (Body b : bodies) {
|
||||||
|
Entity e = (Entity) b.getUserData();
|
||||||
|
if (e instanceof Ball || e instanceof PowerUp) {
|
||||||
|
e.setPos(b.getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
long start = System.nanoTime();
|
long start = System.nanoTime();
|
||||||
for (Brick block : bricks) {
|
for (Brick block : bricks) {
|
||||||
block.render(game.sr);
|
block.render(game.sr);
|
||||||
@ -69,14 +131,12 @@ public class PlayState extends State {
|
|||||||
for (Ball ball : balls) {
|
for (Ball ball : balls) {
|
||||||
ball.render(game.sr);
|
ball.render(game.sr);
|
||||||
}
|
}
|
||||||
|
for (Shield shield : shields) {
|
||||||
|
shield.render(game.sr);
|
||||||
|
}
|
||||||
paddle.render(game.sr);
|
paddle.render(game.sr);
|
||||||
|
|
||||||
if (getShieldCount() > 0) {
|
//debugRenderer.render(world, game.cam.combined.cpy().scl(PIXEL_PER_METER));
|
||||||
game.sr.begin(ShapeType.Filled);
|
|
||||||
game.sr.setColor(Color.SALMON);
|
|
||||||
game.sr.rect(0, 0, BrickBuster.BOARD_WIDTH, getShieldCount() * SHIELD_HEIGHT);
|
|
||||||
game.sr.end();
|
|
||||||
}
|
|
||||||
long renderTime = System.nanoTime() - start;
|
long renderTime = System.nanoTime() - start;
|
||||||
|
|
||||||
game.sb.begin();
|
game.sb.begin();
|
||||||
@ -94,8 +154,9 @@ public class PlayState extends State {
|
|||||||
for (Iterator<Ball> it = balls.iterator(); it.hasNext();) {
|
for (Iterator<Ball> it = balls.iterator(); it.hasNext();) {
|
||||||
Ball ball = it.next();
|
Ball ball = it.next();
|
||||||
ball.update(dt);
|
ball.update(dt);
|
||||||
if (ball.isDead()) {
|
if (ball.isDeleted()) {
|
||||||
it.remove();
|
it.remove();
|
||||||
|
world.destroyBody(ball.getBody());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (balls.isEmpty()) {
|
if (balls.isEmpty()) {
|
||||||
@ -105,15 +166,36 @@ public class PlayState extends State {
|
|||||||
for (Iterator<PowerUp> it = powerUps.iterator(); it.hasNext();) {
|
for (Iterator<PowerUp> it = powerUps.iterator(); it.hasNext();) {
|
||||||
PowerUp powerUp = it.next();
|
PowerUp powerUp = it.next();
|
||||||
powerUp.update(dt);
|
powerUp.update(dt);
|
||||||
if(powerUp.isCaught()) {
|
if(powerUp.isDeleted()) {
|
||||||
it.remove();
|
it.remove();
|
||||||
|
world.destroyBody(powerUp.getBody());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Iterator<Shield> it = shields.iterator(); it.hasNext();) {
|
||||||
|
Shield shield = it.next();
|
||||||
|
shield.update(dt);
|
||||||
|
if(shield.isDeleted()) {
|
||||||
|
it.remove();
|
||||||
|
world.destroyBody(shield.getBody());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Iterator<Brick> it = bricks.iterator(); it.hasNext();) {
|
||||||
|
Brick brick = it.next();
|
||||||
|
brick.update(dt);
|
||||||
|
if (brick.isDeleted()) {
|
||||||
|
it.remove();
|
||||||
|
world.destroyBody(brick.getBody());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (bricks.isEmpty()) {
|
if (bricks.isEmpty()) {
|
||||||
game.setScreen(new MenuState(game));
|
game.setScreen(new MenuState(game));
|
||||||
dispose();
|
dispose();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
world.step(dt, 6, 2);
|
||||||
updateTime = System.nanoTime() - start;
|
updateTime = System.nanoTime() - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +203,8 @@ public class PlayState extends State {
|
|||||||
public void dispose() {
|
public void dispose() {
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
|
||||||
|
world.dispose();
|
||||||
|
|
||||||
powerUps.clear();
|
powerUps.clear();
|
||||||
powerUps = null;
|
powerUps = null;
|
||||||
balls.clear();
|
balls.clear();
|
||||||
@ -131,25 +215,25 @@ public class PlayState extends State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getShieldCount() {
|
public int getShieldCount() {
|
||||||
return shieldCount;
|
return shields.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addShield() {
|
public void addShield() {
|
||||||
shieldCount++;
|
Shield shield = new Shield(this);
|
||||||
paddle.setY(paddle.getY() + SHIELD_HEIGHT);
|
shields.add(shield);
|
||||||
|
paddle.setY(paddle.getY() + Shield.SHIELD_HEIGHT);
|
||||||
for (Ball ball : balls) {
|
for (Ball ball : balls) {
|
||||||
if (ball.isStuck()) {
|
if (ball.isStuck()) {
|
||||||
ball.setY(ball.getY() + SHIELD_HEIGHT);
|
ball.setY(ball.getY() + Shield.SHIELD_HEIGHT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeShield() {
|
public void removeShield(Shield shield) {
|
||||||
shieldCount--;
|
paddle.setY(paddle.getY() - Shield.SHIELD_HEIGHT);
|
||||||
paddle.setY(paddle.getY() - SHIELD_HEIGHT);
|
|
||||||
for (Ball ball : balls) {
|
for (Ball ball : balls) {
|
||||||
if (ball.isStuck()) {
|
if (ball.isStuck()) {
|
||||||
ball.setY(ball.getY() - SHIELD_HEIGHT);
|
ball.setY(ball.getY() - Shield.SHIELD_HEIGHT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user