如何更新图形

时间:2016-01-26 22:58:00

标签: java swing paintcomponent maze

  

每次使用wasd键时如何更新图形?现在我的玩家无法移动,我想每次玩家使用其中一个键移动时更新网格。当按下箭头键时,如何实现和更新每个玩家。我已经完成了这个课程,但是每当按下按键时它似乎都没有移动。每次按下按键时,我如何实现移动并更新网格。我做了代码,但玩家似乎没有移动。任何人都可以告诉我我做错了什么?

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;  // Needed for ActionListener
import javax.swing.event.*;  // Needed for ActionListener
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.Timer;
import java.util.Scanner;

class www extends JFrame
{
    static Maze maze = new Maze ();
    static Timer t;

    //======================================================== constructor
    public www ()
    {
        // 1... Create/initialize components
        // 2... Create content pane, set layout
        JPanel panel = new JPanel ();
        JPanel content = new JPanel ();        // Create a content pane
        content.setLayout (new BorderLayout ()); // Use BorderLayout for panel
        JPanel north = new JPanel ();
        north.setLayout (new FlowLayout ()); // Use FlowLayout for input area

        DrawArea board = new DrawArea (500, 500);
        // 3... Add the components to the input area.

        content.add (north, "North"); // Input area
        content.add (board, "South"); // Output area

        // 4... Set this window's attributes.
        setContentPane (content);
        pack ();
        setTitle ("MAZE");
        setSize (510, 570);
        setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo (null);           // Center window.
    }

    public static void main (String[] args)
    {

        www window = new www ();
        window.setVisible (true);

    }


    class DrawArea extends JPanel
    {
        public DrawArea (int width, int height)
        {
            this.setPreferredSize (new Dimension (width, height)); // size
        }

        public void paintComponent (Graphics g)
        {
            maze.show (g);
            // display current state of colony
        }
    }
}

class Maze 
{
    static Scanner sc;
    private int maze [][];

    public Maze ()
    {
        int [][] grid = 
            {{1,2,1,1,1,1,1,1,1,1,1,1,1},
                {1,0,1,0,1,0,1,0,0,0,0,0,1},
                {1,0,1,0,0,0,1,0,1,1,1,0,1},
                {1,0,0,0,1,1,1,0,0,0,0,0,1},
                {1,0,1,0,0,0,0,0,1,1,1,0,1},
                {1,0,1,0,1,1,1,0,1,0,0,0,1},
                {1,0,1,0,1,0,0,0,1,1,1,0,1},
                {1,0,1,0,1,1,1,0,1,0,1,0,1},
                {1,0,0,0,0,0,0,0,0,0,1,0,1},
                {1,1,1,1,1,1,1,1,1,1,1,0,1}};

        maze = grid;

    }


    public void keyPressed(KeyEvent e, Graphics g)
    {
        int x =  0, y = 0,velX = 0, velY = 0;
        int c =  e.getKeyCode();
        if(c == KeyEvent.VK_LEFT || c == KeyEvent.VK_A)
        {
            velX = -1;
            velY = 0;
            for (int row = 0 ; row < maze.length ; row++)
                for (int col = 0 ; col < maze [0].length ; col++)
                {
                    if (maze [row] [col] == 1) // life
                    {   
                        g.setColor (Color.black);
                    }
                    else if(maze [row][col] == 2)
                    {

                        g.setColor (Color.red);
                    }
                    else 
                    {
                        g.setColor(Color.white);
                    }
                    g.fillRect (col * 20 + 20, row * 20 + 20, 50, 50); // draw life form
            }

        }
        if(c == KeyEvent.VK_UP || c == KeyEvent.VK_W)
        {
            velX = 0;
            velY = -1;
            for (int row = 0 ; row < maze.length ; row++)
                for (int col = 0 ; col < maze [0].length ; col++)
                {
                    if (maze [row] [col] == 1) // life
                    {   
                        g.setColor (Color.black);
                    }
                    else if(maze [row][col] == 2)
                    {

                        g.setColor (Color.red);
                    }
                    else 
                    {
                        g.setColor(Color.white);
                    }
                    g.fillRect (col * 20 + 20, row * 20 + 20, 50, 50); // draw life form
            }
        }
        if(c == KeyEvent.VK_RIGHT || c == KeyEvent.VK_D)
        {
            velX = 1; 
            velY = 0;
            for (int row = 0 ; row < maze.length ; row++)
                for (int col = 0 ; col < maze [0].length ; col++)
                {
                    if (maze [row] [col] == 1) // life
                    {   
                        g.setColor (Color.black);
                    }
                    else if(maze [row][col] == 2)
                    {

                        g.setColor (Color.red);
                    }
                    else 
                    {
                        g.setColor(Color.white);
                    }
                    g.fillRect (col * 20 + 20, row * 20 + 20, 50, 50); // draw life form
            }

        }
        if(c == KeyEvent.VK_DOWN || c == KeyEvent.VK_S)
        {
            velX = 0;
            velY = 1;
            for (int row = 0 ; row < maze.length ; row++)
                for (int col = 0 ; col < maze [0].length ; col++)
                {
                    if (maze [row] [col] == 1) // life
                    {   
                        g.setColor (Color.black);
                    }
                    else if(maze [row][col] == 2)
                    {

                        g.setColor (Color.red);
                    }
                    else 
                    {
                        g.setColor(Color.white);
                    }
                    g.fillRect (col * 20 + 20, row * 20 + 20, 50, 50); // draw life form
            }

        }

    }

    public void keyTyped(KeyEvent e){}

    public void keyReleased(KeyEvent e){}



    public void show (Graphics g)
    {
        for (int row = 0 ; row < maze.length ; row++)
            for (int col = 0 ; col < maze [0].length ; col++)
            {
                if (maze [row] [col] == 1) // life
                {   
                    g.setColor (Color.black);
                }
                else if(maze [row][col] == 2)
                {

                    g.setColor (Color.red);
                }
                else 
                {
                    g.setColor(Color.white);
                }
                g.fillRect (col * 20 + 20, row * 20 + 20, 50, 50); // draw life form
        }

    }


    public class player extends JPanel implements ActionListener,KeyListener
    {

        Timer tm = new Timer(5,this);
        int x =  0, y = 0,velX = 0, velY = 0;
        public player ()
        {
            tm.start ();    
            addKeyListener(this);
            setFocusable(true);
            setFocusTraversalKeysEnabled(false);
        }

        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillRect(x,y,50,30);

        }

        public void actionPerformed(ActionEvent e)
        {
            x = x+velX;
            y = y +velY;
            repaint();
        }

        public void keyPressed(KeyEvent e)
        {
            int c =  e.getKeyCode();
            if(c == KeyEvent.VK_LEFT || c == KeyEvent.VK_A)
            {
                velX = -1;
                velY = 0;

            }
            if(c == KeyEvent.VK_UP || c == KeyEvent.VK_W)
            {
                velX = 0;
                velY = -1;
            }
            if(c == KeyEvent.VK_RIGHT || c == KeyEvent.VK_D)
            {
                velX = 1; 
                velY = 0;
            }
            if(c == KeyEvent.VK_DOWN || c == KeyEvent.VK_S)
            {
                velX = 0;
                velY = 1;
        }

    }

    public void keyTyped(KeyEvent e){}

    public void keyReleased(KeyEvent e){}

2 个答案:

答案 0 :(得分:4)

好的,让我们从一些问题开始......

class www extends JFrame

首先,您应该避免覆盖JFrame,不要向类中添加任何新功能,将自己锁定在单个用例中,并冒着其他问题的风险,这些问题很难诊断。

你的班级名字真的应该以大写字母开头。阅读Code Conventions for the Java TM Programming Language,它将使人们更容易阅读您的代码并让您阅读其他代码。

下一步...

static Maze maze = new Maze ();
static Timer t;

static是设计糟糕的好兆头。您应该避免将它们用作交叉通信机制,因为您无法控制其引用的更改方式,从而难以诊断可能出现的问题

下一步...

class DrawArea extends JPanel
{
    public DrawArea (int width, int height)
    {
        this.setPreferredSize (new Dimension (width, height)); // size
    }

    public void paintComponent (Graphics g)
    {
        maze.show (g);
        // display current state of colony
    }
}

首先,你打破了绘画链,这可能导致绘画工件没有结束,你有义务在执行任何自定义绘画之前调用绘制方法super方法。有关详细信息,请参阅Painting in AWT and SwingPerforming Custom Painting

此外,迷宫不是绘画本身的责任,而是要确定它应该如何最好地代表模型/迷宫

下一步...

public class player extends JPanel implements ActionListener,KeyListener
{
    //...
}

好的,这个课程从未使用过,但这是你唯一一次注册KeyListener。你也过度复杂化了这个过程,因为DrawArea也应该负责绘制播放器和处理用户输入。

作为一般经验法则,由于多种原因,KeyListener不是合适的API。您最好使用Key Bindings API,它可以解决KeyListener的问题,并且可以更改和实施其他输入设备。

您的代码通常不会关注孤立的责任,为什么允许player更改播放器的位置?

OOP的一个关键方面是关于孤立责任,这样可以更容易地改变事物而不会对系统的其他部分产生负面影响,这也是Model-View-Controller范例的支持。

基本思想是,您的模型控制数据,维护状态并定义可以更改的规则(并且可以根据需要提供事件通知)。视图负责呈现模型的状态。控制器是粘合它的粘合剂。

通常在MVC中,模型和视图从不与每个模型进行通信,控制器有责任充当它们之间的沟通渠道。这可以直接实现(直接对控制器进行调用),或者更常见的是通过使用Observer Pattern来实现,其中视图和模型生成控制器响应的事件。

我们需要做的第一件事是定义每个元素的基本功能,每个层将向其他方公开的信息和功能,例如......

public interface GameModel {
    public int[][] getMaze();
    public int[] getPlayerLocation();
    public void setPlayerLocation(int[] location);
    public void update(Set<Direction> directions);
}

public interface GameController {
    public int[][] getMaze();
    public int[] getPlayerLocation();
    public void setDirectionPressed(Direction direction, boolean pressed);
    public void start();
}

public interface GameView {
    public void update();
    public void setController(GameController controller);
    public GameController getController();
}

这是Composition over inheritance概念的开始,它允许您更好地解耦代码,因为您不依赖于类的物理实现,而只是依赖于维护给定合同的协议。 / p>

接下来,我们定义实现....

public class DefaultGameModel implements GameModel {

    private int[][] maze
            = {{1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
            {1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1},
            {1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1},
            {1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1},
            {1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1},
            {1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1},
            {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1},
            {1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1},
            {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
            {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}};

    private int[] playerLocation = new int[]{1, 0};

    @Override
    public int[][] getMaze() {
        return maze;
    }

    @Override
    public int[] getPlayerLocation() {
        return playerLocation;
    }

    @Override
    public void setPlayerLocation(int[] playerLocation) {
        this.playerLocation = playerLocation;
    }

    @Override
    public void update(Set<Direction> directions) {
        int[] location = getPlayerLocation();
        int[][] maze = getMaze();
        int x = location[0];
        int y = location[1];
        if (directions.contains(Direction.UP)) {
            y--;
        } else if (directions.contains(Direction.DOWN)) {
            y++;
        }
        if (directions.contains(Direction.LEFT)) {
            x--;
        } else if (directions.contains(Direction.RIGHT)) {
            x++;
        }
        if (x < 0) {
            x = 0;
        } else if (x >= maze[0].length) {
            x = maze[0].length - 1;
        }
        if (y < 0) {
            y = 0;
        } else if (y >= maze.length) {
            y = maze.length - 1;
        }

        if (maze[y][x] == 0) {
            location = new int[]{x, y};
            setPlayerLocation(location);
        }

    }

}

public class DefaultGameController implements GameController {

    private GameView view;
    private GameModel model;

    private Timer timer;

    private Set<Direction> directions;

    public DefaultGameController(GameView view, GameModel model) {
        this.view = view;
        this.model = model;
        directions = new HashSet<>(4);
        view.setController(this);
    }

    public GameView getView() {
        return view;
    }

    public GameModel getModel() {
        return model;
    }

    @Override
    public int[][] getMaze() {
        return getModel().getMaze();
    }

    @Override
    public int[] getPlayerLocation() {
        return getModel().getPlayerLocation();
    }

    @Override
    public void setDirectionPressed(Direction direction, boolean pressed) {
        if (pressed) {
            directions.add(direction);
        } else {
            directions.remove(direction);
        }
    }

    @Override
    public void start() {
        // This isn't really required for this type of simple example, but what
        // does do is demonstrates at least one possible solution for simple
        // game loop
        //
        // Because of the basic nature of the game, it would be possible to have
        // setDirectionPressed call model.update and view.update
        if (timer != null && timer.isRunning()) {
            timer.stop();
        }
        timer = new Timer(40, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                getModel().update(Collections.unmodifiableSet(directions));
                getView().update();
            }
        });
        timer.start();
    }

}

public class DefaultGameView extends JPanel implements GameView {

    private GameController controller;

    public DefaultGameView() {
        addKeyBinding("left.pressed", KeyEvent.VK_LEFT, true, new MoveAction(Direction.LEFT, true));
        addKeyBinding("left.released", KeyEvent.VK_LEFT, false, new MoveAction(Direction.LEFT, false));
        addKeyBinding("right.pressed", KeyEvent.VK_RIGHT, true, new MoveAction(Direction.RIGHT, true));
        addKeyBinding("right.released", KeyEvent.VK_RIGHT, false, new MoveAction(Direction.RIGHT, false));
        addKeyBinding("up.pressed", KeyEvent.VK_UP, true, new MoveAction(Direction.UP, true));
        addKeyBinding("up.released", KeyEvent.VK_UP, false, new MoveAction(Direction.UP, false));
        addKeyBinding("down.pressed", KeyEvent.VK_DOWN, true, new MoveAction(Direction.DOWN, true));
        addKeyBinding("down.released", KeyEvent.VK_DOWN, false, new MoveAction(Direction.DOWN, false));
    }

    @Override
    public void update() {
        repaint();
    }

    @Override
    public void setController(GameController controller) {
        this.controller = controller;
        revalidate();
        repaint();
    }

    @Override
    public GameController getController() {
        return controller;
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension size = new Dimension(13 * 20, 10 * 20);
        GameController controller = getController();
        if (controller != null) {
            int[][] maze = controller.getMaze();
            size.height = maze.length * 20;
            size.width = maze[0].length * 20;
        }
        return size;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        GameController controller = getController();
        if (controller != null) {
            Graphics2D g2d = (Graphics2D) g.create();
            Dimension size = getPreferredSize();
            int x = (getWidth() - size.width) / 2;
            int y = (getHeight() - size.height) / 2;

            int[][] maze = controller.getMaze();
            for (int row = 0; row < maze.length; row++) {
                int yPos = y + (row * 20);
                for (int col = 0; col < maze[row].length; col++) {
                    int xPos = x + (col * 20);
                    switch (maze[row][col]) {
                        case 1:
                            g2d.setColor(Color.BLACK);
                            break;
                        default:
                            g2d.setColor(Color.WHITE);
                            break;
                    }
                    g2d.fillRect(xPos, yPos, 20, 20);
                }
            }
            int[] playerLocation = controller.getPlayerLocation();
            int xPos = x + (playerLocation[0] * 20);
            int yPos = y + (playerLocation[1] * 20);
            g2d.setColor(Color.RED);
            g2d.fillRect(xPos, yPos, 20, 20);
            g2d.dispose();
        }
    }

    protected void addKeyBinding(String name, int virtualKey, boolean pressed, MoveAction action) {
        addKeyBinding(name, KeyStroke.getKeyStroke(virtualKey, 0, !pressed), action);
    }

    protected void addKeyBinding(String name, KeyStroke keyStroke, MoveAction action) {
        InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = getActionMap();

        inputMap.put(keyStroke, name);
        actionMap.put(name, action);
    }

    public class MoveAction extends AbstractAction {
        private Direction direction;
        private boolean pressed;

        public MoveAction(Direction direction, boolean pressed) {
            this.direction = direction;
            this.pressed = pressed;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            GameController controller = getController();
            if (controller != null) {
                controller.setDirectionPressed(direction, pressed);
            }
        }

    }

}

好吧,对于这样一个简单的问题,这似乎有些奇怪,但是想知道想要添加更多的迷宫,这就像改变模型一样简单。

最后,我们需要把它放在一起......

Maze

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Main {

    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                GameModel model = new DefaultGameModel();
                DefaultGameView view = new DefaultGameView();
                GameController controller = new DefaultGameController(view, model);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(view);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                controller.start();
            }
        });
    }

    public enum Direction {
        UP, DOWN, LEFT, RIGHT;
    }

    public interface GameModel {
        public int[][] getMaze();
        public int[] getPlayerLocation();
        public void setPlayerLocation(int[] location);
        public void update(Set<Direction> directions);
    }

    public interface GameController {
        public int[][] getMaze();
        public int[] getPlayerLocation();
        public void setDirectionPressed(Direction direction, boolean pressed);
        public void start();
    }

    public interface GameView {
        public void update();
        public void setController(GameController controller);
        public GameController getController();
    }

    public class DefaultGameModel implements GameModel {

        private int[][] maze
                = {{1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                {1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1},
                {1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1},
                {1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1},
                {1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1},
                {1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1},
                {1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1},
                {1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1},
                {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1},
                {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}};

        private int[] playerLocation = new int[]{1, 0};

        @Override
        public int[][] getMaze() {
            return maze;
        }

        @Override
        public int[] getPlayerLocation() {
            return playerLocation;
        }

        @Override
        public void setPlayerLocation(int[] playerLocation) {
            this.playerLocation = playerLocation;
        }

        @Override
        public void update(Set<Direction> directions) {
            int[] location = getPlayerLocation();
            int[][] maze = getMaze();
            int x = location[0];
            int y = location[1];
            if (directions.contains(Direction.UP)) {
                y--;
            } else if (directions.contains(Direction.DOWN)) {
                y++;
            }
            if (directions.contains(Direction.LEFT)) {
                x--;
            } else if (directions.contains(Direction.RIGHT)) {
                x++;
            }
            if (x < 0) {
                x = 0;
            } else if (x >= maze[0].length) {
                x = maze[0].length - 1;
            }
            if (y < 0) {
                y = 0;
            } else if (y >= maze.length) {
                y = maze.length - 1;
            }

            if (maze[y][x] == 0) {
                location = new int[]{x, y};
                setPlayerLocation(location);
            }

        }

    }

    public class DefaultGameController implements GameController {

        private GameView view;
        private GameModel model;

        private Timer timer;

        private Set<Direction> directions;

        public DefaultGameController(GameView view, GameModel model) {
            this.view = view;
            this.model = model;
            directions = new HashSet<>(4);
            view.setController(this);
        }

        public GameView getView() {
            return view;
        }

        public GameModel getModel() {
            return model;
        }

        @Override
        public int[][] getMaze() {
            return getModel().getMaze();
        }

        @Override
        public int[] getPlayerLocation() {
            return getModel().getPlayerLocation();
        }

        @Override
        public void setDirectionPressed(Direction direction, boolean pressed) {
            if (pressed) {
                directions.add(direction);
            } else {
                directions.remove(direction);
            }
        }

        @Override
        public void start() {
            // This isn't really required for this type of simple example, but what
            // does do is demonstrates at least one possible solution for simple
            // game loop
            //
            // Because of the basic nature of the game, it would be possible to have
            // setDirectionPressed call model.update and view.update
            if (timer != null && timer.isRunning()) {
                timer.stop();
            }
            timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    getModel().update(Collections.unmodifiableSet(directions));
                    getView().update();
                }
            });
            timer.start();
        }

    }

    public class DefaultGameView extends JPanel implements GameView {

        private GameController controller;

        public DefaultGameView() {
            addKeyBinding("left.pressed", KeyEvent.VK_LEFT, true, new MoveAction(Direction.LEFT, true));
            addKeyBinding("left.released", KeyEvent.VK_LEFT, false, new MoveAction(Direction.LEFT, false));
            addKeyBinding("right.pressed", KeyEvent.VK_RIGHT, true, new MoveAction(Direction.RIGHT, true));
            addKeyBinding("right.released", KeyEvent.VK_RIGHT, false, new MoveAction(Direction.RIGHT, false));
            addKeyBinding("up.pressed", KeyEvent.VK_UP, true, new MoveAction(Direction.UP, true));
            addKeyBinding("up.released", KeyEvent.VK_UP, false, new MoveAction(Direction.UP, false));
            addKeyBinding("down.pressed", KeyEvent.VK_DOWN, true, new MoveAction(Direction.DOWN, true));
            addKeyBinding("down.released", KeyEvent.VK_DOWN, false, new MoveAction(Direction.DOWN, false));
        }

        @Override
        public void update() {
            repaint();
        }

        @Override
        public void setController(GameController controller) {
            this.controller = controller;
            revalidate();
            repaint();
        }

        @Override
        public GameController getController() {
            return controller;
        }

        @Override
        public Dimension getPreferredSize() {
            Dimension size = new Dimension(13 * 20, 10 * 20);
            GameController controller = getController();
            if (controller != null) {
                int[][] maze = controller.getMaze();
                size.height = maze.length * 20;
                size.width = maze[0].length * 20;
            }
            return size;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            GameController controller = getController();
            if (controller != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                Dimension size = getPreferredSize();
                int x = (getWidth() - size.width) / 2;
                int y = (getHeight() - size.height) / 2;

                int[][] maze = controller.getMaze();
                for (int row = 0; row < maze.length; row++) {
                    int yPos = y + (row * 20);
                    for (int col = 0; col < maze[row].length; col++) {
                        int xPos = x + (col * 20);
                        switch (maze[row][col]) {
                            case 1:
                                g2d.setColor(Color.BLACK);
                                break;
                            default:
                                g2d.setColor(Color.WHITE);
                                break;
                        }
                        g2d.fillRect(xPos, yPos, 20, 20);
                    }
                }
                int[] playerLocation = controller.getPlayerLocation();
                int xPos = x + (playerLocation[0] * 20);
                int yPos = y + (playerLocation[1] * 20);
                g2d.setColor(Color.RED);
                g2d.fillRect(xPos, yPos, 20, 20);
                g2d.dispose();
            }
        }

        protected void addKeyBinding(String name, int virtualKey, boolean pressed, MoveAction action) {
            addKeyBinding(name, KeyStroke.getKeyStroke(virtualKey, 0, !pressed), action);
        }

        protected void addKeyBinding(String name, KeyStroke keyStroke, MoveAction action) {
            InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = getActionMap();

            inputMap.put(keyStroke, name);
            actionMap.put(name, action);
        }

        public class MoveAction extends AbstractAction {
            private Direction direction;
            private boolean pressed;

            public MoveAction(Direction direction, boolean pressed) {
                this.direction = direction;
                this.pressed = pressed;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                GameController controller = getController();
                if (controller != null) {
                    controller.setDirectionPressed(direction, pressed);
                }
            }

        }

    }
}

这是一般概念的基本概述,你应该考虑探索基本的OOP和博弈论

答案 1 :(得分:0)

要处理键盘事件,您应该创建实现KeyListener接口的类的实例(或使用明智建议的其他人使用key bindings)并使用addKeyListener方法注册该实例。

构建主窗口时,可以创建MazeDrawArea,但不创建player,也不会注册密钥监听器。

Maze类包含keyPressed等方法,但它没有实现KeyListener接口,因此不会调用这些方法。

你有两个类DrawAreaplayer,它们都扩展了JPanel并渲染了一些东西。将这些类一起使用的想法是什么?我看到DrawArea(使用Maze)也可以渲染红色方块。是否真的需要player中的呈现代码?

要检查是否调用了特定方法,可以使用调试器(在您感兴趣的每种方法中添加断点),或者使用System.out.println将消息打印到控制台。

MadProgrammer所说的关于OOP和MVC的内容也是正确的。至少你应该用大写字母命名类并清理缩进。