如何将控制器连接到此应用程序中的视图?我正在尝试使用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);
}
}