Ping Pong langsam

1

123fa241

Gast
Hi!

ich will ein Ping-Pong-Spiel machen, jedoch ist es sehr langsam (AMD Phenom II 2x2.8Ghz / ATI Radeon HD 5850):
(Code soll noch keinen spielerischen Zweck erfüllen, soll einfach nur einen pendeldenen Punkt darstellen)

Java:
public class GamePanel extends JPanel implements Runnable {
    private ArrayList<FieldObject> objects;

    private Barrier topBarrier;
    private Barrier rightBarrier;
    private Barrier bottomBarrier;
    private Barrier leftBarrier;

    private Kugel kugel;
    private boolean gameRunning = true;

    private Thread gameThread;

    public GamePanel(Dimension dim) {
        objects = new ArrayList<FieldObject>();
        setPreferredSize(dim);

        topBarrier = new Barrier(new Dimension(500, 10), new Point(0, 0));
        rightBarrier = new Barrier(new Dimension(10, 480), new Point(490, 10));
        bottomBarrier = new Barrier(new Dimension(500, 10), new Point(0, 490));
        leftBarrier = new Barrier(new Dimension(10, 480), new Point(0, 10));

        kugel = new Kugel(new Dimension(20, 20), new Point(250, 250));

        objects.add(topBarrier);
        objects.add(rightBarrier);
        objects.add(bottomBarrier);
        objects.add(leftBarrier);


        gameThread = new Thread(this);
        gameThread.start();
    }

    public FieldObject checkCollision(FieldObject obj1) {
        for (FieldObject obj2 : objects) {
            if (obj2.isPointInside(obj1.getLocation()) && !obj2.equals(obj1)) return obj2;
        }
        return null;
    }

    public void run() {

        final int LEFT = 0;
        final int RIGHT = 1;

        int direction = LEFT;

        while (gameRunning) {

            if (direction == LEFT) {
                kugel.setLocation(new Point(--kugel.getLocation().x, kugel.getLocation().y));
                if (checkCollision(kugel) != null) direction = RIGHT;
            }
            else {
                kugel.setLocation(new Point(++kugel.getLocation().x, kugel.getLocation().y));

                if (checkCollision(kugel) != null) direction = LEFT;
            }

            try {
                gameThread.sleep(5);
            }
            catch (Exception exc) {}

            repaint();
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        
        g.drawPolygon(topBarrier.getPolygon());
        g.fillPolygon(topBarrier.getPolygon());
        g.drawPolygon(rightBarrier.getPolygon());
        g.fillPolygon(rightBarrier.getPolygon());
        g.drawPolygon(bottomBarrier.getPolygon());
        g.fillPolygon(bottomBarrier.getPolygon());
        g.drawPolygon(leftBarrier.getPolygon());
        g.fillPolygon(leftBarrier.getPolygon());
        
        g.setColor(Color.BLUE);
        g.fillPolygon(kugel.getPolygon());
    }
}
 
Zuletzt bearbeitet von einem Moderator:

Antoras

Top Contributor
Was heißt sehr langsam? Niedrige FPS oder bewegt sich der Punkt schlicht zu langsam? Bei ersterem müsstest du mal ein KSKB bauen - in deinem geposteten Code kann ich nichts erkennen was unnötig viel Leistung verbraucht. Den Punkt kannst du schneller machen indem du seine Bewegungsschritte pro Durchlauf erhöhst (also von momentan 1 auf z.B. 10).
 
D

dhe325

Gast
Er bewegt sich am Bildschirm ungleichmäßig und ruckelt. FPS habe ich aber scheinbar 194/195.

Klassen:

Java:
public class Main {
    public static void main(String[] args) {
        new MainFrame().setVisible(true);
    }
}

Java:
public class MainFrame extends JFrame {
    private JPanel gamePanel;
    private Dimension fieldSize;

    public MainFrame() {
        super();

        fieldSize = new Dimension(500, 500);
        gamePanel = new GamePanel(fieldSize);
        gamePanel.setBackground(Color.WHITE);
        add(gamePanel);
        pack();
    }
}

Java:
public class GamePanel extends JPanel implements Runnable {
    private ArrayList<FieldObject> objects;

    private Barrier topBarrier;
    private Barrier rightBarrier;
    private Barrier bottomBarrier;
    private Barrier leftBarrier;

    private Kugel kugel;
    private boolean gameRunning = true;

    private Thread gameThread;



        long firstFrame;
        int frames;
        long currentFrame;
        int fps;


    public GamePanel(Dimension dim) {
        objects = new ArrayList<FieldObject>();
        setPreferredSize(dim);

        topBarrier = new Barrier(new Dimension(500, 10), new Point(0, 0));
        rightBarrier = new Barrier(new Dimension(10, 480), new Point(490, 10));
        bottomBarrier = new Barrier(new Dimension(500, 10), new Point(0, 490));
        leftBarrier = new Barrier(new Dimension(10, 480), new Point(0, 10));

        kugel = new Kugel(new Dimension(20, 20), new Point(250, 250));

        objects.add(topBarrier);
        objects.add(rightBarrier);
        objects.add(bottomBarrier);
        objects.add(leftBarrier);


        gameThread = new Thread(this);
        gameThread.start();
    }

    public FieldObject checkCollision(FieldObject obj1) {
        for (FieldObject obj2 : objects) {
            if (obj2.isPointInside(obj1.getLocation()) && !obj2.equals(obj1)) return obj2;
        }
        return null;
    }

    public void run() {

        final int LEFT = 0;
        final int RIGHT = 1;

        int direction = LEFT;

        while (gameRunning) {

            if (direction == LEFT) {
                kugel.setLocation(new Point(--kugel.getLocation().x, kugel.getLocation().y));
                if (checkCollision(kugel) != null) direction = RIGHT;
            }
            else {
                kugel.setLocation(new Point(++kugel.getLocation().x, kugel.getLocation().y));

                if (checkCollision(kugel) != null) direction = LEFT;
            }

            try {
                gameThread.sleep(5);
            }
            catch (Exception exc) {}

            repaint();
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        // fps
        frames++;
        currentFrame = System.currentTimeMillis();

        if (currentFrame > firstFrame + 1000) {
            firstFrame = currentFrame;
            fps = frames;
            frames = 0;
        }

        g.fillPolygon(topBarrier.getPolygon());
        g.fillPolygon(rightBarrier.getPolygon());
        g.fillPolygon(bottomBarrier.getPolygon());
        g.fillPolygon(leftBarrier.getPolygon());
        
        g.setColor(Color.BLUE);
        g.fillPolygon(kugel.getPolygon());

        g.setColor(Color.RED);
        g.drawString("FPS: " + fps, 10, 20);
    }
}

Java:
public abstract class FieldObject {
    protected Point location;
    protected Dimension size;

    public FieldObject(Dimension size, Point location) {
        this.location = location;
        this.size = size;
    }

    public boolean isPointInside(Point p) {

        if (p.x >= location.x
            && p.y >= location.y
            && p.x <= location.x + size.width
            && p.y <= location.y + size.height)
            
            return true;
        else
            return false;
    }



    /**
     * @return the location
     */
    public Point getLocation() {
        return location;
    }

    /**
     * @param location the location to set
     */
    public void setLocation(Point location) {
        this.location = location;
    }

    /**
     * @return the size
     */
    public Dimension getSize() {
        return size;
    }

    /**
     * @param size the size to set
     */
    public void setSize(Dimension size) {
        this.size = size;
    }

    public Polygon getPolygon() {
        int[] xints = {location.x, location.x + size.width, location.x + size.width, location.x};
        int[] yints = {location.y, location.y, location.y + size.height, location.y + size.height};

        Polygon poly = new Polygon(xints, yints, 4);
        return poly;
    }

}

Java:
public class Barrier extends FieldObject {

    private Point point1;
    private Point point2;
    private Point point3;
    private Point point4;


    public Barrier(Dimension size, Point location) {
        super(size, location);
        this.size = size;

        point1 = location;
        point2 = new Point((int) location.getX() + size.width, (int) location.getY());
        point3 = new Point((int) location.getX() + size.width, (int) location.getY() + size.height);
        point4 = new Point((int) location.getX(), (int) location.getY() + size.height);
        
    }

    @Override
    public Polygon getPolygon() {
        int[] xints = {point1.x, point2.x, point3.x, point4.x};
        int[] yints = {point1.y, point2.y, point3.y, point4.y};

        Polygon poly = new Polygon(xints, yints, 4);
        return poly;
    }

    /**
     * @return the point1
     */
    public Point getPoint1() {
        return point1;
    }

    /**
     * @param point1 the point1 to set
     */
    public void setPoint1(Point point1) {
        this.point1 = point1;
    }

    /**
     * @return the point2
     */
    public Point getPoint2() {
        return point2;
    }

    /**
     * @param point2 the point2 to set
     */
    public void setPoint2(Point point2) {
        this.point2 = point2;
    }

    /**
     * @return the point3
     */
    public Point getPoint3() {
        return point3;
    }

    /**
     * @param point3 the point3 to set
     */
    public void setPoint3(Point point3) {
        this.point3 = point3;
    }

    /**
     * @return the point4
     */
    public Point getPoint4() {
        return point4;
    }

    /**
     * @param point4 the point4 to set
     */
    public void setPoint4(Point point4) {
        this.point4 = point4;
    }
}

Java:
public class Kugel extends FieldObject {
    private int speed;
    private int direction;

    public Kugel(Dimension size, Point location) {
        super(size, location);
    }

    /**
     * @return the speed
     */
    public int getSpeed() {
        return speed;
    }

    /**
     * @param speed the speed to set
     */
    public void setSpeed(int speed) {
        this.speed = speed;
    }

    /**
     * @return the direction
     */
    public int getDirection() {
        return direction;
    }

    /**
     * @param direction the direction to set
     */
    public void setDirection(int direction) {
        this.direction = direction;
    }

    
}
 

Antoras

Top Contributor
Ich hab den Code mal ausgeführt, bei mir läuft er aber ruckelfrei. Ich hab zwar keine Ahnung warum das bei dir ruckelt, aber poste mal noch dein OS, JDK version usw.

Vllt. kann dir mit diesen Informationen sonst noch jemand weiterhelfen.

Ändere mal noch die Stelle an der du den Thread schlafen legst in:
Java:
try {
	Thread.sleep(5);
} catch (final Exception exc) {
	exc.printStackTrace();
}
Das ändert zwar nichts an der Ausführung deines Codes, da du mit
Code:
sleep
aber immer nur auf den gerade aktiven Thread zugreifen kannst solltest du die Methode über den statischen Weg aufrufen. Und niemals eine Exception verschlucken.

Edit: Bringt es vllt. eine Verbesserung, wenn du dein GUI auf der EventQueue startest?
Java:
public static void main(final String[] args) {
	EventQueue.invokeLater(new Runnable() {
		@Override
		public void run() {
			new MainFrame().setVisible(true);
		}
	});
}
 
Zuletzt bearbeitet:
2

2343d2

Gast
Hi!

Ich verwende Ubuntu 10.10 x64 mit den aktuellsten 3D-Treibern.

VM:
Code:
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.2) (6b20-1.9.2-0ubuntu2)
OpenJDK 64-Bit Server VM (build 19.0-b09, mixed mode)

Probiere es gleich mal noch in Windows.
 
1

14asd14

Gast
Unter Windows 7 x64 läufts nun auch perfekt und ruckelfrei^^
Dann liegts wohl an meinem Ubuntu... aber wo genau?
 

Antoras

Top Contributor
Könnte auch am OpenJDK liegen oder verwendest du das unter Widows auch? Wenn du keinen triftigen Grund hast das zu verwenden könntest du mal schauen ob es was bringt wenn du mal das JDK von Oracle installierst.
 

Empire Phoenix

Top Contributor
try {
gameThread.sleep(5);
}
catch (Exception exc) {}

Hm also jeder tick dauert bearbeitungszeit + 5 ms
das sollteste mal ändern das die tickrate fest ist
Also threa.sleep(10-bearbeitungszeit)
bearbeitungszeit kannste mit System.currenttimeinmillis einfach berehcen aus differenz vorher nachher
 
A

axscas

Gast
Hi!

Danke für den Tipp mit der gleichen Tickrate, jedoch hat das keine Besserung gebracht.
Selbiges Problem besteht mit der Nutzung des OpenJDKs und des offiziellen Oracle-JDKs.
 

Ivan Dolvich

Mitglied
Ich glaube kaum, dass es an der JDK liegt. Ich laufe auch mit OpenJDK und das ruckeln ist nur minimal und messbar:
Wenn man in der [c]GamePanel.paintComponent(Graphics g)[/c] Sich folgendes am anfang der Methode ausgeben lässt:
Java:
System.out.println(System.currentTimeMillis() - currentFrame);

Dann bekomme ich eine schwankung von 2 - 18ms. Deshalb würde ich das ganze auf Swing schieben, welches ja eher nicht für High-End-Grafik ( ;D )ausgelegt ist.

Ich würde mir überlegen, da bisschen mehr arbeit rein zu stecken und sich ins Thema Double Buffering mit Java beschäftigen. Bei Google gibt es dafür wirklich viel gutes Zeug.
 

Quaxli

Top Contributor
Ich habe mir das Programm mal angesehen. Auf meiner 4 Jahre alten Büro-Möhre (die demnächst endlich getauscht wird) läuft es nichtsdestotrotz flüssig.
Allerdings fand ich es etwas umständlich programmiert. Mir ist z. B. in der jetzigen Version nicht klar, warum da noch Polygone erzeugt werden und auch warum die Objekte die Klassen Punkt und Dimension als Instanzvariable beinhalten statt von Rectanlge zu erben (oder von Rectangle2D falls man genauer rechnen will/muß, ist mir nicht ganz klar. Außerdem hat die Kollision mit der rechten Barriere nicht wirklich funktioniert.

Ich habe daher mal dran rum gefrickelt. :D Unter anderem habe ich die Klasse FieldObject rausgeworfen, die für diese Version nicht wirklich gebraucht wird (später könnte die durchaus Sinn machen). Außerdem habe ich die (Instanz-)Variablen ziemlich ausgedünnt, sowie einige vorhanden Methoden genutzt, wie z. B. intersects(..) von Rectangle oder fillRectangle(..) aus Graphics.
Damit wird das Ganz nach meinem Dafürhalten etwas übersichtlicher.

Du kannst ja mal drüber gucken und das, was Dir gefällt, übernehmen. ;) Ob es Dein eigentliches Problem löst, weiß ich aber nicht, vielleicht bringt es aber ein bißchen was, da einige Rechenschritte fehlen. :bahnhof:

1. Die Hauptklasse:

Java:
import javax.swing.*;
import java.awt.*;

public class MainFrame extends JFrame {

	private static final long	serialVersionUID	= 1L;
	  
  //Main-Methode kann auch hier rein
	public static void main(String[] args) {
		new MainFrame();
	}

	public MainFrame() {
		super();
		GamePanel gamePanel = new GamePanel(new Dimension(500,500));
		gamePanel.setBackground(Color.WHITE);
		add(gamePanel);
		pack();
    setVisible(true); //gehört meines Erachtens hierher
	}
	
}

2. GamePanel

Java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.*;
import java.util.ArrayList;

import javax.swing.JPanel;

public class GamePanel extends JPanel implements Runnable {

	private static final long	serialVersionUID	= 1L;
	
	private ArrayList<Rectangle> 	objects;
	private Kugel										kugel;
	private boolean									gameRunning	= true;
	long														firstFrame;
	int															frames;
	long														currentFrame;
	int															fps;

	
	public GamePanel(Dimension dim) {
		objects = new ArrayList<Rectangle>();
		setPreferredSize(dim);

		Barrier topBarrier = new Barrier(0,0,500,10);
		Barrier rightBarrier = new Barrier(490,10,10,480);
		Barrier bottomBarrier = new Barrier(0,490,500,10);
		Barrier leftBarrier = new Barrier(0,10,10,480);
		kugel = new Kugel(250,250,20,20);

		objects.add(topBarrier);
		objects.add(rightBarrier);
		objects.add(bottomBarrier);
		objects.add(leftBarrier);

		Thread th = new Thread(this);
		th.start();
	}



	public void run() {

		while (gameRunning) {

      kugel.moveObject();
      
      //Kollisionen mal hier gehören aber in extra Methode
      //Die Logik hier paßt nicht mehr, sobald sich die Kugel auch in y-Richtung bewegt!!!
      for(Rectangle r:objects){
      	if(kugel.intersects(r)){
      		kugel.setSpeed(-kugel.getSpeed());
      	}
      }
      
      
			try {
				Thread.sleep(5);
			} catch (Exception exc) {
			}

			repaint();
		}
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);

		// fps
		frames++;
		currentFrame = System.currentTimeMillis();

		if (currentFrame > firstFrame + 1000) {
			firstFrame = currentFrame;
			fps = frames;
			frames = 0;
		}

		for(Rectangle r:objects){
			Barrier b = (Barrier)r;
			b.drawBarrier(g);
		}

		g.setColor(Color.BLUE);
    kugel.drawKugel(g);

		g.setColor(Color.RED);
		g.drawString("FPS: " + fps, 10, 20);
	}
}

3. Barrier

Java:
import java.awt.*;

class Barrier extends Rectangle {


	public Barrier(int x, int y, int w, int h) {
		super(x,y,w,h);
	}

	public void drawBarrier(Graphics g){
		g.fillRect(x, y, width, height);
	}
	
}

4. Kugel

Java:
import java.awt.*;

class Kugel extends Rectangle {

	private static final long	serialVersionUID	= 1L;
	private int	speed = 1;

	public Kugel(int x,int y,int w,int h) {
		super(x,y,w,h);
	}

	public int getSpeed() {
		return speed;
	}

	public void setSpeed(int speed) {
		this.speed = speed;
	}

	public void moveObject(){
		x+=speed;
	}
	
	public void drawKugel(Graphics g){
		g.fillRect(x, y, width, height);
	}


}
 
G

Grillmeister

Gast
Hi,

versuch mal die Geschwindigkeit der Kugel mit der vergangenen Zeit zu multiplizieren:

(vergangene Zeit zur letzten Bewegung)*Geschwindigkeit

Bei dir ist die Geschwindigkeit des Balls nämlich von den FPS abhängig und kann deshalb variieren.
 

Quaxli

Top Contributor
Hi,

versuch mal die Geschwindigkeit der Kugel mit der vergangenen Zeit zu multiplizieren:

(vergangene Zeit zur letzten Bewegung)*Geschwindigkeit

Bei dir ist die Geschwindigkeit des Balls nämlich von den FPS abhängig und kann deshalb variieren.

Da käme was raus.... :autsch:
Wenn, sollte man das schon korrekt angeben:

durchschnittliche Bewegung = Geschwindigkeit * Zeit für den Schleifendurchlauf / 1e9

Die Geschwindigkeit sind dabei Pixel/s
Die Division erfolgt hier durch 1e9, da ich davon ausgegangen bin, daß man idealerweise die Zeit in Nanosekunden mißt.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Y Ping Pong Spiele- und Multimedia-Programmierung 4
M Einfaches Ping-Pong Spiel Spiele- und Multimedia-Programmierung 3
J ping pong ball abprallen lassen Spiele- und Multimedia-Programmierung 12
L Java Ping Pong Spiele- und Multimedia-Programmierung 1
S Ping Pong: KeyListener in Paint und while Spiele- und Multimedia-Programmierung 10
G Ping Pong Frage Spiele- und Multimedia-Programmierung 17
B Ping Pong Spiele- und Multimedia-Programmierung 11
R Ping Pong Spiel Fehlermeldung Spiele- und Multimedia-Programmierung 12
R Ping Pong Spiel Spiele- und Multimedia-Programmierung 28
J Probleme bei Pong Spiele- und Multimedia-Programmierung 9
J Pong Programm Spiele- und Multimedia-Programmierung 1
T Pong Hilfe bei einer Website Spiele- und Multimedia-Programmierung 4
S Pong java.lang.StackOverflowError Spiele- und Multimedia-Programmierung 3
R Pong Spiel Problem Spiele- und Multimedia-Programmierung 1
B LWJGL StackOverFlow Problem nach 30sekunden. (Pong) Spiele- und Multimedia-Programmierung 2
T Torquemada´s erstes Game (Pong) Spiele- und Multimedia-Programmierung 5
A Pong Grafikgestaltung Spiele- und Multimedia-Programmierung 10
R Pong -Reruns möglich machen Spiele- und Multimedia-Programmierung 2
Y Pong Spiel Score Zähler! -.- Spiele- und Multimedia-Programmierung 18
U Pong Spiele- und Multimedia-Programmierung 7
BattleMaster246 Pong - JOGL Spiele- und Multimedia-Programmierung 2
J Tips für ein kleines Pong-Applet Spiele- und Multimedia-Programmierung 4
D Java Pong Probleme Spiele- und Multimedia-Programmierung 7
W Hilfe bei Pong mit Bluej Spiele- und Multimedia-Programmierung 4
M Fragen zu meinem Pong-Clone Spiele- und Multimedia-Programmierung 6
L Probleme Bei Pong Programmierung Spiele- und Multimedia-Programmierung 2
G Pong klon mit Steuerungsprobleme Spiele- und Multimedia-Programmierung 8
B Pong-Klon. Denkfehler bei kollisionstest Spiele- und Multimedia-Programmierung 3
N Pong - noch 2 kleinere Probleme Spiele- und Multimedia-Programmierung 16
G Pong-Klon (Applet!) Spiele- und Multimedia-Programmierung 4
H Performance check Pong Spiele- und Multimedia-Programmierung 19
R Verschieben von Objekten langsam Spiele- und Multimedia-Programmierung 0
W Spiel ist langsam/laggt Spiele- und Multimedia-Programmierung 18
B LWJGL Display.update() ist langsam Spiele- und Multimedia-Programmierung 5
X TiledMap "langsam" verschieben Spiele- und Multimedia-Programmierung 8
O A* funktioniert, aber zu langsam Spiele- und Multimedia-Programmierung 10
M Robot zu langsam Spiele- und Multimedia-Programmierung 4
T Java zu langsam Spiele- und Multimedia-Programmierung 22
T BufferedImage#setRGB #getRGB zu langsam Spiele- und Multimedia-Programmierung 4
B Buttontexte langsam nacheinander erscheinen lassen Spiele- und Multimedia-Programmierung 3
T Mein Vektor-Zeichenprogramm ist zu langsam Spiele- und Multimedia-Programmierung 4
P bildskalierung zu langsam Spiele- und Multimedia-Programmierung 4
J soundlösung zu langsam für spiele Spiele- und Multimedia-Programmierung 16

Ähnliche Java Themen

Neue Themen


Oben