Apfel-Spiel KeyListener

MaZeFrJoTh

Mitglied
Hallo zusammen,
ich habe mir ein kleines Spiel programmiert, was ich von Zeit zu Zeit um Funktionen erweitere. Jedoch gibt es 2 Probleme 1. ich kann den Dialog nicht über die Leertaste schließen sondern nur öffnen. Beim 2. mal Leertaste wird einfach der Button 1 auf diesen dialog ausgeführt. Mein 2. Problem ist das das Spiel nicht richtig schließt sondern sich iwíe nur unsichtbar macht. Dafür bräuchte ich auch noch Schlüsselsequenzen. Hier ist der Quelltext:

Java:
import javax.swing.*;
import java.awt.*; 
import java.awt.image.BufferedImage;
import java.awt.Component;
import java.net.URL;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;

public class Steuerung extends JPanel implements Runnable, KeyListener, ActionListener{ 
        JFrame Fenster; 
        JPanel panel;
        JDialog dialog;
        private boolean gestartet;
        private boolean links = false;        
        private boolean rechts = false;
        private int o = 300;
        private int c = 1;
        private int[] y = new int[44];
        private int p = 0;
        private int punkte = 0;
        private String Name;
        public BufferedImage Hintergrund;
        public BufferedImage Korb;
        public BufferedImage[] Apfel = new BufferedImage[44];
        public ArrayList<Integer> Zahl = new ArrayList<Integer>();
        public int[] Zufall = new int[44];
        public int[] x = new int[44];
        public Timer timer = new Timer(30);
        public static void main(String[] args){ 
            new Steuerung(700,800); 
        } 
        public Steuerung(int w, int h){  
            this.setPreferredSize(new Dimension(w,h));
            Fenster = new JFrame("Apfelbaum 0.3 BETA"); 
            Fenster.setLocation(350,0); 
            Fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
            panel = new JPanel();            
            dialog = new JDialog(Fenster,"Menü",true);
            dialog.add(panel);
            dialog.setSize(500, 500);
            dialog.setLocation(460,150);
            JButton Reset = new JButton("Reset");
            Reset.addActionListener(this);
            Reset.setBounds(100, 100, 100, 60);
            panel.add(Reset);
            Fenster.add(this); 
            Fenster.pack(); 
            Fenster.addKeyListener(this);
            dialog.addKeyListener(this);
            Fenster.setVisible(true);
            dialog.setVisible(false);
            x[1] = 100;
            x[2] = 200;
            x[3] = 300;
            x[4] = 300;
            x[5] = 50;
            x[6] = 400;
            x[7] = 500;
            x[8] = 400;
            x[9] = 500;
            x[10] = 550;
            x[11] = 600;
            x[12] = 550;
            x[13] = 350;
            x[14] = 550;
            x[15] = 250;
            x[16] = 650;
            x[17] = 450;
            x[18] = 350;
            x[19] = 100;
            x[20] = 150;
            x[21] = 225;
            x[22] = 280;
            x[23] = 90;
            x[24] = 325;
            x[25] = 380;
            x[26] = 380;
            x[27] = 465;
            x[28] = 480;
            x[29] = 150;
            x[30] = 465;
            x[31] = 120;
            x[32] = 230;
            x[33] = 150;
            x[34] = 100;
            x[35] = 175;
            x[36] = 200;
            x[37] = 290;
            x[38] = 40;
            x[39] = 350;
            x[40] = 533;
            x[41] = 465;
            x[42] = 620;
            x[43] = 625;
            y[1] = 100;
            y[2] = 150;
            y[3] = 250;
            y[4] = 150;
            y[5] = 200;
            y[6] = 120;
            y[7] = 120;
            y[8] = 50;
            y[9] = 80;
            y[10] = 150;
            y[11] = 250;
            y[12] = 350;
            y[13] = 400;
            y[14] = 200;
            y[15] = 300;
            y[16] = 200;
            y[17] = 375;
            y[18] = 350;
            y[19] = 300;
            y[20] = 350;
            y[21] = 70;
            y[22] = 60;
            y[23] = 225;
            y[24] = 225;
            y[25] = 300;
            y[26] = 200;
            y[27] = 200;
            y[28] = 350;
            y[29] = 250;
            y[30] = 300;
            y[31] = 350;
            y[32] = 225;
            y[33] = 200;
            y[34] = 170;
            y[35] = 120;
            y[36] = 380;
            y[37] = 375;
            y[38] = 294;
            y[39] = 112;
            y[40] = 285;
            y[41] = 243;
            y[42] = 140;
            y[43] = 340;
            Thread th = new Thread(this);
            th.start();
            StarteSpiel();
        } 
        public void paintComponent(Graphics g){ 
            super.paintComponent(g); 
            g.drawImage(Hintergrund, 0, 0, this);
            g.drawImage(Korb, o, 710,this);
            g.drawImage(Apfel[1], x[1], y[1], this);
            g.drawImage(Apfel[2], x[2], y[2], this);
            g.drawImage(Apfel[3], x[3], y[3], this);
            g.drawImage(Apfel[4], x[4], y[4], this);
            g.drawImage(Apfel[5], x[5], y[5], this);
            g.drawImage(Apfel[6], x[6], y[6], this);
            g.drawImage(Apfel[7], x[7], y[7], this);
            g.drawImage(Apfel[8], x[8], y[8], this);
            g.drawImage(Apfel[9], x[9], y[9], this);
            g.drawImage(Apfel[10], x[10], y[10], this);
            g.drawImage(Apfel[11], x[11], y[11], this);
            g.drawImage(Apfel[12], x[12], y[12], this);
            g.drawImage(Apfel[13], x[13], y[13], this);
            g.drawImage(Apfel[14], x[14], y[14], this);
            g.drawImage(Apfel[15], x[15], y[15], this);
            g.drawImage(Apfel[16], x[16], y[16], this);
            g.drawImage(Apfel[17], x[17], y[17], this);
            g.drawImage(Apfel[18], x[18], y[18], this);
            g.drawImage(Apfel[19], x[19], y[19], this);
            g.drawImage(Apfel[20], x[20], y[20], this);
            g.drawImage(Apfel[21], x[21], y[21], this);
            g.drawImage(Apfel[22], x[22], y[22], this);
            g.drawImage(Apfel[23], x[23], y[23], this);
            g.drawImage(Apfel[24], x[24], y[24], this);
            g.drawImage(Apfel[25], x[25], y[25], this);
            g.drawImage(Apfel[26], x[26], y[26], this);
            g.drawImage(Apfel[27], x[27], y[27], this);
            g.drawImage(Apfel[28], x[28], y[28], this);
            g.drawImage(Apfel[29], x[29], y[29], this);
            g.drawImage(Apfel[30], x[30], y[30], this);
            g.drawImage(Apfel[31], x[31], y[31], this);
            g.drawImage(Apfel[32], x[32], y[32], this);
            g.drawImage(Apfel[33], x[33], y[33], this);
            g.drawImage(Apfel[34], x[34], y[34], this);
            g.drawImage(Apfel[35], x[35], y[35], this);
            g.drawImage(Apfel[36], x[36], y[36], this);
            g.drawImage(Apfel[37], x[37], y[37], this);
            g.drawImage(Apfel[38], x[38], y[38], this);
            g.drawImage(Apfel[39], x[39], y[39], this);
            g.drawImage(Apfel[40], x[40], y[40], this);
            g.drawImage(Apfel[41], x[41], y[41], this);
            g.drawImage(Apfel[42], x[42], y[42], this);
            g.drawImage(Apfel[43], x[43], y[43], this);
            g.setColor(Color.red);
            g.setFont(new Font("Arial", Font.PLAIN, 30));
            g.drawString("Punkte: " + Long.toString(punkte), 530, 35);
            g.drawString("Zeit: " + Long.toString(30 - timer.Zeit()), 15, 35);
        } 
        public void run(){ 
            while(Fenster.isVisible()){ 
                if(gestartet == true){
                    for(int n = 1; n <= 44 && gestartet == true; n++){
                        for(int i = 1; i <= 250 && gestartet == true; i++){
                            BewegeObjekte();
                            if(y[Zufall[n]] <= 800){
                                y[Zufall[n]] = y[Zufall[n]] + 3;
                                repaint();
                            }
                            if(y[Zufall[n]] >= 705 && y[Zufall[n]] <= 720){
                                if(x[Zufall[n]] >= o - 5 && x[Zufall[n]] <= o + 125){
                                    PunkteErhöhen();
                                    y[Zufall[n]] = 1000;
                                }
                            }
                            try{
                                Thread.sleep(4);                                
                            }
                            catch(InterruptedException e){}
                        }
                        if(30 - timer.Zeit() <= 0){
                            repaint();
                            StoppeSpiel();
                        }
                    }                    
                }
                repaint();
            } 
        }
        private void Initialisieren(){
            Zufall();
            Hintergrund = LadeBilder("Bilder/Hintergrund.jpg",1)[0];   
            Korb = LadeBilder("Bilder/Korb.png",1)[0];
            Apfel[1] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[2] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[3] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[4] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[5] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[6] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[7] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[8] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[9] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[10] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[11] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[12] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[13] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[14] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[15] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[16] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[17] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[18] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[19] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[20] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[21] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[22] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[23] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[24] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[25] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[26] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[27] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[28] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[29] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[30] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[31] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[32] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[33] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[34] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[35] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[36] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[37] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[38] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[39] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[40] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[41] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[42] = LadeBilder("Bilder/Apfel.png",1)[0];
            Apfel[43] = LadeBilder("Bilder/Apfel.png",1)[0];
            gestartet = false;
        }
        private void BewegeObjekte(){
            if(rechts == true && o <= 572){
                for( int i = 1; i <= 5 && rechts == true; i++){
                    o = o + 1;
                    repaint();
                }
            }
            if(links == true && o >= 7){
                for( int i = 1; i <= 5 && links == true; i++){
                    o = o - 1;
                    repaint();
                }
            }
        }
        private BufferedImage[] LadeBilder(String Pfad, int Bilder){        
            BufferedImage[] animation = new BufferedImage[Bilder];
            BufferedImage source = null;        
            URL Hole_url = getClass().getClassLoader().getResource(Pfad);
        try {
            source = ImageIO.read(Hole_url);
        } catch (IOException e) {}        
        for(int x=0;x<Bilder;x++){
            animation[x] = source.getSubimage(x*source.getWidth()/Bilder, 0, source.getWidth()/Bilder, source.getHeight());
        }        
        return animation;
        }
        private void StarteSpiel(){
            Initialisieren();
            SetzeGestartet(true);
            timer.Countdown();
        }
    
        private void StoppeSpiel(){
            try{
                SetzeGestartet(false);
                BufferedReader reader = new BufferedReader(new FileReader("Punkte.txt"));
                p = Integer.parseInt(reader.readLine());
                reader.close();
            }
            catch (IOException e){}
            if(punkte > p){
                Name = JOptionPane.showInputDialog(null,"Geben Sie Ihren Namen ein", "Neuer Highscore", JOptionPane.PLAIN_MESSAGE);
                Speichern();
                JOptionPane.showMessageDialog(null, "Herzlichen Glückwunsch " + Name + ". sie haben mit " + punkte + " Punkten ihr neuen persöhnlichen Highscore erziehlt.", Name, JOptionPane.INFORMATION_MESSAGE);
            }
            else{
                JOptionPane.showMessageDialog(null, "Sie haben leider nur "  + punkte + " Punkte => Kein neuer Highscore", "Leider kein neuer Highscore", JOptionPane.INFORMATION_MESSAGE);
            }
            try{
                Thread.sleep(3000);
            }
            catch (Exception e){}
            Fenster.setVisible(false);
        }
        public void SetzeGestartet(boolean gestartet) {
            this.gestartet = gestartet;
        }
        public void keyPressed(KeyEvent e){
            if(e.getKeyCode() == KeyEvent.VK_LEFT){
                links = true;              
                rechts = false;
            }           
            if(e.getKeyCode() == KeyEvent.VK_RIGHT){
                rechts = true;
                links = false;
            }
            if(e.getKeyCode() == KeyEvent.VK_SPACE){                
                if(dialog.isVisible()){
                    dialog.setVisible(false);
                }
                else{
                    dialog.setVisible(true);
                }
            }
        }
        public void keyReleased(KeyEvent e){
            if(e.getKeyCode() == KeyEvent.VK_LEFT){
                links = false;
            }                
            if(e.getKeyCode() == KeyEvent.VK_RIGHT){
                rechts = false;
            }
            if(e.getKeyCode() == KeyEvent.VK_ESCAPE){
                if(gestartet == true){
                    StoppeSpiel();
                }
                else{
                    Fenster.dispose();
                }
            }
        }
        public void keyTyped(KeyEvent e){

        }
        public void Zufall(){
            for(int i = 0; i < 43; i++){
                Zahl.add(i + 1);                
            }
            Collections.shuffle(Zahl);
            for(int i = 1; i < 43; i++){
                Zufall[i] = Zahl.get(i);                
            }
        }
        public void PunkteErhöhen(){
            punkte = punkte + 10;
        }
        public void Speichern(){
            try{
                BufferedWriter Puffer = new BufferedWriter(new FileWriter("Punkte.txt"));
                Puffer.write(Integer.toString(punkte));
                Puffer.newLine();
                Puffer.close();  
                BufferedWriter Puffer2 = new BufferedWriter(new FileWriter("Rekord.txt"));
                Puffer2.write(Name);
                Puffer2.newLine();
                Puffer2.close();
            }
            catch (IOException e){}
        }
        public void actionPerformed(ActionEvent event){
            int eingabe = JOptionPane.showConfirmDialog(null, "Bist du dir sicher?", "Highscore löschen", JOptionPane.YES_NO_OPTION);
            if(eingabe == 0){
                try{
                    BufferedWriter Puffer = new BufferedWriter(new FileWriter("Punkte.txt"));
                    Puffer.write(Integer.toString(0));
                    Puffer.newLine();
                    Puffer.close();  
                    BufferedWriter Puffer2 = new BufferedWriter(new FileWriter("Rekord.txt"));
                    Puffer2.write(" ");
                    Puffer2.newLine();
                    Puffer2.close();
                }
                catch (IOException e){}
            }
        }
}

Und hier die 2. Klasse Timer die einwandfrei funktioniert:

Java:
public class Timer{
    private int delta, sekunden;
    private long start, time, stop;
    public Timer(int d){
        delta = d * 1000;
        start = System.currentTimeMillis();
        stop = start + delta;
    }
    public void Countdown(){
        time = System.currentTimeMillis();
        while(time < stop){
            time = System.currentTimeMillis();
            if(time >= start + 1000){
                sekunden++;
                start = start + 1000;
            }
        }
    }
    public int Zeit(){
        return sekunden;
    }
}

Danke für eure Hilfe
 
Zuletzt bearbeitet von einem Moderator:

fisch100

Mitglied
Java:
Fenster.setVisible(false);
Fenster.dispose();
System.exit(0);

damit wird das fenster entsorgt und der thread geschlossen ;)

und so nebenbei: bei deinen exceptions - du solltest dir auch den fehler ausgeben lassen sonst hat das auffangen doch etwas wenig sinn?
 
Zuletzt bearbeitet:

MaZeFrJoTh

Mitglied
ja ich weiß aber im Spiel sind die lästig und solange es funktioniert brauch ich sie nicht ausgeben
aber für das KeyListener Problem hat leider keiner eine Lösung??
 
Zuletzt bearbeitet:

MaZeFrJoTh

Mitglied
Ich glaub das Problem liegt darin, dass wenn mein JDialog geöffnet wird der JButton "gleich makiert ist" und wenn ich dann nochmals Leertaste drücke wird einfach die JButton aktiviert. Aber warum???
 

fisch100

Mitglied
weil space auch als "enter-ersatz" verwendet werden kann - nur sollte eigentlich (kann aber auch eine ausnahme von der programm-struktur sein) das event auslösen - kenn mich leider noch nicht so gut aus ;)
 

beastofchaos

Bekanntes Mitglied
O gott, o gott, o gott!!

Java:
            Apfel[1] = LadeBilder("Bilder/Apfel.png",1)[0];
            ...
            Apfel[43] = LadeBilder("Bilder/Apfel.png",1)[0];
Ist das selbe wie
Java:
for (int i = 1; i <= 43; i++){
     Apfel[i] = LadeBilder("Bilder/Apfel.png",1)[0];
}

das selbe Problem auch hier

Java:
            g.drawImage(Apfel[1], x[1], y[1], this);
            g.drawImage(Apfel[2], x[2], y[2], this);
...
            g.drawImage(Apfel[43], x[43], y[43], this);
Ist das selbe wie
Java:
for (int i = 1; i <= 43; i++){
     g.drawImage(Apfel[i], x[i], y[i], this);
}


Außerdem beginnt ein Array mit 0. Du beginnst erst ab Apfel[1]... ;)
Und wieso das Array, inwiefern unterscheiden sich die Äpfel? Alle haben das selbe Bild, das ihnen per LadeBild() übergeben wird. Dann lad das Bild doch nur einmal.

Das sieht dann so aus (beim Zeichnen):
Java:
        private int[] y = new int[44];
        public int[] Zufall = new int[44];
        public int[] x = new int[44];
        public BufferedImage Apfel = new BufferedImage();  // vorher: public BufferedImage[] Apfel = new BufferedImage[44];

...

    Apfel = LadeBilder("Bilder/Apfel.png",1)[0];

...

    for (int i = 1; i <= 43; i++){
        g.drawImage(Apfel, x[i], y[i], this);          // vorher: (bei meiner Korrektur) Apfel[i]
    }

Ich hoffe, du wirst in Zukunft helfen, schlechten Codes den Krieg zu erklären :p
Ein anderer Nachteil wäre bei deinem Code, dass er total Ressourcen-verschwenderisch(versuch mal im Kopf 44 Bilder mit Koordinaten auswendig zu merken, dann weißt du was ich mein^-^), wodurch der Computer langsamer wird oder du kannst dein Programm nicht erweitern, weil es jetzt schon zu groß ist ;)

Gruß, Thomas

PS: du kensnt die Klasse Point noch nicht anscheinend :p
Java:
    int[] x = new int[44];
    int[] y = new int[44];

    // besser:

    Point[] koords = new Point[44];

...

    koords[1].x = 1;
    koords[2].y = 2;

// oder:
    koords[2] = new Point(1, 2);

Gibt noch etliche Stellen, die sehr schlecht progammiert sind, aber ich möchte nicht zu sehr nerven ;)
 
Zuletzt bearbeitet:

MaZeFrJoTh

Mitglied
ok danke an alle bisher ich werds umschreiben aber das mit dem umständlichen laden der Dateiern hängt damit zusammen das ich auch "verfaulte" Äpfel zeichnen wollte, die - 10 Punkte bringen. Ich hab iwo mal was davon gehört das Java mit den BufferedImages nicht so gut umgehen kann und man deswegen in To.integer oder so umwandeln soll, da es angeblich nicht so ressourcenverschwenderisch ist. Ist da was dran?? Würde es für mich was bringen?? Und wenn ja wie das genau geht???

Ich weiß ich bin noch ein Anfänger und ihr seit besimmt von meinen tausend Fragen genervt aber vllt kann ich irgendwann einem andren helfen. Ach ja und für das mysteriöse Leertastenproblem hat noch immer keiner eine Lösung bzw. Erklärung?
 
Zuletzt bearbeitet:

Z0M813

Mitglied
Gehört zwar nicht zum Thema, aber als Tipp für die Zukunft (Z.59-144 in deinem ersten Code):
Einfach alles schon oben eingeben:
private int[]x = {100, 200, ... , 620, 625};
Spart ein bisschen Arbeit;)
 

MaZeFrJoTh

Mitglied
Es haben sich glücklicherweise viele Probleme geklärt jedoch habe ich noch genau 2:
1. Das mit der Leertaste
2. Weil das "billige" 2D Spiel soviel Ressourcen frisst bzw. manchmal ruckelt, frag ich mich ob dies alleine am mieserablen Quelltext liegt oder auch an den BufferedImages.

Und für Verbesserungvorschläge im Quelltext bin ich auch gerne offen.

Danke.
 

beastofchaos

Bekanntes Mitglied
Ok, wenn du auch verfaulte Äpfel hast

dann mach statt dem Image-Array ein Array von boolean. Äpfel, die faul sind, machst du auf false und sonst true. Beim zeichnen fragst du das dann einfach ab und zeichnest dann entwerder den richtigen oder verfaulten.
Images sind immer das verschwenderischte bei Spielen ;)
 

thewulf00

Bekanntes Mitglied
Schau mal bitte, welchen Typ dein BufferedImage hat. Lädst Du es aus einem PNG? Wenn ja, kann es sein, dass der Typ TYPE_CUSTOM ist, dann wäre die Verarbeitung SEHR langsam.
Was Du in diesem Fall tun musst, können wir Dir hier gern sagen, aber überprüfe es erstmal.
 

MaZeFrJoTh

Mitglied
ja, ich lade eine png ( wäre eine jpg schneller zu laden?), welchen Typ kann ich nicht sagen aber der Code zum Laden der Bilder beginnt ab Zeile 294. Mit den verschiedenen Typen kenn ich mich eben nicht aus, deswegen würde es mich auch interessieren ob ein ManagedImage oder VolatileImage bei meinem Spiel Vorteile gegenüber den BufferedImage hätte. Außerdem glaub ich ist meine Methode LadeBilder (ab Z. 294) viel zu überdimensioniert, da ich die Funktion der animierten Bilder gar nicht benötige.
 

thewulf00

Bekanntes Mitglied
Mach einfach direkt nach Laden des Bildes:
Java:
if (bild.getType() == BufferedImage.TYPE_CUSTOM)
  System.out.println("Achtung! TYPE_CUSTOM wird geladen!");

Die Lösung hier wäre, ein neues BufferedImage mit einem TYPE_INT zu erstellen, und dann das geladene Bild per drawImage reinzumalen - und anschließend das neue zu benutzen. Damit erhöhst Du die Performance.

Prüfe bitte den Typ des Bildes, bei der Codeintegration können wir Dir helfen.

Tipp: VolatileImage gibt auch eine Performance-Verbesserung, aber nur, wenn die Hardware das unterstützt (also auf alten Rechnern bleibt dann das Problem bestehen).
 

beastofchaos

Bekanntes Mitglied
Also ich nehm mir mal kurz die Zeit und versuche mal im Browser diese Methode, wie er sie meint, zu schreiben ;) - mir ist langweilig und ich könnte da auch gebrauchen xD:
Java:
    public void BufferedImage getImage(String path){
        BufferedImage tempImg = null;
        try {
            tempImg = ImageIO.read(new File(path));
        } catch (IOException exc){
            exc.printStackTrace();
            return;
        }

        BufferedImage newImg = new BufferedImage(tempImg.getWidth() ,tempImg.getHeight(), BufferedImage.TYPE_INT_RGB);
        newImg.getGraphics().drawImage(tempImg, 0, 0, this);      // 0, 0 -> Position | this -> Observer
        
        return newImg;
    }
Du könntest natürlich, bevor newImg erstellt wird, per if-Abfrage erstmal schaun, ob tempImg überhaupt vom Typ Custom ist und0, wenn nicht, einfach tempImg übergeben ;)

Gruß, Thomas
 

MaZeFrJoTh

Mitglied
Ja danke für die Implementierung aber wie unterscheidet sich diese von meiner Version?Außerdem das zeichnen würde ich gerne bei der paintComponent- Methode lassen ausser dies ist ungeeignet. :

Java:
private BufferedImage[] LadeBilder(String Pfad, int Bilder){        
            BufferedImage[] animation = new BufferedImage[Bilder];
            BufferedImage source = null;        
            URL Hole_url = getClass().getClassLoader().getResource(Pfad);
        try {
            source = ImageIO.read(Hole_url);
        } catch (IOException e) {}        
        for(int x=0;x<Bilder;x++){
            animation[x] = source.getSubimage(x*source.getWidth()/Bilder, 0, source.getWidth()/Bilder, source.getHeight());
        }        
        return animation;
        }

Und ist BuffererdImage schon das Beste für mein Spiel? Welches Bildformat kann Java am besten zeichnen?
 

wessi86

Mitglied
Hi!
Zu dem Problem mit der Leertaste:
Schon versucht den JDialog auf und den JButton in dem Dialog auf setFocusable(false) zu setzen?
Dann kannst du allerdings den Button nicht mit enter bestätigen, sonder musst mit der Maus draufklicken.
Ich glaube, das Problem hatte ich auch einmal bei einem Dartprogramm von mir und hab das so gelöst.

mfg, Christian
 

MaZeFrJoTh

Mitglied
Das klingt ja mal nach einer Lösung. Danke nochmals.
Es gibt nur noch das eine Problem mit der Performance der BufferedImages und meiner überladenen und schlecht geschriebenen run- Methode.
 

wessi86

Mitglied
Gern geschehen, bei deinen Bildern kann ich dir leider nicht helfen, hab bisher nur bei statischen Anwendungen mit BufferedImages gearbeitet, da hatte ich keine Performance-probleme.
 

thewulf00

Bekanntes Mitglied
Das klingt ja mal nach einer Lösung. Danke nochmals.
Es gibt nur noch das eine Problem mit der Performance der BufferedImages und meiner überladenen und schlecht geschriebenen run- Methode.
Das kriegen wir auch noch hin. Zeig doch mal die aktuelle Routine her. Und die Routine, die die Bilder lädt.
Achja, und mich würde noch interessieren, wie Du die Performance-Messung machst.
 

MaZeFrJoTh

Mitglied
Das kriegen wir auch noch hin. Zeig doch mal die aktuelle Routine her. Und die Routine, die die Bilder lädt.
Achja, und mich würde noch interessieren, wie Du die Performance-Messung machst.

Also die Performance messe ich über einen implementierten fps Zähler, den Taskmanager, der Aufbauzeit die benötigt wird, das Auge(empfundene Flüssigkeit).

Ich hab jetzt mal 2 Teile aus dem Quellcode rauskopiert, die die ganze grafische Darstellung darstellen:

Java:
private BufferedImage[] LadeBilder(String Pfad, int Bilder){        
            BufferedImage[] animation = new BufferedImage[Bilder];
            BufferedImage source = null;        
            URL Hole_url = getClass().getClassLoader().getResource(Pfad);
            try {
                source = ImageIO.read(Hole_url);
            }
            catch (IOException e){}        
            for(int i = 0;i < Bilder;i++){
                animation[i] = source.getSubimage(i*source.getWidth()/Bilder, 0, source.getWidth()/Bilder, source.getHeight());
            }           
            return animation;
        }

Java:
public void paintComponent(Graphics g){ 
            super.paintComponent(g);
            g.drawImage(Hintergrund, 0, 0, this);
            g.drawImage(Korb, o, 710,this);
            for(int i = 1; i <= 43; i++){
                g.drawImage(Apfel, koords[i].x, koords[i].y, this);
            }
            g.setColor(Color.red);
            g.setFont(new Font("Arial", Font.PLAIN, 30));
            g.drawString("Punkte: " + Long.toString(punkte), 530, 35);
            g.drawString("Zeit: " + Long.toString(30 - timer.Zeit()), 15, 35);
        }
 

thewulf00

Bekanntes Mitglied
Also es gibt hier zwei Ansätze, wie man es schneller bekommen könnte.

Zum Einen effektivere Speicher nutzen. In dem andren Thread hast Du sicher gelesen, dass Du das geladene Bild nochmal in ein selbsterstelltes, neues BufferedImage mit Typ TYPE_INT_ARGB malen solltest. Mach eine Funktion, die ein BufferedImage bekommt und genau das tut, und anschließend das neu gemalte zurückgibt. Dann baust Du diese Funktion überall im Ladevorgang ein.
Wenn das nicht reicht, dann informier Dich mal über VolatileImage (was aber die richtige Hardware voraussetzt).
Im Übrigen noch ein Tipp: Mach die Variablen vom Typ Image, aber arbeite mit BufferedImage. Das machts "hinten raus" leichter: [c]Image animation = new BufferedImage(...)[/c]

Zum Anderen könntest Du auch mehr Caching durchführen, so dass jede Umformung und Konvertierung im Spielablauf entfällt.
Wenn Du das auf die Spitze treiben willst, dann würde ich es so machen:
Mache ein Bild, was Du preparedImage nennst, und male dort den Hintergrund und alle Äpfel bis auf den, der gerade fällt hinein. In der Spielschleife malst Du dann nur noch drei Bilder: das preparedImage, den fallenden Apfel und den Korb. Und immer, wenn Du einen neuen Apfel fallen lassen willst, malst Du preparedImage neu.
Auf diese Weise sparst Du dutzende Bildmalereien.
 

MaZeFrJoTh

Mitglied
Danke thewulf00,
Aber ist VolatileImage so viel komplexer oder wie? Wie siehts mit ManagedImages aus? Ach ja was heißt man braucht die richtige hardware? Danke nochmals ich denke das war bisher einer der besten Tipps um die Performance zu erhöhen die ich hier bekommen habe. Noch eine Frage: Wenn man dann zu Beginn des Spiels so viele Bilder hier und dort reinmalen muss hat doch das leider auch negative Einflüsse auf die Startdauer des Spiels, oder nicht??
 

beastofchaos

Bekanntes Mitglied
Wie ist das zu verstehen?
Bisher vermute ich, dass du Äpfel hast und die in einem Korb sammelst. Fältl immer ein Apfel runter und der Korb muss an der Fallstelle sein oder wie funktioniert dein Spiel? Wenn du viele Äpfel rumliegen hast von Anfang an und die während dem Spiel von der Position weggenommen werden oder so, musst du vorerst schon alles extra zeichnen lassen, bis zu dem Moment, wo du sie nicht brauchst (bzw. eingesammelt hast oder so).

Gruß, Thomas
 

thewulf00

Bekanntes Mitglied
Aber ist VolatileImage so viel komplexer oder wie?
Nicht unbedingt, einfach eine andere Art von Image, dessen interne Speicherung sich die Hardware zu nutze macht.


Wie siehts mit ManagedImages aus?
Da weiß ich leider nichts drüber.


Ach ja was heißt man braucht die richtige hardware?
Der ein oder andere hier im Forum hatte gemeldet, dass er mit VolatileImage richtige Performance-Boosts erlebt hat, aber als er einen älteren PC nutzte, brach es wieder ein, wie zuvor. Ich schließe daraus, dass VolatileImage sich gewisse Dinge der Hardware von Grafikkarten zu nutze macht, was die meiste ältere Hardware nicht bietet.


Wenn man dann zu Beginn des Spiels so viele Bilder hier und dort reinmalen muss hat doch das leider auch negative Einflüsse auf die Startdauer des Spiels, oder nicht??
Nun, es gibt immer zwei Möglichkeiten, ein Spiel zu entwickeln: Entweder Du lädst am Anfang alles wichtige vor (und optimierst gleich dort), so dass Du im Spiel sehr schnell und ohne Wartezeit reagieren kannst; oder Du lädst es innerhalb des Spiels, um am Anfang nicht unnötig warten zu müssen.
Einen Tod musst Du sterben. Und da die Spielflüssigkeit innerhalb des Spiels wichtiger ist, als keine Wartezeit am Anfang, würde ich das vorziehen.
Zumal die Wartezeit nicht wirklich bemerkbar sein sollte, d.h. für die Dauer des Vorbereitens geht die Framerate für 1s oder 2s auf 1-10 FPS und das wars.
Größere/Komplexere Spiele machen nicht anders.
 

MaZeFrJoTh

Mitglied
Wie ist das zu verstehen?
Bisher vermute ich, dass du Äpfel hast und die in einem Korb sammelst. Fältl immer ein Apfel runter und der Korb muss an der Fallstelle sein oder wie funktioniert dein Spiel? Wenn du viele Äpfel rumliegen hast von Anfang an und die während dem Spiel von der Position weggenommen werden oder so, musst du vorerst schon alles extra zeichnen lassen, bis zu dem Moment, wo du sie nicht brauchst (bzw. eingesammelt hast oder so).

Gruß, Thomas

Also das Spiel kannst du hier runterladen: http://www.java-forum.org/spiele-multimedia-programmierung/121114-erstes-2d-spiel.html

Aber wenn man quasi den Rechner das Spiel vor dem eigentlichen Start schon alles machen lassen soll dann ist ja keine Zufallsfunktion vorhanden. Oder versteh ich das falsch? Und noch eine Frage die VolatileImage sind immer besser bzw schneller als BufferedImages oder nur in bestimmten fällen? Also angenommen man hat so einen alten PC läuft es dann langsamer oder gleich schnell?
 
Zuletzt bearbeitet:

wessi86

Mitglied
Soweit ich das verstanden habe, soll das so ablaufen: Du malst alle Bilder, bis auf den Apfel, der herunterfällt und den Korb auf ein Bild. Dieses Bild zeichnest du dann auf dein JFrame, danach den Apfel und den Korb. Dies bei jedem neu herunterfallenden von vorne.
Btw: Hat das mit der Leertaste und dem setFocusable() funktioniert?

mfg, Christian
 

thewulf00

Bekanntes Mitglied
Wessi hat recht.
Du malst nur ein Bild, wenn sich für die nächsten Sekunden nichts ändert. Sobald sich was ändert, mals Du das ganze Ding neu.

Den Performance-Unterschied zwischen BufferedImage und VolatileImage auf älterer Hardware kann Dir wohl niemand sagen.
 

MaZeFrJoTh

Mitglied
Danke euch allen ihr habt mir sehr viel geholfen. Ja auch dass mit dem setFocusable hat funktioniert jedoch war das größere Problem das man 1 Taste 2 Funktionen zugeteilt hat und es sich dann immer öffnete, schließte, öffnete.... . Das Problem habe ich dadurch gelöst dass man das Menü durch Leer einblendet und durch umschalt ausblendet.
 

wessi86

Mitglied
Wird die Funktion nicht durch die if-else-abfrage gesplittet?
[JAVA=346]
if(e.getKeyCode() == KeyEvent.VK_SPACE){
if(dialog.isVisible()){
dialog.setVisible(false);
}
else{
dialog.setVisible(true);
}
}
[/code]
Meines erachtens müsste das so funktionieren. In meinem Rollenspiel hab ich das ähnlich gelöst:
Java:
    /**
     * Pause im Spiel.
     */
    public void togglePause() {
        if (pause) {
            pause = false;
        } else {
            pause = true;
        }
    }
[...]
        //Taste: Esc
        if (e.getKeyCode() == 27) {
            togglePause();
        }
Wenn pause = true ist, läuft er in der run-methode nur noch repaint() und sleep() durch und zeichnet in der paintmethode ein Pausenmenü. Das funktioniert wunderbar mit nur einer Taste.

mfg, Christian
 

thewulf00

Bekanntes Mitglied
Danke euch allen ihr habt mir sehr viel geholfen. Ja auch dass mit dem setFocusable hat funktioniert jedoch war das größere Problem das man 1 Taste 2 Funktionen zugeteilt hat und es sich dann immer öffnete, schließte, öffnete.... . Das Problem habe ich dadurch gelöst dass man das Menü durch Leer einblendet und durch umschalt ausblendet.
Wenn Du die richtigen Listener nutzt, kannst Du Deine Ereignisse auf onKeyDown oder onKeyUp einschränken, d.h. Du bekommst pro Tastendruck definitiv nur ein Ereignis.
 

MaZeFrJoTh

Mitglied
Also das Spiel läuft auf einem JFrame und hat einen JDialog vom Typ JPanel. Auf dem JDialog, der durch die Leertaste sichtbar wird, ist ein JButton. Ich glaube das du das mit "Umgebung" gemeint hast.
 

thewulf00

Bekanntes Mitglied
Wichtig ist, dass der Dialog den KeyListener nicht auch noch implementiert, weil sonst wird evtl. jede Taste 2x ausgewertet.

Java:
class Main implements KeyListener {
// ...
public Main() {
  final JFrame window = new JFrame();
  // ...

  window.addKeyListener(this);
}

public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}

}

So nun musst Du das KeyEvent in EINER DER BEIDEN Funktionen auswerten.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
N Hey Leute und zwar versuche ich gerade ein 2D Spiel zu Programmieren aber die Figur will sich nicht nach links oder rechts bewegen :( Java Basics - Anfänger-Themen 12
I Threads Spiel gol Java Basics - Anfänger-Themen 6
N Java Spiel Figur auf dem Hintergrundbild bewegen. Java Basics - Anfänger-Themen 11
J ArrayList vergleichen im spiel Mastermind Java Basics - Anfänger-Themen 2
enesss tictactoe spiel Java Basics - Anfänger-Themen 5
K Java Lotto Spiel; ich komme nicht weiter Java Basics - Anfänger-Themen 15
Jxhnny.lpz TicTacToe Spiel vs Computer. (Probleme) Java Basics - Anfänger-Themen 7
httprt Probleme bei dem erstellen von leveln in meinem Spiel Java Basics - Anfänger-Themen 2
berserkerdq2 Habe ein Spiel entwickelt, dass immer in der 4 Runde einen cast-Fehler erhält Java Basics - Anfänger-Themen 3
berserkerdq2 Spiel hängt sich immer in der 4 Runde auf, obwohl ich jede Runde das gleiche mache Java Basics - Anfänger-Themen 1
Ekooekoo Hilfe spiel Java Basics - Anfänger-Themen 5
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
Kennewick Basketball Spiel Ergebnisse Java Basics - Anfänger-Themen 11
X Erste Schritte Hilfe bei einem kleinen Spiel. Java Basics - Anfänger-Themen 19
D Snake-Spiel ähnliche Aufgabe Hilfe Java Basics - Anfänger-Themen 3
R Hangman-Spiel-zufälliges Wort ermitteln Java Basics - Anfänger-Themen 4
JEP1 Java Dialog Fenster schließen Spiel Java Basics - Anfänger-Themen 0
I Simples Risiko-Spiel Java Basics - Anfänger-Themen 5
Hallolu Pong-Spiel: Schläger schneller werden lassen Java Basics - Anfänger-Themen 9
M Java Spiel wie Wer wird Millionär Java Basics - Anfänger-Themen 1
T Startbildschirm für ein Spiel erstellen Java Basics - Anfänger-Themen 0
Z Kein überprüfen des gesamten Arrays möglich.(Viergewinnt Spiel) Java Basics - Anfänger-Themen 6
G Ufo Spiel programmieren Java Basics - Anfänger-Themen 13
C Java Spiel Java Basics - Anfänger-Themen 3
J Spiel programmieren Java Basics - Anfänger-Themen 16
S Spiel-Programmieren. Wenn ein Objekt den anderen berührt. Java Basics - Anfänger-Themen 6
B Memory Spiel Java Basics - Anfänger-Themen 29
J Memory-Spiel Aktivierung der Methode mit Timer Java Basics - Anfänger-Themen 44
Kamy Ein einfaches "Vier Gewinnt" Spiel für Anfängerin Java Basics - Anfänger-Themen 51
A Breakout-Spiel , Ball mit Platten abprallen lassen Java Basics - Anfänger-Themen 1
S Spiel programmieren mit Java Java Basics - Anfänger-Themen 11
Olis Erste Schritte Simples Memory Spiel möglich? Java Basics - Anfänger-Themen 1
J Spiel mit Button klick starten Java Basics - Anfänger-Themen 9
C Rekursives Backtracking beim Spiel Peg Java Basics - Anfänger-Themen 22
M Spiel programmieren Java Basics - Anfänger-Themen 16
Spencer Reid Feedback zu kleinem Spiel Java Basics - Anfänger-Themen 4
kokojamboo92 Spiel programmieren Java Basics - Anfänger-Themen 1
R Kleines Java Spiel funktioniert nicht. Java Basics - Anfänger-Themen 2
I Spiel Java Basics - Anfänger-Themen 34
H ein einfaches Tic Tac Toe Spiel Java Basics - Anfänger-Themen 1
I Spiel programmieren. Java Basics - Anfänger-Themen 16
B Hilfe bei Escape - Spiel Java Basics - Anfänger-Themen 6
S Java-Spiel Java Basics - Anfänger-Themen 2
M Nim-Spiel geht in den negativen Bereich Java Basics - Anfänger-Themen 1
K Klassen Registrierungsseite für ein Spiel Java Basics - Anfänger-Themen 6
J Programmierung Quiz Spiel Java Basics - Anfänger-Themen 3
J Programmierung Quiz Spiel Java Basics - Anfänger-Themen 2
M Brauche Tipps für ein Spiel Java Basics - Anfänger-Themen 4
S Probleme mit GamGrid Spiel-Erstellung => Actor reagiert nicht auf Tastatur Java Basics - Anfänger-Themen 2
Mxxxt Mosaik Spiel - Steuerpanel wird nicht angezeigt Java Basics - Anfänger-Themen 5
M Erste Schritte Zufallszahl Spiel Problem Java Basics - Anfänger-Themen 7
Z Erste Schritte Kleines 2D. Spiel Objekt Bewegung funktioniert nicht Java Basics - Anfänger-Themen 2
H Spiel Kniffel: Gesamtes Array untersuchen. Java Basics - Anfänger-Themen 15
Tacofan Hangman als fertiges Spiel Java Basics - Anfänger-Themen 7
M Array und Objektorientierung? - TicTacToe Spiel Java Basics - Anfänger-Themen 43
C Klassen Sudoku-Spiel Werte werden nicht gesetzt Java Basics - Anfänger-Themen 4
K Kleines Spiel auf Java programmieren Java Basics - Anfänger-Themen 2
W Tic Tac Toe Spiel ohne Arrays Java Basics - Anfänger-Themen 7
S Im objektorientiertem "Spiel" kämpfen Java Basics - Anfänger-Themen 3
I Klassen Umsetzungsfrage zu Spiel "Zuul" Java Basics - Anfänger-Themen 3
F Mastermind Spiel Java Basics - Anfänger-Themen 9
H Liste ausgeben (Spiel Hey Fisch (software-challenge) ändern Anzahl Fische) Java Basics - Anfänger-Themen 1
F Game-Engine für textbasierendes Spiel: Architektur? Java Basics - Anfänger-Themen 9
K Erste Schritte Frage Antwort Spiel - Fragen zur Planung Java Basics - Anfänger-Themen 2
J Java Spiel Zufallsauswahl für Zugbeginn Java Basics - Anfänger-Themen 3
J Frage Antwort Spiel - Wie Zeitcountdown realisieren? Java Basics - Anfänger-Themen 2
L Erste Schritte Spiel: Glückliches Sieben Java Basics - Anfänger-Themen 3
T Hangman spiel Java Basics - Anfänger-Themen 5
J 2 Pc's - Spiel gegeneinander ?! Java Basics - Anfänger-Themen 3
V Spiel Programmieren Java Basics - Anfänger-Themen 9
P 2D-Spiel und Bildschirmgröße Java Basics - Anfänger-Themen 2
O Methoden Fehlermeldung(Illegal start of expression) bei 4-Gewinnt-Spiel Java Basics - Anfänger-Themen 5
T Blöcke für ein Jump and Run Spiel Java Basics - Anfänger-Themen 8
S 2D-Spiel mit Threads... Java Basics - Anfänger-Themen 3
S 2D-Spiel im Vollbild an größe anpassen? Java Basics - Anfänger-Themen 3
M hangman spiel Java Basics - Anfänger-Themen 1
K JTextField in ein Spiel einfügen Java Basics - Anfänger-Themen 2
S Mosaik Spiel Java Basics - Anfänger-Themen 19
pinar memory spiel Java Basics - Anfänger-Themen 10
T OOP Mein erstes Java-Spiel - Schiffe versenken! Java Basics - Anfänger-Themen 2
K Erste Schritte Wie mache ich weiter? (Spiel-Menü) Java Basics - Anfänger-Themen 9
C Java Applet in html. Pong - old school Spiel Java Basics - Anfänger-Themen 10
J Variablen Invalid Character - Error -> Spiel mit Variablenergebnissen Java Basics - Anfänger-Themen 8
K Schere Stein Papier Spiel Java Basics - Anfänger-Themen 3
A Feedback zum Spiel Java Basics - Anfänger-Themen 5
F Hilfe bei meinem Spiel Java Basics - Anfänger-Themen 3
C Lotto Spiel Java Basics - Anfänger-Themen 23
Jagson Dotcom Spiel - Dots Random setzen Java Basics - Anfänger-Themen 8
Dogge Farben-Spiel Java Basics - Anfänger-Themen 20
K Diverse Bugs in einem Snake Spiel Java Basics - Anfänger-Themen 4
2 Lotto-Spiel Java Basics - Anfänger-Themen 9
X Datentypen Probleme mit Char bei meinem 1. Spiel Java Basics - Anfänger-Themen 20
D Erste Schritte Einstieg in die Java Spiel Programmierung Java Basics - Anfänger-Themen 7
H kleines Spiel [Processing] Java Basics - Anfänger-Themen 7
P NullPointerException in Memory-Spiel Java Basics - Anfänger-Themen 5
R Server/Client für Spiel Java Basics - Anfänger-Themen 2
K Hilfe, komme nicht weiter in meinem JAVA-Spiel Java Basics - Anfänger-Themen 3
J Programm(Spiel) neustarten Java Basics - Anfänger-Themen 8
M Suche Beispiel-Spiel Java Basics - Anfänger-Themen 3
C Java Nullpointer Exception in 2D-Spiel Snake Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben