贪吃蛇之小蛇吃食物长大
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.net.URL; import java.util.Date; import java.util.Random; import java.util.Scanner; //创建一个游戏界面类,也是主启动类 public class SrartGame { public static void main(String[] args) { //创建游戏窗体 JFrame frame=new JFrame("贪吃蛇"); //关闭窗口事件 frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置窗口的初始位置及大小,注:每个游戏窗口的大小需要进行计算,不能随便写 frame.setBounds(100,100,900,700); //设置窗口大小不可变 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; //创建一个食物的随机数组 Random random=new Random(); //创建游戏当前状态变量,开始,停止 boolean isStart=false;//默认停止 //定时器,Timer:时间 Timer timer=new Timer(100,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的坐标位置,所以我们需要减去 } //绘制面板的方法,这个方法是JPanel类中自带的画组件方法,我们游戏所有的东西,都使用这个画笔来画 protected void paintComponent(Graphics g){ super.paintComponent(g);//这个调用父类的方法不用清除,这个方法是只,如果UI等于null,那他就会自动的清屏一下 //绘制静态的面板 this.setBackground(Color.BLACK);//为面板设置一个颜色 //将头部图片header图片画到,“this”:当前面板,g:用当前方法中的画笔。xy坐标分别为:25,11 Data.header.paintIcon(this,g,25,11); //绘制蛇活动的黑色界面框,x坐标要和头部图片的x坐标一致 g.fillRect(25,75,850,600); //判断小蛇方向 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]);//身体 } //把食物画到游戏界面上 Data.food.paintIcon(this,g,foodx,foody);//this:当前类,画笔:g,坐标:foodx,foody //游戏状态 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坐标处的位置 } } //事件监听: //的定时方法,需要通过固定的事件来刷新,如:1秒10次 //有了上面的Timer定时器,那我们就可以让小蛇动起来 @Override public void actionPerformed(ActionEvent e) { if(isStart){//如果游戏是开始状态,就让小蛇起来 //吃食物 if(snakeX[0]==foodx&&snakeY[0]==foody){//重合 length++;//长度加1 //长度+1后,再次随机重新生成食物 //初始化食物坐标,把食物随便分布在界面上 foodx=25+25*random.nextInt(34);//*以一个随机的数据random.nextInt(34);34:等于游戏界面x轴除以25等于多少,这个位置我们就写多少,这个位置写对,那食物只不会超出游戏界面 的边界 foody=75+25*random.nextInt(24);//同上,但这个是为什么要*75呢,因为头部的表头图片占用了50的坐标位置,所以我们需要减去 } //右移,后一节移动到前一节的位置 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 } } repaint();//重画页面 } timer.start();//定时器开启 } //实现监听接口的方法 //按压方法 @Override public void keyPressed(KeyEvent e) { //获得键盘的按键 int KeyCode=e.getKeyCode();//获得键盘按键是那一个 if(KeyCode==KeyEvent.VK_SPACE){//VK_SPACE:空格,如果按下的是空格键 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); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义