首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未调用Repaint()

未调用Repaint()
EN

Stack Overflow用户
提问于 2013-04-10 17:21:22
回答 2查看 136关注 0票数 0

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

我使用swing,我使用Canvas来绘制图形,但是KeyListener不起作用,所以我停止使用Canvas,开始使用paintComponent(Graphics g)。KeyListener现在正在响应,但是当我的while循环调用repaint()方法时,我的图形不会刷新。

我的代码:

代码语言:javascript
复制
    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);

            }
        });

然后:

代码语言:javascript
复制
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);
            }
        }
    }
}
}

和:

代码语言:javascript
复制
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 {
}

我希望你能理解我的问题,并能帮助我,谢谢:)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-10 18:09:01

  1. 您正在创建您的类direction的不同实例,因此您看到的问题
  2. 您不应该像这样使用static。它与良好的OO-programming
  3. Use Swing键绑定背道而驰,而不是使用KeyListener
  4. Follow java命名约定(你的代码现在真的很难读懂):类以大写字母开头,方法和变量以小写字母开头。使用CamelCase来连接单词。
  5. 不要在不需要的时候使用extend (JFrameThread等)
  6. 尝试分离你程序的不同概念(一部分应该负责显示(显示棋盘,敌人,玩家),另一部分负责对用户输入做出反应(按下左键,右键,等等)第三个用于处理游戏逻辑(玩家位置、敌人位置、棋盘等)。

这里是一个非常糟糕的尝试来解释这些不同的建议:

代码语言:javascript
复制
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);
                }
            }
        });

    }

}

请注意,显示和游戏的逻辑在这里完全交织在一起,所以我不太遵循建议nr6。

票数 2
EN

Stack Overflow用户

发布于 2013-04-10 17:27:23

指定给帧/boarddirection与您尝试绘制的目标不同。在主循环中创建一个新的引用

我还建议您使用key bindings而不是关键的监听器

已更新

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

代码语言:javascript
复制
direction dessin = new direction();
b.add(dessin);

但是在你的threadLoop中,你创建了一个新的(断开连接的) direction,并开始尝试更新它……

代码语言:javascript
复制
public void run() {
    g = new direction();
    g.run();
}

...this永远不会绘制,因为它与屏幕没有连接。

您还可以在board中创建第三个引用...

代码语言:javascript
复制
g = new direction();

所有这些断开连接的direction类都没有人可以相互绘制或通信,也没有必要。

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

已更新

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15921810

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档