实验二 贪吃蛇的开发制作

软件实习项目二 —— Java实现贪吃蛇小游戏的开发制作

一、实验任务

(1)该题要求实现贪吃蛇的基本功能。

(2)屏幕上随机出现一个“食物”,称之为豆子。⬆️⬇️⬅️➡️控制“蛇”的移动。吃到“豆子”以后的“蛇”的身体加长一点,得分增加,“蛇”碰到边界,或蛇头与蛇身相撞,蛇死亡,游戏状态转为结束。

(3)为游戏设计初识欢迎界面,游戏界面,游戏结束界面。

二、实验准备

(1)具体编程语言:Java

(2)确定锁定图形界面:Java Swing

三、设计思路

(1)游戏需要开始界面,游戏进行中的界面,犯规失败导致游戏重新开始的界面。主要的角色蛇、食物的设计,背景面板、边框的设计

(2)编写方法,通过键盘上的上下左右键控制蛇身运动,蛇身是否与墙体或自身碰撞,是则犯规失败。食物的随机生成与判断是否被吃掉,蛇身的加长,得分的增加,蛇身随着蛇头一起运动

(3)增加线程对时间进行控制,增加计时功能

四、功能实现

(1)游戏界面的设计,背景面板的构造,蛇的构造,食物的构造

class SnakeDemo extends JComponent{
   
    /**
     *
     */
    private static final long serialVersionUID = 3794762291171148906L;
    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 = "D";//默认向下走
    private String current_direction = "D";//当前方向
    private boolean first_launch = false;//设置初始状态下的豆豆没有吃到
    private boolean iseaten = false;//设置初始状态为没吃到
    private boolean isrun = false;//设置初始状态为停止运动
    private int randomx,randomy;//设置一个随即坐标生成豆豆
    private int body_length = 5;//身体长度初始化为5
    private int food = 0;
    private Thread run;
    private JLabel label1 = new JLabel("得分:");
    private JLabel label2 = new JLabel("用时:");
    private JLabel label3 = new JLabel("规则:");
    private JTextArea explain = new JTextArea("按下空格键以开始或暂停游戏,按下ESC键以重新开始游戏。" +
            "通过键盘上的 上️、下️、左️、右️ 键来控制蛇身的运动走向,使蛇吃豆豆来增加分数️。" +
            "注意不要让蛇吃到自己身体的部分或撞到墙壁,否则游戏结束,得分归零");
    private JLabel Score = new JLabel("0");
    private JLabel Time = new JLabel("");
    private Font f1 = new Font("Miriam Fixed",Font.PLAIN,18);
    private Font f2 = new Font("Miriam Fixed",Font.PLAIN,13);
    private JPanel p = new JPanel();
    private int hour = 0;
    private int min = 0;
    private int sec = 0;
    private boolean pause = true;//设置初始状态暂停

    public SnakeDemo(){
   
        String lookAndFeel =UIManager.getSystemLookAndFeelClassName();
        try {
   
            UIManager.setLookAndFeel(lookAndFeel);
        } catch (ClassNotFoundException e1) {
   
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        } catch (InstantiationException e1) {
   
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
   
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        } catch (UnsupportedLookAndFeelException e1) {
   
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        }

        //布局
        add(label1);
        label1.setBounds(500, 10, 80, 20);
        label1.setFont(f1);

        add(Score);
        Score.setBounds(500, 35, 80, 20);
        Score.setFont(f1);

        add(label2);
        label2.setBounds(500, 60, 80, 20);
        label2.setFont(f1);

        add(Time);
        Time.setBounds(500, 85, 80, 20);
        Time.setFont(f1);

        add(p);
        p.setBounds(498, 110, 93, 1);
        p.setBorder(BorderFactory.createLineBorder(Color.lightGray));

        add(label3);
        label3.setBounds(500, 115, 80, 20);
        label3.setFont(f1);

        add(explain);
        explain.setBounds(498, 138, 100, 350);
        explain.setFont(f2);
        explain.setLineWrap(true);
        explain.setOpaque(false); 

        //画头部
        g.setColor(Color.ORANGE);
        g.fillRoundRect(head.x, head.y, 20, 20, 10, 10);

        g.setPaint(new GradientPaint(115,135,Color.YELLOW,230,135,Color.GREEN,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, 20, 20);
            }
            //初始化豆豆的位置
            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, 20, 20);
            }
        
        //画墙
        g.setStroke( new BasicStroke(4,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
        g.setBackground(Color.white);
        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.LIGHT_GRAY);
            g.drawLine(5+i*22,9,5+i*22,472);
            if(i <= 20)
            {
   
                g.drawLine(4,10+i*22,491,10+i*22);
            }
        }

(2)游戏的过程,需要玩家用户通过⬆️⬇️⬅️➡️键来控制蛇身的运动方向,来吃掉随机生成的食物。如果蛇身碰撞的墙体或咬到自身身体部分,则判断为失败,游戏结束。再设置其他功能操作的按钮,如以按下空格来开始暂停游戏,按下ESC键来重新开始游戏。

addKeyListener(new KeyAdapter() {
   
            public void keyPressed(KeyEvent e) {
   
                super.keyPressed(e);
                if(e.getKeyCode() == KeyEvent.VK_RIGHT)
                {
   
                    if(isrun && current_direction != "L")
                    {
   
                        direction = "R";
                    }
                }
                if(e.getKeyCode() == KeyEvent.VK_LEFT)
                {
   
                    if(isrun && current_direction != "R")
                    {
   
                        direction = "L";
                    }
                }
                if(e.getKeyCode() == KeyEvent.VK_UP)
                {
   
                    if(isrun && current_direction != "D")
                    {
   
                        direction = "U";
                    }
                }
                if(e.getKeyCode() == KeyEvent.VK_DOWN)
                {
   
                    if(isrun && current_direction != "U")
                    {
   
                        direction = "D";
                    }
                }
                if(e.getKeyCode() == KeyEvent.VK_ESCAPE)
                {
   
                    direction = "D";//默认向下走
                    current_direction = "D";//当前方向
                    first_launch = false;
                    iseaten = false;
                    isrun = true;
                    body_length = 5;
                    head = new Tile(227,100);
                    Score.setText("0");
                    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");
                }
                if(e.getKeyCode() == KeyEvent.VK_SPACE)//按空格键开始和暂停
                {
   
                    if(!pause)//暂停
                    {
   
                        pause = true;
                        isrun = false;
                    }
                    else//开始
                    {
   
                        pause = false;
                        isrun = true;
                    }
                }
            }
        });
    
            //每次刷新身体
            for(int i = 0;i < body_length;i++)
            {
   
                g.fillRoundRect(body[i].x, body[i].y, 20, 20, 20, 20);
            }

            if(EATEN())//豆豆被吃后重新随机生成豆豆
            {
   
                ProduceRandom();
                g.fillOval(rando
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值