为什么我的重绘方法没有重新绘制?

时间:2015-05-06 12:20:23

标签: java swing jpanel paint repaint

我不确定原因,但由于某种原因,我的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类中的主要绘制方法:

    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());
}
}

添加控制器的类:

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");
}
}

1 个答案:

答案 0 :(得分:1)

从评论到问题可以看出问题不在于repaint方法,而是在更改时引用的MazeModel类的实例重新绘制player时播放器的坐标和被引用的坐标。

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

为了克服这个问题,我建议您将模型作为参数传递给视图的构造函数。我的意思是说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);
}

我希望能解决你的问题。