贪吃蛇

  • 窗口
public class StartGame {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("贪吃蛇");
        jFrame.setBounds(10, 10, 900, 720);
        jFrame.add(new GamePanel());
        jFrame.setResizable(false);
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}
  • 面板
public class GamePanel extends JPanel {
    private int length; //蛇的长度
    private int[] snakeX; //蛇的X坐标 34 * 24
    private int[] snakeY; //蛇的X坐标 34 * 24
    private String direction; //默认向右移动
    private boolean isStart = false; //游戏当前状态(是否开始, 默认为false)
    private boolean isFail = false; //游戏当前状态(是否失败, 默认为false)
    //随机生成食物
    private Random random;
    private int footX; //食物X坐标
    private int footY; //食物Y坐标

    public GamePanel() {
        startOff();
        //获得焦点和键盘事件
        this.setFocusable(true);
    }

    //初始化数据
    public void init() {
        //设置背景
        this.setBackground(Color.WHITE);

        this.length = 3; //初始为3

        direction = "R"; //默认向右移动

        snakeX = new int[816]; //蛇的X坐标 34 * 24
        snakeY = new int[816]; //蛇的Y坐标 34 * 24
        //初始蛇身体坐标
        this.snakeX[0] = 100;
        this.snakeY[0] = 100; //蛇头
        this.snakeX[1] = 75;
        this.snakeY[1] = 100; //第一节身体
        this.snakeX[2] = 50;
        this.snakeY[2] = 100; //第二节身体

        //食物坐标
        random = new Random();
        this.footX = 25 + 25 * random.nextInt(34);
        this.footY = 75 + 25 * random.nextInt(24);
    }

    //
    public void startOff() {
        init();
        //键盘监听
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                //按下空格
                if (keyCode == KeyEvent.VK_SPACE) {
                    if (isFail) {
                        //重新开始
                        isFail = false;
                        init();
                    } else {
                        isStart = !isStart; // 暂停/开始
                    }
                }
                //按下上键
                if (keyCode == KeyEvent.VK_UP && !direction.equals("D")) {
                    direction = "U"; // 上
                }
                //按下下键
                if (keyCode == KeyEvent.VK_DOWN && !direction.equals("U")) {
                    direction = "D"; // 下
                }
                //按下左键
                if (keyCode == KeyEvent.VK_LEFT && !direction.equals("R")) {
                    direction = "L"; // 左
                }
                //按下右键
                if (keyCode == KeyEvent.VK_RIGHT && !direction.equals("L")) {
                    direction = "R"; // 右
                }
                repaint(); //重新绘制该组件
            }
        });

        //定时器(事件监听)
        new Timer(100, (e) -> {
            //如果开始. 就移动
            if (isStart && !isFail) {
                //身体移动
                for (int i = length - 1; i > 0; i--) {
                    snakeX[i] = snakeX[i - 1];
                    snakeY[i] = snakeY[i - 1];
                }
                //蛇头上移动
                if ("U".equals(direction)) {
                    //触碰上边界
                    /*if (snakeY[0] <= 75) {
                        snakeY[0] = 675;
                    }*/
                    snakeY[0] = snakeY[0] - 25;
                }
                //蛇头下移动
                if ("D".equals(direction)) {
                    //触碰下边界
                    /*if (snakeY[0] >= 650) {
                        snakeY[0] = 50;
                    }*/
                    snakeY[0] = snakeY[0] + 25;
                }
                //蛇头左移动
                if ("L".equals(direction)) {
                    //触碰左边界
                    /*if (snakeX[0] <= 25) {
                        snakeX[0] = 850;
                    }*/
                    snakeX[0] = snakeX[0] - 25;
                }
                //蛇头右移动
                if ("R".equals(direction)) {
                    //触碰右边界
                    /*if (snakeX[0] >= 850) {
                        snakeX[0] = 0;
                    }*/
                    snakeX[0] = snakeX[0] + 25;
                }
                //失败判断,撞到边界
                if (snakeX[0] <= 0 || snakeX[0] >= 875 || snakeY[0] <= 50 || snakeY[0] >= 675) {
                    snakeX[0] = -25;
                    snakeY[0] = -25;
                    isFail = true;
                }
                //吃食物
                if (snakeX[0] == footX && snakeY[0] == footY) {
                    //长度加1
                    length++;
                    //重新生成食物
                    footX = 25 + 25 * random.nextInt(34);
                    footY = 75 + 25 * random.nextInt(24);
                }
                //失败判断(撞到自己)
                for (int i = 1; i < length; i++) {
                    if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                        isFail = true;
                        break;
                    }
                }
            }
            repaint(); //重新绘制该组件
        }).start(); //开启定时器
    }

    //绘制面板
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); //清屏

        //绘制静态面板
        g.setColor(Color.BLACK);
        g.fillRect(25, 11, 850, 53); //头部
        g.fillRect(25, 75, 850, 600); //游戏界面

        //绘制小蛇
        g.setColor(Color.GRAY);
        g.fillRect(snakeX[0], snakeY[0], 25, 25);
        g.setColor(Color.WHITE);
        //g.fillRect(snakeX[1], snakeY[1], 25, 25);
        //g.fillRect(snakeX[2], snakeY[2], 25, 25);
        for (int i = 1; i < length; i++) {
            g.fillRect(snakeX[i], snakeY[i], 25, 25);
        }

        //头部文字
        g.setFont(new Font("华文彩云", Font.BOLD, 40)); //设置字体
        g.drawString("贪 吃 蛇", 400, 50);
        //积分
        g.setFont(new Font("微软雅黑", Font.BOLD, 18)); //设置字体
        g.drawString("长度 " + length, 35, 35);
        g.drawString("分数 " + (length - 3) * 10, 35, 55);

        //游戏状态
        if (!isStart && !isFail) {
            g.setFont(new Font("微软雅黑", Font.BOLD, 40)); //设置字体
            g.drawString("按下空格开始游戏!", 300, 300);
        }
        if (isFail) {
            g.setColor(Color.RED);
            g.setFont(new Font("微软雅黑", Font.BOLD, 40)); //设置字体
            g.drawString("游戏失败,按空格键重新开始", 200, 300);
        }

        //绘制食物
        g.setColor(Color.GRAY);
        g.fillOval(footX, footY, 25, 25);
    }
}
posted @ 2021-03-11 00:46  Zzzy君不见  阅读(16)  评论(0编辑  收藏  举报