java贪食蛇游戏

废话不多说,直接上代码,也比较简单。

1. 游戏桌面实体类

/**
 * @author lk-tony
 * @Title: 桌面实体类
 * @Description:
 * @date 2023/2/13 10:20
 */
public class Desk {
    private Integer dWidth;
    private Integer dHeight;
    /**
     * 坐标系
     */
    private Integer[][] field;

    public Desk(Integer dWidth, Integer dHeight) {
        this.dWidth = dWidth;
        this.dHeight = dHeight;
        field = new Integer[dWidth][dHeight];
    }

    public Integer getdWidth() {
        return dWidth;
    }

    public void setdWidth(Integer dWidth) {
        this.dWidth = dWidth;
    }

    public Integer getdHeight() {
        return dHeight;
    }

    public void setdHeight(Integer dHeight) {
        this.dHeight = dHeight;
    }

    public Integer[][] getField() {
        return field;
    }

    public void setField(Integer[][] field) {
        this.field = field;
    }
}

2. 坐标点类

/**
 * @author lk-tony
 * @Title: 点实体类
 * @Description:
 * @date 2023/2/13 10:20
 */
public class Point {

    private Integer x;
    private Integer y;

    public Point(Integer x, Integer y) {
        this.x = x;
        this.y = y;
    }

    public Integer getX() {
        return x;
    }

    public void setX(Integer x) {
        this.x = x;
    }

    public Integer getY() {
        return y;
    }

    public void setY(Integer y) {
        this.y = y;
    }
}

3.贪食蛇实体类

/**
 * @author lk-tony
 * @Title: 贪食蛇实体类
 * @Description:
 * @date 2023/2/13 10:20
 */
public class Snake {

    private final Random random = new Random();

    private List<Point> body = new LinkedList<>();

    /**
     * 0 左  1 上  2 右  3 下
     */
    private Integer dir;

    public Integer getDir() {
        return dir;
    }

    public void setDir(Integer dir) {
        this.dir = dir;
    }

    public List<Point> getBody() {
        return body;
    }

    public void setBody(List<Point> body) {
        this.body = body;
    }

    public void init(Integer x, Integer y) {
        // 初始化蛇
        for (int i = 0; i < 4; i++) {
            body.add(new Point(x + i, y));
        }
    }

    /**
     * 检查是否死亡
     *
     * @return
     */
    public Boolean checkDeath(Desk desk) {
        // 判断蛇头与蛇身的点是否有重合,重合则死亡,蛇头是否超过边界,过界则死亡
        Point head = body.get(0);
        for (int i = 1; i < body.size(); i++) {
            if (head.getX().equals(body.get(i).getX()) && head.getY().equals(body.get(i).getY())) {
                return true;
            }
        }
        if (head.getX() < 0) {
            return true;
        }
        if (head.getY() < 0) {
            return true;
        }
        if (head.getX() > desk.getdWidth()) {
            return true;
        }
        if (head.getY() > desk.getdHeight()) {
            return false;
        }
        return false;
    }

    /**
     * 移动一步
     */
    public boolean moveOneStep(Point food) {
        boolean isEatFood = false;
        Point endPoint = new Point(0,0);
        endPoint.setX(body.get(body.size() - 1).getX());
        endPoint.setY(body.get(body.size() - 1).getY());
        Point head = body.get(0);
        // 蛇所有的点换成它上一个节点
        for (int i = body.size() - 1; i > 0; i--) {
            body.get(i).setX(body.get(i - 1).getX());
            body.get(i).setY(body.get(i - 1).getY());
        }
        // 蛇头的最新位置
        switch (dir) {
            case 0:
                // 左
                head.setX(head.getX() - 1);
                break;
            case 1:
                // 上
                head.setY(head.getY() - 1);
                break;
            case 2:
                // 右
                head.setX(head.getX() + 1);
                break;
            case 3:
                //  下
                head.setY(head.getY() + 1);
                break;
            default:
        }
        // 如果蛇头当前位置是食物,则在蛇尾后增加一个点
        if (head.getX().equals(food.getX()) && head.getY().equals(food.getY())) {
            System.out.println("x=" + head.getX() + "y=" + head.getY());
            body.add(endPoint);
            isEatFood = true;
        }
        return isEatFood;
    }

    /**
     * 生成食物
     */
    public Point produceFood(Desk desk) {
        // 随机获取桌面内的点,要求点与蛇身不重复
        Point food = null;
        boolean flag = true;
        while (flag) {
            Integer randomX = random.nextInt(desk.getdWidth());
            Integer randomY = random.nextInt(desk.getdHeight());
            // 判断随机点是否在蛇身,在则继续随机
            boolean isOk = true;
            for (Point point : body) {
                if (point.getX().equals(randomX) && point.getY().equals(randomY)) {
                    isOk = false;
                    break;
                }
            }
            if (isOk) {
                flag = false;
                food = new Point(randomX, randomY);
            }
        }
        return food;
    }

    /**
     * 刷新蛇身与食物坐标
     */
    public void refresh(Desk desk, Point food) {
        Integer[][] field = new Integer[desk.getdWidth()][desk.getdHeight()];
        // 画上蛇身
        for (Point point : body) {
            field[point.getX()][point.getY()] = 1;
        }
        // 画上食物
        field[food.getX()][food.getY()] = 1;
        desk.setField(field);
    }
}

4.游戏启动类

/**
 * @author lk-tony
 * @Title: 游戏实体类
 * @Description:
 * @date 2023/2/13 10:20
 */
public class SnakeGame extends JComponent {

    private static Integer unit = 10;

    private static Desk desk = new Desk(50, 50);

    private static Snake snake = new Snake();

    private static Point food = null;

    private static Integer score = 0;

    private static String menInfo = "";

    public SnakeGame() {
        setBackground(Color.WHITE);
        // 先往上走
        snake.setDir(1);
        snake.init(25, 25);
        // 每0.5秒刷新界面
        new Timer(100, (event) -> {
            // 判断是否死亡
            if (snake.checkDeath(desk)) {
                System.out.println("is dead");
                return;
            }
            // 生成食物
            if (null == food) {
                food = snake.produceFood(desk);
            }
            // 移动一步
            boolean isEatFood = snake.moveOneStep(food);
            if (isEatFood) {
                food = snake.produceFood(desk);
                score++;
            }
            // 刷新界面
            snake.refresh(desk, food);
            // 显示分数
            menInfo = String.format(" 分数  %d", score);
            repaint();
        }).start();

    }
    
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLACK);
        Polygon p = new Polygon();
        p.addPoint(0, 0);
        p.addPoint(0, desk.getdHeight() * unit);
        p.addPoint(desk.getdWidth() * unit, desk.getdHeight() * unit);
        p.addPoint(desk.getdWidth() * unit, 0);
        g.drawPolygon(p);
        g2d.setColor(Color.BLUE);
        for (int x = 0; x < desk.getField().length; x++) {
            for (int y = 0; y < desk.getField()[x].length; y++) {
                if (null != desk.getField()[x][y] && desk.getField()[x][y] == 1) {
                    int xPoint = x * unit;
                    int yPont = y * unit;
                    g2d.fillRect(xPoint, yPont, unit, unit);
                    //System.out.println("x=" + xPoint +" , y=" + xPoint);
                }
            }
        }

        g2d.setColor(Color.RED);
        g2d.drawString(menInfo, desk.getdWidth() * unit + 10, 10);
    }


    /**
     * 创建界面
     */
    private static void createAndShowGUI() {
        final JFrame f = new JFrame("Snake");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(800, 800);
        f.add(new SnakeGame());
        f.setVisible(true);
        f.setLocationRelativeTo(f.getOwner());
        f.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                // 获取对应的键盘字符代码
                int keyCode = e.getKeyCode();
                // 0 左  1 上  2 右  3 下
                // 键盘按上
                if (keyCode == 38) {
                    snake.setDir(1);
                }
                // 键盘按下
                if (keyCode == 40) {
                    snake.setDir(3);
                }
                // 键盘按左
                if (keyCode == 37) {
                    snake.setDir(0);
                }
                // 键盘按右
                if (keyCode == 39) {
                    snake.setDir(2);
                }
            }
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception ex) {
            }
            createAndShowGUI();
        });
    }
}

  

  

  

posted @ 2023-03-29 10:06  诸神的毁灭者  阅读(29)  评论(0)    收藏  举报