如何在此程序中“使用”控制器?

时间:2015-12-21 15:23:31

标签: java swing user-interface model-view-controller

如何将控制器连接到此应用程序中的视图?我正在尝试使用MVC模式在Swing中创建一个简单的蛇游戏。

我认为我的运动逻辑是正确的,但我不明白我如何使用控制器?我希望箭头键对应方向,所以如果我按下“向上”键,我希望控制器将其发送到模型(Snake),然后将其发送到视图(MainFrame)。

我不确定这是否是正确的做法。

public class GameLoop {


    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                MainFrame mainFrame = new MainFrame();
                Snake snake = new Snake(mainFrame);
                Controller controller = new Controller(snake);
            }

        });
    }

}


public class Controller {



private List<ControllerListener> listeners;

    public Controller(ControllerListener... listeners) {
        this.listeners = new ArrayList<>(Arrays.asList(listeners));
    }

    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        Direction dir = null;
        switch( keyCode ) { 
            case KeyEvent.VK_UP:
                dir = Direction.NORTH;
                break;

            case KeyEvent.VK_DOWN:
                dir = Direction.SOUTH;
                break;

            case KeyEvent.VK_LEFT:
                dir = Direction.WEST;
                break;

            case KeyEvent.VK_RIGHT :
                dir = Direction.EAST;
                break;
        }

        for(ControllerListener listener: listeners) {
            listener.controllerUsed(dir);
        }
    } 


}


public interface ControllerListener {

    void controllerUsed(Direction dir);

    }

    public enum Direction {
    WEST, NORTH, EAST, SOUTH;

    }


    public class MainFrame implements SnakeListener {

    private JFrame frame = new JFrame();
    private JPanel drawPanel = new DrawPanel();
    private List<Integer[]> snakeParts = new ArrayList<Integer[]>();

    public MainFrame() {


        frame.add(drawPanel);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }


    private class DrawPanel extends JPanel {

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.GRAY);
            g.fillRect(0, 0, getWidth(), getHeight());

            g.setColor(Color.BLACK);
            for(Integer[] part : snakeParts) {
                g.fillOval(part[0], part[1], 10, 10);
            }


        }

        public Dimension getPreferredSize() {
            return new Dimension(800, 600);
        }

    }


    @Override
    public void snakeMoved(List<Integer[]> snakeParts) {
        this.snakeParts = snakeParts;
        drawPanel.repaint();
    }
}


public interface SnakeListener {

void snakeMoved(List<Integer[]> snakeParts);

}


public class Snake implements ControllerListener {

    private int headX, headY;
    private Direction direction;
    private List<Integer[]> snakeParts = new ArrayList<>();

    private List<SnakeListener> snakeListeners;

    public Snake(SnakeListener... listeners) {
        snakeListeners = new ArrayList<>(Arrays.asList(listeners));

        headX = 10;
        headY = 10;
        direction = Direction.EAST;

        Integer[] part = new Integer[2];
        part[0] = headX;
        part[1] = headY;
        snakeParts.add(part);
    }

    public void move(Direction dir) {
        direction = dir;
        Integer[] part = {headX, headY};
        switch(dir) {
        case EAST:
            headX++;
            part[0] = headX;
            break;

        case NORTH:
            headY--;
            part[1] = headY;
            break;

        case SOUTH:
            headY++;
            part[1] = headY;
            break;

        case WEST:
            headX--;
            part[0] = headX;
            break;
        default:
            break;
        }

        snakeParts.add(part);
        snakeParts.remove(0);

        for(SnakeListener listener : snakeListeners) {
            listener.snakeMoved(snakeParts);
        }
    }

    private void checkDefeat() {
        // TODO Auto-generated method stub

    }

    @Override
    public void controllerUsed(Direction dir) {
        move(dir);
    }

}

0 个答案:

没有答案