Polygon-Animation mit Darstellungsfehlern

raute89

Mitglied
Hallo zusammen

Ich programmiere Animationen für die Java-Version eines Brettspiels. Grundsätzlich geht es darum, einen Bauern per Mausklick auswählen zu können, um diesen danach zu bewegen. Da der Mausklick aber nur genau auf der Spielfigur das ensprechende Event auslösen soll, hab ich an ein Polygon gedacht, das die Form der Spielfigur hat.

Mein Problem ist nun, dass ich die Bewegung dieses Bauern-Polygons auf meiner GUI (die auch JPanels enthält) nicht graphisch ansprechbar hinkriege. Als ich den Bauern noch in einem JLabel hatte, funktioniert alles prima. Beim Polygon flackert jedoch alles wild - da die Animation alle 10-100 ms einen Schritt macht, sieht man sie bisweilen gar nicht mehr.

Ich habe diverse Sachen wie Doppel-Pufferung etc. schon probiert, habs aber leider bis jetzt nicht hingekriegt.

Ich programmiere das erste Mal eine GUI in Java und bin für hilfreiche Tips dankbar (auch falls jemand eine komplett andere Lösung für mein Problem hat... ich mag die Polygone eh nicht so;) )

Danke!

Code:
Java:
package bufferedImage;

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.TexturePaint;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class AnimationBI extends JFrame {
	
	//linkes Panel
	JPanel mainPanel;
	//rechtes Panel
	JPanel secondPanel;

	ImageIcon farmer;
	Point farmerPosition;
	//Für Doppelpufferung
	Image dbImage;
	Graphics dbGraphics;
	
	Container cont;
	Polygon polygon;
	//Polygonpunkte
	int[] polygonX;
	int[] polygonY;
	//TexturePaint um Bild auf Polygon zu legen
	Paint tpaint;
	//BufferedImage um Bild auf Polygon zu legen
	BufferedImage buImg;
	
	private Timer timer;

	public AnimationBI() {

		try {
			farmer = new ImageIcon(getClass().getResource("blue_farmer.png"));
			buImg = ImageIO.read(getClass().getResource("blue_farmer.png"));
		} catch (Exception e) {
			//nichts
		}
		farmerPosition = new Point(100, 100);
		mainPanel = new JPanel();
		mainPanel.setLayout(null);
		mainPanel.setBounds(20, 20, 200, 400);
		mainPanel.setBackground(Color.GREEN);
		mainPanel.setVisible(true);
		cont = getContentPane();
		add(mainPanel);

		// Zweites Panel
		secondPanel = new JPanel();
		mainPanel.setLayout(null);
		add(secondPanel);
		secondPanel.setBounds(240, 20, 200, 400);
		secondPanel.setBackground(Color.BLACK);
		secondPanel.setVisible(true);

		setBounds(0, 0, 600, 480);
		setVisible(true);

		// Polygon
		polygonX = new int[] { 100, 110, 173, 183, 183, 100 };
		polygonY = new int[] { 110, 100, 100, 110, 214, 214 };
		polygon = new Polygon(polygonX, polygonY, 6);

		tpaint = new TexturePaint(buImg, polygon.getBounds2D());

		timer = new Timer();
		timer.scheduleAtFixedRate(new ScheduleTask(), new Date(), 3);

	}

	public void paint(Graphics g) {
		// super.paint(g);
		Graphics2D g2d = (Graphics2D) g.create();
		tpaint = new TexturePaint(buImg, polygon.getBounds2D());
		g2d.setPaint(tpaint);
		g2d.drawPolygon(polygon);
		g2d.fillPolygon(polygon);
	}

	public void update(Graphics g) {

		// Double-Buffer initialisieren
		if (dbImage == null) {
			dbImage = createImage(this.getSize().width, this.getSize().height);
			dbGraphics = dbImage.getGraphics();
		}
		// Hintergrund löschen
		dbGraphics.setColor(getBackground());
		dbGraphics.fillRect(0, 0, this.getSize().width, this.getSize().height);
		// Vordergrund zeichnen
		dbGraphics.setColor(getForeground());
		paint(dbGraphics);
		// Offscreen anzeigen
		g.drawImage(dbImage, 0, 0, this);
	}

	class ScheduleTask extends TimerTask {

		public ScheduleTask() {
		}

		public void run() {
			for (int i = 0; i < 20; i++) {
				polygon.translate(10, 10);
				repaint();

				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// nichts
				}
			}
		}
	}
}
 

Michael...

Top Contributor
Was mir so auf den ersten Blick auffällt:
- eine Periodendauer von 3 ms im Timer ist ziemlich heftig.
- die for-Schleife inkl. dem Thread.sleep(100). Ist das wirklich so gewollt???
Ich vermute den Fehler in der Verwendung von TimerTask.
 

raute89

Mitglied
Was mir so auf den ersten Blick auffällt:
- eine Periodendauer von 3 ms im Timer ist ziemlich heftig.
- die for-Schleife inkl. dem Thread.sleep(100). Ist das wirklich so gewollt???
Ich vermute den Fehler in der Verwendung von TimerTask.

ja, die for-Schleife war so gewollt, weil ich die Animation mitverfolgen wollte und bei kleinerer Verzögerung das Flackern zu gross, resp. die Bewegung beinahe unsichtbar wurde. Als ich statt dem Polygon ein JLabel verwendet hatte, ging die Animation mit dem TimerTask (mit 3ms Periodendauer) und dem Thread.Sleep() eigentlich ganz gut... Ich hab mich aber gegen das JLabel entschieden, weil ich 1. nur das Bild bewegen will (und nicht noch den rechteckigen Hintergrund, was da der Fall war) und 2. das MouseEvent nur dann auslösen will, wenn der Klick GENAU auf dem Polygon ist (via polygon.contains() )

Gruss raute
 

Quaxli

Top Contributor
Ich hab' mal dran rumgefrickelt und etliches geändert:

- die Panels habe ich rausgeschmissen, da nicht klar war, wozu die gut sind
- damit war das Null-Layout überflüssig
- den Timer habe ich durch einen eigenen Thread ersetzt
- die Doppelbufferung habe ich rausgeworfen und stattdessen ein JPanel genommen
- das g.create() durch einen cast ersetzt
- ...

Rausgekommen ist der Code unten. Die Animation läuft jetzt schon mal flüssig. Schau Dir halt mal an, was Du davon verwenden kannst. Falls Du noch Fragen hast melde Dich.


Java:
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
 
public class AnimationBI extends JPanel implements Runnable{
    
 
    ImageIcon farmer;
    Polygon polygon;
    int[] polygonX;
    int[] polygonY;

    Paint tpaint;
    BufferedImage buImg;

    JFrame frame;
    
    public static void main(String[] args){
    	new AnimationBI();
    }
 
    public AnimationBI() {
 
        try {
            farmer = new ImageIcon(getClass().getResource("pics/blue_farmer.png"));
            buImg  = ImageIO.read(getClass().getResource("pics/blue_farmer.png"));
        } catch (Exception e) { }
        
        setPreferredSize(new Dimension(600,480));
        setLayout(null);
        
        frame = new JFrame("TEST");
        frame.setSize(600,480);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(this);
        
        frame.setVisible(true);
 
        // Polygon
        polygonX = new int[] { 100, 110, 173, 183, 183, 100 };
        polygonY = new int[] { 110, 100, 100, 110, 214, 214 };
        polygon = new Polygon(polygonX, polygonY, 6);
 
        tpaint = new TexturePaint(buImg, polygon.getBounds2D());
 
        Thread th = new Thread(this);
        th.start();
    }
 
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        //Hier nix machen mit g ausser vielleicht ein cast !!!!
        Graphics2D g2d = (Graphics2D) g;
        
        
        g.setColor(Color.GREEN);
        g.fillRect(20,20,200,400);
        
        g.setColor(Color.BLACK);
        g.fillRect(240, 20, 200, 400);
        
        tpaint = new TexturePaint(buImg, polygon.getBounds2D());
        g2d.setPaint(tpaint);
        g2d.drawPolygon(polygon);
        g2d.fillPolygon(polygon);
    }
 

		public void run() {
			while(frame.isVisible()){
        polygon.translate(1, 1);
        repaint();

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            // nichts
        }
    }
			
		}
}
 

Michael...

Top Contributor
Naja, Der Timer ruft alle 3 Millisekunden die run des TimerTask auf, der 20 mal das Polygon verschiebt und Neuzeichnet, dabei jedes Mal 100 Millisekunden wartet. Warum nicht gleich den Timer mit einer Periodendauer von 100 ms laufen lassen und dafür im TimerTask keine Schleife und kein sleep verwenden.

Ausserdem warum die überschriebene update(). Das sollte eingentlich für so einen Zweck nicht notwendig sein. Warum zeichnest Du überhaupt das Polygon, warum nicht einfach nur das Bild des Bauern?

Wenn's mit JLabel besser läuft, könntest Du die Methode beibehalten. JLabel ist ja transparent. Das Polygon könntest Du parallel mitändern und somit auch dessen contains nutzen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
U Wie funktioniert Polygon? AWT, Swing, JavaFX & SWT 1
M Polygon per Drag&Drop verschieben AWT, Swing, JavaFX & SWT 26
C Polygon Koordinaten richtig sortieren AWT, Swing, JavaFX & SWT 7
S GeneralPath in Polygon umwandeln..? AWT, Swing, JavaFX & SWT 5
Q AWT Path2D Polygon mit "Loch" AWT, Swing, JavaFX & SWT 0
S Polygon mit double-Koordinaten AWT, Swing, JavaFX & SWT 2
S AWT Skalieren von Polygon über Area klappt nicht AWT, Swing, JavaFX & SWT 4
S Swing Polygon-Button AWT, Swing, JavaFX & SWT 21
C Clipping funktioniert mit eigenem Polygon nicht AWT, Swing, JavaFX & SWT 8
B Polygon mit contains() nutzen AWT, Swing, JavaFX & SWT 4
F polygon object "stirbt" vor Ausführung in paint() AWT, Swing, JavaFX & SWT 4
U offenes Polygon AWT, Swing, JavaFX & SWT 2
D Polygon mit der Maus zeichnen AWT, Swing, JavaFX & SWT 2
K Polygon in image variable? AWT, Swing, JavaFX & SWT 2
P Animation läuft nicht korrekt AWT, Swing, JavaFX & SWT 8
Ernesto95 JavaFX Return Value nach Beendigung einer Animation AWT, Swing, JavaFX & SWT 15
H Simple Animation mit Swing AWT, Swing, JavaFX & SWT 2
DeBoiJoshua 2D-Grafik Gif Animation will nicht laden AWT, Swing, JavaFX & SWT 1
S JavaFX WebView zeigt keine Animation AWT, Swing, JavaFX & SWT 5
E showAndWait is not allowed during animation or layout processing Memory FX AWT, Swing, JavaFX & SWT 2
A 2D-Grafik Ruckelfreie Animation AWT, Swing, JavaFX & SWT 20
L JavaFX Animation, erst zeichnen dann anzeigen AWT, Swing, JavaFX & SWT 4
L JavaFX Animation für Panel wechsel AWT, Swing, JavaFX & SWT 3
J Java FX Koordinaten NACH Animation setzen, wie? AWT, Swing, JavaFX & SWT 9
Pr0m3theus Animation nach Event AWT, Swing, JavaFX & SWT 6
F JavaFX Timeline Animation soll X- und Y-Position während Animation ändern AWT, Swing, JavaFX & SWT 2
javampir 2D-Grafik Effizienz bei animation AWT, Swing, JavaFX & SWT 0
C Pixel-Rendering/Animation Performance in BufferedImage AWT, Swing, JavaFX & SWT 1
wolfgang63 JavaFX Animation, Kreise im vorgegebem Takt durchs Fenster laufen lassen AWT, Swing, JavaFX & SWT 3
P Ansatz für 2D Animation gesucht AWT, Swing, JavaFX & SWT 2
Thallius HHübsche Kopier Animation? AWT, Swing, JavaFX & SWT 5
L JPanel kleine "Animation" AWT, Swing, JavaFX & SWT 7
E Animation läuft nicht mehr flüssig AWT, Swing, JavaFX & SWT 8
E Warum macht die einfache Animation einen kleinen Fehler? AWT, Swing, JavaFX & SWT 14
B 2D-Grafik Dynamisches Erstellen von Images und deren Animation AWT, Swing, JavaFX & SWT 4
R Swing Komponenten bleiben bei Animation unsichtbar AWT, Swing, JavaFX & SWT 7
J GIF Animation AWT, Swing, JavaFX & SWT 2
B Swing Thread+Animation AWT, Swing, JavaFX & SWT 7
R Swing Animation mit JLayeredPane? AWT, Swing, JavaFX & SWT 8
K 3D-Grafik Animation AWT, Swing, JavaFX & SWT 4
U Gif Animation mit JLabel AWT, Swing, JavaFX & SWT 3
P KeyListener + Animation AWT, Swing, JavaFX & SWT 2
D 2D-Grafik Animation flackert AWT, Swing, JavaFX & SWT 8
StupidAttack Animation, JComponent AWT, Swing, JavaFX & SWT 3
S SWT Rudimentäre Bild Animation AWT, Swing, JavaFX & SWT 3
C Animation auf einem JPanel AWT, Swing, JavaFX & SWT 3
A paintComponent() - Animation AWT, Swing, JavaFX & SWT 2
S Ich brauche eine Idee: Animation mit teil eines Bildes AWT, Swing, JavaFX & SWT 16
H "Animation" AWT, Swing, JavaFX & SWT 2
S Animation korrekt darstellen AWT, Swing, JavaFX & SWT 8
Developer_X Nach Animation Button adden AWT, Swing, JavaFX & SWT 3
Developer_X Swing JPanel-THE ANIMATION AWT, Swing, JavaFX & SWT 3
T JFrame und Scale-Animation AWT, Swing, JavaFX & SWT 8
M Animation berechnen AWT, Swing, JavaFX & SWT 4
M Animation auf JPanel per Knopfdruck AWT, Swing, JavaFX & SWT 12
P Problem bei Animation AWT, Swing, JavaFX & SWT 2
K Animation auf GUI AWT, Swing, JavaFX & SWT 3
R ruckelfreie animation AWT, Swing, JavaFX & SWT 8
T Animation will nicht trotz Thread. AWT, Swing, JavaFX & SWT 14
S animation Flackern trotz doppelpufferung wieso? AWT, Swing, JavaFX & SWT 2
S Animation geht nicht AWT, Swing, JavaFX & SWT 3
m@nu Animation in GlassPane: Performanceeinbruch JFrame maximiert AWT, Swing, JavaFX & SWT 17
rudi.schraml Animation von Robotern auf FactoryFloor - repaint()? AWT, Swing, JavaFX & SWT 7
J Animation - Runnable AWT, Swing, JavaFX & SWT 3
O Animation in einem JPanel AWT, Swing, JavaFX & SWT 2
H Animation startet nicht/ Thread AWT, Swing, JavaFX & SWT 6
N Animation nach einem bestimmten Ereignis starten lassen? AWT, Swing, JavaFX & SWT 4
A Problem mit Animation AWT, Swing, JavaFX & SWT 4
M Animation mit Keylistener AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben