JAVA贪吃蛇小游戏

在这里插入图片描述

one

package com.wang;

/**
 * 枚举:枚举就是几个固定的常量
 */
public enum  Direction {
      UP,DOWN,LEFT,RIGHT
}

**

two

**

package com.wang;

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

public class MainFrame extends JFrame {

    // 蛇
    private Snake snake;
    // 定时器,在指定的时间调用这个蛇移动的方法
    private Timer timer;
    private JPanel jPanel;  // 游戏棋盘
    private Node food; // 食物
    public MainFrame() throws HeadlessException {
        // 初始化食物
        initFood();
        // 初始化窗体参数
        initFrame();
        // 初始化游戏棋盘
        initGamePanel();
        // 初始化蛇
        initSnake();
        // 初始化定时器
        initTimer();
        // 设置键盘监听,让蛇随着上下左右方向移动
        setListener();
    }

    // 初始化食物
    private void initFood() {
        food = new Node();
        food.random();
    }

   // 设置一个键盘监听
    private void setListener() {
        addKeyListener(new KeyAdapter() {
            // 当键盘按下时,会自动调用此方法
            @Override
            public void keyPressed(KeyEvent e) {
                System.out.println("键盘按下");
                // 键盘中的每一个键都有一个编号
                switch (e.getKeyCode()){
                    case KeyEvent.VK_UP: // 上键
                       // 修改蛇的运动方向
                        if (snake.getDirection()!=Direction.DOWN){
                            snake.setDirection(Direction.UP);
                        }
                        break;
                    case KeyEvent.VK_DOWN: // 下键
                        if (snake.getDirection()!=Direction.UP){
                            snake.setDirection(Direction.DOWN);
                        }
                        break;
                    case KeyEvent.VK_LEFT: // 左键
                        if (snake.getDirection()!=Direction.RIGHT){
                            snake.setDirection(Direction.LEFT);
                        }
                        break;
                    case KeyEvent.VK_RIGHT: // 右键
                        if (snake.getDirection()!=Direction.LEFT){
                            snake.setDirection(Direction.RIGHT);
                        }
                        break;
                }
            }
        });
    }

    //初始化定时器
    private void initTimer() {
        // 创建定时任务对象
        timer = new Timer();
        // 初始化定时任务
        TimerTask timerTask = new  TimerTask(){
            @Override
            public void run() {
                snake.move();
                // 判断蛇是否和食物重合
                Node head = snake.getBody().getFirst();
                if (head.getX()==food.getX()&&head.getY()==food.getY()){
                       snake.eat(food);
                       food.random();
                }
                // 重绘游戏棋盘
                jPanel.repaint();
            }
        };
        // 每100毫秒,执行一次定时任务
        timer.scheduleAtFixedRate(timerTask,0,100);
    }

    private void initSnake() {
        snake = new Snake();
    }
    // 初始化游戏棋盘
    private void initGamePanel(){
       jPanel = new JPanel(){
            // 绘制游戏棋盘中的内容
            @Override
            public void paint(Graphics graphics){

                // 清空棋盘
                graphics.clearRect(0,0,600,600);

                // Graphics graphics 可以看作是一个画笔,他提供了很多方法可以来绘制一些基本的图形(直线,矩形等)
                   // 绘制40条横线
                for (int i = 0; i <= 40; i++) {
                    graphics.drawLine(0,i*15,600,i*15);
                }
                   // 绘制40条竖线
                for (int i = 0; i <= 40; i++) {
                    graphics.drawLine(i*15,0,i*15,600);
                }
                   // 绘制蛇
                LinkedList<Node> body = snake.getBody();
                for (Node node : body) {
                    graphics.fillRect(node.getX()*15,node.getY()*15,15,15);
                }
                // 绘制实物
                graphics.fillRect(food.getX()*15,food.getY()*15,15,15);
            }
        };
        // 把棋盘添加到窗体中
        add(jPanel);
    }

    // 初始化窗体参数
    private void initFrame(){
        // 设置宽高
        setSize(610,640);
        // 设置窗体的位置
        setLocation(400,400);
        // 设置关闭按钮的作用(退出程序)
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗体大小不可变
        setResizable(false);
    }

    public static void main(String[] args) {
        // 创建窗体对象,并显示
        new MainFrame().setVisible(true);
    }
}

**

three

**

package com.wang;

import java.util.Random;

/**
 * 节点类:每一条蛇是由若干个节点组成的,每一个节点有横纵坐标来确定位置
 */
public class Node {
    private int x;
    private int 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;
    }

    public Node(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public Node() {
    }

    // 随机生成位置的方法
    public void random(){
        Random random = new Random();
        // 随机生成横坐标
        this.x = random.nextInt(40);
        // 随机生成纵坐标
        this.y = random.nextInt(40);
    }
}

**

four

**

package com.wang;

import java.util.LinkedList;

/**
 * Snake类表示蛇
 *│一条蛇有多个节点使用LinkedList集合存储Node节点,蛇出生的时候有6个节点。
 * */

public class Snake {
    // 蛇的身体
    private LinkedList<Node> body;

    // 蛇的运动方向,默认向左
    private Direction direction = Direction.LEFT;
    // 蛇是否活着
    private boolean isLiving = true;
    public Direction getDirection() {
        return direction;
    }

    public void setDirection(Direction direction) {
        this.direction = direction;
    }

    public LinkedList<Node> getBody() {
        return body;
    }

    public void setBody(LinkedList<Node> body) {
        this.body = body;
    }

    public Snake() {
        // 初始化蛇的身体
        initSnake();
    }
    private void initSnake() {
         // 创建集合
        body = new LinkedList<>();
        // 创建6个节点,添加到集合中
        body.add(new Node(16,20));
        body.add(new Node(17,20));
        body.add(new Node(18,20));
        body.add(new Node(19,20));
        body.add(new Node(20,20));
        body.add(new Node(21,20));
    }

    // 蛇回沿着舌头的方向移动
    // 控制蛇移动:在蛇头的运动方向添加一个节点,然后把蛇尾的节点删除
    public void move(){
        if (isLiving){
            // 要去获取蛇头
            Node head = body.getFirst();
            switch (direction){
                case UP:
                    // 舌头的上面添加一个节点
                    body.addFirst(new Node(head.getX(),head.getY()-1));
                    break;
                case DOWN:
                    body.addFirst(new Node(head.getX(),head.getY()+1));
                    break;
                case LEFT:
                    body.addFirst(new Node(head.getX()-1,head.getY()));
                    break;
                case RIGHT:
                    body.addFirst(new Node(head.getX()+1,head.getY()));
                    break;
            }
            // 删除最后的节点
            body.removeLast();

            // 判断蛇是否撞墙
            head = body.getFirst();
            if (head.getX()<0||head.getY()<0||head.getX()>=40||head.getY()>=40){
                 isLiving = false;
            }
            // 判断蛇是否碰到自己的身体
            for (int i = 1; i <body.size() ; i++) {
                Node node = body.get(i);
                if (head.getX()==node.getX()&&head.getY()==node.getY()){
                        isLiving = false;
                }
            }
        }
    }
  // 吃食物:沿着舌头的移动方向添加一个节点
    public void eat(Node food) {
        // 获取蛇头
        Node head = body.getFirst();
        switch (direction){
            case UP:
                // 舌头的上面添加一个节点
                body.addFirst(new Node(head.getX(),head.getY()-1));
                break;
            case DOWN:
                body.addFirst(new Node(head.getX(),head.getY()+1));
                break;
            case LEFT:
                body.addFirst(new Node(head.getX()-1,head.getY()));
                break;
            case RIGHT:
                body.addFirst(new Node(head.getX()+1,head.getY()));
                break;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值