没有调用Repaint()

时间:2013-04-10 09:21:22

标签: java swing jpanel repaint

我正在开发一个学校项目的游戏,一个类似炸弹人的游戏。

我正在使用swing并且我使用Canvas绘制我的图形,但KeyListener无效,所以我使用Canvas退出并开始使用paintComponent(Graphics g)。 KeyListener现在正在响应,但是当我的while循环调用repaint()方法时,我的图形不会刷新。

我的代码:

    dispose();

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                board b = new board();
                b.setSize(630, 650);
                b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                b.setVisible(true);
                direction dessin = new direction();
                b.add(dessin);
                b.setVisible(true);
                dessin.setBackground(Color.BLACK);

            }
        });

然后:

package Bm;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;

import javax.swing.JComponent;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class direction extends JPanel implements Runnable {

static float bmx = 35;
static float bmy = 35;
static float ex = 520;
static float ey = 520;
static float v = 0.03f;

static boolean gauche;
static boolean droite;
static boolean haut;
static boolean bas;

static void movEnnemi() {

    int r = 1 + (int) (Math.random() * ((4 - 1) + 1));
    Ennemi.droite = false;
    Ennemi.gauche = false;
    Ennemi.bas = false;
    Ennemi.haut = false;

    switch (r) {
    case 1:
        Ennemi.droite = true;
        break;
    case 2:
        Ennemi.gauche = true;
        break;
    case 3:
        Ennemi.bas = true;
        break;
    case 4:
        Ennemi.haut = true;
        break;
    }

    try {
        Thread.sleep(5);
    } catch (Exception e) {
    }
    ;

}

public direction() {
    super();
}

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

    for (int ligne = 0; ligne < board.gridHauteur; ligne++) {
        for (int colonne = 0; colonne < board.gridLargeur; colonne++) {

            switch (board.plateau1[ligne][colonne]) {
            case 0:
                g.setColor(Color.lightGray);
                g.fillRect(30 * ligne, 30 * colonne, 30, 30);
                break;
            case 1:
                g.setColor(Color.black);
                g.fillRect(30 * ligne, 30 * colonne, 30, 30);
                board.plateau1[ligne][colonne] = board.BLOCKED;
                break;
            case 2:
                g.setColor(Color.darkGray);
                g.fillRect(30 * ligne, 30 * colonne, 30, 30);
                board.plateau1[ligne][colonne] = board.BLOCKED;
                break;
            }
        }
    }
    g.setColor(Color.blue);
    g.fillRect((int) ex, (int) ey, 20, 20);
    g.setColor(Color.red);
    g.fillRect((int) bmx, (int) bmy, 21, 21);
    g.dispose();
}

public void run() {

    long dernierTempsLoop = System.currentTimeMillis();

    while (true) {

        long delta = (System.currentTimeMillis() - dernierTempsLoop);
        dernierTempsLoop = System.currentTimeMillis();
        movEnnemi();

        for (int i = 0; i < delta / 5; i++) {
            logic(5);
            Ennemi.logic(5);
        }
        if ((delta % 5) != 0) {
            logic(delta % 5);
            Ennemi.logic(delta % 5);
        }

        System.out.println((int) (bmx / 30) + " - " + (int) (bmy / 30));

        try {
            Thread.sleep(20);
        } catch (Exception e) {
        }
        ;
        repaint(); // <== HERE
    }
}

public static void logic(long delta) {

    float dx = 0;
    float dy = 0;
    if (gauche) {
        dx--;
    }
    if (droite) {
        dx++;
    }
    if (haut) {
        dy--;
    }
    if (bas) {
        dy++;
    }
    if ((dx != 0) || (dy != 0)) {
        joueur.mouvement(dx * delta * v, dy * delta * v);
        if (joueur.mouvement((dx * delta * v), (dy * delta * v)) == false) {
            if (joueur.mouvement(0, dy * delta * v)) {
                joueur.mouvement(0, dy * delta * v);
            }
            if (joueur.mouvement(dx * delta * v, 0)) {

                joueur.mouvement(dx * delta * v, 0);
            }
        }
    }
}
}

并且:

package Bm;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Timer;

import javax.swing.*;

@SuppressWarnings("serial")
class board extends JFrame implements KeyListener {

static JPanel p;
public Timer fpstimer;
public direction g;
static final int BLOCKED = 1;
static int gridLargeur = 21;
static int gridHauteur = 21;
int fenLargeur = 630;
int fenHauteur = 650;
public static int plateau1[][] = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1 },
        { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } };

public board() {
    super("Bomberman");
    g = new direction();
    addKeyListener(this);
    threadLoop p = new threadLoop("loop");
    p.start();
}

public static boolean blocked(double d, double e) {

    return plateau1[(int) d][(int) e] == BLOCKED;

}

public void keyPressed(KeyEvent e) {

    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
        direction.gauche = true;
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
        direction.droite = true;
    }
    if (e.getKeyCode() == KeyEvent.VK_DOWN) {
        direction.bas = true;
    }
    if (e.getKeyCode() == KeyEvent.VK_UP) {
        direction.haut = true;
    }
    if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
        System.exit(0);
    }
}

public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
        direction.gauche = false;
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
        direction.droite = false;
    }
    if (e.getKeyCode() == KeyEvent.VK_DOWN) {
        direction.bas = false;
    }
    if (e.getKeyCode() == KeyEvent.VK_UP) {
        direction.haut = false;
    }
}

public void keyTyped(KeyEvent e) {
}
}

class threadLoop extends Thread {

public direction g;

threadLoop(String name) {
    super(name);
}

public void run() {
    g = new direction();
    g.run();

}

}

public class Jouer {
}

我希望你能理解我的问题,能够帮助我,谢谢你。)

2 个答案:

答案 0 :(得分:2)

  1. 您正在创建班级direction的不同实例,因此您遇到了问题
  2. 您不应该像这样使用static。这违背了良好的OO编程
  3. 使用Swing键绑定而不是使用KeyListener
  4. 遵循java命名约定(您的代码现在很难阅读):类以大写字母,方法和带小写字母的变量开头。使用CamelCase连接单词。
  5. 不需要时extendJFrameThread等等。
  6. 尝试分离程序的各种概念(一部分应负责显示(显示板,敌人,玩家),另一部分对用户输入作出反应(按下左键,按下右键)等等...)和第三个处理游戏逻辑(玩家位置,敌人位置,棋盘等等)。)。
  7. 这是一个非常蹩脚的尝试来解释这些建议:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.event.ActionEvent;
    import java.awt.event.KeyEvent;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.Random;
    
    import javax.swing.AbstractAction;
    import javax.swing.ImageIcon;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.KeyStroke;
    import javax.swing.SwingUtilities;
    
    public class Game {
    
        private static final String ICON_URL = "http://images2.wikia.nocookie.net/__cb20100515002803/fanon/images/a/a2/Bomberman_sprite.png";
    
        private static final int GRID_SIZE = 24;
        private static final int SQUARE_SIZE = 30;
    
        private JFrame frame;
    
        private Board board;
    
        private static class Board extends JPanel {
    
            private int[][] grid;
    
            private int playerX;
            private int playerY;
    
            private ImageIcon playerIcon;
    
            public Board() throws MalformedURLException {
                // Some code to generate a random pseudo-board
                Random random = new Random();
                grid = new int[GRID_SIZE][];
                for (int i = 0; i < GRID_SIZE; i++) {
                    grid[i] = new int[GRID_SIZE];
                    for (int j = 0; j < GRID_SIZE; j++) {
                        int r = random.nextInt(10);
                        grid[i][j] = r > 8 ? 2 : r > 6 ? 1 : 0;
                    }
                }
                playerIcon = new ImageIcon(new URL(ICON_URL));
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(GRID_SIZE * SQUARE_SIZE, GRID_SIZE * SQUARE_SIZE);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                // pseudo-board painting
                for (int i = 0; i < grid.length; i++) {
                    for (int j = 0; j < grid[i].length; j++) {
                        switch (grid[i][j]) {
                        case 1:
                            g.setColor(Color.GREEN);
                            g.fillRect(i * SQUARE_SIZE, j * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
                            break;
                        case 2:
                            g.setColor(Color.RED);
                            g.fillRect(i * SQUARE_SIZE, j * SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE);
                            break;
    
                        default:
                            break;
                        }
                    }
                }
                // Player painting
                int x = playerX * SQUARE_SIZE + (SQUARE_SIZE - playerIcon.getIconWidth()) / 2;
                int y = playerY * SQUARE_SIZE + (SQUARE_SIZE - playerIcon.getIconHeight()) / 2;
                g.drawImage(playerIcon.getImage(), x, y, this);
            }
    
            public int getPlayerX() {
                return playerX;
            }
    
            public int getPlayerY() {
                return playerY;
            }
    
            public void setPlayerX(int playerX) {
                if (playerX >= 0 && playerX < GRID_SIZE && grid[playerX][playerY] == 0) {
                    this.playerX = playerX;
                    repaint();
                }
            }
    
            public void setPlayerY(int playerY) {
                if (playerY >= 0 && playerY < GRID_SIZE && grid[playerX][playerY] == 0) {
                    this.playerY = playerY;
                    repaint();
                }
            }
        }
    
        private class MoveLeftAction extends AbstractAction {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                board.setPlayerX(board.getPlayerX() - 1);
            }
    
        }
    
        private class MoveRightAction extends AbstractAction {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                board.setPlayerX(board.getPlayerX() + 1);
            }
    
        }
    
        private class MoveUpAction extends AbstractAction {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                board.setPlayerY(board.getPlayerY() - 1);
            }
    
        }
    
        private class MoveDownAction extends AbstractAction {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                board.setPlayerY(board.getPlayerY() + 1);
            }
    
        }
    
        private class ExitAction extends AbstractAction {
    
            @Override
            public void actionPerformed(ActionEvent e) {
                int i = JOptionPane.showConfirmDialog(board, "Are you sure you want to exit?");
                if (i == JOptionPane.YES_OPTION) {
                    System.exit(0);
                }
            }
    
        }
    
        protected void initUI() throws MalformedURLException {
            frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setResizable(false);
            board = new Board();
            board.setBackground(Color.BLACK);
            board.registerKeyboardAction(new MoveLeftAction(), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), JComponent.WHEN_FOCUSED);
            board.registerKeyboardAction(new MoveRightAction(), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), JComponent.WHEN_FOCUSED);
            board.registerKeyboardAction(new MoveUpAction(), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), JComponent.WHEN_FOCUSED);
            board.registerKeyboardAction(new MoveDownAction(), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), JComponent.WHEN_FOCUSED);
            board.registerKeyboardAction(new ExitAction(), KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
            frame.add(board);
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        new Game().initUI();
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                        JOptionPane.showMessageDialog(null, "Could not load icon from Internet", "Unable to start", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });
    
        }
    
    }
    

    请注意,游戏的显示和逻辑完全交织在一起,所以我不太关注6号的建议。

答案 1 :(得分:1)

您分配给框架direction的{​​{1}}与您尝试绘制的内容不同。您在主循环中创建一个新引用

我还建议你使用key bindings而非关键听众

<强>更新

您构建一个初始board,然后将其添加到屏幕。这实际上是将呈现的内容。

direction

但是在您的direction dessin = new direction(); b.add(dessin); 中,您创建了一个新的(已断开连接的)threadLoop并开始尝试更新它...

direction

...这永远不会画画,因为它与屏幕无关。

您还可以在public void run() { g = new direction(); g.run(); } ...

中创建第三个引用
board

所有这些断开连接的g = new direction(); 类都没有人可以绘制或与每个类进行通信,这是不必要的。

我会在direction中创建一个引用,将其添加到框架并将该引用传递给board

<强>更新

您可以查看this。这是一个基本示例,演示了一个简单的线程动画引擎和游戏资产移动的键绑定