用java的GUI写简易的贪吃蛇

用java的GUI写简易的贪吃蛇

大概思路

1、贪吃蛇界面绘制
2、绘制静态小蛇
3、让小蛇简单能动
4、让小蛇能够根据键盘来动
5、小蛇能够长大
6、关于失败以及积分的判定
在写代码之前,应该明白,游戏的界面都应该放在面板上,游戏的主要内容也都是写在面板的那个类上的。而面板上,我们写这个游戏核心几个点就是 paintComponent 和 keyPressed 以及 actionPerformed
第一段代码,new一个窗口,添加面板
第二段代码 面板的代码
第三段代码 获取小蛇和食物所需的素材

在这里插入public class StartGame {
    public static void main(String[] args) {
    //在这里调用窗口
        StartGame startGame=new StartGame();
        startGame.fram();
    }
    public void fram(){
        //先new一个窗口
        JFrame jFrame=new JFrame();
        //设定窗口不可动
        jFrame.setResizable(false);
        //设置尺寸,尺寸需要计算
       jFrame.setBounds(100,100,900,670);
       //添加面板
        Container container= jFrame.getContentPane();
jFrame.add(new GamePnal());
//这个一定要放在添加面板后,否则会键盘监听失效
        jFrame.setVisible(true);
    }

}

Data类用于获取小蛇的素材
public class Data {
//用URL获取地址
   public static URL header=Data.class.getResource("header.png");
    public  static URL food=Data.class.getResource("food.png");
    public static  URL body=Data.class.getResource("body.png");
    public static URL up=Data.class.getResource("up.png");
    public static URL down=Data.class.getResource("down.png");
    public static URL left=Data.class.getResource("left.png");
    public static URL right=Data.class.getResource("right.png");
     public  static ImageIcon header1=new ImageIcon(header);
     //将一个个地址放入图片图标中
    public  static ImageIcon food1=new ImageIcon(food);
    public  static ImageIcon body1=new ImageIcon(body);
    public  static ImageIcon up1=new ImageIcon(up);
    public  static ImageIcon down1=new ImageIcon(down);
    public  static ImageIcon left1=new ImageIcon(left);
    public  static ImageIcon right1=new ImageIcon(right);

}

//面板类
public class GamePnal extends JPanel  implements  KeyListener ,ActionListener{
//我们要写面板以及键盘监听器和动作监听器,就直接继承和实现接口,会更省我们的时间
    int length=3;
    //这里放小蛇的x和y坐标,用数组放
    int[] snakex=new int[100];
    int[]  snakey=new int[100];
    //写一个小蛇的方向
    String fangxiang;
    //start用于判断是否处于游戏开始状态
    public static boolean start=false;
    //fail用于判断小蛇是否处于失败状态
    public  static  boolean fail=false;
    //Timer用于刷新小蛇,这里的100是毫秒值
    Timer timer=new Timer(100,this);//调用的前提是事件监听器
    int foodx;//食物的x和y
    int foody;
    Random random=new Random();//用一个随机数,用于改变食物的位置
    int socre;
//构造器  用于调用焦点以及键盘监听器
    public GamePnal()
    {
      ui();
      this.setFocusable(true);
      this.addKeyListener(this);
      //用于刷新
      timer.start();
      socre=0;
    }
    //ui是初始化数据的地方
    public  void ui(){
        foodx=25+25*random.nextInt(30);
        foody=75+25*random.nextInt(20);
        //2对应的是尾巴。1是第一节身体,0是头的位置
snakex[0]=100;  snakex[1]=75; snakex[2]=50;
snakey[0]=150;  snakey[1]=150;snakey[2]=150;
fangxiang="right";//默认初始时,头向右
    }
    @Override
    protected void paintComponent(Graphics g) {
    
        super.paintComponent(g);
        //将header1素材写进来
        setBackground(Color.CYAN);
        Data.header1.paintIcon(this,g,25,61);
        g.fillRect(25,125,850,500);
        //添加自己想要添加的元素
        g.setColor(Color.red);
        g.setFont(new Font("微软雅黑",Font.BOLD,40));
        g.drawString("追风的皮卡",300,45);
        g.setColor(Color.green);
        g.setFont(new Font("微软雅黑",Font.BOLD,20));
        //把积分、长度写进来 
        g.drawString("长度"+length,750,85);
        g.drawString("分数"+socre,750,105);
        Data.food1.paintIcon(this,g,foodx,foody);
//根据字符串来把小蛇的头的方向画出来
        if (fangxiang.equals("right")){
            Data.right1.paintIcon(this,g,snakex[0],snakey[0]);
        }else if (fangxiang.equals("left")){
            Data.left1.paintIcon(this,g,snakex[0],snakey[0]);
        }else if (fangxiang.equals("down")){
            Data.down1.paintIcon(this,g,snakex[0],snakey[0]);
        }else if (fangxiang.equals("up")){
            Data.up1.paintIcon(this,g,snakex[0],snakey[0]);
        }
        //用一个循环画出小蛇身体,记得用循环,方便后期小蛇开始长大,可以循环画身体
        for (int i = 1; i < length; i++) {
            Data.body1.paintIcon(this,g,snakex[i],snakey[i]);
        }
if(start==false){
    g.setColor(Color.cyan);
    g.setFont(new Font("微软雅黑",Font.BOLD,30));
    g.drawString("按下空格开始游戏",300,250);
}
if (fail){
    g.setColor(Color.blue);
    g.setFont(new Font("微软雅黑",Font.BOLD,30));
    g.drawString("菜狗,按空格再重新开始吧",300,250);
}
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }
   @Override
    public void keyPressed(KeyEvent e) {
        int key=e.getKeyCode();
        if (key==KeyEvent.VK_SPACE){
            //如果蛇死了,就会调用初始化
           if(fail){ui();}
           //当游戏开始后,需要改变start状态
           else  { start=!start;
           // repaint();非常关键,可以重画,没有这个代码的话,按空格键,会没有效果
               repaint();}
        }
        //根据键盘,来改变字符串
        if (key==KeyEvent.VK_UP){
            fangxiang="up";
        }
        else if (key==KeyEvent.VK_DOWN){
            fangxiang="down";
        }
        else if (key==KeyEvent.VK_RIGHT){
            fangxiang="right";
        }
        else if (key==KeyEvent.VK_LEFT){
            fangxiang="left";
        }

    }

    @Override
    public void keyReleased(KeyEvent e) {
    }
    @Override
    public void actionPerformed(ActionEvent e) {
//判断小蛇吃食物
        if (snakex[0]==foodx&&snakey[0]==foody){
            length++;
            socre=socre+5;
            foodx=25+25*random.nextInt(30);
            foody=75+25*random.nextInt(20);
        }
        //判断游戏是开始后状态
 if (start&&fail==false) {
 //第一个循环是让小蛇的身体能够动起来,根据位置的赋值
    for (int i = length - 1; i > 0; i--) {

        snakex[i] = snakex[i - 1];
        snakey[i] = snakey[i - 1];
    }

    if (fangxiang.equals("right")) {
    //让头部加25,上面的循环才起作用
        snakex[0] = snakex[0] + 25;
        //用于边界判断
        if (snakex[0] > 850) {
            snakex[0] = 25;
        }
    } else if (fangxiang.equals("up")) {
        snakey[0]=snakey[0]-25;
        if (snakey[0]<135){snakey[0]=645;}
    } else if (fangxiang.equals("down")) {
      
        snakey[0]=snakey[0]+25;
        if (snakey[0]>620){snakey[0]=125;}
    } else if (fangxiang.equals("left")) {
        snakex[0] = snakex[0] - 25;
    if (snakex[0] < 25) {snakex[0]=850;}}
     for (int i = 1; i < length; i++) {
         if(snakex[0]==snakex[i]&&snakey[0]==snakey[i]){
             fail=true;
         }
     }
    repaint();//极其关键
}
    }
    }

最后,提醒几点自己本人写这个代码犯过的错
repaint();这行代码一定记得使用
jFrame.setVisible(true); 这行代码在窗口的类中一定记得放在最后,不要放在添加面板代码的前面,否则你的键盘监听器会失效
这是写好后的窗口
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值