贪吃蛇(经典小游戏)

package snack;

import javax.swing.*;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;

public class MainJFram extends JFrame {
    public static Font font1=new Font("宋体",Font.BOLD,20);
    private Snake snake;//蛇
    private JPanel jPanel,jPanel1;//游戏棋盘
    private  Timer tiner;//定时器,在规定的时间内调用蛇移动的方法
    private Node food;

    private MainJFram(){

        //初始化窗体参数
        inFrame();
        //初始化游戏棋盘
        GamePanel();
        //初始化蛇
        initSnake();
        //初始化食物
        initFood();
        //添加菜单栏
        MEnu();

       // initTimer();
        //设置一个键盘监听,让蛇随着上下左右方向移动
        setKeyListener();
    }

    private void initFood() {
        food=new Node();
        food.random();

    }

    private void setKeyListener() {
        addKeyListener(new KeyAdapter() {
            //当键盘按下时,会自动调用此方法
            @Override
            public void keyPressed(KeyEvent e) {
                //键盘中的每一个键都有一个编号
                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 MEnu(){
        JMenuBar menBar=new JMenuBar();
        JMenu buton=new JMenu("开始游戏");
       // JMenu buton1=new JMenu("暂停");
        // Menu buton2=new JMenu("继续游戏");
        JMenu buton3=new JMenu("退出游戏");

        buton.addMenuListener(new MenuListener() {
            @Override
            public void menuSelected(MenuEvent e) {
                //初始化定时器开始运行
                initTimer();
            }

            @Override
            public void menuDeselected(MenuEvent e) {

            }

            @Override
            public void menuCanceled(MenuEvent e) {

            }
        });

        buton3.addMenuListener(new MenuListener() {
            @Override
            public void menuSelected(MenuEvent e) {
                //初始化定时器开始运行
               System.exit(0);
            }

            @Override
            public void menuDeselected(MenuEvent e) {

            }

            @Override
            public void menuCanceled(MenuEvent e) {

            }
        });
        menBar.add(buton);

        menBar.add(buton3);
        setJMenuBar(menBar);
    }
   //初始化定时器
    private void initTimer() {
      //创建定时器对象
      tiner=new Timer();
  //初始化,定时任务
  TimerTask tinerTask=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毫秒执行一次
      tiner.scheduleAtFixedRate(tinerTask,0,200);//(定时任务,延迟时间)
  }

     private void initSnake() {
      snake=new Snake();
  }

  //初始化游戏棋盘
    private void GamePanel() {
     jPanel=new JPanel(){  //JPanel(){pa}
          // 绘制游戏棋盘中的内容
          @Override
          public void paint(Graphics g) {
            //清空棋盘
              g.clearRect(0,0,600,600);
            //Graphics g可以看作是一个画笔,提供了很多方法,可以绘制很多的图形
             //绘制40条横线
              for (int i = 0; i <= 40; i++) {
                  g.drawLine(0,i*15,600,i*15);//设置x坐标的起始坐标和结束坐标
              }

             // 绘制40条横线
              for (int i = 0; i <= 40; i++) {
                  g.drawLine(i*15,0,i*15,600);//设置y坐标的起始坐标,和结束坐标
              }

              //绘制蛇
              LinkedList<Node> body=snake.getBody();//通过这个集合获得蛇的身体
              for(Node node:body){
                  g.setColor(Color.green);
                  g.fillRect(node.getX()*15,node.getY()*15,15,15);//填充颜色
              }

              //绘制食物
              g.fillRect(food.getX()*15,food.getY()*15,15,15);
              //g.setColor(Color.green);
          }
      };

      //把棋盘添加到窗体
      add(jPanel);

  }

  //初始化窗体参数
     private void inFrame() {
      Toolkit tk = Toolkit.getDefaultToolkit();
      java.awt.Image img = tk.getImage ("src/img.png");
      setIconImage(img);
      // 给窗体设置图标方法
         setTitle("贪吃蛇");
      //设置窗体的大小
      setSize(610,640);
      //设置窗体的位置
      setLocation(400,200);
      //关闭窗口
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      //设置窗体大小不可变
      setResizable(false);
  }

    public static void main(String[] args) {
    //创建窗体对象,并显示
        new MainJFram().setVisible(true);
}
}
package snack;
//enum 枚举:枚举就是几个固定的常量
public enum Direction {
    UP,DOWN,LEFT,RIGHT;
}
package snack;

import java.util.Random;

//节点类:每一条蛇是由若干节点组成,每一个节点由横纵坐标来确定位置
public class Node {
    private int x;
    private int y;
//空参构造,有参与构造,和get set方法
    public Node(){

    }

    public Node(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;
    }

    //随机生成位置的方法
    public  void random(){
        //创建random对象
        Random r=new Random();
        //随机x,y生成坐标
         this.x=r.nextInt(40);
         this.y=r.nextInt(40);
    }
}
package snack;

import javax.swing.*;
import java.util.LinkedList;

//一条蛇由多个节点使用LinkedLIstanbul集合存储N哦的节点,蛇出生的时候有3给节点
public class Snake {
    //蛇的身体
    private LinkedList<Node> body;
    //定义一个蛇的运动方向,默认左移
    private Direction direction=Direction.LEFT;
    //蛇是否活着
    public boolean isLiving=true;
    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));
        body.add(new Node(22,20));
        body.add(new Node(23,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;
            JOptionPane.showMessageDialog(null, "游戏结束!");
        }
   //判断蛇是否碰到自己身体
        for (int i = 0; i < body.size(); i++) {
          Node node=body.get(i);
          if((head.getX()==node.getX())&&(head.getY()== node.getY())){
           // isLiving=false;
          }
        }
 }
    }

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

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

    public Direction getDirection() {
        return direction;
    }

    public void setDirection(Direction direction) {
        this.direction = direction;
    }
    //沿着蛇头的移动方向添加一个节点
    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;
        }
    }
}

总的代码量并不算多,创建四个类

MainJFram类:主要用于创建一些能够调用的方法

Direction类:使用键盘来控制蛇的移动(枚举)

Node类:节点类:每一条蛇是由若干节点组成,每一个节点由横纵坐标来确定位置

Snake类:一条蛇由多个节点使用LinkedLIstanbul集合存储N哦的节点,蛇出生的时候有3给节点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值