getSubImage sorgt für starken Performanceeinbruch

I

Idiat

Gast
Hallo zusammen,

beim Anzeigen eines Tilesets in einem FullScreen und beim darstellen einer Spielfigur
tritt bei mir das Problem auf, dass sich die Spielfigur nur sehr unflüssig bewegt.

Nach längerem suchen fiel mir dann auf, dass die getSubImage()-Methode für dieses Problem sorgt.

Mein Vorgehen: Ich schneide mit Hilfe des Codes unten 32x32 große Bilder aus einem großten Tileset aus und lade diese in eine ArrayList (tiles).

Java:
int width=picTileset.getWidth()/32;
int height=picTileset.getHeight()/32;	
for(int x=0;x<width;x++){
	for(int y=0;y<height;y++){
		tile = picTileset.getSubimage(x*32, y*32, 32, 32);
		this.tiles.add(tile);			
	}
}
(selber Code ist auch im unteren vorhanden)

Wenn ich die Bilder einzeln in die ArrayList lade und anzeige geht das ganze problemlos,
sobald ich auch nur ein Image mit getSubImage clippe geht es nicht mehr und es muss ja
wohl eine Möglichkeit geben dies über getSubImage zu machen statt die Grafiken
alle einzeln zu laden.

Woran liegt das ganze?

Außerdem fiel mir auf, dass es beim Bewegen der Grafik zur Anschlagverzögerung von Windows
kommt, wenn man eine Taste gedrückt hält. Sprich: Die Grafik bewegt sich erst einmal
und dann nach längerem Halten durchgehend. Wie kann ich das ganze umgehen ohne
die Verzögerung in Windows herunterzusetzen? Schließlich hab ich das Problem in anderen
2D-Spielen auch nicht.


Hier der gesamte Code, hoffe er ist nicht zu lang.

Main.java
Java:
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;

public class Main implements KeyListener {	
	
    private static DisplayMode modes[] = {
        new DisplayMode(800, 600, 32,0),
        new DisplayMode(800, 600, 24,0),
        new DisplayMode(800, 600, 16,0),
        new DisplayMode(640, 480, 32,0),
        new DisplayMode(640, 480, 24,0),
        new DisplayMode(640, 480, 16,0),
    };
    
    private boolean running;
    protected ScreenManager s;
    
    //tile engine
    ArrayList<BufferedImage> tiles = new ArrayList<BufferedImage>();
    public Image face;
    public BufferedImage tile;
    public BufferedImage test;
    
    int map_width = 32;
    int map_height = 24;
	
    int[][][] map = new int[map_width][map_height][3];
    
    int sx = 32;
    int sy = 32;
    
    String mess = "";
    
    public static void main(String[] args){
        Main c = new Main();
    	c.run();
    }

    //stop method
    public void stop() {
        running = false;
    }
    
    //call init and gameloop
    public void run() {
        try{
            init();     
            loadImages();
            loadMap();
            gameLoop();
 
        }finally{
            s.restoreScreen();
        }
    }
    
    //set to full screen
    public void init() {
        s = new ScreenManager();
        DisplayMode dm = s.findFirstCompatibleMode(modes);
        s.setFullScreen(dm);
        
        Window w = s.getFullScreenWindow();
        w.setFocusTraversalKeysEnabled(false);
        w.addKeyListener(this);
        w.setFont(new Font("Arial", Font.PLAIN, 20));
        w.setBackground(Color.BLACK);
        w.setForeground(Color.WHITE);
        running = true;
 
        mess = "press escape to exit";
    }

    
    //load images
    public void loadImages(){

		try {
			BufferedImage picTileset=ImageIO.read(new File("gfx/Tileset2.png"));	
			int width=picTileset.getWidth()/32;
			int height=picTileset.getHeight()/32;	
			for(int x=0;x<width;x++){
				for(int y=0;y<height;y++){
					tile = picTileset.getSubimage(x*32, y*32, 32, 32);
					this.tiles.add(tile);			
				}
			}	
			
		}catch (IOException error){
			System.err.println("gfx not found");
			error.printStackTrace();
		}  
        face = new ImageIcon("gfx/face.png").getImage();       
    }
    
    public void loadMap(){
    	
		try {
			BufferedInputStream buf=new BufferedInputStream(new FileInputStream("D:\\test.test"));
			ObjectInputStream read = new ObjectInputStream(buf);

			map=(int[][][]) read.readObject();
			String name=(String) read.readObject();
			String fileName=(String) read.readObject();

			read.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
		}
    }
    
    //main gameLoop
    public void gameLoop() {
        long startTime = System.currentTimeMillis();
        long cumTime = startTime;
        
        while(running){
            long timePassed = System.currentTimeMillis() - cumTime;
            cumTime += timePassed;
            
            update(timePassed);
            
            Graphics2D g = s.getGraphics();
            draw(g);
            g.dispose();
            s.update();
            
            try{
                Thread.sleep(20);
            }catch(Exception ex){}
        }
    }
    
    
    //keyPressed
    public void keyPressed(KeyEvent ke){
        
    	int keyCode = ke.getKeyCode();
        if(keyCode == KeyEvent.VK_ESCAPE){
            stop();   
        }else if(keyCode== KeyEvent.VK_F1){
        	
        }else{
            mess = "Pressed : "+KeyEvent.getKeyText(keyCode);
            ke.consume();
        }	
        
    	
        switch (ke.getKeyCode()) {
        case KeyEvent.VK_RIGHT: {
            sx+=2;
        }
        break;
        case KeyEvent.VK_LEFT: {
            sx-=2;
        }
        break;
        case KeyEvent.VK_DOWN: {
            sy+=2;
        }
        break;
        
        case KeyEvent.VK_UP: {
            sy-=2;
        }
        break;
    }
      
    }
    
    //keyReleased
    public void keyReleased(KeyEvent e){
        int keyCode = e.getKeyCode();
        mess = "Released : "+KeyEvent.getKeyText(keyCode);
        e.consume();
    }
    
    //last method from interface
    public void keyTyped(KeyEvent e){
        e.consume();
    }
    
    //update animation
    public void update(long timePassed){
        
    }

    //draws to screen
    public void draw(Graphics2D g){
        Window w = s.getFullScreenWindow();
      
        g.setColor(w.getBackground());
        g.fillRect(0, 0, s.getWidth(), s.getHeight());
        g.setColor(w.getForeground());
  
    	for(int x=0;x < map.length;x++){
			for(int y=0;y < map[0].length;y++){
				for(int z=0; z<=0; z++){
					if(map[x][y][z] != 0){				
						g.drawImage(tiles.get(0), x*32, y*32, null);
					}	
				}
			}
		}	      
        g.drawImage(face, sx, sy, null);
        g.drawString(mess, 30, 30);     
	}
}

ScreenManager.java
Java:
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

public class ScreenManager {

private GraphicsDevice vc;
    
    // give vc access to monitor screen
    public ScreenManager() {
        GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
        vc = e.getDefaultScreenDevice();      
    }
    
    //get all compatible DM
    public DisplayMode[] getCompatibleDisplayModes() {
        return vc.getDisplayModes();
    }

    //compares DM passed in vc DM and see if they match
    public DisplayMode findFirstCompatibleMode(DisplayMode modes[]) {
        DisplayMode goodModes[] = vc.getDisplayModes();
        for(int x=0; x<modes.length; x++) {
            for(int y=0; y<goodModes.length;y++) {
                if(displayModesMatch(modes[x],goodModes[y])) {
                    return modes[x];
                }
            }
        }
        return null;
    }
            
    //get current DM
    public DisplayMode getCurrentDisplayMode() {
        return vc.getDisplayMode();       
    }
    
    //checks if two modes match each other
    public boolean displayModesMatch(DisplayMode m1, DisplayMode m2) {
        if(m1.getWidth() != m2.getWidth() || m1.getHeight() != m2.getHeight()){
            return false;
        }
        if(m1.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m2.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI && m1.getBitDepth() != m2.getBitDepth()){
            return false;
        }
        if(m1.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m2.getRefreshRate() != DisplayMode.REFRESH_RATE_UNKNOWN && m1.getRefreshRate() != m2.getRefreshRate()){
            return false;
        }
        
        return true;
    }
    
    //make frame full screen
    public void setFullScreen(DisplayMode dm) {
        JFrame f = new JFrame();
        f.setUndecorated(true);
        f.setIgnoreRepaint(true);
        f.setResizable(false);
        vc.setFullScreenWindow(f);
        
        if(dm != null && vc.isDisplayChangeSupported()){
            try{
                vc.setDisplayMode(dm);
            }catch(Exception ex){}
        }
        f.createBufferStrategy(2);     
    }   
    
    //set graphics object = to this
    public Graphics2D getGraphics(){
        Window w = vc.getFullScreenWindow();
        if(w != null){
            BufferStrategy s = w.getBufferStrategy();
            return (Graphics2D)s.getDrawGraphics();
        }else{
            return null;
        }
    }
    
    //updates display
    public void update(){
        Window w = vc.getFullScreenWindow();
        if(w != null){
            BufferStrategy s = w.getBufferStrategy();
            if(!s.contentsLost()){
                s.show();
            }
        }
    }
    
    public Window getFullScreenWindow(){
        return vc.getFullScreenWindow();
    }
    
    //get width of window
    public int getWidth(){
        Window w = vc.getFullScreenWindow();
        if(w != null){
            return w.getWidth();
        }else{
            return 0;
        }
    }
    
    //get height of window
    public int getHeight(){
        Window w = vc.getFullScreenWindow();
        if(w != null){
            return w.getHeight();
        }else{
            return 0;
        }
    }
    
    //get out of full screen
    public void restoreScreen(){
        Window w = vc.getFullScreenWindow();
        if(w != null){
            w.dispose();
        }
    }
    
    //create image compatible with monitor
    public BufferedImage createCompatibleImage(int w, int h, int t){
        Window win = getFullScreenWindow();
        if(win != null){
            GraphicsConfiguration gc = win.getGraphicsConfiguration();
            return gc.createCompatibleImage(w,h,t);
        }
        return null;
    }
 
}

Beim OOP kam es bis jetzt oft zu Fehlern, deswegen gehe ich hier gerade sparsam mit mehreren Klassen um. Wird aber dann noch geändert, sobald sich die Figur mal flüssig bewegt, ich bitte also
um Verständnis und hoffe der Code ist auch so lesbar.

Viele Grüße,
Idiat
 

muckelzwerg

Bekanntes Mitglied
Schau Dir mal an, was getSubImage() macht.
Es gibt ein neues BufferedImage zurück, dafür muss der Platz angelegt werden und die Daten müssen kopiert werden.
Warum machst Du das denn so?
Du kannst doch ruhig einzelne BufferedImages verwenden. Die kannst Du ja am Anfang einmal aus einem großen Bild rausschneiden, wenn Du unbedingt eins haben willst.


Für das Problem mit den Tasten, musst Du anders arbeiten. Nimm mit dem KeyListener nur Ereignisse entgegen und leg sie in einer Queue ab. Die wird dann regelmäßig abgearbeitet. (kann auch schneller sein, als die Bildrate)
Außerdem solltest Du nicht mit "sx + ..." direkt an jedem Ereignis arbeiten, sondern Bewegungszustände ein- und ausschalten, die dann Deine Objekte bewegen.
 

JTryn

Mitglied
Super, vielen Dank! Wenn es schneller als die Bildrate ist, vermute ich, dass man das ganze dann mit einem Timer regeln muss.
Ich versuch das jetzt mal und melde mich, wenn es wieder zu
Problemen kommen sollte, danke schon einmal :)
 

muckelzwerg

Bekanntes Mitglied
Eigentlich solltest Du eine Spielschleife haben, die mit maximaler Geschwindigkeit (kann immernoch "sleep" enthalten) durchlaufen wird. Und dann entscheidest Du je nach abgelaufener Zeit, was zu tun ist. Also z.B. ob wieder gezeichnet werden soll, oder ob nur die Eingabeereignisse verarbeitet werden ...
 

Kr0e

Gesperrter Benutzer
Nochmal eben zu getSubImage(). Auch wenn es in diesem Thread um was anderes geht, wollte ich noch kurz erwaehnen, dass auch bei der Benutzung von "compatible Buffered Images" ggf. Probleme bei dieser Funktion auftreten koennen. Ich selber hatte das Problem auf meinen Rechnern bisher onch nicht, aber als ich mal meine Progamme auf anderen PCs/Plattformen getestet habe, war diese Methode recht lahm. Der Grund war damals alte/falsche TReiber. GErade bei Laptop-ATI Karten kann es passieren, dass OpenGL nicht sonderlich gut implementiert ist...
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D getsubimage aus BufferedImage und Rueckwandlung in ein ImagePlus bild Spiele- und Multimedia-Programmierung 0
B getSubimage() (ich bin einfach zu blöd) Spiele- und Multimedia-Programmierung 2
N Minecraft Frage für einen Minecraft Server Spiele- und Multimedia-Programmierung 2
Drachenbauer Speicher-Tool für ein Spiel schreiben Spiele- und Multimedia-Programmierung 13
B Deepmind Poker Bot für PokerStars konfigurieren? Spiele- und Multimedia-Programmierung 2
G Minecraft PlayerBot (Listener Thread für jeden Spieler?) Spiele- und Multimedia-Programmierung 3
K Wie bekomme ich eine Transition für alle Objekte zum stoppen? Spiele- und Multimedia-Programmierung 1
E Organisation für Game Spiele- und Multimedia-Programmierung 1
Excess Ballerfisch für Android Spiele- und Multimedia-Programmierung 3
coolian ich brauche irgendeine gui lib für lwjgl2 Spiele- und Multimedia-Programmierung 51
krgewb Anderer Algorithmus für Bounding Box Spiele- und Multimedia-Programmierung 9
MiMa MP3 Dateien für Metadaten abgleichen Spiele- und Multimedia-Programmierung 0
Freshy Bot für Discord Spiele- und Multimedia-Programmierung 61
R Ideen für die Backend-Entwicklung eines Games gesucht Spiele- und Multimedia-Programmierung 8
G Mikrophon-/Audiosteuerung für einen Character Spiele- und Multimedia-Programmierung 1
P Tennis- Spielstand- Zähler für Schule programmieren Spiele- und Multimedia-Programmierung 6
M Logik für ein Quiz Spiele- und Multimedia-Programmierung 7
P Hilfe für Seminar Arbeit Spiele- und Multimedia-Programmierung 9
MiMa Metadaten für Multimedia Daten ermitteln Spiele- und Multimedia-Programmierung 4
G Übungsprogramm für Matheaufgaben Spiele- und Multimedia-Programmierung 1
F Algorithmus für bessere Kollisionsabfragen Spiele- und Multimedia-Programmierung 10
S Bilder Für Schachfiguren Spiele- und Multimedia-Programmierung 14
Timo_neu_in_java Suche etwas einfaches für Anfänger Spiele- und Multimedia-Programmierung 6
I Minecraft Suche Plugin Developer für Minecraft Netzwerk! Spiele- und Multimedia-Programmierung 2
S GUI erstellen für Text Adventure Spiele- und Multimedia-Programmierung 4
S Eigene Klasse vec_t - 3 oder 4 Einheiten für x, y, z und w Spiele- und Multimedia-Programmierung 11
R Vererbbarer GameLoop für Engine Spiele- und Multimedia-Programmierung 14
J Vektor für Gravitation erzeugen Spiele- und Multimedia-Programmierung 34
I Minecraft: Craftingrecipe für Braustand ändern Spiele- und Multimedia-Programmierung 9
Z Minimax-Algorithmus für TicTacToe Spiele- und Multimedia-Programmierung 5
H KI für Spiele Spiele- und Multimedia-Programmierung 1
S Pssende Datenstruktur für ein Netz Spiele- und Multimedia-Programmierung 5
S MouseEvents für Sprites Spiele- und Multimedia-Programmierung 3
I Spectator Modus für Spiel ähnlich zu Terraria Spiele- und Multimedia-Programmierung 8
K Bestes Bildformat für Spielegrafiken und deren Einbindung in Java Spiele- und Multimedia-Programmierung 2
J mehrere Listener für einen Button / Label Spiele- und Multimedia-Programmierung 1
C Port umleiten: lesen und schreiben für MCServer-Client über Skype Spiele- und Multimedia-Programmierung 0
J Musik Bibliothek für GUI Spiele- und Multimedia-Programmierung 7
B Hauptmenü für Spiel Spiele- und Multimedia-Programmierung 1
R Ratschlag für 2D-3D Engine für die Spieleentwicklung gesucht Spiele- und Multimedia-Programmierung 4
Androbin KI für Verfolgung im Raster Spiele- und Multimedia-Programmierung 2
A Bot für Browsergame Spiele- und Multimedia-Programmierung 2
H Tutorials für Fortgeschrittene 3D-Anwedungen Spiele- und Multimedia-Programmierung 2
lord239123 suche Graphiker für ein Pokemon-Spiel Spiele- und Multimedia-Programmierung 6
Furtano Vektoren für Bewegung für eine 2D-Simulation Spiele- und Multimedia-Programmierung 3
T Sinusgenerator für eine Hp Spiele- und Multimedia-Programmierung 8
J Menü für Snakespiel in einzelnem JFrame Spiele- und Multimedia-Programmierung 5
M Minecraft weitere Java Entwickler für minecraft projekt gesucht Spiele- und Multimedia-Programmierung 0
Guybrush Threepwood Ketzerische Frage: Opus-Codec für Java Spiele- und Multimedia-Programmierung 14
L Hilfe bei Klassendesign für Spiel Spiele- und Multimedia-Programmierung 2
N Animationen für ein 2D game Spiele- und Multimedia-Programmierung 6
S Aufbau für 2D Spiele Spiele- und Multimedia-Programmierung 7
L Client für ein Browsergame Spiele- und Multimedia-Programmierung 21
Devil0s Swing Elemente für Inventar? Spiele- und Multimedia-Programmierung 9
Kenan89 Ansatzfrage: Kartenspiel für 2 Spieler Online Spiele- und Multimedia-Programmierung 3
F Ideen für spiel Spiele- und Multimedia-Programmierung 4
P Spielfeld für RPG Spiele- und Multimedia-Programmierung 15
Hoppelmann Alphamap (Bild) für 3D-Terrain generieren Spiele- und Multimedia-Programmierung 2
S Algorithmus zur Ressourcesuche für die KI Spiele- und Multimedia-Programmierung 5
M Farbwerte für Flächen aus einem Bild erkennen Spiele- und Multimedia-Programmierung 3
K Einfache Engine für einfaches 3D gesucht Spiele- und Multimedia-Programmierung 10
C KI für Skatspiel - Wie können die Computerspieler eigenständig handeln? Spiele- und Multimedia-Programmierung 10
S Aufbau von Klassen für Spiel Spiele- und Multimedia-Programmierung 13
Kenan89 Kleines Projekt für Java Spiele- und Multimedia-Programmierung 5
M Empfehlungen für ein 2D-Jump'n'run Spiele- und Multimedia-Programmierung 4
A Grundlagensuche für Spiel Spiele- und Multimedia-Programmierung 8
C Wo ist der MP3 Plugin für JMF? Spiele- und Multimedia-Programmierung 3
qwerqer Design Pattern gesucht für Spielregeln Spiele- und Multimedia-Programmierung 2
M Java als Programmiersprache für kommerzielle Spieleentwicklung? Spiele- und Multimedia-Programmierung 3
K Game Engine für selbstprogrammiertes Spiel Spiele- und Multimedia-Programmierung 27
Y Warum Thread für Spieleprogrammierung? Spiele- und Multimedia-Programmierung 27
A Music für Android game Spiele- und Multimedia-Programmierung 3
Gossi Probleme beim Laden der Images aus dem "Tutorial für Java-Spiele" Spiele- und Multimedia-Programmierung 4
M Minecraft Suche Java Programmierer (für Minecraft) Spiele- und Multimedia-Programmierung 2
Luk10 Tipps für bessere Animationen / Grafik Engine Spiele- und Multimedia-Programmierung 2
T 2D Menü für 3D Spiel Spiele- und Multimedia-Programmierung 5
T Grundlagenwissen für den 3D Raum Spiele- und Multimedia-Programmierung 6
M technologie für video, webcam & co Spiele- und Multimedia-Programmierung 25
C Java für große Spiele geeignet ? Spiele- und Multimedia-Programmierung 101
D Libraryempfehlung für Effekte Spiele- und Multimedia-Programmierung 3
B Spiele programmieren für ein Fenster? Spiele- und Multimedia-Programmierung 14
D Tabelle für Spiel Spiele- und Multimedia-Programmierung 3
N Grundlagen für ein Jump&Run Spiele- und Multimedia-Programmierung 3
S Datenbank gesucht für Bilder(gif-dateien) Spiele- und Multimedia-Programmierung 5
J Suche 3D Programm für jMonkeyEngine Spiele- und Multimedia-Programmierung 5
W 3D-APIs für Java - Eine Übersicht Spiele- und Multimedia-Programmierung 8
D Problem beim Öffnen einer PHP für eine Highscore Spiele- und Multimedia-Programmierung 5
S Game Client für kleine Competition Spiele- und Multimedia-Programmierung 3
F Programm für Bildbearbeitung gesucht: Skalieren und Speichern Spiele- und Multimedia-Programmierung 6
K Lösungsansätze für ein Spiel Spiele- und Multimedia-Programmierung 2
Plastagen Frameworls für Animationen und co Spiele- und Multimedia-Programmierung 3
aze Wie Transform3D für PosPathInterpolator bestimmen Spiele- und Multimedia-Programmierung 8
M Musik für Spiel wo downloaden? Spiele- und Multimedia-Programmierung 7
R Netzwerkstruktur für ein kleines Spiel Spiele- und Multimedia-Programmierung 8
O KI (künstliche Intelligenz) für Schachlogik Spiele- und Multimedia-Programmierung 4
J Brauche denkanstoß für kleines grafikframework Spiele- und Multimedia-Programmierung 3
A Countdown-Timer für Spiel Spiele- und Multimedia-Programmierung 4
J Tips für ein kleines Pong-Applet Spiele- und Multimedia-Programmierung 4
S Ein Thread für alle Animationen oder mehrere? Spiele- und Multimedia-Programmierung 2
S Grafik erstellen für Java Spiel Spiele- und Multimedia-Programmierung 8

Ähnliche Java Themen

Neue Themen


Oben