【无标题】

贪吃蛇项目(java版)

1. 首先创键一个蛇的类,包含成员x,y来确定蛇的位置

public class SNode {
    //x坐标
    int x;
    //y坐标
    int y;
    //节点的颜色
    Color color;

    //构造函数 用来创建对象的 但是需要你给我传递x y 颜色这三个变量
    public SNode(int x, int y, Color color) {
        this.x = x;
        this.y = y;
        this.color = color;
    }

    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 Color getColor() {
        return color;
    }

    public void setColor(Color color) {
        this.color = color;
    }
}

2.在中间容器Mainpanel上面画蛇运动的地图

public class MainPanel extends JPanel {

    //定义整个活动范围
    static int xWidth = 30;   //表示x方向有30个格子
    static int yWidth = 30;
    static int unit = 20; //表示格子的宽度

3.蛇的初始化,由于Java的坐标系中左上角(0,0)而且向下y值增大,向右x值增大,故编码如下

 public MainPanel() {
        SNode node1 = new SNode(xWidth / 2, yWidth / 2, Color.red);
        SNode node2 = new SNode(xWidth / 2, yWidth / 2 + 1, Color.red);
        snake.add(node1);
        snake.add(node2);
protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i = 0; i < snake.size(); i++) {
            // g.setColor 设置颜色的
            g.setColor(snake.get(i).getColor());
            //画图形 fillOval 画矩形
            g.fillOval(snake.get(i).getX() * unit, snake.get(i).getY() * unit, unit, unit);
        }
        g.setColor(food.getColor());
        //画图形 fillOval 画矩形
        g.fillOval(food.getX() * unit, food.getY() * unit, unit, unit);
    }

`
4.生成一个键盘事件,能够控制蛇的移动,而且蛇在没有控制下,会自动移动

4.1键盘事件

 KeyAdapter keyAdapter = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                 int key=e.getKeyCode();
                 int dir=0;

                 //根据按键的不同,我们需要去调整蛇的移动位置
                 if(key==KeyEvent.VK_UP){
                     dir=1;
                 }else if (key==KeyEvent.VK_DOWN){
                     dir=-1;
                 }else if (key==KeyEvent.VK_LEFT){
                     dir=2;
                 }else if (key==KeyEvent.VK_RIGHT){
                     dir=-2;
                 }
                  snakeMove(dir);
            }

4.2 自动移动代码

int autoDir=1;//自动移动的反向
int delay=2000;
Timer t;
 KeyAdapter keyAdapter = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                 int key=e.getKeyCode();
                 int dir=0;

                 //根据按键的不同,我们需要去调整蛇的移动位置
                 if(key==KeyEvent.VK_UP){
                     dir=1;
                 }else if (key==KeyEvent.VK_DOWN){
                     dir=-1;
                 }else if (key==KeyEvent.VK_LEFT){
                     dir=2;
                 }else if (key==KeyEvent.VK_RIGHT){
                     dir=-2;
                 }
                 autoDir=dir;
                 //按下了键 就应该要移动,所以就在键盘事件中调用移动方法
                snakeMove(dir);
            }
             ActionListener actionListener=new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                snakeMove(1);//定时器中的方向应该是受键盘控制的
            }
        };
      t = new Timer(2000,actionListener);//注意进口是javax.swing.Timer();
      t.start();

    }
    //我们将蛇运动的逻辑定义一个方法,dir表示移动的方向
    void snakeMove (int dir){




        int oldHeadX=snake.get(0).getX();
        int oldHeadY=snake.get(0).getY();
        if (oldHeadX==food.x&&oldHeadY==food.y){
             snake.add(food);
             //吃了东西我就判断一下 调整下定时器的速度
            if((snake.size()-2)%2==0){
                delay=delay-100;
                //注意我们带了delay 还需要设置该定时器 才会生效--
                t.setDelay(delay);
            }
             food=createNewNode();

}
  switch(dir){
            case 1:
                oldHeadY--;//(我们的原点是 0 0)
                break;
            case -1:
                oldHeadY++;
                break;
            case 2://表示左
                oldHeadX--;
                break;
            case -2://表示右
                oldHeadX++;
                break;
        }
        //再去掉最后一个节点
        snake.removeLast();
        //最后把新的头节点接在最前面
        SNode node1=new SNode(oldHeadX,oldHeadY,Color.red);
        snake.addFirst(node1);
        repaint();//图形界面需要手动刷新
    }

5.创建食物

food=createNewNode();
SNode createNewNode(){
        boolean flag=true;
        Random random =new Random();
        int x=0;
        int y=0;
        while(flag){
            //不断生成点(随机生成)
             x=random.nextInt(xWidth-5);
          y=random.nextInt(yWidth-5);
            for (int i=0;i<snake.size();i++){
                SNode node=snake.get(i);
                //重复了 结束内循环
                if(node.getX()==x&&node.getY()==y){
                    break;
                }
                if(i==snake.size()-1){
                    flag=false;//结束循环
                }
            }
        }
        SNode sNode=new SNode(x,y,Color.black);
        return sNode;
    }
     protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(food.getColor());
        //画图形 fillOval 画矩形
        g.fillOval(food.getX() * unit, food.getY() * unit, unit, unit);
    }

6.游戏死亡规则

撞到自己

//死亡判断--撞自己
        for (int i=1;i<snake.size();i++){
            SNode node=snake.get(i);
            if (oldHeadX==node.getX() && oldHeadY==node.getY()){
                System.out.println("撞自己");
                System.exit(-1);
            }
        }

撞墙

//是否撞墙
        if (oldHeadX<0||oldHeadX>xWidth-1||oldHeadY<0||oldHeadY>yWidth-1){
            System.out.println("撞墙");
            System.exit(-1);
        }

7.难度升级机制

 if (oldHeadX==food.x&&oldHeadY==food.y){
             snake.add(food);
             //吃了东西我就判断一下 调整下定时器的速度
            if((snake.size()-2)%2==0){
                delay=delay-100;
                //注意我们带了delay 还需要设置该定时器 才会生效--
                t.setDelay(delay);
            }

8.运行主函数

public static void main(String[] args) {
        JFrame frame = new JFrame("贪吃蛇");
        frame.setBounds(0, 0, xWidth * unit, yWidth * unit);
        MainPanel sn = new MainPanel();
        frame.add(sn);//顶层容器去放中间容器
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        frame.setResizable(false);
        //如果要让键盘事件生效,需要让MainPanel获取焦点
        sn.setFocusable(true);
    }

}

总结*:通过本次项目,让我见识到了Java的swing类的强大,对Java的学习也充满了信心,但是在编程的过程中也意识到了自己实际开发的思维还不够成熟,知识只停留于表面,还需要多多开发项目*

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值