贪吃蛇小游戏

贪吃蛇

帧:如果时间片足够小,就是动画,一秒30帧。连起来是动画,拆开就是静态图片。

键盘监听:

定时器:Timer

基本步骤:

  1. 定义数据

  2. 绘画

  3. 监听

    1. 事件监听

    2. 键盘监听

package com.zhang.snake;

import javax.swing.*;

/**
* 主启动类
*/
public class MyGame {
   public static void main(String[] args) {
       //创建 JFrame(); 实例对象
       JFrame frame = new JFrame();
       //设置窗口大小
       frame.setBounds(10,10,900,720);
       //设置窗口可见性
       frame.setVisible(true);
       //设置窗口不可变动
       frame.setResizable(false);
       //设置窗口可关闭性
       frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
       //创建游戏页面
       frame.add(new MyGamePanel());
  }
}
package com.zhang.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 MyGamePanel extends JPanel implements KeyListener, ActionListener {

   //定义蛇的数据结拜
   public int length;//默认长度
   public int[] snakeX = new int[600];//横坐标 X
   public int[] snakeY = new int[500];//纵坐标 Y
   public String fx;//小蛇头部方向
   //游戏的开始与停止事件,默认为停止状态
   public boolean isStrait = false;
   //游戏失败判断,默认不失败
   public boolean isFail = false;
   //定义定时器
   //参数一:多少时间执行一次
   //参数二:监听器,监听当前类 this 指当前类
   Timer timer = new Timer(100, this);//一百毫秒执行一次
   //定义食物的坐标
   public int foodx;
   public int foody;
   //创建随机数组
   Random random = new Random();
   //定义分数
   int score;

   //创建构造器
   public MyGamePanel(){
       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] = 50;  snakeY[2] = 100;//小蛇的第二节身体部分
       fx = "R";//小蛇头部方向,默认向右
       //初始化食物坐标
       foodx = 25 + 25 * random.nextInt(34);
       foody = 75 + 25 * random.nextInt(24);
       //分数默认为0
       score = 0;
  }

   //绘制游戏的界面
   @Override
   protected void paintComponent(Graphics g) {
       //清屏
       super.paintComponent(g);
       //设置背景
       this.setBackground(Color.WHITE);
       //绘制静态页面
       g.fillRect(25,75,850,600);
       //设置广告栏
       MyGameData.header.paintIcon(this, g, 25, 11);
       //把食物放到界面上
       MyGameData.food.paintIcon(this, g, foodx, foody);

       //分数
       g.setColor(Color.blue);
       g.setFont(new Font("微软雅黑", Font.BOLD, 18));
       g.drawString("长度 " + length, 700, 35);
       g.drawString("分数 " + score, 700, 55);

       //渲染小蛇头部
       if("R".equals(fx)){
           MyGameData.right.paintIcon(this, g, snakeX[0], snakeY[0]);
      }else if("L".equals(fx)){
           MyGameData.left.paintIcon(this, g, snakeX[0], snakeY[0]);
      }else if("U".equals(fx)){
           MyGameData.up.paintIcon(this, g, snakeX[0], snakeY[0]);
      }else if("D".equals(fx)){
           MyGameData.down.paintIcon(this, g, snakeX[0], snakeY[0]);
      }

       //渲染身体部分
       for (int i = 1; i < length; i++) {
           MyGameData.body.paintIcon(this, g, snakeX[i], snakeY[i]);
      }

       if(isStrait==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("游戏失败,按下空格重新开始游戏!",150,300);
      }

  }

   //监听键盘事件,按下键时
   @Override
   public void keyPressed(KeyEvent e) {
       //获取键盘按压的按键,16进制的数字
       int keyCode = e.getKeyCode();
       if(keyCode == KeyEvent.VK_SPACE){
           //如果游戏失败,则重新开始
           if(isFail){
               isFail = !isFail;
               init();//重新开始
          }else {
               //正常开始游戏
               isStrait = !isStrait;
          }
           //刷新
           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 actionPerformed(ActionEvent e) {
       if(isStrait && isFail==false){//如果游戏是开始状态,就让小蛇动起来

           //食物监听
           if(snakeX[0] == foodx && snakeY[0] == foody){
               //身体的长度 +1
               length++;
               //分数 +10
               score += 10;
               //再次随机生成食物
               foodx = 25 + 25 * random.nextInt(34);
               foody = 75 + 25 * random.nextInt(24);
          }

           //移动身体,后一节移到前一节的位置;snakeX[1]=snakeX[0]
           for (int i = length-1; i > 0; i--) {
               snakeX[i] = snakeX[i-1];
               snakeY[i] = snakeY[i-1];
          }
           //改变头部走向
           if(fx.equals("R")){
               snakeX[0] += 25;
               if(snakeX[0] > 850){snakeX[0] = 25;}//判断边界
          }else if(fx.equals("L")){
               snakeX[0] -= 25;
               if(snakeX[0] < 25){snakeX[0] = 850;}//判断边界
          }else if(fx.equals("U")){
               snakeY[0] -= 25;
               if(snakeY[0] < 75){snakeY[0] = 600;}//判断边界
          }else if(fx.equals("D")){
               snakeY[0] += 25;
               if(snakeY[0] > 650){snakeY[0] = 75;}//判断边界
          }
           //如果头部撞到自己的身体,则游戏失败
           for (int i = 1; i < length; i++) {
               if(snakeX[0]==snakeX[i] && snakeY[0] == snakeY[i]){
                   isFail = true;
              }
          }
           //刷新
           repaint();
      }
       timer.start();//开启定时器
  }

   @Override
   public void keyTyped(KeyEvent e) {}
   @Override
   public void keyReleased(KeyEvent e) {}


}
package com.zhang.snake;

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

public class MyGameData {

   //头部
   public static final URL headerUrl = MyGameData.class.getResource("statics/header.png");
   public static final ImageIcon header = new ImageIcon(headerUrl);

   //上、下、左、右
   public static final URL upUrl = MyGameData.class.getResource("statics/up.png");
   public static final URL downUrl = MyGameData.class.getResource("statics/down.png");
   public static final URL leftUrl = MyGameData.class.getResource("statics/left.png");
   public static final URL rightUrl = MyGameData.class.getResource("statics/right.png");
   public static final ImageIcon up = new ImageIcon(upUrl);
   public static final ImageIcon down = new ImageIcon(downUrl);
   public static final ImageIcon left = new ImageIcon(leftUrl);
   public static final ImageIcon right = new ImageIcon(rightUrl);

   //身体
   public static final URL bodyUrl = MyGameData.class.getResource("statics/body.png");
   public static final ImageIcon body = new ImageIcon(bodyUrl);

   //食物
   public static final URL foodUrl = MyGameData.class.getResource("statics/food.png");
   public static final ImageIcon food = new ImageIcon(foodUrl);

}

总结:

GUI编程

  • GUI

  • AWT

    • 组件

    • 容器

    • 面板

    • 事件监听

    • 文本框监听

    • 画图类 paint(g)

    • 鼠标监听器

    • 窗口监听器

    • 键盘监听器

  • Swing

    • 容器

    • 面板:可以带滚动条的

    • label

      • 普通标签

      • 图片标签

      • 图像标签

    • 按钮

      • 普通按钮

      • 带图片的按钮

      • 单选框

      • 多选框

    • 列表

      • 下拉框

      • 列表框

    • 文本框

      • 普通文本

      • 密码框

      • 文本域

posted @ 2021-03-21 01:37  初夏_雨露  阅读(12)  评论(0)    收藏  举报