java贪吃蛇/Java swing

java贪吃蛇小游戏:

        1.可自定义蛇头部和尾部,身体是随机颜色的球状;自定义食物图片,自定义背景

        2.显示当前分数(长度)

        3.可自定义蛇移动速度(四种速度)

        4.可进行游戏暂停

        5.菜单:游戏指南、速度设置(速度一、速度二、速度三、速度四)、开始游戏、暂停游戏、退出游戏。

游戏截图:

        

 

 欢迎体验!!!

上代码!!

目录结构:

 

ComeOn.java

package com.losen.greedysnake.domain;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * 2023/6/24 1131
 */


public class ComeOn extends JFrame implements ActionListener  {
    static  JFrame frame = new  JFrame( );
    public static void main(String[] args) {
        System.out.print("main");
        new  ComeOn();
    }
    public  ComeOn(){                                                 //设置启动界面
        System.out.print("构造函数star");
        frame.setUndecorated(true);                                //用于取消边框背景
        frame.setLayout (null);
        frame.setSize(1600,900);
        frame.setLocation(300, 100);
        frame.setLocationRelativeTo (null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        AddButton();
        AddPicture();
    }
    //定义进入游戏按钮
    public  void  AddButton() {
        RButton  enterButton =new RButton("进入游戏");
        enterButton.setFont(new Font("华文行楷", Font.BOLD, 35));
        enterButton.setForeground(Color.red);
        enterButton.setBounds (700,  600 , 200, 100);
        enterButton.setBackground(Color.white);
        frame.add(enterButton);
        enterButton.addActionListener(this);
        //定义按键
    }
    //加入背景图片
    public  void  AddPicture() {
        ImageIcon img = new ImageIcon("src\\image\\startbackground.png");
        JLabel Label= new JLabel(img);
        Label.setBounds(90,23,img.getIconWidth(),img.getIconHeight());            //设置大小
        frame.getLayeredPane().add(Label,new Integer(Integer.MIN_VALUE));      //设置图片底层和按钮在容器中的顺序
        JPanel  jp  =(JPanel)frame.getContentPane();
        jp.setOpaque(false);                                                   //设置透明与否
    }

    /*设置按钮的监听器事件
     * 进入按钮的监听器事件的主要功能是当点击按钮以后,程序关掉启动界面,并转入运行界面。
     * 主要实现原理是定义一个新界面的类,作为运行界面,然后定义一个关掉启动界面的方法,然后在监听器事件中,
     * 调用关掉界面的方法,实例化运行界面
     */
    @Override

    public void actionPerformed(ActionEvent e) {
        new  pushButtonMusic ();
        // TODO 自动生成的方法存根
        closeThis();		                                                       //关掉新界面的方法
        try {
            new Frame2 ();                                                         //实例化运行界面
        } catch (InterruptedException e1) {
            // TODO 自动生成的 catch 块
            e1.printStackTrace();
        }  //创建新的窗体,以达到切换窗体的效果
    }
    private void closeThis() {
        // TODO 自动生成的方法存根
        frame.dispose();
    }
    /*
     * 游戏运行界面,实例化SnakeGame类,并加入到运行界面中
     */
    class  Frame2 extends JFrame      {
        JFrame    frame1 = new  JFrame(); //游戏图形界面
        public   Frame2() throws InterruptedException{
            frame1.setUndecorated(true);
            frame1.setBounds(200,70,1600,900);
            //  frame1.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame1.setVisible(true);
            SnakeGame sn = new SnakeGame();
            frame1.add(sn);
            sn.requestFocus();//布局的中间
        }
    }
}

RButton.java

package com.losen.greedysnake.domain;

/*在Java  swing中的button无法设置圆角按钮,为了一定程度上完善游戏界面,故而设置了圆角按钮。
 * 定义圆角按钮;
 */
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;

import javax.swing.JButton;


/**
 * @author losen
 * @version 1.0
 * @DateTime 2023/6/24 11:32
 */
public class RButton extends JButton {
    private static final long serialVersionUID = 39082560987930759L;
    public static final Color BUTTON_COLOR1 = new Color(205, 255, 205);     //设置按钮的第一种颜色
    public static final Color BUTTON_COLOR2 = new Color(51, 55, 47);        //设置按钮的第二种颜色
    // public static final Color BUTTON_COLOR1 = new Color(125, 161, 237);
    // public static final Color BUTTON_COLOR2 = new Color(91, 118, 173);
    public static final Color BUTTON_FOREGROUND_COLOR = Color.WHITE;
    private boolean hover;

    public RButton(String name) {
        this.setText(name);   //添加名字
        setFont(new Font("system", Font.PLAIN, 12)); //设置字体
        setBorderPainted(false);               //设置边界可见否
        setForeground(BUTTON_COLOR2);           //设置前景色
        setFocusPainted(false);
        setContentAreaFilled(false);
        //定义鼠标事件,即当鼠标进入到按钮界面时,按钮颜色会发生变化,鼠标离开按钮区域时也会发生变化
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                setForeground(BUTTON_FOREGROUND_COLOR);
                hover = true;
                repaint();
            }

            @Override
            public void mouseExited(MouseEvent e) {
                setForeground(BUTTON_COLOR2);
                hover = false;
                repaint();
            }
        });
    }
    //设置按钮圆角
    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        int h = getHeight();
        int w = getWidth();
        float tran = 1F;
        if (!hover) {
            tran = 0.3F;
        }

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        GradientPaint p1;
        GradientPaint p2;
        //当点击按钮之后,按钮颜色和字体会发生变化
        if (getModel().isPressed()) {
            p1 = new GradientPaint(0, 0, new Color(0, 0, 0), 0, h - 1,
                    new Color(100, 100, 100));
            p2 = new GradientPaint(0, 1, new Color(0, 0, 0, 50), 0, h - 3,
                    new Color(255, 255, 255, 100));
        } else {
            p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h - 1,
                    new Color(0, 0, 0));
            p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0,
                    h - 3, new Color(0, 0, 0, 50));
        }

        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                tran));
        RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1,
                h - 1, 20, 20);
        Shape clip = g2d.getClip();
        g2d.clip(r2d);
        GradientPaint gp = new GradientPaint(0.0F, 0.0F, BUTTON_COLOR1, 0.0F,
                h, BUTTON_COLOR2, true);

        g2d.setPaint(gp);
        g2d.fillRect(0, 0, w, h);
        g2d.setClip(clip);
        g2d.setPaint(p1);
        g2d.drawRoundRect(0, 0, w - 1, h - 1, 20, 20);
        g2d.setPaint(p2);
        g2d.drawRoundRect(1, 1, w - 3, h - 3, 18, 18);
        g2d.dispose();
        super.paintComponent(g);
    }
}

package com.losen.greedysnake.domain;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ReComeOn extends  JFrame   implements ActionListener{
    public  static  void main(String [] args) {
        new  ReComeOn();
    }
    JFrame frame2=new JFrame();
    JButton reComeOnButton=new  JButton("重新开始");
    JButton  closeButton =new JButton("结束游戏");


    //定义界面按钮等内容。
    public  ReComeOn() {
        frame2.setUndecorated(true);  //用于取消边框背景
        frame2.setSize(800,480);
        frame2.setLocation(600,300);
        //frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame2.setVisible(true);
        frame2.setLayout(null);

        //设置按钮颜色

        Color  color2=new  Color(124,252,0);
        reComeOnButton.setBackground(color2);
        Color color1 = new Color(124,252,0 );
        closeButton.setBackground(color1 );
        //设置按钮大小和位置
        reComeOnButton.setBounds(140, 364, 120, 110);
        closeButton.setBounds(280,270,120,110);
        //设置按钮颜色和字体
        reComeOnButton.setFont(new Font("华文行楷", Font.BOLD, 20));
        closeButton.setFont(new Font("华文行楷", Font.BOLD, 20));
        //在容器中加入按钮
        frame2.add(reComeOnButton);
        frame2.add(closeButton);
        addPicture();
        reComeOnButton.addActionListener(this);
        closeButton.addActionListener(this);
    }

    //设置背景图片
    public  void  addPicture() {      //游戏结束时弹出的界面的背景
        ImageIcon deadPicture = new ImageIcon("src/image/gameover.png");
        JLabel  pictureLabel  =new  JLabel(deadPicture);
        pictureLabel.setBounds(0, 0,deadPicture.getIconWidth(), deadPicture.getIconHeight());
        frame2.getLayeredPane().add(pictureLabel,new Integer(Integer.MIN_VALUE));
        JPanel  jp1=(JPanel)frame2.getContentPane();
        jp1.setOpaque(false);
    }
    //按钮加入监听器事件
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO 自动生成的方法存根
        if(e.getSource()==reComeOnButton) {
            closeThis();
            new  Frame3();
        }
        if(e.getSource()==closeButton) {
            System.exit(0);
        }
    }
    private void closeThis() {
        // TODO 自动生成的方法存根
        frame2.dispose();
    }

    //	游戏运行界面,实例化SnakeGame类,并加入到运行界面中
    class  Frame3 extends JFrame      {
        JFrame  frame1 = new JFrame(); //游戏图形界面
        public   Frame3(){
            frame1.setUndecorated(true);  //用于取消边框背景
            frame1.setBounds(200,70,1600,900);
            /// frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame1.setVisible(true);
            SnakeGame sn  =new SnakeGame();
            frame1.add(sn);
            sn.requestFocus();//布局的中间
        }
    }
}

     SnakeGame.java

package com.losen.greedysnake.domain;

import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JApplet;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.Timer;


/**
 * @author losen
 * @version 1.0
 * @DateTime 2023/6/24 11:32
 *
 * SnakeGame类来设计贪吃蛇小游戏的运行界面,运行界面是贪吃蛇游戏的主体部分,  界面主要包括两个方面的内容,
 * 一方面是运行界面的内容,贪吃蛇长度显示,游戏说明,速度控制,游戏开始,暂停退出等按钮。
 * 另一方面,主要包括贪吃蛇的形状和移动,贪吃蛇移动区域,随机点的定义
 * 运行界面的过程是这样的:在开始姐爱你点击进入游戏按钮以后,程序运行到运行界面,开始播放背景音乐。
 * 点击游戏说明按钮,弹出一个对话框,说明游戏运行的操作过程。点击开始按钮以后,
 * 贪吃蛇开始向上移动,鼠标在向上区域点击,贪吃蛇向上,向左区域点击,贪吃蛇向左,依次赖推。
 * 当贪吃蛇碰到草莓时,吃掉它,蛇身变长,并有背景音乐显示,长度显示加一,
 * 点击暂停按钮游戏暂停,点击退出按钮后,退出游戏。
 * 当贪吃蛇撞到自己或者墙体的时候,贪吃蛇会死亡,然后弹出一个界面,重启界面,用来决定游戏继续进行或者退出游戏。
 * 贪吃蛇的形状和移动通过数组的形式实现,在界面中,定义一个x轴和y轴定义的坐标系,定义一个数组,数组的移动就是贪吃蛇的移动,
 * 移动方式是贪吃蛇坐标的改变,可以通过鼠标控制或键盘控制来实现贪吃蛇的移动,
 * 随机点产生是在坐标系中产生随机数来实现,
 */
public class SnakeGame extends JPanel  implements ActionListener   {
    private final int length = 33;//定义活动范围,食物以及蛇可活动纵向范围,要比边界范围-1
    private final int width = 55;//定义活动范围,食物以及蛇可活动横向范围,要比边界范围-1
    private final int unit = 25;//定义单位长度
    private final  int GameLOCX=40;
    private final  int  GameLOCY=40;
    private  final int GameWidth=width*unit;
    private  final  int GameLength=length*unit;
    //随机点坐标
    int newY1 =0 ;
    int newX1 = 0 ;

    int mousex=1;
    int mousey=1;
    //播放背景音乐
    AudioClip christmas = loadSound("src/Music/backgroundMusic.wav");
    int direction = 1;//定义一个按下按钮后要去的方向
    private ArrayList<SnakeNode> snake = new ArrayList<SnakeNode>();//定义蛇身的数组集合
    private int Direction;//定义蛇头的方向
    private int Length ;//定义蛇身的长度
    private SnakeNode newNode = new SnakeNode(1,1,Color.BLACK);//定义随机点

    boolean  startFlag  =false;
    //定义按钮,速度控制,开始暂停退出按钮等
    RButton   SspeedButton , TspeedButton,FspeedButton,THspeedButton ,ShowButton;
    RButton    startButton , stopButton , quitButton  ,reComeOnButton,closeButton;
    //定义标签,长度显示,方向显示,按钮提示等
    JLabel  snakeScore, label1,  label3,label4;
    //初始速度控制
    private static int Difficult_Degree=1;
    //蛇的移动控制,利用线程来实现用鼠标控制,利用计时器来实现用键盘控制。
    Thread  tr= new Thread(new ThingsListener());
    Timer time = new Timer(1000, new ThingsListener1());//定义一个定时器对象,这里我们还要创建一个ThingsListener事件

    public SnakeGame() {//初始化区域
        //循环播放背景音乐
        christmas.loop ();

        // time.start();
        tr.start();
        //定义按键
        //在容器中添加按钮标签等的时候,需要说明布局管理为空,不然的话,加进去的按钮会按照一定的布局来实现,
        this.setLayout (null);
        //定义按钮
        startButton = new  RButton("开始游戏");
        stopButton =new  RButton("暂停游戏");
        quitButton =new  RButton("退出游戏");

        FspeedButton =new  RButton("速度一");
        SspeedButton =new  RButton("速度二");
        TspeedButton=new  RButton("速度三");
        THspeedButton=new  RButton("速度四");
        ShowButton  =new   RButton("游戏指南");

        //定义标签
        snakeScore =new  JLabel("3");
        label1 =new  JLabel("当前长度");

        label3 =new  JLabel("速度设置");
        label4 =new  JLabel( );

        //设置字体
        startButton.setFont(new Font("宋体", Font.BOLD, 35));
        stopButton.setFont(new Font("宋体", Font.BOLD, 35));
        quitButton.setFont(new Font("宋体", Font.BOLD, 35));

        FspeedButton.setFont(new Font("宋体", Font.BOLD, 15));
        TspeedButton.setFont(new Font("宋体", Font.BOLD, 15));
        SspeedButton.setFont(new Font("宋体", Font.BOLD, 15));
        THspeedButton.setFont(new Font("宋体", Font.BOLD, 15));

        ShowButton.setFont(new Font("宋体", Font.BOLD, 30));

        label1.setFont(new Font("宋体", Font.BOLD, 35));
        snakeScore.setFont(new Font("宋体", Font.BOLD, 50));

        label3.setFont(new Font("宋体", Font.BOLD, 30));
        label4.setFont(new Font("宋体", Font.BOLD, 35));
        //定义按钮标签位置
        startButton.setBounds (1390, 500 , 190, 90);
        stopButton.setBounds (1390,  600 , 190, 90);
        quitButton.setBounds (1390,  700 , 190, 90);
        snakeScore.setBounds(1450, 70, 150, 90);
        label1.setBounds(1390, 10, 190, 90);

        ShowButton.setBounds(1390, 170, 190, 90);

        label3.setBounds(1390, 270, 190, 90);
        label4.setBounds(0, 0, 190, 90);

        FspeedButton.setBounds (1390, 350 , 85, 60);
        SspeedButton.setBounds (1500,350 , 85, 60);
        TspeedButton.setBounds (1390, 420 , 85, 60);
        THspeedButton.setBounds (1500, 420 , 85, 60);

        THspeedButton.setBackground(Color.green);
        SspeedButton.setBackground(Color.blue);
        TspeedButton.setBackground(Color.red);
        FspeedButton.setBackground(Color.red);

        // 添加 按钮和标签,用this关键字指向当前容器

        this.add(startButton);
        this.add(stopButton);
        this.add(quitButton);

        this.add(FspeedButton);
        this.add(SspeedButton);
        this.add(TspeedButton);
        this.add(THspeedButton);

        this.add(label1);
        this.add(snakeScore);
        this.add( ShowButton);
        this.add(label3);
        this.add(label4);

        // 添加三个按键的监听事件
        startButton.addActionListener(this);
        stopButton.addActionListener(this);
        quitButton.addActionListener(this);

        THspeedButton.addActionListener(this);
        SspeedButton.addActionListener(this);
        TspeedButton.addActionListener(this);
        FspeedButton.addActionListener(this);
        ShowButton.addActionListener(this);

        snake.add(new SnakeNode(width/2,length/2 ,Color.red));
        snake.add(new SnakeNode(width/2,length/2+1 ,Color.blue));
        snake.add(new SnakeNode(width/2,length/2+2 ,Color.green));

        Direction = 1;//定义初始方向为向上
        Length = 3;//蛇身长度为3
        CreateNode1();//产生随机点
        // CreateNode2();
     /*//采用键盘控制的控制模式,利用键盘的上下左右键,来实现让·direction的变化,从而使贪吃蛇能够按照键盘的控制来实现移动
        this.addKeyListener(new KeyAdapter() {//捕捉键盘的按键事件 设置监听器
            public void keyPressed(KeyEvent e) {

                switch(e.getKeyCode()) {
                    case KeyEvent.VK_UP://按下向上,返回1
                        direction = 1;
                        break;
                    case KeyEvent.VK_DOWN://按下向下,返回-1
                        direction = -1;
                        break;
                    case KeyEvent.VK_LEFT://按下相左,返回2
                        direction = 2;
                        break;
                    case KeyEvent.VK_RIGHT://按下向右,返回-2
                        direction = -2;
                        break;
                    default:
                        break;
                }
                if(direction + Direction !=0) {//不能反向运动
                    Direction = direction;
                    Move(direction);
                    repaint();
                }
            }
        });
        */

        //采用 鼠标控制的控制模式     通过监听鼠标在容器中的位置,点击上下左右区域,改变direction的值,即可实现贪吃蛇的移动,
        this.addMouseListener(new MouseAdapter(){  //匿名内部类,鼠标事件
            public void  mousePressed(MouseEvent e){
                int a=0;//鼠标完成点击事件
                //e.getButton就会返回点鼠标的那个键,左键还是右健,3代表右键
                mousex = e.getX();  //得到鼠标x坐标
                mousey = e.getY();  //得到鼠标y坐标
                double  k=0.6;            //直线斜率
                double  Y1=0.6*mousex;
                double  Y2=-0.6*mousex+810;
                double   X1=1.6*mousey;
                double   X2=-1.6*mousey+1350;
                if(mousex > X1&&mousex<X2&&mousey>0&&mousey<405) {   //第一象限  		向上
                    label4.setText( "向上" );
                    a=1;
                }
                if(mousex>X2&&mousex<X1&&mousey>405&&mousey<810) {  // 第二象限             向下
                    label4.setText( "  向下" );
                    a=2;
                }
                if(mousex>0&&mousex<675&&mousey>Y1&&mousey<Y2) {    //第三象限     向左
                    label4.setText( " 向左" );
                    a=3;
                }
                if(mousex>675&&mousex<1350&&mousey>Y2&&mousey<Y1) {   //第四象限    向右
                    label4.setText( "  向右" );
                    a=4;
                }

                switch( a) {
                    case  1://按下向上,返回1
                        direction = 1;
                        break;
                    case 2://按下向下,返回-1
                        direction = -1;
                        break;
                    case 3://按下相左,返回2
                        direction = 2;
                        break;
                    case 4://按下向右,返回-2
                        direction = -2;
                        break;
                    default:
                        break;
                }

                if(direction + Direction !=0) {//不能反向运动
                    Direction = direction;
                    Move(direction);
                    repaint();
                }
            }

        });
    }
    /*定义蛇移动的方法
     *   贪吃蛇的移动方法主要包括方向控制,碰到随机点,碰到自己,碰到边界以及设计贪吃蛇从前向后的移动
     *
     */
    public void Move(int direction) {
        int FirstX = snake.get(0).getX();            //获取蛇第一个点的横坐标
        int FirstY = snake.get(0).getY();            //获取蛇第一个点的纵坐标
        if(!startFlag)
            return ;
        //方向控制
        switch(direction) {
            case 1:
                FirstY--;
                break;
            case -1:
                FirstY++;
                break;
            case 2:
                FirstX--;
                break;
            case -2:
                FirstX++;
                break;
            default:
                break;
        }
        //当碰到随机点时
        if(FirstX == newNode.getX()&&FirstY == newNode.getY()) {
            new eatFoodMusic();
            getNode();
            return;
        }
        //当碰到蛇身自己时
        for(int x = 0; x < Length; x++) {
            if((FirstX==snake.get(x).getX())&&(FirstY == snake.get(x).getY())) {
                startFlag=false;
                new DeadMusic();
                new ReComeOn();
                christmas.stop ();
            }
        }
        //当贪吃蛇撞到边界
        if(FirstX < 1  || FirstX >55  || FirstY < 1 || FirstY >33) {
            startFlag=false;
            new DeadMusic();
            new ReComeOn();
            christmas.stop ();
            //	new  Test();
        }
        //定义循环,使得贪吃蛇从前向后移动
        for(int x = Length - 1; x > 0; x--) {
            snake.get(x).setX(snake.get(x-1).getX());
            snake.get(x).setY(snake.get(x-1).getY());
        }
        snake.get(0).setX(FirstX);
        snake.get(0).setY(FirstY);
        repaint();
    }
    //获取随机点
    public void getNode() {
        snake.add(new SnakeNode());
        Length++;

        for(int x = Length-1; x >0; x--) {
            snake.get(x).setX(snake.get(x-1).getX());
            snake.get(x).setY(snake.get(x-1).getY());
            snake.get(x).setColor(snake.get(x-1).getColor());
        }
        snakeScore.setText( ""+( Length ));         //定义蛇的长度
        snake.get(0).setX(newNode.getX());
        snake.get(0).setY(newNode.getY());
        snake.get(0).setColor(newNode.getColor());
        CreateNode1();//产生随机点
        // CreateNode2();
        repaint();
        //当长度超过10的时候,产生鼓掌声
        if(Length==10) {
            new applauseMusic();
        }
    }

    public void CreateNode1() {                     //创造随机点的方法

        Boolean flag = true;
        while(flag) {
            newY1 = new Random().nextInt(15)+1;
            newX1= new Random().nextInt(25)+1;
            for(int x = 0; x < Length; x++) {
                if(snake.get(x).getX() == newX1 && snake.get(x).getY() == newY1) {
                    flag = true;
                    break;
                }
                flag = false;
            }
            //随机点不能超出面板,并且不能出现在蛇身上

            for(int i = 0; i < Length; i++) {
                if(snake.get(i).getX()> 5&& snake.get(i).getX()<newX1  &&snake.get(i).getY() > 5
                        && snake.get(i).getY()<newY1) {
                    flag = true;
                    break;
                }
                flag= false;
            }
        }

        Color color = new Color(new Random().nextInt(255),new Random().nextInt(255),new Random().nextInt(255));
        newNode.setColor(color);
        newNode.setX(newX1);
        newNode.setY(newY1);
    }

    /*
     * 这里是自己新建一个事件处理,每隔Timer的时间间隔,就开始移动Directon的位置,
     * 由因为Direction的位置是构造方法中定义好的,所以就会自动地移动方向。而每当玩家使用键盘时,Direction的值变化,之后每次自动移动的方向也随之变化。
     *
     *
     */
    //定义内部类,贪吃蛇不断移动

    public class ThingsListener1 implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            Move(direction);
        }
    }//

    public AudioClip loadSound ( String filename )
    {
        URL url = null;
        try
        {
            url = new URL ("file:" + filename);
        }
        catch (MalformedURLException e)
        {}
        return JApplet.newAudioClip (url);
    }

    /*
     * 当startflag为真的时候,贪吃蛇在线程时间的脉冲下继续移动,这个过程包含在if语句块中,当程序启动时,每隔1.2s就有一个响应,
     *上一个方法采用Timer, Timer的构造方法是Timer(int delay, ActionListner listener)通俗的说就是创建一个每 delay秒触发一次动作的计时器,
     * 每隔特定的时间就会触发特定的事件。可以使用start方法启动计时器。
     * 优点在于形式简单,缺点在于当采用速度控制的时候不易控制,而同样作为时间触发作用的线程控制可以实现这个目的,即通过控制时间来控制贪吃蛇的移动速度
     * 之所以之前的设计有错误,在于while后面没有用if进行startflag的检验,即startflag只有在真的条件下才可以移动,时间脉冲触发下才可以移动。
     *
     *
     */
    //定义线程类,使得贪吃蛇能够在线程的控制下不断移动
    class ThingsListener  implements  Runnable   {
        @Override
        public void run() {
            // TODO 自动生成的方法存根
            while( true) {
                if(startFlag) {
                    Move(Direction);
                    repaint();
                }
                try {
                    Thread.sleep(1200/Difficult_Degree);
                }catch(InterruptedException  e){
                    e.printStackTrace();
                }
            }
        }//设置一个监听器事件,用来控制蛇的不断移动
    }
    //定义图像类,画出贪吃蛇移动的运行界面,如贪吃蛇的形状,背景图片,蛇头蛇尾等
    //描述蛇函数的主体形状,随机点的形状和蛇的形状

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);//加背景
        Image  im=Toolkit.getDefaultToolkit().getImage("src/image/background.png");
        g.drawImage(im, 0, 0, this.getWidth(), this.getHeight(), this);//画出蛇头
        if(direction ==1||Direction==1){

            Toolkit toolup = this.getToolkit();
            Image headup =  toolup.getImage( "src/image/up.png");
            g.drawImage(headup,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);
        }else if(direction ==-1){

            Toolkit tooldown = this.getToolkit();
            Image headdown =  tooldown.getImage( "src/image/down.png");
            g.drawImage(headdown,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);

        }else if(direction ==2){
            Toolkit toolleft = this.getToolkit();
            Image headleft =  toolleft.getImage( "src/image/left.png");
            g.drawImage(headleft,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);
        }else if(direction ==-2){
            Toolkit toolright = this.getToolkit();
            Image headright =  toolright.getImage( "src/image/right.png");
            g.drawImage(headright,snake.get(0).getX()*unit, snake.get(0).getY()*unit, unit, unit,this);
        }
        //画出食物的形状
        Toolkit tool1 = this.getToolkit();
        Image food=  tool1.getImage( "src/image/food.png");
        g.drawImage(food,newNode.getX()*unit, newNode.getY()*unit, unit, unit,this);

//        Toolkit tool2 = this.getToolkit();
//        Image food1=  tool2.getImage( "src/image/gameover.png");
//        g.drawImage(food1,newNode.getX()*unit, newNode.getY()*unit, unit, unit,this);

        //绘制指定矩形的边框。矩形的左边和右边位于 x 和 x + width。顶边和底边位于 y 和 y + height。使用图形上下文的当前颜色绘制该矩形。
        g.drawRect(40, 30, 1350, 810 );
        for(int x = 1; x < Length-1; x++) {                   //利用循环,来绘制蛇的形状
            g.setColor(snake.get(x).getColor());
            g.fillOval(snake.get(x).getX()*unit, snake.get(x).getY()*unit, unit, unit);   //给蛇的每一个节点画椭圆
        }
        for(int x = Length-1; x < Length; x++) {
            Toolkit toolright = this.getToolkit();
            Image headright =  toolright.getImage( "src/image/");   // 蛇尾巴吧
            g.drawImage(headright,snake.get(x).getX()*unit, snake.get(x).getY()*unit, unit,unit,this);//利用循环,来绘制蛇的形状
        }
    }

    //设置按钮的监听器事件
    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO 自动生成的方法存根
        //按开始键
        if(e.getSource() == startButton) {
            new  pushButtonMusic ();
            startFlag = true;
            startButton.setEnabled(false);
            stopButton.setEnabled(true);

        }//按暂停键
        if(e.getSource() == stopButton) {
            new  pushButtonMusic ();
            startFlag = false;
            startButton.setEnabled(true);
            stopButton.setEnabled(false);
        }
        //        退出程序
        if(e.getSource() == quitButton) {

            System.exit(0);
        }//按游戏指南建
        if(e.getSource() ==  ShowButton) {
            new  pushButtonMusic ();
            JDialog frame = new JDialog();//构造一个新的JFrame,作为新窗口。
            frame.setBounds( 600,300,815,515 );
            JTextArea  Myarea=new  JTextArea(3,10);
            Myarea.setText("嗨,你好,欢迎体验贪吃蛇小游戏!\n "
                    +"这个小游戏点击开始按钮后贪吃蛇开始移动,你身体的前后左右移动\n"+"会使贪吃蛇也前后左右移动。\n"
                    + "你的任务是通过控制蛇的移动来吃掉小草莓,这样贪吃蛇就长大了。\n"
                    +"点击暂停游戏按钮可以使得贪吃蛇停止移动,"
                    +"点击退出游戏按钮自然游\n"+"戏就结束啦!\n"
                    + "点击速度一,速度二等按钮就可以控制贪吃蛇的移动速度,以提高\n"+"康复效率!\n"
                    +"此游戏素材部分来源于网络,如果有侵犯到您的利益 \n"+"请立刻联系我们,任何单位或个人不准用于商业用途。");
            frame.setLayout(null);
            Myarea.setBounds( 10,10,815,350);
            Myarea.setFont(new Font("宋体",Font.BOLD,25));
            frame.add(Myarea);
            frame.setModalityType(JDialog.ModalityType.APPLICATION_MODAL);    // 设置模式类型。
            frame.setVisible(true);
        }//按速度一键
        if(e.getSource() == FspeedButton) {
            new speedButtonMusic ();
            Difficult_Degree= 2;
        }//按速度二键
        if(e.getSource() == SspeedButton) {
            new speedButtonMusic ();

            Difficult_Degree=  3;
        }//按速度三键
        if(e.getSource() == TspeedButton) {
            new speedButtonMusic ();
            Difficult_Degree= 4;
        }//按速度四键
        if(e.getSource() == THspeedButton) {
            new  speedButtonMusic ();
            Difficult_Degree= 5;
        }
        this.requestFocus();
    }

}

SnakeNode.java

package com.losen.greedysnake.domain;

import java.awt.Color;

public class SnakeNode {    //定义蛇身集合中的各个元素点,x,y。以及颜色三个蛇的关键组成
    private int x;
    private int y;
    private Color color;

    public int setX=20;
    public int setY=20;

    public SnakeNode() {
        super();

    }
    public SnakeNode(int x, int y, Color color) {
        super();
        this.x = x;
        this.y = y;
        this.color = color;
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    public Color getColor() {
        return color;
    }
    public void setColor(Color color) {
        this.color = color;
    }
}

applauseMusic.java
package com.losen.greedysnake.domain;
/*
 * 设置程序运行背景音乐,包括 点击按钮音乐,鼓励音,撞墙音乐,吃食物音乐等等,
 * 音乐类的设置可以在snakeGame类中实现,由于音乐太多,故而集中到一起,可以在需要添加的地方实例化即可。
 */
import java.applet.AudioClip;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JApplet;
//添加鼓励音
class applauseMusic
{
    AudioClip christmas = loadSound("src/music/applauseMusic.wav");
    public applauseMusic  ()
    {
        christmas.play ();
    }
    public AudioClip loadSound ( String filename )
    {
        URL url = null;
        try
        {
            url = new URL ("file:" + filename);
        }
        catch (MalformedURLException e)
        {}
        return JApplet.newAudioClip (url);
    }
}
//添加吃到食物的音乐
class eatFoodMusic
{
    AudioClip christmas = loadSound("src/music/eatFoodMusic.wav");
    public eatFoodMusic  ()
    {
        christmas.play ();
    }
    public AudioClip loadSound ( String filename )
    {
        URL url = null;
        try
        {
            url = new URL ("file:" + filename);
        }
        catch (MalformedURLException e)
        {}
        return JApplet.newAudioClip (url);
    }
}

//添加撞墙音乐
class DeadMusic
{
    AudioClip christmas = loadSound("src/music/DeadMusic.wav");
    public  DeadMusic   ()
    {
        christmas.play ();
    }
    public AudioClip loadSound ( String filename )
    {
        URL url = null;
        try
        {
            url = new URL ("file:" + filename);
        }
        catch (MalformedURLException e)
        {}
        return JApplet.newAudioClip (url);
    }
}

//添加 按键音乐
class  pushButtonMusic
{
    AudioClip christmas = loadSound("src/music/pushButtonMusic.wav");
    public pushButtonMusic  ()
    {
        christmas.play ();
    }
    public AudioClip loadSound ( String filename )
    {
        URL url = null;
        try
        {
            url = new URL ("file:" + filename);
        }
        catch (MalformedURLException e)
        {}
        return JApplet.newAudioClip (url);
    }
}
// 添加速度控制音乐
class    speedButtonMusic{
    AudioClip christmas = loadSound("src/music/encouragMusic.wav");
    public speedButtonMusic()
    {
        christmas.play ();
    }
    public AudioClip loadSound ( String filename )
    {
        URL url = null;
        try
        {
            url = new URL ("file:" + filename);
        }
        catch (MalformedURLException e)
        {}
        return JApplet.newAudioClip (url);
    }
}

运行ComeOn中的主类即可启动游戏。

如果对你有用别忘了回来点个赞噢~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哆le

一分两分也是爱,不求多哈哈哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值