Compare commits

..

3 Commits

Author SHA1 Message Date
1f9c2e6db0 Decrease chance of glue powerup dropping from 50% to 8%
Increase default ball speed to 350px/sec
Change paddle speed control to time-based, 375px/sec
2018-11-12 09:54:07 +04:00
3e0d4657f2 Add PowerUp logic + GluePowerUp 2018-11-12 09:28:12 +04:00
28e0ed27f3 Entity take float in constructor instead of int 2018-11-12 09:27:29 +04:00
7 changed files with 160 additions and 20 deletions

View File

@ -3,12 +3,12 @@ package com.me.brickbuster;
import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.GL20;
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.*;
import com.me.brickbuster.entity.Brick;
import com.me.brickbuster.entity.Paddle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
public class BrickBuster extends ApplicationAdapter { public class BrickBuster extends ApplicationAdapter {
@ -22,18 +22,24 @@ public class BrickBuster extends ApplicationAdapter {
private Ball ball; private Ball ball;
private Paddle paddle; private Paddle paddle;
private ArrayList<Brick> bricks; private ArrayList<Brick> bricks;
private ArrayList<PowerUp> powerUps;
private boolean playing = false; private boolean playing = false;
@Override @Override
public void create () { public void create () {
ball = new Ball(this); ball = new Ball(this);
paddle = new Paddle(this); paddle = new Paddle(this);
powerUps = new ArrayList<PowerUp>();
bricks = new ArrayList<Brick>(); bricks = new ArrayList<Brick>();
for (int col = 0; col < 13; col++) { for (int col = 0; col < 13; col++) {
for (int row = 0; row < 7; row++) { for (int row = 0; row < 7; row++) {
int x = 15 + (col * (Brick.BLOCK_WIDTH + 10)); int x = 15 + (col * (Brick.BLOCK_WIDTH + 10));
int y = 15 + Brick.BLOCK_HEIGHT + (row * (Brick.BLOCK_HEIGHT + 10)); int y = 15 + Brick.BLOCK_HEIGHT + (row * (Brick.BLOCK_HEIGHT + 10));
bricks.add(new Brick(this, x, HEIGHT - y)); Class<? extends PowerUp> powerUpType = null;
if (MathUtils.randomBoolean(0.08f)) {
powerUpType = GluePowerUp.class;
}
bricks.add(new Brick(this, powerUpType, x, HEIGHT - y));
} }
} }
} }
@ -49,17 +55,31 @@ public class BrickBuster extends ApplicationAdapter {
block.render(); block.render();
} }
for (PowerUp powerUp : powerUps) {
powerUp.render();
}
ball.render(); ball.render();
paddle.render(); paddle.render();
} }
public void update(float dt) { public void update(float dt) {
if (Gdx.input.justTouched() && !isPlaying()) { if (Gdx.input.justTouched() && (!isPlaying() || ball.isStuck())) {
playing = true; playing = true;
ball.launch(); ball.launch();
} }
ball.update(dt); ball.update(dt);
paddle.update(dt); paddle.update(dt);
for (Iterator<PowerUp> it = powerUps.iterator(); it.hasNext();) {
PowerUp powerUp = it.next();
powerUp.update(dt);
if(powerUp.isCaught()) {
it.remove();
}
}
if (getBricks().isEmpty()) { if (getBricks().isEmpty()) {
create(); create();
playing = false; playing = false;
@ -89,4 +109,9 @@ public class BrickBuster extends ApplicationAdapter {
public ArrayList<Brick> getBricks() { public ArrayList<Brick> getBricks() {
return bricks; return bricks;
} }
public void addPowerUp(PowerUp powerUp) {
this.powerUps.add(powerUp);
}
} }

View File

@ -14,9 +14,13 @@ public class Ball extends Entity {
public static final int RADIUS = 12; public static final int RADIUS = 12;
public static final Color BALL_COLOR = Color.CHARTREUSE; public static final Color BALL_COLOR = Color.CHARTREUSE;
public static final float DEFAULT_SPEED = 350;
public static final float BOOST_SPEED = 450;
public static final int BLOCKS_FOR_BOOST = 39;
public Vector2 direction; public Vector2 direction;
public float speed = 300; private float speed;
private boolean isStuck = false;
public Ball(BrickBuster brickBuster) { public Ball(BrickBuster brickBuster) {
super(brickBuster,BrickBuster.WIDTH/2, Paddle.PADDLE_Y + Paddle.PADDLE_HEIGHT + RADIUS); super(brickBuster,BrickBuster.WIDTH/2, Paddle.PADDLE_Y + Paddle.PADDLE_HEIGHT + RADIUS);
@ -51,8 +55,9 @@ public class Ball extends Entity {
if (nearest.dst(new_pos.x, new_pos.y) <= RADIUS) { if (nearest.dst(new_pos.x, new_pos.y) <= RADIUS) {
brickIterator.remove(); brickIterator.remove();
if (getBrickBuster().getBricks().size() <= 39) { brick.hit();
speed = 450; if (getBrickBuster().getBricks().size() <= BLOCKS_FOR_BOOST) {
speed = BOOST_SPEED;
} }
Utils.reflect(direction, segment.nor()); Utils.reflect(direction, segment.nor());
brick_collision = true; brick_collision = true;
@ -86,9 +91,18 @@ public class Ball extends Entity {
public void launch() { public void launch() {
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));
speed = DEFAULT_SPEED;
isStuck = false;
} }
public void paddleCollision() { public void paddleCollision() {
Paddle paddle = getBrickBuster().getPaddle();
if (paddle.isSticky()) {
speed = 0;
isStuck = true;
setY(Paddle.PADDLE_Y + Paddle.PADDLE_HEIGHT + RADIUS);
return;
}
float paddleCenter = getBrickBuster().getPaddle().getX() + Paddle.PADDLE_WIDTH/2; float paddleCenter = getBrickBuster().getPaddle().getX() + Paddle.PADDLE_WIDTH/2;
float rel = MathUtils.clamp((getX() - paddleCenter) + 50, 5, 95); float rel = MathUtils.clamp((getX() - paddleCenter) + 50, 5, 95);
float newAngle = MathUtils.PI - (MathUtils.PI * (rel/100)); float newAngle = MathUtils.PI - (MathUtils.PI * (rel/100));
@ -98,6 +112,12 @@ public class Ball extends Entity {
public void reset() { public void reset() {
setX(getBrickBuster().getPaddle().getX() + Paddle.PADDLE_WIDTH/2); setX(getBrickBuster().getPaddle().getX() + Paddle.PADDLE_WIDTH/2);
setY(Paddle.PADDLE_Y + Paddle.PADDLE_HEIGHT + RADIUS); setY(Paddle.PADDLE_Y + Paddle.PADDLE_HEIGHT + RADIUS);
getBrickBuster().getPaddle().setSticky(false);
getBrickBuster().setPlaying(false); getBrickBuster().setPlaying(false);
} }
public boolean isStuck() {
return isStuck;
}
} }

View File

@ -10,10 +10,13 @@ public class Brick extends Entity {
public static final int BLOCK_WIDTH = 50; public static final int BLOCK_WIDTH = 50;
public static final int BLOCK_HEIGHT = 20; public static final int BLOCK_HEIGHT = 20;
private Class<? extends PowerUp> powerUpType;
private Vector2[] vertices; private Vector2[] vertices;
public Brick(BrickBuster brickBuster, int x, int y) { public Brick(BrickBuster brickBuster, Class<? extends PowerUp> powerUpType, int x, int y) {
super(brickBuster, x, y); super(brickBuster, x, y);
this.powerUpType = powerUpType;
this.vertices = new Vector2[] { this.vertices = new Vector2[] {
new Vector2(x, y), new Vector2(x, y),
@ -35,6 +38,18 @@ public class Brick extends Entity {
public void update(float dt) { public void update(float dt) {
} }
public boolean hit() {
if (powerUpType != null) {
try {
PowerUp powerUp = powerUpType.getConstructor(BrickBuster.class, Brick.class).newInstance(getBrickBuster(), this);
getBrickBuster().addPowerUp(powerUp);
} catch(Exception e) {
}
}
return true;
}
public Vector2[] getVertices() { public Vector2[] getVertices() {
return vertices; return vertices;
} }

View File

@ -10,7 +10,7 @@ public abstract class Entity {
private BrickBuster brickBuster; private BrickBuster brickBuster;
private Vector2 pos; private Vector2 pos;
public Entity(BrickBuster brickBuster, int x, int y) { public Entity(BrickBuster brickBuster, float x, float y) {
this.shapeRenderer = new ShapeRenderer(); this.shapeRenderer = new ShapeRenderer();
this.brickBuster = brickBuster; this.brickBuster = brickBuster;
this.pos = new Vector2(x, y); this.pos = new Vector2(x, y);

View File

@ -0,0 +1,17 @@
package com.me.brickbuster.entity;
import com.badlogic.gdx.graphics.Color;
import com.me.brickbuster.BrickBuster;
public class GluePowerUp extends PowerUp {
public GluePowerUp(BrickBuster brickBuster, Brick brick) {
super(brickBuster, brick, Color.WHITE);
}
@Override
public void activate() {
getBrickBuster().getPaddle().setSticky(true);
}
}

View File

@ -14,7 +14,9 @@ public class Paddle extends Entity {
public static final int PADDLE_WIDTH = 100; public static final int PADDLE_WIDTH = 100;
public static final int PADDLE_HEIGHT = 10; public static final int PADDLE_HEIGHT = 10;
public static final int PADDLE_Y = 15; public static final int PADDLE_Y = 15;
public static final int PADDLE_SPEED = 6; public static final int PADDLE_SPEED = 375;
private boolean sticky = false;
public Paddle(BrickBuster brickBuster) { public Paddle(BrickBuster brickBuster) {
super(brickBuster, BrickBuster.WIDTH / 2 - PADDLE_WIDTH / 2, PADDLE_Y); super(brickBuster, BrickBuster.WIDTH / 2 - PADDLE_WIDTH / 2, PADDLE_Y);
@ -23,7 +25,7 @@ public class Paddle extends Entity {
@Override @Override
public void render() { public void render() {
getShapeRenderer().begin(ShapeType.Filled); getShapeRenderer().begin(ShapeType.Filled);
getShapeRenderer().setColor(PADDLE_COLOR); getShapeRenderer().setColor(isSticky()? Color.GRAY : PADDLE_COLOR);
getShapeRenderer().rect(getX(), getY(), PADDLE_WIDTH, PADDLE_HEIGHT); getShapeRenderer().rect(getX(), getY(), PADDLE_WIDTH, PADDLE_HEIGHT);
getShapeRenderer().end(); getShapeRenderer().end();
} }
@ -32,21 +34,21 @@ public class Paddle extends Entity {
public void update(float dt) { public void update(float dt) {
Ball ball = getBrickBuster().getBall(); Ball ball = getBrickBuster().getBall();
if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) { if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
if (getX() - PADDLE_SPEED < 0) { if (getX() - PADDLE_SPEED * dt < 0) {
return; return;
} }
setX(getX() - PADDLE_SPEED); setX(getX() - PADDLE_SPEED * dt);
if (!getBrickBuster().isPlaying()) { if (!getBrickBuster().isPlaying() || ball.isStuck()) {
ball.setX(ball.getX() - PADDLE_SPEED); ball.setX(ball.getX() - PADDLE_SPEED * dt);
} }
} }
if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) { if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
if (getX() + PADDLE_SPEED + PADDLE_WIDTH > BrickBuster.WIDTH) { if (getX() + PADDLE_SPEED * dt + PADDLE_WIDTH > BrickBuster.WIDTH) {
return; return;
} }
setX(getX() + PADDLE_SPEED); setX(getX() + PADDLE_SPEED * dt);
if (!getBrickBuster().isPlaying()) { if (!getBrickBuster().isPlaying() || ball.isStuck()) {
ball.setX(ball.getX() + PADDLE_SPEED); ball.setX(ball.getX() + PADDLE_SPEED * dt);
} }
} }
} }
@ -58,4 +60,11 @@ public class Paddle extends Entity {
); );
} }
public boolean isSticky() {
return sticky;
}
public void setSticky(boolean sticky) {
this.sticky = sticky;
}
} }

View File

@ -0,0 +1,54 @@
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.me.brickbuster.BrickBuster;
import com.me.brickbuster.Utils;
import net.dermetfan.utils.Pair;
public abstract class PowerUp extends Entity {
public static final int RADIUS = 10;
public static final int FALL_SPEED = 100;
private Color color;
private boolean isCaught;
public PowerUp(BrickBuster brickBuster, Brick brick, Color color) {
super(brickBuster, brick.getX() + Brick.BLOCK_WIDTH/2, brick.getY() + Brick.BLOCK_HEIGHT/2);
this.color = color;
}
@Override
public void render() {
getShapeRenderer().begin(ShapeRenderer.ShapeType.Filled);
getShapeRenderer().setColor(color);
getShapeRenderer().circle(getX(), getY(), RADIUS);
getShapeRenderer().end();
}
@Override
public void update(float dt) {
setY(getY() - FALL_SPEED * dt);
Pair<Vector2, Vector2> paddle = getBrickBuster().getPaddle().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();
isCaught = true;
}
if (getY() + RADIUS < 0) {
isCaught = true;
}
}
public abstract void activate();
public boolean isCaught() {
return isCaught;
}
}