贪吃蛇之添加毒食物

 

package WyktJpxc;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
//创建一个游戏界面类,也是主启动类
public class SrartGame {

    public static void main(String[] args) {
        //创建游戏窗体
        JFrame frame=new JFrame("贪吃蛇");
        //关闭窗口事件
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //设置窗口的初始位置及大小,注:每个游戏窗口的大小需要进行计算,不能随便写
        frame.setBounds(100,100,900,750);
        //设置窗口大小不可变
        frame.setResizable(false);
        //游戏界面都应该在面板上,把游戏面板添加到游戏中
        frame.add(new GamePanel());


        //设置窗口可见性
        frame.setVisible(true);
    }
}

//创建游戏的面板,并实现监听接口好,然后创建监听内部类,再实现定时器接口让小蛇动起来
class GamePanel extends JPanel implements KeyListener, ActionListener {

    //定义蛇的数据结构
     int length;//蛇的长度


    //用蛇活动的界面框的宽和高都除以他的x轴数值,然后两个数再相*,得到这个蛇最长的节数,经过计算结果为816,所以我们现在创建蛇的x坐标和y坐标的数值都去除25,再相*,不要小于816就可以了,为什么要用25除呢,因为我们设置蛇的坐标是5*25
    int snakeX[]=new int[600];//蛇的x坐标25*25
    int snakeY[]=new int[500];//蛇的Y坐标25*25


    //创建小蛇的初始方向,向右
    String fx;

    //创建食物的坐标
    int foodx;
    int foody;
    //创建有毒食物
    int Poisonousfoodx;
    int Poisonousfoody;
    //创建一个食物的随机数组
    Random random=new Random();
    //创建一个有毒食物的随机数组
    Random random1=new Random();


    //创建游戏当前状态变量,开始,停止
    boolean isStart=false;//默认停止

    //游戏失败状态
    boolean isFail=false;

    //进行积分统计
    int score;

    //创建一个定时器时间属性
     int date=110;

    //定时器,Timer:时间
    Timer timer=new Timer(date,this);//100毫秒执行一次定时器,this.监听当前类,

    //创建构造器
    public GamePanel(){
        //调用init方法
        init();
        //获得焦点和键盘事件
        this.setFocusable(true);//获得焦点事件,设置为true后可以获取键盘的一些距焦事件
        //设置为true后可以获取键盘的一些距焦事件
        this.addKeyListener(this);//获得,键盘监听事件因为我们这个GamePanel类有继承KeyListener的事件监听接口,所以我们只需要获取当前类就可以了,如果写在其他类的话,我们只需要new一个类的监听器就可以了

        timer.start();//游戏一开始定时器就启动

    }

    //创建游戏初始化方法
    public void init(){
        //初始化小蛇的长度为3,并设置小蛇初始化坐标为100的位置上
        length=3;
        snakeY[0]=100;snakeX[0]=100;//小蛇头的坐标,脑袋
        snakeY[1]=100;snakeX[1]=75;//第一个身体的坐标
        snakeY[2]=100;snakeX[2]=50;//第二个身体坐标
        fx="R";  //小蛇的初始方向,向右

        //初始化食物坐标,把食物随便分布在界面上
        foodx=25+25*random.nextInt(34);//*以一个随机的数据random.nextInt(34);34:等于游戏界面x轴除以25等于多少,这个位置我们就写多少,这个位置写对,那食物只不会超出游戏界面 的边界
        foody=75+25*random.nextInt(24);//同上,但这个是为什么要*75呢,因为头部的表头图片占用了50的坐标位置,所以我们需要减去
        System.out.println("foodx"+foodx);
        System.out.println(foody);
        score=0;//默认积分为0

        //初始化毒食物坐标,把食物随便分布在界面上
            Poisonousfoodx = 25 + 25 * random1.nextInt(34);
            Poisonousfoody= 175 + 25 * random1.nextInt(24);
            System.out.println("Poisonousfoodx" + Poisonousfoodx);
            System.out.println(Poisonousfoody);



    }

    //绘制面板的方法,这个方法是JPanel类中自带的画组件方法,我们游戏所有的东西,都使用这个画笔来画
    protected void paintComponent(Graphics g){
        super.paintComponent(g);//这个调用父类的方法不用清除,这个方法是只,如果UI等于null,那他就会自动的清屏一下
        //绘制静态的面板
        this.setBackground(Color.cyan);//为面板设置一个颜色
        //将头部图片header图片画到,“this”:当前面板,g:用当前方法中的画笔。xy坐标分别为:25,11
        Data.header.paintIcon(this,g,25,11);
        //绘制蛇活动的黑色界面框,x坐标要和头部图片的x坐标一致
        g.fillRect(25,75,850,600);

        //把积分画到面板上去
        g.setColor(Color.white);//设置颜色为白
        g.setFont(new Font("微软雅黑",Font.BOLD,18));//Font.BOLD:字体为粗体,18号;
        //把食物画到游戏界面上
        Data.food.paintIcon(this,g,foodx,foody);//this:当前类,画笔:g,坐标:foodx,foody

        //把有毒食物画到画板上
        Data.Poisonousfood.paintIcon(this,g,Poisonousfoodx,Poisonousfoody);//this:当前类,画笔:g

        //获取蛇的长度
        g.drawString("长度"+length,750,35);//这个“长度”画到坐标为:750,35的位置
        g.drawString("积分"+score,750,55);//把这个”积分“画到坐标为:750,35的位置


        //判断小蛇方向
        if (fx.equals("R")){//右

            //把小蛇的图片画到面板上去,,“this”:当前面板,g:用当前方法中的画笔。xy坐标分别为:snakeX[0],snakeY[0]
            Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);//蛇初始化向右,并且方向要通过判断来获取方向
        }else if(fx.equals("L")){//左

            Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(fx.equals("U")){//上

            Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);
        }else if(fx.equals("D")){//下

            Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);
        }


        //通过for循环,动态添加小蛇的长度
        for(int i=1;i<length;i++){
            Data.body.paintIcon(this,g,snakeX[i],snakeY[i]);//身体
        }




        //游戏状态
        if(isStart==false){//如果isStart是flast那就画一段文字,drawString :画一个String文字
            //设置画笔颜色为白色
            g.setColor(Color.white);
            //设置字体
            g.setFont(new Font("微软雅黑",Font.BOLD,40));//Font.BOLD:字体为粗体,40号
            g.drawString("按下空格开始游戏",300,300);//将“按下空格开始游戏”内容画到300,300坐标处的位置
        }
        //把失败状态画上去
        if(isFail){//默认为true
            //设置字体
            g.setFont(new Font("微软雅黑",Font.BOLD,40));//Font.BOLD:字体为粗体,40号
            g.drawString("失败 按下空格重新游戏",300,300);//将“按下空格开始游戏”内容画到300,300坐标处的位置
        }

    }


    //事件监听:
    //的定时方法,需要通过固定的事件来刷新,如:1秒10次
    //有了上面的Timer定时器,那我们就可以让小蛇动起来
    @Override
    public void actionPerformed(ActionEvent e) {
        if(isStart&&isFail==false){//如果游戏是开始状态,并且失败状态为false,就让小蛇动起来
            //吃食物
            if(snakeX[0]==foodx&&snakeY[0]==foody){//重合
                length++;//长度加1 //当设置吃一个食物能加10个长度是,运行游戏失败后,再吃到食物会出现在上一回合的死亡的位置出现上一回合蛇的身体,如果撞到会正常的失败,目前无法解决,先记录
                score=score+10;//分数也加10
                //长度+1后,再次随机重新生成食物
                //初始化食物坐标,把食物随便分布在界面上
                foodx=25+25*random.nextInt(34);//*以一个随机的数据random.nextInt(34);34:等于游戏界面x轴除以25等于多少,这个位置我们就写多少,这个位置写对,那食物只不会超出游戏界面 的边界
                foody=75+25*random.nextInt(24);//同上,但这个是为什么要*75呢,因为头部的表头图片占用了50的坐标位置,所以我们需要减去
        
        //当好食物被吃了,也随机刷新毒食物
        Poisonousfoodx=25+25*random1.nextInt(34);
                Poisonousfoody=75+25*random1.nextInt(24);            

        //判断吃到毒食物
            }else if(snakeX[0]==Poisonousfoodx&&snakeY[0]==Poisonousfoody){//重合
               length =length-3;//长度-3
                score=score-30;//分数也-30
                //长度+1后,再次随机重新生成食物
                //初始化食物坐标,把食物随便分布在界面上
                Poisonousfoodx=25+25*random1.nextInt(34);
                Poisonousfoody=75+25*random1.nextInt(24);

            }


            //右移,后一节移动到前一节的位置
            for(int i=length-1;i>0;i--){//让身体向前移,length-1:-1是为了减去头部 i>0:这样就是为了让每一个身体都动起来
                snakeX[i]=snakeX[i-1];//向前移动一节,因为当前设置头部一直会动,那如果身体只有两节,那相当于原本身体等于2,那snakeX[i-1]后等于1,那snakeX[i-1]又把值赋给了snakeX[i],又等于:snakeX[1]=snakeX[0],1变成0,所以在界面上会出现在向前移动,所以只要头部会移动那身体也会移动;
                snakeY[i]=snakeY[i-1];//同上理
            }
            //挖制蛇头的走
            if(fx.equals("R")){
                snakeX[0]=snakeX[0]+25;//让蛇头右前移动
                //判断向右移动的边界,如果小蛇大于游戏的边界
                if(snakeX[0]>850){//游戏界面最大为816,所以大于850,就相当于超出界面
                    snakeX[0]=25;//界面开始的坐标
                }
            }else if(fx.equals("L")){
                snakeX[0]=snakeX[0]-25;//向左移动
                if(snakeX[0]<25){//游戏界面最小的坐标为25,所以小于25,就相当于超出界面
                    snakeX[0]=850;//界面开始的坐标
                }
            }else if(fx.equals("U")){//上
                snakeY[0]=snakeY[0]-25;
                if(snakeY[0]<75){//因为有头部图片,占用了一些位置,所以是75,就相当于超出界面
                    snakeY[0]=650;//界面y从上到下轴的距离为650
                }

            }else if(fx.equals("D")){
                snakeY[0]=snakeY[0]+25;
                if(snakeY[0]>650){//因为有头部图片,占用了一些位置,所以是75,就相当于超出界面
                    snakeY[0]=75;//界面y从上到下轴的距离为650
                }
            }

            //判定:撞到自己就算失败
            for(int i=1;i<length;i++){//i=1,不能把头部算进去,不然,会直接判定为撞到自己
                if(snakeX[0]==snakeX[i]&&snakeY[0]==snakeY[i]){//如果头坐标和尾部坐标重合就判定为失败,snakeX[0]:头snakeX[i]:尾
                    isFail=true;
                }
            }



            repaint();//重画页面
        }
        timer.start();//定时器开启

    }
    //实现监听接口的方法
    //按压方法
    @Override
    public void keyPressed(KeyEvent e) {
        //获得键盘的按键
        int KeyCode=e.getKeyCode();//获得键盘按键是那一个
        if(KeyCode==KeyEvent.VK_SPACE){//VK_SPACE:空格,如果按下的是空格键
            if(isFail==true){//
                //重新开始游戏
                isFail=false;
                init();//重新调用初始化方法
            }else{
                //暂停游戏
                isStart=!isStart;//取反,不能写死


            }
            repaint();//重画页面
        }
        //小蛇移动,这个判断可以改小蛇脑袋的方向
        if(KeyCode==KeyEvent.VK_UP){//上
            fx="U";
        }else if(KeyCode==KeyEvent.VK_DOWN){//下
            fx="D";
        }else if(KeyCode==KeyEvent.VK_LEFT){//左
            fx="L";
        }else if(KeyCode==KeyEvent.VK_RIGHT){//右
            fx="R";
        }
    }


    @Override
    public void keyTyped(KeyEvent e) {

    }



    @Override
    public void keyReleased(KeyEvent e) {

    }


}

 

package WyktJpxc;

import javax.swing.*;
import java.net.URL;
import java.util.Date;
//创建游戏的数据中心,来存放游戏中的所有数据
class Data{
    //使用绝对路径来获取图片的位置 “/”:当前项目
    public static URL headerURL= Date.class.getResource("/statics/header.png");//表示从“/”:当项目的statics包中获取到名为header.png的头部图片
    //把头部图片转化为图标画到游戏界面中
    public static ImageIcon header=new ImageIcon(headerURL);
    
    public static URL upURL=Date.class.getResource("/statics/up.png");//贪吃蛇向上的图片位置
      //把转向上的图片转化为图标画到游戏界面中
     public static ImageIcon up=new ImageIcon(upURL);
     
    public static URL downURL=Date.class.getResource("/statics/down.png");//贪吃蛇下上的图片位置
     //把转向下的图片转化为图标画到游戏界面中
     public static ImageIcon down=new ImageIcon(downURL);
     
    public static URL leftURL=Date.class.getResource("/statics/left.png");//贪吃蛇向左的图片位置
     //把转向左的图片转化为图标画到游戏界面中
     public static ImageIcon left=new ImageIcon(leftURL);
     
    public static URL rightURL=Date.class.getResource("/statics/right.png");//贪吃蛇向右的图片位置
     //把转向右的图片转化为图标画到游戏界面中
     public static ImageIcon right=new ImageIcon(rightURL);
     
    public static URL bodyURL=Date.class.getResource("/statics/body.png");//贪吃蛇身体的图片位置
      //把身体的图片转化为图标画到游戏界面中
     public static ImageIcon body=new ImageIcon(bodyURL);
     
    public static URL foodURL=Date.class.getResource("/statics/food.png");//贪吃蛇食物的图片位置
      //把食物的图片转化为图标画到游戏界面中
     public static ImageIcon food=new ImageIcon(foodURL);

    public static URL PoisonousfoodURL1=Date.class.getResource("/statics/Poisonousfood.png");//贪吃蛇有毒食物的图片位置
    //把食物的图片转化为图标画到游戏界面中
    public static ImageIcon Poisonousfood=new ImageIcon(PoisonousfoodURL1);
     
}

 

posted @ 2022-04-21 23:14  hollg  阅读(174)  评论(9)    收藏  举报