Gui实战之贪吃蛇

|本项目源于【狂神说Java】GUI编程入门到游戏实战

B站收UP主:遇见狂神说。即可看见教程

或者点击链接GUI编程入门到游戏实战

贪吃蛇

目录

贪吃蛇

一、初始静态界面

1、主启动类:

2、数据中心类

3、游戏面板类

二、小蛇绘制

三、小蛇移动

定时器实现小蛇移动

小蛇方向控制

小蛇吃食物

小蛇失败判定

添加游戏数据面板

四、Data数据类

五、StartGame 主函数开启

六、GamePanel 游戏面板

七、游戏素材

八、总结:


一、初始静态界面
1、主启动类:

游戏主窗口的创建,大小不可变

 package com.gui.lesson01.game;
 ​
 import javax.swing.*;
 ​
 public class StartGame {
 ​
     public static void main(String[] args) {
         JFrame frame = new JFrame();
 ​
         frame.setBounds(10,10,815,630);
         frame.setResizable(false);//窗口大小不可变
         frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
         frame.setVisible(true);
 ​
         //正常游戏界面都应该在面板上
         frame.add(new GamePanel());
     }
 }
 ​
2、数据中心类
 package com.gui.lesson01.game;
 ​
 import javax.swing.*;
 import java.net.URL;
 ​
 public class Data {
     //使用相对路径存放素材
     static URL headURL = Data.class.getResource("statics/head.png");
     static URL upURL = Data.class.getResource("statics/up.png");
     static URL downURL = Data.class.getResource("statics/down.png");
     static URL leftURL = Data.class.getResource("statics/left.png");
     static URL rightURL = Data.class.getResource("statics/right.png");
     static URL bodyURL = Data.class.getResource("statics/body.png");
     static URL foodURL = Data.class.getResource("statics/food.png");
 ​
     //将上面获取的图片绘制成图标
     static ImageIcon head = new ImageIcon(headURL);
     static ImageIcon up = new ImageIcon(upURL);
     static ImageIcon down = new ImageIcon(downURL);
     static ImageIcon left = new ImageIcon(leftURL);
     static ImageIcon right = new ImageIcon(rightURL);
     static ImageIcon body = new ImageIcon(bodyURL);
     static ImageIcon food = new ImageIcon(foodURL);
 }
 ​
3、游戏面板类
 package com.gui.lesson01.game;
 ​
 import javax.swing.*;
 import java.awt.*;
 ​
 public class GamePanel extends JPanel {
     //绘制组件函数,我们在游戏中所有的东西使用画笔来画
 ​
     @Override
     protected void paintComponent(Graphics g) {
         super.paintComponent(g);//清屏作用,不用出现闪屏
         //绘制静态面板
         this.setBackground(Color.black);
         Data.head.paintIcon(this,g,25,0);//游戏头部,广告栏
         g.fillRect(25,65,750,500);//默认游戏界面
     }
 }
 ​

二、小蛇绘制
  • 修改GamePanel类,并且赋予小蛇初始位置

修改GamePanel类

 package com.gui.lesson01.game;
 ​
 import javax.swing.*;
 import java.awt.*;
 ​
 public class GamePanel extends JPanel {
 ​
     //定义蛇的数据结构
     int length;//蛇的长度
     int[] snakeX = new int[600];
     int[] snakeY = new int[500];
     //构造器
     public GamePanel(){
         init();
     }
 ​
     //初始化小蛇
     public void init(){
         length = 1;
         snakeX[0] = 100;snakeY[0] = 100;//脑袋坐标
         snakeX[1] = 75;snakeY[1] = 100;//第一块身体坐标
         snakeX[2] = 25;snakeY[2] = 100;//第二块身体坐标
     }
 ​
     //绘制组件函数,我们在游戏中所有的东西使用画笔来画
     @Override
     protected void paintComponent(Graphics g) {
         super.paintComponent(g);//清屏作用,不用出现闪屏
         //绘制静态面板
         this.setBackground(Color.BLUE);
         Data.header.paintIcon(this,g,25,0);//游戏头部,广告栏
         g.fillRect(25,65,750,500);//默认游戏界面
 ​
         //绘制静态的小蛇
         Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
         for (int i = 1; i < length; i++) {
             Data.body.paintIcon(this,g,snakeX[i],snakeY[i] );//身体的坐标
         }
     }
 }
 ​

新增游戏状态

 package com.gui.lesson01.game;
 ​
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 ​
 public class GamePanel extends JPanel implements KeyListener {
 ​
     //定义蛇的数据结构
     int length;//蛇的长度
     int[] snakeX = new int[600];
     int[] snakeY = new int[500];
     String fx;//蛇的初始方向
     //游戏状态,默认不开始
     boolean isStart = false;
 ​
     //构造器
     public GamePanel(){
         init();
         //获得焦点和键盘事件
         this.setFocusable(true);
         this.addKeyListener(this);
     }
 ​
     //初始化小蛇
     public void init(){
         length = 3;
         snakeX[0] = 100;snakeY[0] = 100;//脑袋坐标
         snakeX[1] = 75;snakeY[1] = 100;//第一块身体坐标
         snakeX[2] = 25;snakeY[2] = 100;//第二块身体坐标
         fx = "R";//初始方向向右
     }
 ​
     //绘制组件函数,我们在游戏中所有的东西使用画笔来画
     @Override
     protected void paintComponent(Graphics g) {
         super.paintComponent(g);//清屏作用,不用出现闪屏
         //1.绘制静态面板
         this.setBackground(Color.BLUE);
         Data.header.paintIcon(this,g,25,0);//游戏头部,广告栏
         g.fillRect(25,65,750,500);//默认游戏界面
 ​
         //2.绘制静态的小蛇
         Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
         for (int i = 1; i < length; i++) {
             Data.body.paintIcon(this,g,snakeX[i],snakeY[i] );//身体的坐标
         }
         //3.画游戏状态
         if (!isStart){
             g.setColor(Color.white);
             g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体,第二个参数加粗
             g.drawString("按下空格开始游戏!",300,450);
 ​
         }
     }
 ​
     //游戏状态的键盘监听事件
     @Override
     public void keyPressed(KeyEvent e) {
         int keyCode = e.getKeyCode();//获得键盘按键是哪一个
         if (keyCode == KeyEvent.VK_SPACE){//如果按下键盘,则取反游戏状态
             isStart = !isStart;
             repaint();
         }
 ​
     }
 ​
 ​
     @Override
     public void keyTyped(KeyEvent e) { }
     @Override
     public void keyReleased(KeyEvent e) { }
 }
 ​

三、小蛇移动
定时器实现小蛇移动
  • 想要小蛇动起来,即要用到定时器及时更新面板状态

  • 面板实现ActionListener,重写actionPerformed方法

修改GamePanel类

 package com.gui.lesson01.game;
 ​
 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;
 ​
 public class GamePanel extends JPanel implements KeyListener, ActionListener {
 ​
     //定义蛇的数据结构
     int length;//蛇的长度
     int[] snakeX = new int[600];
     int[] snakeY = new int[500];
     String fx;//蛇的初始方向
     //游戏状态,默认不开始
     boolean isStart = false;
 ​
     //定时器
 //    Timer timer = new Timer(100,this);//监听当前类,100毫秒刷新一次
     Timer timer = new Timer(100,this);
 ​
     //构造器
     public GamePanel(){
         init();
         //获得焦点和键盘事件
         this.setFocusable(true);//获得焦点事件
         this.addKeyListener(this);//获得事件监听事件
         timer.start();//游戏一开始就开始计时
     }
 ​
     //初始化小蛇
     public void init(){
         length = 3;
         snakeX[0] = 100;snakeY[0] = 100;//脑袋坐标
         snakeX[1] = 75;snakeY[1] = 100;//第一块身体坐标
         snakeX[2] = 25;snakeY[2] = 100;//第二块身体坐标
         fx = "R";//初始方向向右
     }
 ​
     //绘制组件函数,我们在游戏中所有的东西使用画笔来画
     @Override
     protected void paintComponent(Graphics g) {
         super.paintComponent(g);//清屏作用,不用出现闪屏
         //1.绘制静态面板
         this.setBackground(Color.BLUE);
         Data.header.paintIcon(this,g,25,11);//游戏头部,广告栏
         g.fillRect(25,65,750,500);//默认游戏界面
 ​
         //2.绘制静态的小蛇
         Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
         for (int i = 1; i < length; i++) {
             Data.body.paintIcon(this,g,snakeX[i],snakeY[i] );//身体的坐标
         }
         //3.画游戏状态
         if (!isStart){
             g.setColor(Color.white);
             g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体,第二个参数加粗
             g.drawString("按下空格开始游戏!",300,450);
 ​
         }
     }
 ​
     //游戏状态的键盘监听事件
     @Override
     public void keyPressed(KeyEvent e) {
         int keyCode = e.getKeyCode();//获得键盘按键是哪一个
         if (keyCode == KeyEvent.VK_SPACE){//如果按下键盘,则取反游戏状态
             isStart = !isStart;
             repaint();
         }
 ​
     }
     //事件监听-需要用到固定时间来刷新,1S10次
     @Override
     public void actionPerformed(ActionEvent e) {
         if(!isStart){//如果是开始状态。就让小蛇动起来
             //移动
             for (int i = length-1; i > 0 ; i--) {//后一节的位置移动到前一节
                 snakeX[i] = snakeX[i-1];
                 snakeY[i] = snakeY[i-1];
 ​
             }
             if(fx.equals("R")){
                 snakeX[0] = snakeX[0] + 25;
             }
             //边界判断
             if(snakeX[0]>750){
                 snakeX[0] = 25;
             }
             repaint();//重画页面
         }
         timer.start();//定时开启~
     }
 ​
 ​
     @Override
     public void keyTyped(KeyEvent e) { }
     @Override
     public void keyReleased(KeyEvent e) { }
 }
 ​
小蛇方向控制
  • 控制方向则要严格计算每次坐标的大小

  • 比如向上走超出边框则马上从最底再次进入游戏界面

  • 例如蛇走到顶端,下一步出现在底端的坐标则刚好放在最下方的时刻,即为(游戏界面最底端到最顶端的距离-蛇头宽度)

修改GamePanel类

 package com.gui.lesson01.game;
 ​
 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;
 ​
 public class GamePanel extends JPanel implements KeyListener, ActionListener {
     //定义蛇的数据结构
     int length;//蛇的长度
     int[] snakeX = new int[600];
     int[] snakeY = new int[500];
     String fx;//蛇的初始方向
     //游戏状态,默认不开始
     boolean isStart = false;
 ​
     //定时器
     Timer timer = new Timer(100,this);//监听当前类,100毫秒刷新一次
 ​
     //构造器
     public GamePanel(){
         init();
         //获得焦点和键盘事件
         this.setFocusable(true);//获得焦点事件
         this.addKeyListener(this);//获得事件监听事件
         timer.start();//游戏一开始就开始计时
     }
 ​
     //初始化小蛇
     public void init(){
         length = 3;
         snakeX[0] = 100;snakeY[0] = 100;//脑袋坐标
         snakeX[1] = 75;snakeY[1] = 100;//第一块身体坐标
         snakeX[2] = 25;snakeY[2] = 100;//第二块身体坐标
         fx = "R";//初始方向向右
     }
 ​
     //绘制组件函数,我们在游戏中所有的东西使用画笔来画
     @Override
     protected void paintComponent(Graphics g) {
         super.paintComponent(g);//清屏作用,不用出现闪屏
         //1.绘制静态面板
         this.setBackground(Color.BLUE);
         Data.header.paintIcon(this,g,25,11);//游戏头部,广告栏
         g.fillRect(25,65,750,500);//默认游戏界面
 ​
         //把小蛇画上去
         if(fx.equals("R")){
             Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
         }else if(fx.equals("up")){
             Data.up.paintIcon(this,g,snakeX[0],snakeY[0]);
         }else if(fx.equals("down")){
             Data.down.paintIcon(this,g,snakeX[0],snakeY[0]);
         }else if(fx.equals("L")){
             Data.left.paintIcon(this,g,snakeX[0],snakeY[0]);
         }
         //2.绘制静态的小蛇
         //Data.right.paintIcon(this,g,snakeX[0],snakeY[0]);
         for (int i = 1; i < length; i++) {
             Data.body.paintIcon(this,g,snakeX[i],snakeY[i] );//身体的坐标
         }
         //3.画游戏状态
         if (!isStart){
             g.setColor(Color.white);
             g.setFont(new Font("微软雅黑",Font.BOLD,40));//设置字体,第二个参数加粗
             g.drawString("按下空格开始游戏!",300,450);
 ​
         }
     }
 ​
     //游戏状态的键盘监听事件
     @Override
     public void keyPressed(KeyEvent e) {
         int keyCode = e.getKeyCode();//获得键盘按键是哪一个
         if (keyCode == KeyEvent.VK_SPACE){//如果按下键盘,则取反游戏状态
             isStart = !isStart;
             repaint();
         }
         //小蛇移动监听
         if (keyCode==KeyEvent.VK_UP){
             fx="up";
         }else if (keyCode==KeyEvent.VK_DOWN){
             fx="down";
         }else if (keyCode==KeyEvent.VK_LEFT){
             fx="left";
         }else if (keyCode==KeyEvent.VK_RIGHT){
             fx="right";
         }
     }
     //事件监听-需要用到固定时间来刷新,1S10次
     @Override
     public void actionPerformed(ActionEvent e) {
         if(!isStart){//如果是开始状态。就让小蛇动起来
             //移动
             for (int i = length-1; i > 0 ; i--) {//后一节的位置移动到前一节
                 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; }
             }else if(fx.equals("L")){
                 snakeX[0] = snakeX[0] - 25;
                 if(snakeX[0]<25){ snakeX[0] = 25; }
             }else if(fx.equals("up")){
                 snakeY[0] = snakeY[0] - 25;
                 if(snakeY[0]<75){ snakeX[0] = 650; }
             }else if(fx.equals("down")){
                 snakeY[0] = snakeY[0] + 25;
                 if(snakeX[0]>650){ snakeX[0] = 75; }
             }
             repaint();//重画页面
         }
         timer.start();//定时开启~
     }
 ​
 ​
     @Override
     public void keyTyped(KeyEvent e) { }
     @Override
     public void keyReleased(KeyEvent e) { }
 }
小蛇吃食物
  • 定义食物坐标,并且需要一个random来使食物随机生成在界面上

 //初始化食物的坐标
 int foodX;
 int foodY;
 Random random=new Random();
  • 在画板中,将食物画到界面上

 //把食物画上去
 Data.food.paintIcon(this,g,foodX,foodY);
  • 在监听事件中,判定吃食物

 //吃食物判断
 if (snakeX[0]==foodX && snakeY[0]==foodY){
     length++;//长度+1
     //再次随机生成食物
     //初始化食物,把食物随机分布在界面上
     foodX=25+25*random.nextInt(34);
     foodY=75+25*random.nextInt(24);
 }
小蛇失败判定
  • 新建游戏状态

 boolean isFail= false;//默认游戏状态失败
  • 绘制失败在画板上

 if (isFail){
     g.setColor(Color.red);
     g.setFont(new Font("微软雅黑", Font.BOLD, 40));//设置字体
     g.drawString("失败,按下空格重新开始!", 300, 450);
 }
  • 监听键盘事件判断游戏状态

 if (keyCode==KeyEvent.VK_SPACE){//如果按下空格,则取反游戏状态
     if (isFail){
         //重新开始
         isFail=false;
         init();//重新开始重置游戏初始状态
     }else {
         isStart=!isStart;
     }
     repaint();
 }
  • 游戏事件监听,当小蛇撞到自己判断游戏失败

 //失败判断,撞到自己算失败
 for (int i=1;i<length;i++){
     if (snakeX[0]==snakeX[i] && snakeY[0]==snakeY[i]){
         isFail=true;
     }
 }
添加游戏数据面板
  • 新增游戏初始分数

 //初始化分数
 int score;
 //初始化小蛇
 public void init() {
     length = 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);
     foodY=75+25*random.nextInt(24);
     //初始分数
     score=0;
 }
  • 画分数和长度到面板

 //画积分和长度
 g.setColor(Color.WHITE);
 g.setFont(new Font("宋体", Font.BOLD, 15));
 g.drawString("长度:"+length,750,35);
 g.drawString("分数:"+score,750,50);
  • 事件判断吃到食物分数增加10

 //吃食物判断
 if (snakeX[0]==foodX && snakeY[0]==foodY){
     length++;//长度+1
     score=score+10;
     //再次随机生成食物
     //初始化食物,把食物随机分布在界面上
     foodX=25+25*random.nextInt(34);
     foodY=75+25*random.nextInt(24);
 }

四、Data数据类
 package cn.lxz.day07.snake;
 import javax.swing.*;
 import java.net.URL;
 public class Data {
     //头部图片
     public static URL headerUrl = Data.class.getResource("/statics/header.png");
     public static ImageIcon header = new ImageIcon(headerUrl);
     //头部:上下左右
     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);
 }

五、StartGame 主函数开启
 package cn.lxz.day07.snake;
 import javax.swing.*;
 public class StartGame {
     public static void main(String[] args) {
         //1.新建一个窗口
         JFrame frame = new JFrame("狂神说Java-贪吃蛇小游戏");
         frame.setBounds(600,10,900,720);  // 设置窗口的位置和大小
         frame.setResizable(false); //窗口大小不可调整,即固定窗口大小
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置关闭事件,游戏可以关闭
         //2.添加我们自己编写的画布背景
         frame.add(new GamePanel());
         frame.setVisible(true); //将窗口展示出来
     }
 }

六、GamePanel 游戏面板
 package cn.lxz.day07.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 {
     //定义蛇的数据结构
     int lenth; //蛇的长度
     int[] snakeX = new int[600];  //蛇的坐标x
     int[] snakeY = new int[500];  //蛇的坐标y
     String fx = "R"; //蛇的方向 : 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();
     }
     //初始化方法
     public void init() {
         lenth = 3;//初始小蛇有三节,包括小脑袋
         //初始化开始的蛇,给蛇定位,
         snakeX[0] = 100;
         snakeY[0] = 100;
         snakeX[1] = 75;
         snakeY[1] = 100;
         snakeX[2] = 50;
         snakeY[2] = 100;
         //初始化食物数据
         foodx = 25 + 25 * random.nextInt(34);
         foody = 75 + 25 * random.nextInt(24);
         score = 0; //初始化游戏分数
     }
     /**
      * 一开始我们进来我们需要绘制面板
      * Alt+ins Overrid 里面有个paintComponent方法用来绘制组件
      * 画组件
      *
      * @param g 游戏中的所有东西,都用这只g画笔来画就够了
      */
     public void paintComponent(Graphics g) {
         super.paintComponent(g);//清屏
         //绘制静态面板
         this.setBackground(Color.pink); //设置面板的背景色
         Data.header.paintIcon(this, g, 25, 11); //绘制头部广告栏
         /**
          * Paints the icon.
          * The top-left corner of the icon is drawn at
          * the point (<code>x</code>, <code>y</code>)
          * in the coordinate space of the graphics context <code>g</code>.
          * If this icon has no image observer,
          * this method uses the <code>c</code> component
          * as the observer.
          *
          * @param c the component to be used as the observer
          *          if this icon has no image observer
          * @param g the graphics context
          * @param x the X coordinate of the icon's top-left corner
          * @param y the Y coordinate of the icon's top-left corner
          */
         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 < lenth; i++) {
             Data.body.paintIcon(this, g, snakeX[i], snakeY[i]); //蛇的身体长度根据lenth来控制
         }
         //画食物
         Data.food.paintIcon(this, g, foodx, foody);
         g.setColor(Color.white);
         g.setFont(new Font("微软雅黑", Font.BOLD, 18));
         g.drawString("长度 " + lenth, 750, 35);
         g.drawString("分数 " + score, 750, 50);
         //游戏提示
         if (isStart == false) {
             g.setColor(Color.white);
             g.setFont(new Font("微软雅黑", Font.BOLD, 40));
             g.drawString("按下空格开始游戏!", 300, 300);
         }
         //失败判断
         if (isFail) {
             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;
             }
             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) {
         //如果游戏处于开始状态,并且没有结束,则小蛇可以移动
         if (isStart && isFail == false) {
             //右移:即让后一个移到前一个的位置即可 !
             for (int i = lenth - 1; i > 0; i--) { //除了脑袋都往前移:身体移动
                 snakeX[i] = snakeX[i - 1]; //即第i节(后一节)的位置变为(i-1:前一节)节的位置!
                 snakeY[i] = snakeY[i - 1];
             }
             //通过方向控制,头部移动
             if (fx.equals("R")) {
                 snakeX[0] = snakeX[0] + 25;
                 if (snakeX[0] > 850) snakeX[0] = 25;
             } 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;
                 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) {
                 //1.长度加一
                 lenth++;
                 //每吃一个食物,增加积分
                 score = score + 10;
                 //2.重新生成食物
                 foodx = 25 + 25 * random.nextInt(34);
                 foody = 75 + 25 * random.nextInt(24);
             }
             //结束判断,头和身体撞到了
             for (int i = 1; i < lenth; i++) {
                 //如果头和身体碰撞,那就说明游戏失败
                 if (snakeX[i] == snakeX[0] && snakeY[i] == snakeY[0]) {
                     isFail = true;
                 }
             }
             repaint(); //需要不断的更新页面实现动画
         }
         timer.start();//让时间动起来!
     }
 }

七、游戏素材

img

img

img

img

img

img

img

八、总结:

GUI中常用的几种容器和标签方法就到这里结束了,在贪吃蛇小游戏中,几乎涵盖了所有的GUI基础,还有javaSE的部分知识

还可优化的点:

  • 游戏拓展性:

    • 比如可以有多种样子的食物,分别代表不同的分数

    • 添加等级,到达一定分数就将定时器的时间缩短,以实现小蛇速度的提升

    • 连接数据库,将游戏数据写入数据库,再次打开游戏可以继续玩上次记录

参考资料

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值