2D-Grafik repaint()-Aufruf. Und nichts geschieht.

StephanL

Mitglied
Hi,

ich arbeite mich, wie ich bereits in einem anderen Thread geschrieben habe, gerade in AWT und Swing ein und versuche ein kleines Spiel zu programmieren. Leider stehe ich schon wieder vor einem Problem, das könnte in nächster Zeit wohl häufiger vorkommen...

Ich habe bereits ein grafisches Spielfeld (16*16 Felder) aufgebaut, die Spielfigur gezeichnet und den KeyListener programmiert, sodass die Figur sich auf bestimmten Elementen bewegen kann, zu anderen jedoch keinen Zutritt hat. Es funktioniert eigentlich auch alles wunderbar, das Spielfeld wird gezeichnet, der KeyListener berechnet die richtigen Koordinaten bei Tastendruck etc. Leider bleibt die Spielfigur aber, wenn sie sich eigentlich bewegen sollte, an ihrer Position stehen.

Die Funktion repaint() müsste an der Stelle, an der ich sie stehen habe, eigentlich aufgerufen werden (ich habe es mit einem System.out.println() an derselben Stelle getestet). Trotzdem bleibt das Bild unverändert. Woran kann das liegen? Bzw. was genau macht die Funktion repaint eigentlich? Die Figur wird mit Hilfe von drawPlayer() gezeichnet, was wiederum über paintComponent() aufgerufen wird. Müsste repaint() drawComponent() nicht neu auslösen?

Vielleicht kann mir hier jemand weiterhelfen, würde mich sehr freuen.

Gruß
Stephan
 
Zuletzt bearbeitet:
Hi,

okay, danke, dann weiß ich gerade echt nicht weiter :noe:

Ich wollte euch zunächst meinen Kraut- und Rüben-Quellcode ersparen, ich poste mal ein paar wichtige Ausschnitte hier.

Aus der Klasse KeyIn:
Java:
@Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();

        if (ingame) {
            if (e.getKeyCode() == KeyEvent.VK_LEFT && Board.se[(KeyIn.playerPosX-blocksize)/blocksize][(KeyIn.playerPosY)/blocksize] instanceof Boden) {
                KeyIn.playerPosX -= blocksize;
            }
            if (key == KeyEvent.VK_RIGHT && Board.se[(KeyIn.playerPosX+blocksize)/blocksize][(KeyIn.playerPosY)/blocksize] instanceof Boden) {
                KeyIn.playerPosX += blocksize;
            }
            if (key == KeyEvent.VK_DOWN && Board.se[(KeyIn.playerPosX)/blocksize][(KeyIn.playerPosY+blocksize)/blocksize] instanceof Boden) {
                KeyIn.playerPosY += blocksize;
            }
            if (key == KeyEvent.VK_UP && Board.se[(KeyIn.playerPosX)/blocksize][(KeyIn.playerPosY-blocksize)/blocksize] instanceof Boden) {
                KeyIn.playerPosY -= blocksize;
            } else {
                KeyIn.playerPosX += 0;
                KeyIn.playerPosY += 0;
            }
            System.out.println(KeyIn.getPlayerPosX() + ", " + KeyIn.getPlayerPosY());
        }
        this.repaint();
    }
Hier wird unten die Repaint-Methode aufgerufen. Der KeyListener ansich funktioniert perfekt.

Auszüge der Klasse Board
Java:
// Konstruktor
public Board() {
        setDimensionD();
        
        this.addKeyListener(new KeyIn());
        
        setFocusable(true);
        
        setBackground(Color.BLACK);
        setDoubleBuffered(true);
}

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

private void doDrawing(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        
        g2d.setColor(Color.BLACK);
        g2d.fillRect(0,0,d.width, d.height);
        
        drawMap(g2d);
        
        if (ingame) {
            playGame(g2d);
        } else {
            
        }
        
        g2d.drawImage(img, 5, 5, this);
        Toolkit.getDefaultToolkit().sync();
        g2d.dispose();
    }


private void playGame(Graphics2D g2d) {
        if(dying) {
            //death();
        } else {
            drawPlayer(g2d);
        }
    }

private void drawPlayer(Graphics2D g2d) {
        g2d.drawImage(ImageLoader.getImage("spieler"), KeyIn.getPlayerPosX(), KeyIn.getPlayerPosY(), this);
    }
Wie gesagt wird alles korrekt gezeichnet, aber bei Bewegung der Spielfigur (betätigen einer Pfeiltaste), ändern sich zwar die KeyIn.playerPos[X,Y]-Variablen (mittels Konsolenausgabe geprüft), jedoch nicht die bildliche Ausgabe.

Hier noch die Hauptklasse Spiel mit Main-Methode
Java:
public Spiel() {
        InitUI();
    }
    
    private void InitUI() {
        add(new Board());
        Board b = new Board();
        KeyIn keys = new KeyIn();
        b.addKeyListener(keys);
        setTitle("Adventurer");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(620,620);
        setLocationRelativeTo(null);
        setVisible(true);
    }
    
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Spiel spiel= new Spiel();
                spiel.setVisible(true);
            }
        });
    }

Wahrscheinlich ist es irgendwas ganz simples, aber ich bin blutiger Anfänger, daher komme ich einfach nicht drauf....

Gruß
Stephan
 
Hm ich finds übertrieben unübersichtlich mit den ganzen draw Methoden. Ich verstehe nicht ganz wieso du this.repaint in der KeyIn Klasse aufrufst, den Zusammenhang zu blicken ist aber mit den Auszügen auch schwer. Normalerweise rufst du repaint in deiner Component Klasse auf. Also in deiner KeyIn Klasse setzt du die x/y positionen, fertig. Repaint rufst du dann in deiner drawPlayer Methode auf.
 
Ich fürchte, wenn ich den gesamten Code poste, wird es erstrecht unübersichtlich. Man könnte mich als Code-Messi bezeichnen, daran sollte ich arbeiten. Ich danke dir trotzdem schon mal für deine Mühen, ich werde mich morgen noch einmal daran versuchen.

Warum der Aufruf im KeyListener? So wurde es uns in der Uni beigebracht. Ich habe es so gedeutet, dass man das macht, weil dadurch jedes Mal zu einem repaint() aufgerufen wird, wenn ein Tastendruck ausgeübt wird, also eine Bewegung beabsichtigt ist.
 
Ein Klassiker: du hast zwei Instanzen von Board. Die erste ist anonym und wird der Klasse Spiel hinzugefügt (add(new Board())), auf der zweiten (Board b = new Board()😉 registrierst du die KeyListener.
Zu deinem restlichen Code sag ich mal nix.
 
Zuletzt bearbeitet:

Zurück
Oben