PDA

View Full Version : Best way to draw moving stuff? [JAVA]



weequ
08-03-2011, 06:58 PM
Well currently i'm clearing the area with clearRect and every time drawing the stuff instantly after that.

The problem is that when I do this all the things I draw flash.


Solutions I thought of.
-Somehow drawing everything to an image first and then painting the image on top of everything.
-Using some sort of layers (labels?) and moving them on the screen.


What you think is the best solution?

Here is my current source code: (It's crap)

import javax.swing.*;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.*;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.Timer;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;


import java.lang.Math;

public class Peli extends JFrame implements ActionListener, MouseListener, KeyListener {
public final int leveys = 800;//Montako pixeliä
public final int korkeus = 800;
public double currentx = 400;
public double currenty = 400;
public double currentangle = 0;
public double targetx = 400;
public double targety = 400;
public long timebetween;
public Timer timer = new Timer(100, this);
public boolean ud, dd, rd, ld;
public double xerotus;
public double yerotus;
public double hypotenuusa;
public boolean pause = true;

public Peli() {
//addKeyListener(new TAdapter());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(leveys, korkeus);
setResizable(false);
addMouseListener(this);
addKeyListener(this);
setVisible(true);
//setFocusable(true);
timer.start();
}

public void keyPressed(KeyEvent e) {
//System.out.println("KEYPRESSED");
int key = e.getKeyCode();

if (key == KeyEvent.VK_LEFT) {
ld = true;
}

if (key == KeyEvent.VK_RIGHT) {
rd = true;
}

if (key == KeyEvent.VK_UP) {
ud = true;
}

if (key == KeyEvent.VK_DOWN) {
dd = true;
}
}

public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();

if (key == KeyEvent.VK_LEFT) {
ld = false;
}

if (key == KeyEvent.VK_RIGHT) {
rd = false;
}

if (key == KeyEvent.VK_UP) {
ud = false;
}

if (key == KeyEvent.VK_DOWN) {
dd = false;
}
}

public void keyTyped(KeyEvent e) {

}



public void actionPerformed(ActionEvent e) {
if (!pause) {
move();
repaint();
}
}


public void mouseClicked(MouseEvent e) {
System.out.println("The frame was clicked.");

}

public void mouseEntered(MouseEvent e) {
pause = false;
System.out.println("GAME RESUMED");

}

public void mouseExited(MouseEvent e) {
pause = true;
System.out.println("GAME PAUSED");
}

public void mousePressed(MouseEvent e) {

}

public void mouseReleased(MouseEvent e) {

}


public void paint(Graphics g) { //THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//super.paint(g);
g.setColor(Color.CYAN);
g.clearRect(0, 0, leveys, korkeus);
g.fillOval((int) currentx-10, (int) currenty-10, 20, 20);
g.setColor(Color.BLACK);
g.drawLine((int) currentx, (int) currenty, (int) (currentx+(15/hypotenuusa)*xerotus), (int) (currenty+(15/hypotenuusa)*yerotus));
g.drawString("PISTEET: ", leveys-100, korkeus-20);
g.dispose();
}

public void move() {
Point p = getMousePosition();
if (p == null) return;
xerotus = p.getX()-currentx;
yerotus = p.getY()-currenty;
hypotenuusa = Math.sqrt(xerotus*xerotus+yerotus*yerotus);
currentangle = Math.atan(yerotus/xerotus);
//System.out.println(currentangle);
if (rd == true) {
currentx = currentx-(5/hypotenuusa)*yerotus;
currenty = currenty-(5/hypotenuusa)*(-xerotus);
}
if (ld == true) {
currentx = currentx+(5/hypotenuusa)*yerotus;
currenty = currenty+(5/hypotenuusa)*(-xerotus);
}
if (ud == true) {
currentx = currentx+(10/hypotenuusa)*xerotus;
currenty = currenty+(10/hypotenuusa)*yerotus;
}
if (dd == true) {
currentx = currentx-(5/hypotenuusa)*xerotus;
currenty = currenty-(5/hypotenuusa)*yerotus;
}
//if (targetx > currentx) {
// currentx++;
//}
//if (targetx < currentx) {
// currentx--;
//}
//if (targety > currenty) {
// currenty++;
//}
//if (targety < currenty) {
// currenty--;
//}
}

public static void main(String[] args) {

Peli pelifraami = new Peli();
//pelifraami.setResizable(false);
//pelifraami.addMouseListener(pelifraami);
//pelifraami.setVisible(true);
pelifraami.setCursor(JFrame.CROSSHAIR_CURSOR);
//System.out.println(pelifraami.getMousePosition().g etX());


}

}

regex_
08-03-2011, 08:22 PM
you need to double-buffer, take a look at the BufferStrategy class.

Richard
08-03-2011, 08:24 PM
Double buffering is something commonly used if you are changing content of the image very rapidly, you can find out more about it here: double buffering (http://download.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html).

If you'd like a simpler single line of code, add this to the top of your paint/repaint method, makes drawing much smoother:


g1.setRenderingHint(RenderingHints.KEY_ANTIALIASIN G, RenderingHints.VALUE_ANTIALIAS_ON);

(Assuming g1 is an instance of Graphics2D)

weequ
08-03-2011, 09:55 PM
Yea double buffering was one of the solutions I thought of. Just didn't know it has a name.
Well I guess I'll try that. Thanks for the help.

Richard what does that single line of code actually do?