Java版贪吃蛇游戏

 

实现代码:

public class Main {
    public static void main(String[] args) {
        WelcomeJFrame jg=new WelcomeJFrame();
    }
}
/*
*贪吃蛇蛇头的横纵坐标
 */
public class Head {
    public int x;
    public int y;
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Snake extends JComponent implements KeyListener {

    //集合中存储蛇的坐标
    List<Head> headList = new ArrayList<>();
    //分数
    int score=0;
    int weight=300;
    int high=440;
    //随机产生食物坐标
    int a,b;
    //移动标记
    int dirction;

    //空格长度&&游戏难度
    int space;
    boolean isRuning=true;
    boolean isEating=true;
    boolean isChange=false;
    public Snake(int space){
        this.space=space;
        this.setFocusable(true);  // 获取焦点
        this.addKeyListener(this); // 监听键盘事件
        headList.add(new Head());
        a = 4;
        b = 5;
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (isRuning) {
                    try {
                        Thread.sleep(300);
                        repaint();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            }
        }).start();

    }
    /*
    *绘图
     */
    public void paintComponent(Graphics graphics) {
        /*
        用这个方法调用父类中定义的paintComponent方法,确保在显示新的图画之前清空视图区域
         */
        super.paintComponent(graphics);
        for (int i = 1; i <= weight / space; i++) {
            /*
            第一个点的x坐标,第一个点的y坐标;第二个点的x坐标,第二个点的y坐标
             */
            graphics.drawLine(i * space, 0, i * space, high);
        }
        for (int i = 1; i <= high / space; i++) {
            graphics.drawLine(0, i * space, weight, i * space);
        }
        graphics.setColor(Color.BLUE);
        if (isChange) {
            isChange = false;
            a = new Random().nextInt(14) + 1;
            b = new Random().nextInt(21) + 1;
        }
        graphics.fillRect(a * space, b * space, space, space);
        graphics.setColor(Color.BLACK);

        for (int i = 0; i < headList.size(); i++) {
            if (i==0){
                graphics.setColor(Color.RED);
            }else {
                graphics.setColor(Color.BLACK);
            }
            graphics.fillRect(headList.get(i).x, headList.get(i).y, space, space);
        }
        move(headList, dirction);

        if (isEating) {
            headList.remove(headList.size() - 1);
        }
        isEating = true;
    }

    /*
    蛇移动
     */
    public void move(List<Head> heads, int dirction){
        Head OldHead = heads.get(0);
        Head Newheads = new Head();
        switch (dirction) {
            //上
            case 1:
                Newheads.x = OldHead.x;
                Newheads.y = OldHead.y - space;
                break;
            //下
            case 2:
                Newheads.x = OldHead.x;
                Newheads.y = OldHead.y + space;
                break;
            //左
            case 3:
                Newheads.x = OldHead.x + space;
                Newheads.y = OldHead.y;
                break;
            //右
            case 4:
                Newheads.x = OldHead.x - space;
                Newheads.y = OldHead.y;
                break;
        }
        //是否越界
       cross(Newheads.x,Newheads.y);
        //是否吃到自己
       eatself(heads);
       //是否吃到食物
        EatFood(Newheads.x,Newheads.y);
        //避免随机产生的食物与蛇体重合
        Chonghe(heads);
        //更新蛇头坐标
        heads.add(0, Newheads);

    }
    /*
    判断是否越界
     */
    public void cross(int x,int y){
        if ((x < 0 || x > 280) || (y < 0 || y > 420)) {
            isRuning = false;
            JOptionPane.showMessageDialog(this,"游戏结束,得分为"+score+"");
            System.exit(0);
        }
    }

    /*
    判断是否碰到自己
     */
    public void eatself(List<Head> heads){
        for (int i = 1; i < heads.size(); i++) {
            if (heads.get(0).x == heads.get(i).x && heads.get(0).y == heads.get(i).y) {
                isRuning = false;
                JOptionPane.showMessageDialog(this,"游戏结束,得分为"+score+"");
                System.exit(0);
            }
        }
    }

    /*
    吃到食物
     */
    public void EatFood(int x, int y) {
        if (x == a * space && y == b * space) {
            isEating = false;
            isChange = true;
            score=score+10;
        }
    }

    /*
    避免食物生成在蛇身上
     */
    public void Chonghe(List<Head> heads) {
        for (int i = 0; i < heads.size(); i++) {
            if (a == heads.get(i).x && b == heads.get(i).y) {
                a = new Random().nextInt(14) + 1;
                b = new Random().nextInt(21) + 1;
            }
        }
    }
    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        //上
        if ((keyCode == 87 || keyCode == 38) && dirction != 2) {
            dirction = 1;
        }
        //下
        else if ((keyCode == 83 || keyCode == 40) && dirction != 1) {
            dirction = 2;
        }//左
        else if ((keyCode == 68 || keyCode == 39 )&& dirction != 4) {
            dirction = 3;

        }//右
        else if ((keyCode == 65 || keyCode == 37 )&& dirction != 3) {
            dirction = 4;

        }

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }
}
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/*
第一次显示的窗体,游戏开始前选择游戏难度的窗体
 */
public class WelcomeJFrame extends JFrame implements ActionListener ,ChangeListener{
    JPanel jpanel1,jpanel2;
    JButton button1,button2;
    JLabel jlable1,jlabl2;
    JFrame jFrame;
    JSpinner mJSpinner;
    String[] s = new String[]{"简单", "一般", "困难"};;
    int number=20;
    public WelcomeJFrame(){
        this.setTitle("贪吃蛇小游戏");
        this.setBounds(500, 200, 300, 400);

        jpanel1=new JPanel();
        jpanel2=new JPanel();
        button1=new JButton("开始");
        button2=new JButton("退出");
        jlable1=new JLabel("选择难度");
        this.setLayout(new BorderLayout(10, 10));
        jpanel1.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
        jpanel1.add(button1);
        jpanel1.add(jlable1);
        SpinnerModel model = new SpinnerListModel(s);
        mJSpinner = new JSpinner(model);
        mJSpinner.setSize(50, 50);
        jpanel1.add(mJSpinner);
        jpanel1.add(button2);
        ImageIcon mIcon = new ImageIcon("D:\\贪吃蛇.png");
        jlabl2=new JLabel(mIcon);
        jpanel2.add(jlabl2);
        this.add(jpanel1,BorderLayout.SOUTH);
        this.add(jpanel2,BorderLayout.CENTER);
        this.setResizable(false);
        this.setBackground(Color.blue);
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        button1.addActionListener(this);
        button2.addActionListener(this);
        mJSpinner.addChangeListener(this);

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==button2){
            JOptionPane.showMessageDialog(this,"谢谢使用,再见!");
            System.exit(0);
        }else if(e.getSource()==button1){
            this.dispose();
            Snake snake=new Snake(number);
            snake.setBackground(Color.BLUE);
            jFrame=new JFrame();
            jFrame.add(snake);
            jFrame.setBounds(500, 200, 320, 480);
            jFrame.setResizable(false);
            jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            jFrame.setVisible(true);
        }
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        switch (mJSpinner.getValue().toString()) {
            case "简单":
                number = 20;
                break;
            case "一般":
                number = 15;
                break;
            case "困难":
                number = 10;
                break;
            default:
                break;
        }

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值