Masz tutaj kod bazowy, dalej już powinieneś sobie poradzić.
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.*;
import java.util.List;
public class GameTest {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setVisible(true);
}
static class Frame extends JFrame {
private JPanel mainPanel;
private List<GameEntity> gameEntityList = new ArrayList<GameEntity>();
private volatile boolean gameOver = false;
private Thread th = null;
private long time = 0;
public Frame() {
super("Test frame");
gameEntityList.add(new Bullet(new Vector(50, 200), new Vector(30,10), new Vector(100, 0)));
gameEntityList.add(new Bullet(new Vector(550, 205), new Vector(30,10), new Vector(-150, 0)));
mainPanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of overridden methods use File | Settings | File Templates.
Frame.this.draw(g);
}
};
mainPanel.setPreferredSize(new Dimension(640, 480));
add(mainPanel);
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e); //To change body of overridden methods use File | Settings | File Templates.
gameOver = true;
try {
th.join();
} catch (InterruptedException e1) {
e1.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
});
th = new Thread(new Runnable() {
@Override
public void run() {
time = System.currentTimeMillis();
while (!gameOver) {
long cur_time = System.currentTimeMillis();
if (cur_time - time >= 10) {
float dt = ((float)(cur_time - time)) / 1000.0f;
time = cur_time;
Frame.this.update(dt);
} else {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
}
});
th.start();
}
private void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(0,0, mainPanel.getWidth(), mainPanel.getHeight());
for(GameEntity gameEntity : gameEntityList) {
gameEntity.draw(g);
}
}
private void update(float dt) {
for(GameEntity gameEntity : gameEntityList) {
gameEntity.update(dt);
}
List<GameEntity> dead = new ArrayList<GameEntity>();
List<GameEntity> newObj = new ArrayList<GameEntity>();
for(int i=0; i<gameEntityList.size(); i++) {
for (int j=i+1; j<gameEntityList.size(); j++) {
if (gameEntityList.get(i).testCollision(gameEntityList.get(j))) {
gameEntityList.get(i).setAlive(false);
gameEntityList.get(j).setAlive(false);
Vector c1 = gameEntityList.get(i).getPosition().add(gameEntityList.get(i).getSize().mul(0.5f));
Vector c2 = gameEntityList.get(j).getPosition().add(gameEntityList.get(j).getSize().mul(0.5f));
newObj.add(new Explosion(c1.add(c2).mul(0.5f), 100, 1.0f, 50));
}
}
}
for(GameEntity gameEntity : gameEntityList) {
if (!gameEntity.isAlive()) {
dead.add(gameEntity);
}
}
gameEntityList.removeAll(dead);
gameEntityList.addAll(newObj);
repaint();
}
}
public static interface GameEntity {
public Vector getPosition();
public Vector getSize();
public void draw(Graphics g);
public void update(float dt);
public boolean testCollision(GameEntity gameEntity);
public boolean isAlive();
public void setAlive(boolean b);
}
public static class Bullet implements GameEntity {
private Vector pos;
private Vector size;
private Vector velocity;
private boolean alive;
public Bullet(Vector pos, Vector size, Vector velocity) {
this.pos = pos;
this.size = size;
this.velocity = velocity;
this.alive = true;
}
@Override
public Vector getPosition() {
return pos;
}
@Override
public Vector getSize() {
return size;
}
@Override
public void draw(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect((int)pos.getX(), (int)pos.getY(), (int)size.getX(), (int)size.getY());
}
@Override
public void update(float dt) {
pos.add((new Vector(velocity)).mul(dt));
}
@Override
public boolean testCollision(GameEntity gameEntity) {
return !(getPosition().getX() > gameEntity.getPosition().getX()+gameEntity.getSize().getX() ||
getPosition().getX() + getSize().getX() < gameEntity.getPosition().getX() ||
getPosition().getY() > gameEntity.getPosition().getY()+gameEntity.getSize().getY() ||
getPosition().getY() + getSize().getY() < gameEntity.getPosition().getY());
}
public boolean isAlive() {
return alive;
}
public void setAlive(boolean alive) {
this.alive = alive;
}
}
public static class Explosion implements GameEntity {
private float time;
private float maxTime;
private float speed;
private Vector pos;
private Vector[] particlesPos;
private Vector[] particlesV;
public Explosion(Vector pos, int pNo, float maxTime, float speed) {
this.time = 0;
this.maxTime = maxTime;
this.speed = speed;
this.pos = pos;
this.particlesPos = new Vector[pNo];
this.particlesV = new Vector[pNo];
for(int i=0; i<pNo; i++) {
particlesPos[i] = new Vector(pos);
double ang = 2 * Math.PI * Math.random();
particlesV[i] = new Vector((float)Math.cos(ang), (float)Math.sin(ang)).mul((float)Math.random()*speed);
}
}
@Override
public Vector getPosition() {
return pos;
}
@Override
public Vector getSize() {
return new Vector(2 * speed * time, 2 * speed * time);
}
@Override
public void draw(Graphics g) {
g.setColor(new Color( (int)((1.0f - time/maxTime) * 255), 0,0));
for(int i=0; i<particlesPos.length; i++) {
g.fillRect((int) particlesPos[i].getX() - 2, (int) particlesPos[i].getY() - 2, 4, 4);
}
}
@Override
public void update(float dt) {
time += dt;
for(int i=0; i<particlesPos.length; i++) {
particlesPos[i].add(new Vector(particlesV[i]).mul(dt));
}
}
@Override
public boolean testCollision(GameEntity gameEntity) {
return false;
}
@Override
public boolean isAlive() {
return time < maxTime;
}
@Override
public void setAlive(boolean b) {
}
}
public static class Vector {
private float x,y;
public Vector(float x, float y) {
this.x = x;
this.y = y;
}
public Vector(Vector v) {
this.x = v.x;
this.y = v.y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public Vector add(Vector b) {
this.x += b.x;
this.y += b.y;
return this;
}
public Vector mul(float f) {
this.x *= f;
this.y *= f;
return this;
}
};
}