Skip to content

Instantly share code, notes, and snippets.

@Hulzenga
Created August 9, 2015 18:24
Show Gist options
  • Save Hulzenga/0ab7943133bc62e79cec to your computer and use it in GitHub Desktop.
Save Hulzenga/0ab7943133bc62e79cec to your computer and use it in GitHub Desktop.
import javax.swing.*;
import javax.swing.Timer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.*;
import java.util.List;
public class AsyncBalls extends JPanel {
static final int BORDER = 800;
static final float GRAVITY = 30.0f;
static final float BOUNCE_FACTOR = 0.8f;
final List<Ball> balls = new ArrayList<>();
private Queue<Float> popTimes = new LinkedList<>();
public static void main(String[] args) {
JFrame f = new JFrame();
AsyncBalls ab = new AsyncBalls();
ab.setSize(BORDER, BORDER);
f.add(ab);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setResizable(false);
f.setSize(BORDER, BORDER);
f.setVisible(true);
ab.loadPopTimes();
Timer t = new Timer(16, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// the game loop
ab.render(16 / 1000.0f);
}
});
t.setRepeats(true);
t.start();
}
public void update(Queue<Float> newPopTimes) {
if (!popping) {
popping = true;
timer = newPopTimes.poll();
}
while (newPopTimes.size() > 0) {
popTimes.add(newPopTimes.poll());
}
}
public void loadPopTimes() {
new Thread() {
@Override
public void run() {
Queue<Float> popTimes = new LinkedList<Float>();
try (Scanner s = new Scanner(new File("sprites"))) {
while (s.hasNext()) {
popTimes.add(s.nextFloat());
}
} catch (FileNotFoundException e) {
//handle error
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
update(popTimes);
}
});
}
}.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Ball b: balls) {
b.draw(g);
}
}
private boolean popping = false;
private float timer = 0f;
public void render(float delta) {
updateBalls(delta);
if (popping) {
timer -= delta;
if (timer <= 0.0f) {
balls.add(Ball.spawnRandomBall(BORDER));
if (popTimes.size() > 0) {
timer += popTimes.poll();
} else {
popping = false;
}
}
}
this.repaint(); //draw the world
}
public void updateBalls(float delta) {
//let gravity do its thing and update positions
for (Ball b : balls) {
//ignore x component for simplicity
b.vY += GRAVITY * delta;
b.y += b.vY * delta;
}
//cull balls out of frame
for (Iterator<Ball> iter = balls.iterator(); iter.hasNext();) {
Ball b = iter.next();
if (b.y < 0.0f) {
iter.remove();
}
}
}
public interface drawable {
public void draw(Graphics g);
}
//Just a simple ball
public static class Ball {
static final float DEFAULT_BALL_SIZE = 30.0f;
public float x, y, r; //position x, y and radius r
public float vX, vY; //velocity x and y component
public Ball(float x, float y, float r) {
this.x = x;
this.y = y;
this.r = r;
}
public void draw(Graphics g) {
g.fillOval((int) x, (int) y, (int) r, (int) r);
}
private static final Random rnd = new Random();
public static Ball spawnRandomBall(int bound) {
return new Ball(rnd.nextFloat() * bound, rnd.nextFloat() * bound, DEFAULT_BALL_SIZE);
}
}
}
0.0
0.0
0.0
0.0
0.0
4.0
3.0
2.0
1.0
0.0
0.0
0.0
0.0
0.0
4.0
3.0
2.0
1.0
0.0
0.0
0.0
0.0
0.0
4.0
3.0
2.0
1.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment