小曾公子 2016-12-12 14:12 采纳率: 40%
浏览 1621

java 贪吃蛇,类之间的调用

想把MyFrame里面的菜单、键盘监听、事件监听、绘制界面分离出来 各自形成一个类 ,
但是弄了好久也没有做出来,所以请教各位大神们,怎么讲这些分解出来。谢谢了~!~
(由于没有C币了 , 所以。。。抱歉了)

 package zeng;

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Iterator;
import java.util.LinkedList;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

public class MyFrame extends KeyAdapter implements ActionListener{
    JFrame frame ;
    Canvas canvas;
    Container container;
    JLabel label;           // 计分
    Snake snake = null;     // 蛇

    public static final int DEFAULT_WIDTH = 800;    // 界面宽
    public static final int DEFAULT_HEIGHT = 600;   // 界面高
    public static final int nodeWidth = 10;         // 结点宽
    public static final int nodeHeight = 10;        // 结点高

    JMenuItem start = new JMenuItem("开始");
    JMenuItem exit = new JMenuItem("退出");
    JMenuItem paused = new JMenuItem("暂停/开始");
    JMenuItem speedUp = new JMenuItem("加速");
    JMenuItem speedDown = new JMenuItem("减速");
    JMenuItem about = new JMenuItem("关于贪吃蛇");

    JMenuBar menuBar;
    JMenu file;
    JMenu function;
    JMenu help;

    // 初始化游戏界面
    public MyFrame()
    {   
        // 设置界面
        frame = new JFrame();
        frame.setTitle("贪吃蛇");
        frame.setLocation(200,200);

        container = frame.getContentPane();

        label = new JLabel("分数:", JLabel.CENTER);
        container.add(label, BorderLayout.SOUTH);

        canvas = new Canvas();
        canvas.setSize(DEFAULT_WIDTH-20, DEFAULT_HEIGHT-20);
        container.add(canvas, BorderLayout.CENTER);

        menuBar = new JMenuBar();
        frame.setJMenuBar(menuBar);

        file = new JMenu("文件");
        function = new JMenu("功能");
        help = new JMenu("帮助");

        file.add(start);
        start.addActionListener(this);
        file.add(exit);
        exit.addActionListener(this);

        function.add(paused);
        paused.addActionListener(this);
        function.add(speedUp);
        speedUp.addActionListener(this);
        function.add(speedDown);
        speedDown.addActionListener(this);

        help.add(about);
        about.addActionListener(this);

        menuBar.add(file);
        menuBar.add(function);
        menuBar.add(help);

        frame.addKeyListener(this);
        frame.pack();
        frame.setResizable(false);                              // 窗口大小不能变化
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   // 窗口关闭方式
        frame.setVisible(true);                                 // 显示
        begin();                    // 开始游戏
    }

    // 绘制游戏界面(包括蛇和食物)
    public void repaint(){
        Graphics g = canvas.getGraphics();
        // 背景
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT);
        // 蛇
        g.setColor(Color.BLACK);
        LinkedList<Node> snakeNode = snake.nodeArray;
        Iterator<Node> it = snakeNode.iterator();
        while (it.hasNext()) {
            Node n = (Node) it.next();
            drawNode(g, n);
        }
        // 食物
        g.setColor(Color.RED);
        Node n = snake.food;
        drawNode(g, n);
        updateScore();
    }
    // 绘画某一结点(蛇身或食物)
    private void drawNode(Graphics g, Node n) {
        g.fillRect(n.x * nodeWidth, n.y * nodeHeight, nodeWidth - 1, nodeHeight - 1);
    }
    // 更新分数
    public void updateScore() {
        String s = "分数:" + snake.score;
        label.setText(s);
    }
    // 游戏开始,放蛇
    void begin() {
        if (snake == null || !snake.running) {
            snake = new Snake(this, DEFAULT_WIDTH / nodeWidth, DEFAULT_HEIGHT / nodeHeight);
            (new Thread(snake)).start();
        }
    }
    // 菜单监听事件
    @Override
    public void actionPerformed(ActionEvent e){
        if(snake.running){
            if(e.getSource() == start){         // 开始
                snake.running = false;
                begin();
            }
            else if(e.getSource() == exit){     // 退出
                int select=JOptionPane.showConfirmDialog(null, "确认退出", "提示", 
                    JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
                if(select==JOptionPane.OK_OPTION){
                    System.exit(0);
                }
            }   
            else if(e.getSource() == paused){   // 暂停/继续
                snake.changePauseState();
            }
            else if(e.getSource() == speedUp){  // 加速
                snake.speedUp();
            }
            else if(e.getSource() == speedDown){// 减速
                snake.speedDown();
            }
            else if(e.getSource() == about){    // 关于贪吃蛇
                JOptionPane.showMessageDialog(null, "贪吃蛇\n"+"制作人:小曾      计本1501\n"
                                            +"    按上下左右键控制蛇的方向\n"
                                            +"    按‘+’或PageUp 加速 、按‘-’或PageDown加速\n"
                                            +"    按空格或p\t暂停/开始");
            }
        }
    }
    // 键盘监听
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        if (snake.running)
            switch (keyCode) {
            case KeyEvent.VK_UP:                    // 方向键:上
                snake.changeDirection(Snake.UP);
                break;
            case KeyEvent.VK_DOWN:                  // 方向键:下
                snake.changeDirection(Snake.DOWN);
                break;
            case KeyEvent.VK_LEFT:                  // 方向键:左
                snake.changeDirection(Snake.LEFT);
                break;
            case KeyEvent.VK_RIGHT:                 // 方向键:右
                snake.changeDirection(Snake.RIGHT);
                break;
            case KeyEvent.VK_ADD:                   // ‘+’键
            case KeyEvent.VK_PAGE_UP:               // PageUp键
                snake.speedUp();                    // 加速
                break;
            case KeyEvent.VK_SUBTRACT:              // ‘-’键
            case KeyEvent.VK_PAGE_DOWN:             // PageDown键
                snake.speedDown();                  // 减速
                break;
            case KeyEvent.VK_SPACE:                 // 空格键
            case KeyEvent.VK_P:                     // P键
                snake.changePauseState();           // 暂停或继续
                break;
            default:
            }
        // 重新开始(回车键、S键)
        if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_ENTER) {
            snake.running = false;
            begin();
        }
    }
}

package zeng;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.JOptionPane;

public class Snake implements Runnable{
Node food;
MyFrame myFrame;
LinkedList nodeArray = new LinkedList();

int maxX;
int maxY;
boolean[][] matrix;
int timeInterval = 200;
int score = 0;
boolean running = false;
boolean paused = false;
double speedChangeRate = 0.75;
int direction = 2;
public static final int UP = 2;
public static final int DOWN = 4;
public static final int LEFT = 1;
public static final int RIGHT = 3;

// 初始化界面
public Snake(MyFrame myFrame, int maxX, int maxY){
    this.myFrame = myFrame;
    this.maxX = maxX;
    this.maxY = maxY;
    matrix = new boolean[maxX][];
    for (int i = 0; i < maxX; ++i) {
        matrix[i] = new boolean[maxY];
        Arrays.fill(matrix[i], false);
    }
    int initArrayLength = maxX > 20 ? 10 : maxX / 2;
    for (int i = 0; i < initArrayLength; ++i) {
        int x = maxX / 2 + i;
        int y = maxY / 2;
        nodeArray.addLast(new Node(x, y));
        matrix[x][y] = true;
    }
    food = createFood();
    matrix[food.x][food.y] = true;
}
// 改变方向
public void changeDirection(int newDirection) {

    if (direction % 2 != newDirection % 2) {
        direction = newDirection;
    }
}
// 生成食物和放置位置
private Node createFood() {
    int x = 0;
    int y = 0;
    do {
        Random r = new Random();
        x = r.nextInt(maxX);
        y = r.nextInt(maxY);
    } while (matrix[x][y]);
    return new Node(x, y);
}
// 蛇移动
public boolean moveOn() {
    Node n = (Node) nodeArray.getFirst();
    int x = n.x;
    int y = n.y;
    switch (direction) {
        case UP:
            y--;
            break;
        case DOWN:
            y++;
            break;
        case LEFT:
            x--;
            break;
        case RIGHT:
            x++;
            break;
    }
    if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {
        if (matrix[x][y]) {                     // 吃到食物或者撞到身体
            if (x == food.x && y == food.y) {   // 吃到食物
                nodeArray.addFirst(food);       // 在头部加上一结点
                score += 10;
                food = createFood();
                matrix[food.x][food.y] = true;
                return true;
            } else
                return false;                   // 撞到身体
        } else {                                // 什么都没有碰到
            nodeArray.addFirst(new Node(x, y)); // 加上头部
            matrix[x][y] = true;
            n = (Node) nodeArray.removeLast();  // 去掉尾部
            matrix[n.x][n.y] = false;
            return true;
        }
    }
    return false;                               // 越界(撞到墙壁)
}
// 蛇运动线程
public void run() {
    running = true;
    while (running) {
        try {
            Thread.sleep(timeInterval);
        } catch (Exception e) {
            break;
        }
        if (!paused) {
            if (moveOn()) {         // 未结束
                myFrame.repaint();
            } else {                // 游戏结束
                JOptionPane.showMessageDialog(null, "GAME OVER", "Game Over", JOptionPane.INFORMATION_MESSAGE);
                break;
            }
        }
    }
    running = false;
}
// 加速
public void speedUp() {
    timeInterval *= speedChangeRate;
}
// 减速
public void speedDown() {
    timeInterval /= speedChangeRate;
}
// 暂停/继续
public void changePauseState() {
    paused = !paused;
}

}

 package zeng;

 public class Node {
    int x;
    int y;

    public Node(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

package zeng;

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


  • 写回答

1条回答

  • 黑码哥 2016-12-12 14:22
    关注

    最近正在学习java哦 哈哈。。

    评论

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 来真人,不要ai!matlab有关常微分方程的问题求解决,
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算