import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.geom.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class BasicGameDoubleBuffering {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Basic Game");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel implements Runnable{
private int squareX = 50;
private int squareY = 50;
private int offsetY = 0;
private int offsetX = 0;
private int squareW = 20;
private int squareH = 20;
private Thread animator;
private long numPaintJobs = 0L;
private Image im = null;
private Graphics dbg = null;
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
moveImage(e);
}
});
setFocusable(true);
requestFocus();
// facciamo partire il metodo run
if (animator == null ) {
animator = new Thread(this);
animator.start();
}
}
private void moveSquare(int x, int y) {
if ((squareX!=x) || (squareY!=y)) {
squareX=x;
squareY=y;
}
}
private void moveImage(KeyEvent ke){
int kc = ke.getKeyCode();
System.out.println(kc);
if ((kc == ke.VK_LEFT)||(kc == ke.VK_KP_LEFT)) {squareX = squareX - 5;}
if ((kc == ke.VK_RIGHT)||(kc == ke.VK_KP_RIGHT)){squareX = squareX + 5;}
}
public Dimension getPreferredSize() {
return new Dimension(250,200);
}
private void gameRender(){
if (im == null){
im = createImage(250, 200);
if (im == null){
return;
} else dbg = im.getGraphics();
}
// disegno sul contesto grafico
dbg.setColor(Color.BLUE);
dbg.fillRect(0,0,250,200);
dbg.setColor(Color.RED);
dbg.fillRect(squareX,squareY,squareW,squareH);
dbg.setColor(Color.WHITE);
dbg.drawRect(squareX,squareY,squareW,squareH);
dbg.setColor(Color.BLACK);
dbg.drawRect(squareX-1,squareY-1,squareW +2,squareH +2 );
// qualche prova con metodi della classe Graphics2D
Graphics2D g2 = (Graphics2D) dbg;
g2.setColor(Color.GREEN);
g2.draw(new Rectangle2D.Double(10.0,10.0, 50.0,50.0));
g2.draw(new Line2D.Double(23.0, 12.0, 100.0, 100.0));
g2.setColor(Color.WHITE);
g2.drawString("love this",100,100);
g2.draw(new CubicCurve2D.Double(0.0,0.0,
-10.0, 30.0,
20.0, 90.0,
250.0, 250.0));
// siccome è un oggetto privato e non può toccarlo
// nessuno non esiste il rischio che venga toccato
// quindi non lo butto via alla fine delle operazioni
// di disegno: me lo tengo e ci disegno sopra tutte
// le volte
}
private void mypaint() {
Graphics g;
try{
g = this.getGraphics();
g.drawImage(im, 0,0, null);
g.dispose();
}
catch(Exception e){
}
// stampo tanto per vedere quante volte venga invocato paintComponent
System.out.println("P #: " + numPaintJobs);
numPaintJobs++;
}
public void run(){
while(true){
gameUpdate();
gameRender();
mypaint();
try {
// aspetta 30 ms
Thread.currentThread().sleep(20L);
}catch(InterruptedException ex){}
}
}
private void gameUpdate(){
squareX++;
// prendiamo il resto della divisione intera
// in modo che squareX non superi 250
squareX = (squareX)% 250;
// collochiamo il punto su una parabola
// che passa per 0,0 e 250,0
squareY = (int)((-1)*(squareX*(squareX - 250))/150)%200 ;
}
}