简易贪吃蛇的实现

实验要求

实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子,上下左右控制“蛇”的移动,吃到“豆子”以后“蛇”的身体加长一点,得分增加,“蛇”碰到边界或,蛇头与蛇身相撞,蛇死亡,游戏结束。为游戏设计初始欢迎界面,游戏界面,游戏结束界面。

实验分析

贪吃蛇实验图形界面由蛇头,蛇身,食物等组成。
蛇头部分通过键盘方向键进行上下左右的移动。豆子随机生成,操纵蛇头吃到随机的豆子,蛇身长度变长,得分增加。据此,可分析出具体需要实现的功能:
1.构建合适的网格,并且设置好墙。
2.在适当的位置产生豆子,即网格内部,且不是蛇身的地方。
3.通过键盘控制实现蛇头的移动
4.实现蛇身的刷新。当蛇在去吃食物的移动过程中,蛇头按照方向去往邻近的一个网格,蛇身的每一个结点取代上一个结点的位置,蛇尾处的结点消失。蛇吃到豆子的那一次移动,豆子即为蛇头的位置,其余不再取代上一个结点的位置。
5.判断是否撞墙与撞到自身,即蛇头的位置是否与墙及自己身体的坐标重合。
6.进行计分与计时。

实验进行

构建网格与其他说明界面

private JLabel label2 = new JLabel("所花时间:");
    private JLabel label3 = new JLabel("得分");                            //   标签
    private JLabel label4 = new JLabel("说 明:");
    private JTextArea explain = new JTextArea("游戏界面按上下左右键实现移动,按ESC重新开始,按空格键可以实现暂停和开始");
    private JLabel score = new JLabel("");
    private JLabel Time = new JLabel("");
    private Font f = new Font("微软雅黑",Font.PLAIN,15);
    private Font f2 = new Font("微软雅黑",Font.PLAIN,13);
    private JPanel p = new JPanel();                                         //面板
    private int hour =0;                    // 定义时间,小时,分钟,秒
    private int min =0;
    private int sec =0 ;
    private int sco=0;
    private boolean pause = false;
    add(label3);
        label3.setBounds(500, 10, 80, 20);
        label3.setFont(f);
        add(score);
        score.setBounds(500, 35, 80, 20);
        score.setFont(f);
        add(label2);
        label2.setBounds(500, 60, 80, 20);
        label2.setFont(f);                                                 // 标签
        add(Time);
        Time.setBounds(500, 85, 80, 20);
        Time.setFont(f);
        add(p);
        p.setBounds(498, 110, 93, 1);
        p.setBorder(BorderFactory.createLineBorder(Color.black));

        add(label4);
        label4.setBounds(500, 115, 80, 20);
        label4.setFont(f);
        add(explain);
        explain.setBounds(498, 138, 90, 350);
        explain.setFont(f2);
        explain.setLineWrap(true);
        explain.setOpaque(false);
                //墙
        g.setStroke( new BasicStroke(4,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
        g.setBackground(Color.black);
        g.drawRect(2, 7, 491, 469);                                      //  第一个块的颜色,位置

        //网格线
        for(int i = 1;i < 22;i++)
        {
     
            g.setStroke( new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
            g.setColor(Color.black);
            g.drawLine(5+i*22,9,5+i*22,472);
            if(i <= 20)
            {
     
                g.drawLine(4,10+i*22,491,10+i*22);
            }
        }

进行蛇整体的布局及移动还有食物的生成

public class Snake extends JComponent {
                     //建一个贪吃蛇的类对其进行编辑
    private static final long serialVersionUID = 3794762291171148906L;                 // 定义了一个私有的静态的不可改变的long类型的   名字是VersionUID,
    private final int MAX_SIZE = 400;//蛇身体最长为400节
    private Tile temp = new Tile(0,0);
    private Tile temp2 = new Tile(0,0);
    private Tile head = new Tile(227,100);//头部的位置初始化为(227,100)
    private Tile[] body = new Tile[MAX_SIZE];
    private String direction = "R";//默认向右走
    private String current_direction = "R";//当前方向
    private boolean first_launch = false;
    private boolean iseaten = false;
    private boolean isrun = true;
    private int randomx,randomy;
    private int body_length = 5;//身体长度初始化为5
    private Thread run;

    public void paintComponent(Graphics g1){
        // 指调用父类的绘制事件,在重写父类函数时经常会调用一下相应的父类方法
        super.paintComponent(g1);                           // super关键字用来调用父类中定义的构造器,控制对象的父类的部分结构
        Graphics2D g = (Graphics2D) g1;                       //  画(Graphics g)
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,RenderingHints.VALUE_STROKE_NORMALIZE);

        //画头部
        g.setColor(Color.red);               // 设置颜色
        g.fillRoundRect(head.x, head.y, 20, 20, 10, 10);

        g.setPaint(new GradientPaint(115,135,Color.CYAN,230,135,Color.MAGENTA,true));

        if(!first_launch)                                                                     //定义蛇初始化身体的颜色
        {
     
            //初始化身体
            int x = head.x;
            for(int i = 0;i < body_length;i++)
            {
     
                x -= 22;//相邻两个方块的间距为2个像素,方块宽度都为20像素
                body[i].x = x;
                body[i].y = head.y;
                g.fillRoundRect(body[i].x, body[i].y, 20, 20, 10, 10);
            }
            //初始化食物位置
            ProduceRandom();
            g.fillOval(randomx, randomy, 19, 19);
        }
        else
        {
     
            //每次刷新身体
            for(int i = 0;i < body_length;i++)
            {
     
                g.fillRoundRect(body[i].x, body[i].y, 20, 20, 10, 10);
            }

            if(EatFood())//被吃了重新产生食物,并且计入得分
            {
     
                ProduceRandom();
                g.fillOval(randomx, randomy, 19, 19);
                iseaten = false;
                sco++;
                showScore();
            }
            else
            {
     
                g.fillOval(randomx, randomy, 19, 19);
            }
        }

对是否撞墙以及是否撞到自己进行判断以及处理

public void HitWall(){
     //判断是否撞墙
        if(current_direction == "L")
        {
     
            if(head.x < 7)
            {
     
                int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
                if(result==JOptionPane.YES_NO_OPTION)
                {
     
                    direction = "R";//默认向右走
                    current_direction = "R";//当前方向
                    first_launch = false;
                    iseaten = false;
                    isrun = true;
                    body_length = 5;
                    head = new Tile(227,100);
                    hour =0;
                    min =0;
                    sec =0 ;
                    for(int i = 0; i < MAX_SIZE;i++)
                    {
     
                        body[i].x = 0;
                        body[i].y = 0;
                    }

                    run = new Thread();
                    run.start();
                    System.out.println("Start again");
                }
                else
                {
     
                    run.stop();
                }
            }
        }
        if(current_direction == "R")
        {
     
            if(head.x > 489)
            {
     
                int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
                if(result==JOptionPane.YES_NO_OPTION)
                {
     
                    direction = "R";//默认向右走
                    current_direction = "R";//当前方向
                    first_launch = false;
                    iseaten = false;
                    isrun = true;
                    body_length = 5;
                    head = new Tile(227,100);
                    hour =0;
                    min =0;
                    sec =0 ;
                    for(int i = 0; i < MAX_SIZE;i++)
                    {
     
                        body[i].x = 0;
                        body[i].y = 0;
                    }

                    run = new Thread();
                    run.start();
                    System.out.println("Start again");
                }
                else
                {
     
                    run.stop();
                }
            }
        }
        if(current_direction == "U")
        {
     
            if(head.y < 12)
            {
     
                int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
                if(result==JOptionPane.YES_NO_OPTION)
                {
     
                    direction = "R";//默认向右走
                    current_direction = "R";//当前方向
                    first_launch = false;
                    iseaten = false;
                    isrun = true;
                    body_length = 5;
                    head = new Tile(227,100);
                    hour =0;
                    min =0;
                    sec =0 ;
                    for(int i = 0; i < MAX_SIZE;i++)
                    {
     
                        body[i].x = 0;
                        body[i].y = 0;
                    }

                    run = new Thread();
                    run.start();
                    System.out.println("Start again");
                }
                else
                {
     
                    run.stop();
                }
            }
        }
        if(current_direction == "D")
        {
     
            if(head.y > 472)
            {
     
                int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
                if(result==JOptionPane.YES_NO_OPTION)
                {
     
                    direction = "R";//默认向右走
                    current_direction = "R";//当前方向
                    first_launch = false;
                    iseaten = false;
                    isrun = true;
                    body_length = 5;
                    head = new Tile(227,100);
                            hour =0;
                    min =0;
                    sec =0 ;
                    for(int i = 0; i < MAX_SIZE;i++)
                    {
     
                        body[i].x = 0;
                        body[i].y = 0;
                    }

                    run = new Thread();
                    run.start();
                    System.out.println("Start again");
                }
                else
                {
     
                    run.stop();
                }
            }
        }
    }

    public void HitSelf(){
     //判断是否撞到自己身上
        for(int i = 0;i < body_length; i++)
        {
     
            if(body[i].x == head.x && body[i].y == head.y)
            {
     
                int result=JOptionPane.showConfirmDialog(null, "Game over! Try again?", "Information", JOptionPane.YES_NO_OPTION);
                if(result==JOptionPane.YES_NO_OPTION)
                {
     
                    direction = "R";//默认向右走
                    current_direction = "R";//当前方向
                    first_launch = false;
                    iseaten = false;
                    isrun = true;
                    body_length = 5;
                    head = new Tile(227,100);
                    hour =0;
                    min =0;
                    sec =0 ;
                    for(int j = 0; j < MAX_SIZE;j++)
                    {
     
                        body[j].x = 0;
                        body[j].y = 0;
                    }

                    run = new Thread();
                    run.start();
                    System.out.println("Start again");

                }
                else
                {
     
                    run.stop();
                }
                break;
            }
        }
    }

运行结果
简易贪吃蛇的实现_第1张图片

你可能感兴趣的:(实验日志,java)