贪食蛇(Snake)

 

[D:\贪食蛇素材statics]:

 

package Game_snake;

import javax.swing.*;

public class StartGrame
{
   public static void main(String[] args)
  {
       JFrame frame=new JFrame("贪食蛇");
       frame.setBounds(10,10,900,720);
       frame.setResizable(false);
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       //2.画板jpanel 可以加入到Frame
       frame.add(new GamePanel());//设置颜色
       frame.setVisible(true);

  }
}

 

package Game_snake;

import javax.swing.*;
import java.net.URL;

//存放外部数据
public class Data
{
   //头部的图片   URL 定位资源图片   imageIcon :图片
   public static URL headrURL=Data.class.getResource("/statics/header.png");         //当前这个类点class获取它的反对象
   public static ImageIcon header=new ImageIcon(headrURL);
   //头部

   public static URL upURL=Data.class.getResource("/statics/up.png");
   public static URL downURL=Data.class.getResource("/statics/down.png");
   public static URL leftURL=Data.class.getResource("/statics/left.png");
   public static URL rightURL=Data.class.getResource("/statics/right.png");
   public static ImageIcon up=new ImageIcon(upURL);
   public static ImageIcon down=new ImageIcon(downURL);
   public static ImageIcon left=new ImageIcon(leftURL);
   public static ImageIcon right=new ImageIcon(rightURL);
   //身体
   public static URL bodyURL=Data.class.getResource("/statics/body.png");
   public static ImageIcon body=new ImageIcon(bodyURL);
   //食物
   public static URL foodURL=Data.class.getResource("/statics/food.png");
   public static ImageIcon food=new ImageIcon(foodURL);
}

 

package Game_snake;

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 GamePanel extends JPanel implements KeyListener, ActionListener {//ActionListener事件监听在Timer按alt+enter
   int lengt;//蛇的长度
   int [] snakex=new int[600];//蛇的坐标x
   int [] snakey=new int[500];//蛇的坐标y
   String fx;//R右 //L左 U 上 D 下

   boolean isStart=false;//游戏是否开始
   Timer timer=new Timer(100,this);//定时器     每隔一百毫秒动一次
   //定义一个食物
   int foodx;
   int foody;
   Random random=new Random();   //随机数的类

   //死亡判断
   boolean isFail=false;

   //积分系统
   int score;


//构造器 调用初始化方法
   public GamePanel()
  {
       init();
       //获取键盘的监听事件
      this.setFocusable(true);//键盘焦点聚集在游戏上面
       this.addKeyListener(this);
       timer.start();//(构造器也得)让时间动起来 如果在初始化的时候不让它运行,计时器就不能动了,就调用不到actionPerformed方法

  }


   //初始化数据
   public void init()
  {
       lengt=3;
       snakex[0]=100;snakey[0]=100; //头的位置坐标
       snakex[1]=75;snakey[1]=100; //第一个身体
       snakex[2]=50;snakey[2]=100; //第二个身体
       fx="R";
       foodx=25+25*random.nextInt(34);//25开始加上游戏的屏幕坐标
       foody=75+25*random.nextInt(24);

       score=0;
  }


   //画板:画界面,画蛇
   //Graphics:画笔
   @Override
   protected void paintComponent(Graphics g) {//重写父类的方法(画面版方法)
       super.paintComponent(g);//调用父类(清屏)
       //2.画板jpanel 可以加入到Frame
       this.setBackground(Color.BLACK);//设置背景的颜色
       //绘制头部广告栏
       Data.header.paintIcon(this,g,25,11);//绘画位置 g是画笔 xy为边界
       //绘制游戏区域
       g.fillRect(25,75,850,600);            //填充矩形
       //画一条静态小蛇
       if(fx.equals("R"))
      {
           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 (int i=1;i<lengt;i++)
      {
           Data.body.paintIcon(this,g,snakex[i],snakey[i]);//蛇的身体长度通过length来控制
      }

       //画积分
       g.setColor(Color.white);
       g.setFont(new Font("微软雅黑",Font.BOLD,18));//字体
       g.drawString("长度:"+lengt,750,35);//位置
       g.drawString("分数:"+score,750,50);


       //画食物
       Data.food.paintIcon(this,g,foodx,foody);

       //游戏提示:是否开始
       if (isStart==false)
      {
           //画一个文字,String
           g.setColor(Color.WHITE);//设置画笔颜色
           g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
           g.drawString("按下空格开始游戏",300,300);
      }
       //失败提醒
       if (isFail)
      {
           //画一个文字,String
           g.setColor(Color.RED);//设置画笔颜色
           g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体
           g.drawString("游戏失败,按下空格从新开始",200,300);
      }
  }



   @Override
   //键盘监听
   public void keyTyped(KeyEvent e) {
       //键盘按下,弹起 :敲击
  }

   //接收键盘的输入:监听
   @Override
   public void keyPressed(KeyEvent e) {//键盘按下,未释放

//获取按下的键盘是哪个键
       int keyCode= e.getKeyCode();
       if (keyCode==KeyEvent.VK_SPACE)//如果按下是空格键
      {
           if (isFail)//失败, 游戏在来一遍
          {
               isFail=false;
               init();//重新初始化游戏
          }else {//如果不是失败而按的空格就是暂停游戏
               isStart=!isStart;
          }
          // isStart = !isStart;//启动或者暂停
           repaint();//刷新界面
      }
       //键盘控制走向
       if (keyCode==KeyEvent.VK_LEFT)
      {
           fx="L";
      }else if (keyCode==KeyEvent.VK_RIGHT)
      {
           fx="R";
      }else if (keyCode==KeyEvent.VK_UP)
      {
           fx="U";
      }else if (keyCode==KeyEvent.VK_DOWN)
      {
           fx="D";
      }
  }

   @Override
   public void keyReleased(KeyEvent e) {
//释放某个建
  }



   @Override
   //定时器,监听时间,帧:执行定时操作
   public void actionPerformed(ActionEvent e) {//实行定时操作
       //Timer实现这个接口,alt+enter
       //如果游戏处于开始转态 。并且游戏没有结束加上isFail==false
       if (isStart && isFail==false)
      {
           //右移
           for (int i=lengt-1;i>0;i--)//减一就是减掉蛇的头部 。 除了脑袋,身体都向前移动 。 i>0就一直往前走
          {
               snakex[i]=snakex[i-1];//后面一节的身体给前面那节它就会往前拱了 (就是后面的值不停的刷新过去)
               snakey[i]=snakey[i-1];
          }
           //通过控制方向让头部移动
           if (fx.equals("R"))
          {
               snakex[0]=snakex[0]+25;//头部右边移动
               //边界判断
               if (snakex[0]>850)//(边界判断)
              {
                  // snakex[0]=25;//回到最开始的位置
                   isFail=true;
              }
          }else if (fx.equals("L"))
              {
                   snakex[0]=snakex[0]-25;//头部左边移动
                   //边界判断
                   if (snakex[0]<25)//(边界判断)
                  {
                       snakex[0]=850;//回到最开始的位置
                  }
              }else if (fx.equals("U"))
          {
               snakey[0]=snakey[0]-25;//头部上边移动   往上走就是y轴
               //边界判断
               if (snakey[0]<75)//(边界判断)
              {
                   snakey[0]=650;//回到最开始的位置
              }
          }else if (fx.equals("D"))
          {
               snakey[0]=snakey[0]+25;//头部下边移动
               //边界判断
              if (snakey[0]>650)//(边界判断)
              {
                   snakey[0]=75;//回到最开始的位置
              }
          }
           //如果小蛇的头和食物坐标重合了
           if (snakex[0]==foodx&&snakey[0]==foody)
          {
               //长度加一
               lengt++;
               score=score+10;//吃到食物就增加10分
               //重新生成食物
               foodx=25+25*random.nextInt(34);//25开始加上游戏的屏幕坐标
               foody=75+25*random.nextInt(24);
          }
           //结束判断
           for(int i=1;i<lengt;i++)
          {
               if (snakex[0]==snakex[i] && snakey[0]==snakey[i])//如果小蛇头部与身体重合了
              {
                   isFail=true;//游戏失败
              }
          }
           //每次移动完做一件事情,就刷新界面   如果不刷新,游戏就动不了
           repaint();
      }
       timer.start();//(时间动起来) 让计时器动起来   必须要启动才能运行否则运行不了
  }

}
 
posted @ 2022-07-23 13:29  zjw_rp  阅读(107)  评论(0编辑  收藏  举报