界面版贪吃蛇

内容概要:

        在JFrame容器里加入一个JPanel,

        对JPane进行绘画:方格+蛇身+食物

        创建一个计时器(Time)+任务(TimerTask)对JPanel进行重绘

        在任务里加入吃移动+判断是否活着+蛇吃食物

可用加入登录注册界面: 带登录页面的猜数字小游戏_小菜鸡℡的博客-CSDN博客

 主线

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.TimerTask;
import java.util.Timer;


public class GluttonousSnakeGame extends JFrame{
    
    private JPanel JP;
    private Snake snake = new Snake();
    
    public GluttonousSnakeGame(){
        init();
        repaintEveryPeriod();//计时器
        initDirectionListener();//方向监听
        this.setVisible(true);
    }
    
    
    private void init() {
        this.setTitle("贪吃蛇");
        this.setSize(600,401);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setResizable(false);
        
        //对JPanel进行绘画
        JP= new JPanel(){
            @Override
            public void paint(Graphics g) {
                //绘制方格
                g.clearRect(0,0,600,401);
    
                for (int i = 0; i < 37; i++) {
                    g.drawLine(0,i*10 ,580,i*10);
                }
    
                for (int i = 0; i < 59; i++) {
                    g.drawLine(i*10,0,i*10,360);
                }
                
                
                //获取蛇身
                LinkedList<Grid> body = snake.getBody();
                g.setColor(Color.RED);
                
                //绘制蛇头
                g.fillRect(body.getFirst().getX(),body.getFirst().getY(),10,10);
                g.setColor(Color.BLACK);
                
                //遍历集合 绘制蛇身。
                for (int i = 1; i < body.size(); i++) {
                    g.fillRect(body.get(i).getX(),body.get(i).getY(),10,10);
                }
                
                //新食物
                int[] ints = snake.newFood();
                g.fillRect(ints[0], ints[1], 10, 10);
            }
        };
        this.add(JP);
    }
    
    /**
     * 计时器,重绘
     */
    private void repaintEveryPeriod(){
        Timer t = new Timer();//计时器
        TimerTask task = new TimerTask(){//任务
            @Override
            public void run() {
                snake.move();
                if (snake.isAlive()==false){
                    Thread.currentThread().stop();
                }
                //吃食物
                snake.addBody();
                //重绘
                JP.repaint();
            }
        };
        //可根据getBody().size()设置蛇的速度,积分等
            t.schedule(task,0, 100);
        
        
    }
    
    /**
     * 对蛇行进的方向进行监听
     */
    private void initDirectionListener() {
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                switch (keyCode) {
                    case KeyEvent.VK_UP:
                        if (snake.getDirection() !=KeyEvent.VK_DOWN)
                            snake.setDirection(KeyEvent.VK_UP);
                        break;
                    case KeyEvent.VK_DOWN:
                        if (snake.getDirection() !=KeyEvent.VK_UP)
                        snake.setDirection(KeyEvent.VK_DOWN);
                        break;
                    case KeyEvent.VK_LEFT:
                        if (snake.getDirection() !=KeyEvent.VK_RIGHT)
                        snake.setDirection(KeyEvent.VK_LEFT);
                        break;
                    case KeyEvent.VK_RIGHT:
                        if (snake.getDirection() !=KeyEvent.VK_LEFT)
                        snake.setDirection(KeyEvent.VK_RIGHT);
                        break;
                }
            }
        });
    }
}

 

方格 

package test1;


public class Grid {
    private int x;
    private int y;
    
    public Grid() {
    }
    
    public Grid(int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    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;
    }
}

 

 蛇

package test1;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Random;


public class Snake {
    Random random = new Random();
    //食物坐标为食物左上角坐标,最多只能在最下和右侧倒数第二格出现,不然出界
    private int foodY = (random.nextInt(36)) * 10;
    private int foodX = (random.nextInt(58)) * 10;
    
    private LinkedList<Grid> body = new LinkedList();
    
    private int direction = KeyEvent.VK_DOWN;
    
    public int getDirection() {
        return direction;
    }
    
    public void setDirection(int direction) {
        this.direction = direction;
    }
    
    
    public Snake(){
        body.add(new Grid(200,100));
        body.add(new Grid(210,100));
        body.add(new Grid(220,100));
        body.add(new Grid(230,100));
        body.add(new Grid(240,100));
        body.add(new Grid(250,100));
        body.add(new Grid(260,100));
    }
    
    public void setBody(LinkedList<Grid> body) {
        this.body = body;
    }
    
    public LinkedList<Grid> getBody() {
        return body;
    }
    
    /**
     * 蛇随着键盘上下左右,而移动
     */
    public void move(){
        Grid first = body.getFirst();
        switch (direction){
            case KeyEvent.VK_UP:
                body.addFirst(new Grid(first.getX(),first.getY() - 10));
                body.removeLast();
                break;
            case KeyEvent.VK_DOWN:
                body.addFirst(new Grid(first.getX(),first.getY() + 10));
                body.removeLast();
                break;
            case KeyEvent.VK_LEFT:
                body.addFirst(new Grid(first.getX() - 10,first.getY()));
                body.removeLast();
                break;
            case KeyEvent.VK_RIGHT:
                body.addFirst(new Grid(first.getX() + 10,first.getY()));
                body.removeLast();
                break;
        }
    }
    
    /**
     *判断蛇是否活着,即是否撞壁,撞自己
     */
    public boolean isAlive(){
        int y = body.getFirst().getY();
        int x = body.getFirst().getX();
        if (x<0 || y<0 || x>570 || y>350){//蛇头坐标为蛇头左上角坐标,最下和右侧倒数第二格碰撞就会死亡
            return false;
        }
    
        for (int i = 3; i < body.size(); i++) {
            Grid grid = body.get(i);
            if (x == grid.getX() && y == grid.getY()){
                return false;
            }
        }
        return true;
    }
    
    /**
     * 创建食物
     * 食物如果出现在蛇身体上,则重新生成
     */
    public int[] newFood(){
        for (int i = 0; i < body.size(); i++) {
            if (body.get(i).getX() == foodX && body.get(i).getY() == foodY){
                //食物坐标为食物左上角坐标,最多只能在最下和右侧倒数第二格出现,不然出界
                foodY = (random.nextInt(36)) * 10;
                foodX = (random.nextInt(58)) * 10;
            }
        }
        return new int[]{foodX,foodY};
    }
    
    /**
     * 蛇吃食物增加身体
     * a,在蛇尾添加:取蛇在刷新前的最后一节坐标,在刷新后加上
     * b,另一种方法在头部添加:在迟到食物之后不.removeLast();
     *  不是在键盘监听里写判断,这样会出现延迟。吃一个食物增加n节
     *  另写一个方法在 move()调用
     */
    public void addBody() {
       if (body.getFirst().getX() == foodX && body.getFirst().getY() == foodY){
            int bodyLastX = body.getLast().getX();
            int bodyLastY = body.getLast().getY();
            body.add(new Grid(bodyLastX,bodyLastY));
        }
    }
}

 视频原解:小贤讲Java的个人空间_哔哩哔哩_bilibili

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值