为什么我的重绘方法不重绘?

Why is my repaint method not repainting?

我不确定为什么,但出于某种原因,我的 repaint 方法不起作用。我知道机芯运行正常,因为我还有 println(); 语句来帮助我检查。我不确定这是因为我如何将我的角色绘制到 JPanel 上,还是因为我使用的是 BufferedImage(我不明白为什么会出现这个问题,但是只是一个猜测)。这里是应该更新的地方的代码(这只是向上移动的代码,其他都是一样的):

public class MazeController implements KeyListener {
MazeModel model;
MazePanel panel;
Maze maze = new Maze();

public MazeController(MazePanel panel, MazeModel model){
    this.panel = panel;
    this.model = model;
}

public void keyPressed(KeyEvent e){ //all of the different movement keys
    switch(e.getKeyCode()){ //get the Player's key press
    //UP
    case KeyEvent.VK_W:
    case KeyEvent.VK_UP:
        model.setPreviousY(model.getPlayerX()); //keeps the old y coordinate just incase of collision
        model.moveUP(model.getPlayerY()); //moves up based on the Player's y coordinate
        maze.collisionChecker(model.getPlayerX(), model.getPlayerY());
        //after checking
        if(maze.getCollision() != true){
            System.out.println("You move up!"); //console output
            panel.repaint(); //moving the image only if it is a valid move
        }
        else if(maze.getCollision() == true){
            System.out.println("Illegal move, there is a wall!");
            model.setPlayerY(model.getPreviousY()); //resets there coordinate
            maze.setCollision(false); //resets the collision
        }

        System.out.println("Your current coordinates are: " + model.getPlayerX() + ", " + model.getPlayerY()); //checking coordinates
        break;

这是MazePanel中的主要绘制方法class:

    public MazePanel(){ //constructor
    setPreferredSize(new Dimension(500, 500)); //map size
    setBackground(Color.DARK_GRAY); //ground color
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    maze.paintWall(g); //creates the walls
    p.playerPaint(g);
    e.paintEnemy(g);
}

我正在尝试让 p.playerPaint(g); 在玩家尝试移动时正确重绘。我再次知道 KeyEvents 正在工作,因为我能够在我的 println(); 中看到声明指出它正确地进行了 x 和 y 坐标的方向移动。

玩家绘画方法:

class Player extends Entity{ //inheritance
Image i = new Image();
MazeModel model = new MazeModel();
//image = i.getPlayer();
private BufferedImage image = i.getPlayer();

public void setPlayerStart(int x, int y){
    model.setPlayerX(x); //sets the starting x position of the player's image
    model.setPlayerY(y); //sets the starting y position of the player's image
    System.out.println("Your current coordinates are " + model.getPlayerX() + ", " + model.getPlayerY());
}

public void playerPaint(Graphics g){
    g.drawImage(image, model.getPlayerX(), model.getPlayerY(), null); //creates the user
    System.out.println("Your current coordinates are " + model.getPlayerX() + ", " + model.getPlayerY());
}
}

Class 添加控制器:

public class MazeView extends JFrame { //FlowLayout
private MazePanel panel;
private MazeModel model;
private MazeController controller;

MazeView(){ //creating the JFrame and JPanel
    panel = new MazePanel();
    model = new MazeModel();
    controller = new MazeController(panel, model);

    this.setLayout(new FlowLayout()); //non null FlowLayout
    addKeyListener(controller);
    add(panel);
    this.pack();
    this.setTitle("Maze game by Tyler Webster");
}
}

从问题的评论可以看出问题不在于repaint方法,而在于MazeModel的实例class 在更改玩家坐标时被引用,而在重新绘制 player.

时被引用

主要问题是在 MazeView 构造函数中初始化 MazeController 之前初始化了一个新实例 MazeModelMazeModel 的另一个新实例也在 Player class 的构造函数中初始化。

为了解决这个问题,我建议您将模型作为参数传递给视图的构造函数。我的意思是 Player 的构造函数应该是:

public Player(MazeModel model){
    this.model = model;
    //rest of the constructor.
}

构造函数MazeView应该是:

public MazeView(MazeModel model){
    p = new Player(model);
    //all the other code
}

MazeView构造函数应改为:

MazeView(){ //creating the JFrame and JPanel
    model = new MazeModel();
    panel = new MazePanel(model);
    controller = new MazeController(panel, model);
}

希望这能解决您的问题。