贪吃蛇(java实现)

该代码创建了一个简单的贪吃蛇游戏,使用Java编写。初始化了蛇的位置和长度,设置了随机食物生成,并通过定时器控制蛇的移动。当蛇吃到食物时,长度增加,食物重新生成。同时,代码包含了对蛇移动方向的控制和边界检测,防止蛇撞墙或吃到自己,以及游戏开始和结束的状态管理。
摘要由CSDN通过智能技术生成

 设置贪吃蛇的身体,并生成随机食物。

 int slong = 2;//蛇当前长度
    int[] Snakex = new int[100];
    int[] Snakey = new int[100];//蛇坐标
    int fx = 1;//蛇的方向 0-左 1-右 2-上 3-下
    Timer timer = new Timer(100, this);//设置定时器,每100毫秒一次

    int foodx;
    int foody;//食物位置
    Random random = new Random();//随机数,随机位置生成食物
    int started = 0;//游戏信息 0-未开始 1-开始 2-结束

 创建贪吃蛇的窗口以及贪吃蛇和食物的初始位置:

 

public void myJFrame() {

        this.setTitle("贪吃蛇"); //标题
        this.setSize(800, 600); //窗口大小
        this.setResizable(false); //窗口是否可以改变大小=否
        this.setDefaultCloseOperation(Snake.EXIT_ON_CLOSE); //窗口关闭方式为关闭窗口同时结束程序

        int width = Toolkit.getDefaultToolkit().getScreenSize().width; //获取屏幕宽度
        int height = Toolkit.getDefaultToolkit().getScreenSize().height; //获取屏幕高度

        this.setLocation((width - 800) / 2, (height - 600) / 2); //设置窗口默认位置以屏幕居中

        this.setFocusable(true);
        this.addKeyListener(this);


        this.setVisible(true); //窗口是否显示=是

        //蛇的初始位置
        Snakex[0] = 60;
        Snakey[0] = 100;
        Snakex[1] = 40;
        Snakey[1] = 100;

        //随机食物的初始位置
        foodx = random.nextInt(39);
        foody = random.nextInt(22);
        foodx = foodx * 20;
        foody = foody * 20 + 80;

        System.out.println(foodx + "," + foody);
    }

用paint方法绘制界面:使用fillRect填充矩形,设置色块大小为20*20,绘制贪吃蛇、随机食物、界面。

 //覆写paint方法,绘制界面
    public void paint(Graphics g) {
        //绘制背景,使用fillRect填充矩形
        g.setColor(Color.BLUE);
        g.fillRect(0, 0, 800, 600);

        //绘制游戏区域
        g.setColor(Color.black);
        g.fillRect(0, 80, 800, 520);

        //绘制蛇
        for (int i = 0; i < slong; i++) {
            g.setColor(Color.CYAN);
            g.fillRect(Snakex[i], Snakey[i], 20, 20);
        }
        g.setColor(Color.yellow);
        g.fillRect(Snakex[0],Snakey[0],20,20);

        //绘制食物
        g.setColor(Color.yellow);
        g.fillOval(foodx, foody, 20, 20);


        if (started == 0) {
            g.setColor(Color.BLACK);//设置画笔颜色
            g.setFont(new Font("微软雅黑", 10, 20)); //设置字体
            g.drawString("按下“空格键”开始游戏", 300, 65); //绘制字符
        } else if (started == 1) {
            g.setColor(Color.BLACK);//设置画笔颜色
            g.setFont(new Font("微软雅黑", 10, 20)); //设置字体
            g.drawString("当前分数为:", 300, 65); //绘制字符
            g.drawString(String.valueOf(slong - 2), 420, 65); //绘制字符
        } else if (started == 2) {
            g.setColor(Color.BLACK);//设置画笔颜色
            g.setFont(new Font("微软雅黑", 10, 20)); //设置字体
            g.drawString("游戏结束-", 250, 65); //绘制字符
            g.drawString("最终分数为:", 350, 65); //绘制字符
            g.drawString(String.valueOf(slong - 2), 470, 65); //绘制字符
        }
    }

操作监听:坐标改变,贪吃蛇以及食物也就改变,在贪吃蛇移动过程中,需要进行判断:蛇是否撞墙、是否超出游戏区域、是否吃到了食物、是否吃到了自己。之后进行监听操作实现贪吃蛇方向的移动。

       //操作监听——控制蛇的不断移动
    @Override
    public void actionPerformed(ActionEvent e) {
            //判断游戏是否开始
        if (started == 1) {
            //通过循环控制蛇移动
            for (int i = slong - 1; i > 0; i--) {
                Snakex[i] = Snakex[i - 1];
                Snakey[i] = Snakey[i - 1];
            }

            //判断蛇移动的方向
            if (fx == 0) {
                Snakex[0] = Snakex[0] - 20;
            } else if (fx == 1) {
                Snakex[0] = Snakex[0] + 20;
            } else if (fx == 2) {
                Snakey[0] = Snakey[0] - 20;
            } else if (fx == 3) {
                Snakey[0] = Snakey[0] + 20;
            }

            //判断蛇是否撞到墙外
            if (Snakex[0] < 0 || Snakex[0] > 780 || Snakey[0] < 80 || Snakey[0] > 580) {
                started = 2;
            }
            //判断蛇是否吃到了食物
            if (Snakex[0] == foodx && Snakey[0] == foody) {

                slong++;

                foodx = random.nextInt(39);
                foody = random.nextInt(22);
                foodx = foodx * 20;
                foody = foody * 20 + 80;

                System.out.println(foodx + "," + foody);
            }

                //判断是否吃到了自己
            for (int i = 1; i < slong; i++) {
                if (Snakex[0] == Snakex[i] && Snakey[0] == Snakey[i]) {
                    started = 2;
                }
            }

                //判断食物是否随机在了蛇身上
            for (int i = 0; i < slong; i++) {
                if (foodx == Snakex[i] && foody == Snakey[i]) {

                    //随机食物的初识位置
                    foodx = random.nextInt(39);
                    foody = random.nextInt(22);
                    foodx = foodx * 20;
                    foody = foody * 20 + 80;

                    System.out.println(foodx + "," + foody);
                }
            }

            repaint();
        }
        timer.start();
    }

    //输入
    @Override
    public void keyTyped(KeyEvent e) {

    }

    //键盘按下——控制游戏的开始以及蛇的移动方向
    @Override
    public void keyPressed(KeyEvent e) {
         //获取从键盘输入的键
        int key = e.getKeyCode();
            //判断是否为空格
        if (key == KeyEvent.VK_SPACE) {
            if (started == 0) {
                started = 1;
            } else if (started == 1) {
                started = 0;
            } else if (started == 2) {
                started = 0;

                slong = 2;//蛇当前长度

                //蛇的初识位置
                Snakex[0] = 60;
                Snakey[0] = 100;
                Snakex[1] = 40;
                Snakey[1] = 100;

                //随机食物的初识位置
                foodx = random.nextInt(39);
                foody = random.nextInt(22);
                foodx = foodx * 20;
                foody = foody * 20 + 80;

                // 初始化方向
                fx = 1;
            }

            repaint();
            timer.start();

            //左
        } else if (key == KeyEvent.VK_LEFT) {
            if (fx != 1) {
                fx = 0;
            }
            //右
        } else if (key == KeyEvent.VK_RIGHT) {
            if (fx != 0) {
                fx = 1;
            }
            //上
        } else if (key == KeyEvent.VK_UP) {
            if (fx != 3) {
                fx = 2;
            }
            //下
        } else if (key == KeyEvent.VK_DOWN) {
            if (fx != 2) {
                fx = 3;
            }
        }

    }

    // 弹起
    @Override
    public void keyReleased(KeyEvent e) {

    }

    //    点击
    @Override
    public void mouseClicked(MouseEvent e) {

    }

    //    按下
    @Override
    public void mousePressed(MouseEvent e) {

    }

    //    抬起
    @Override
    public void mouseReleased(MouseEvent e) {

    }

    //    进入
    @Override
    public void mouseEntered(MouseEvent e) {

    }

    //    离开
    @Override
    public void mouseExited(MouseEvent e) {

    }

可以运行! (以下代码只是其中的一个类) package chy.snake.entities; import java.awt.Color; import java.awt.Graphics; import java.awt.Point; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import chy.snake.listener.SnakeListener; import chy.snake.util.Global; public class Snake { public static final int up = 1; public static final int down = -1; public static final int left = -2; public static final int right = 2; private int oldDirection,newDirection; //newDirection:一次时间 间隔内输入的最后方向 private Point oldTail; private boolean life; //life 为 true或者false,初始为true, 用于118行 private LinkedList<Point> body = new LinkedList<Point> (); //需要经常访问蛇的第一个和最后一个节点,使用链表LinkedList存放蛇的身体节点,因为它有getFirst(),getLast(),removeLast(),方法 private Set<SnakeListener> listeners = new HashSet<SnakeListener>(); public Snake(){ init(); } public void init(){ //初始化 int x = Global.WIDTH/2; int y = Global.HEIGHT/2; for(int i=0;i<3;i++){ //初始长度3 body.addLast(new Point(x-i,y)); //是addLast } oldDirection = newDirection = right; //初始方向 右 life = true; } public void die(){ life = false; } public void move(){ System.out.println("Snake's move"); if (!(oldDirection + newDirection == 0)){ oldDirection = newDirection; } //1.去尾 oldTail = body.removeLast(); int x = body.getFirst().x; int y = body.getFirst().y; //蛇头的x,y坐标 switch(oldDirection){ case up: y--; break; case down: y++; break; case left: x--; break; case right: x++; break; } Point newHead = new Point(x,y); //2.加头 body.addFirst(newHead); } public void changeDirection(int direction){ /*无效方向:在蛇的这一次移动之后和下一次移动之前的 这个时间间隔内输入了多个方向,只有最后一个方向 是 有效方向,其余的都为无效方向*/ System.out.println("Snake's changeDirection"); newDirection = direction; //将一个时间间隔内按得最后方向,赋给 newDirection } public void eatFood(){ System.out.println("Snake's eatFood"); body.addLast(oldTail); //后面的节点不去掉 } public boolean isEatFood(){ System.out.println("Snake's isEatFood"); return false; } public boolean isEatBody(Snake snake){ //比较蛇是否吃到身体 System.out.println("snake's isEatBody"); for(int i= 1;i<body.size();i++){ //i 从蛇头结点的下一个节点开始,排除蛇头结点 if(body.get(i).equals(this.getHead())){ //如果i 的节点 和 头结点 相同 return true; } } return false; } public void drawMe(Graphics g){ System.out.println("Snake's drawMe"); g.setColor(Color.GREEN); //设置蛇的颜色 for(Point p : body){ g.fill3DRect(p.x * Global.CELL_SIZE, p.y * Global.CELL_SIZE, Global.CELL_SIZE, Global.CELL_SIZE, true); } } public Point getHead(){ //得到蛇头节点,判断吃食物 return body.getFirst(); } private class SnakeDriver implements Runnable{ //线程,不停的调用move方法 @Override public void run() { // TODO 自动生成的方法存根 while(life){ // 42和46行,life为true 或者false move(); for(SnakeListener l : listeners){ l.snakeMoved(Snake.this); //循环,依次调用SnakeMoved方法 } try { Thread.sleep(300); } catch (InterruptedException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } } public void start(){ new Thread(new SnakeDriver()).start(); //启动线程的方法 } public void addSnakeListener(SnakeListener l){ if(l != null){ this.listeners.add(l); } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值