• Java开发扫雷游戏项目,JFram类的使用


    视频

    JFram类写扫雷游戏_哔哩哔哩_bilibili

    笔记

    码云地址:saolei: java的JFram类写扫雷游戏

    开发工具:idea

    语言:Java

    jdk:1.8及以上

    开发步骤

    新建Java空项目---imgs包---com.ycy包

    启动类

    GameWin.java
    1. package com.ycy;
    2. import javax.swing.*;
    3. import java.awt.*;
    4. import java.awt.event.MouseAdapter;
    5. import java.awt.event.MouseEvent;
    6. public class GameWin extends JFrame {
    7. int wigth = 2 * GameUtil.OFFSET + GameUtil.MAP_W * GameUtil.SQUARE_LENGTH;
    8. int height = 4 * GameUtil.OFFSET + GameUtil.MAP_H * GameUtil.SQUARE_LENGTH;
    9. Image offScreenImage = null;
    10. MapBottom mapBottom = new MapBottom();
    11. MapTop mapTop = new MapTop();
    12. GameSelect gameSelect = new GameSelect();
    13. //是否开始,f未开始,t开始
    14. boolean begin=false;
    15. void launch(){
    16. GameUtil.START_TIME=System.currentTimeMillis();
    17. this.setVisible(true);
    18. if(GameUtil.state==3){
    19. this.setSize(500,500);
    20. }else {
    21. this.setSize(wigth,height);
    22. }
    23. this.setLocationRelativeTo(null);
    24. this.setTitle("扫雷游戏");
    25. this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    26. //鼠标事件
    27. this.addMouseListener(new MouseAdapter() {
    28. @Override
    29. public void mouseClicked(MouseEvent e) {
    30. super.mouseClicked(e);
    31. switch (GameUtil.state){
    32. case 0 :
    33. if(e.getButton()==1){
    34. GameUtil.MOUSE_X = e.getX();
    35. GameUtil.MOUSE_Y = e.getY();
    36. GameUtil.LEFT = true;
    37. }
    38. if(e.getButton()==3) {
    39. GameUtil.MOUSE_X = e.getX();
    40. GameUtil.MOUSE_Y = e.getY();
    41. GameUtil.RIGHT = true;
    42. }
    43. case 1 :
    44. case 2 :
    45. if(e.getButton()==1){
    46. if(e.getX()>GameUtil.OFFSET + GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W/2)
    47. && e.getX()2) + GameUtil.SQUARE_LENGTH
    48. && e.getY()>GameUtil.OFFSET
    49. && e.getY()
    50. mapBottom.reGame();
    51. mapTop.reGame();
    52. GameUtil.FLAG_NUM=0;
    53. GameUtil.START_TIME=System.currentTimeMillis();
    54. GameUtil.state=0;
    55. }
    56. }
    57. if(e.getButton()==2){
    58. GameUtil.state=3;
    59. begin=true;
    60. }
    61. break;
    62. case 3:
    63. if(e.getButton()==1){
    64. GameUtil.MOUSE_X = e.getX();
    65. GameUtil.MOUSE_Y = e.getY();
    66. begin = gameSelect.hard();
    67. }
    68. break;
    69. default:
    70. }
    71. }
    72. });
    73. while (true){
    74. repaint();
    75. begin();
    76. try {
    77. Thread.sleep(40);
    78. } catch (InterruptedException e) {
    79. e.printStackTrace();
    80. }
    81. }
    82. }
    83. void begin(){
    84. if(begin){
    85. begin=false;
    86. gameSelect.hard(GameUtil.level);
    87. dispose();
    88. GameWin gameWin = new GameWin();
    89. GameUtil.START_TIME = System.currentTimeMillis();
    90. GameUtil.FLAG_NUM=0;
    91. mapBottom.reGame();
    92. mapTop.reGame();
    93. gameWin.launch();
    94. }
    95. }
    96. @Override
    97. public void paint(Graphics g) {
    98. if(GameUtil.state==3){
    99. g.setColor(Color.white);
    100. g.fillRect(0,0,500,500);
    101. gameSelect.paintSelf(g);
    102. }else {
    103. offScreenImage = this.createImage(wigth, height);
    104. Graphics gImage = offScreenImage.getGraphics();
    105. //设置背景颜色
    106. gImage.setColor(Color.orange);
    107. gImage.fillRect(0, 0, wigth, height);
    108. mapBottom.paintSelf(gImage);
    109. mapTop.paintSelf(gImage);
    110. g.drawImage(offScreenImage, 0, 0, null);
    111. }
    112. }
    113. public static void main(String[] args) {
    114. GameWin gameWin = new GameWin();
    115. gameWin.launch();
    116. }
    117. }
    BottomNum.java
    1. package com.ycy;
    2. /**
    3. * 底层数字类
    4. */
    5. public class BottomNum {
    6. void newNum() {
    7. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    8. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    9. if(GameUtil.DATA_BOTTOM[i][j]==-1){
    10. for (int k = i-1; k <=i+1 ; k++) {
    11. for (int l = j-1; l <=j+1 ; l++) {
    12. if(GameUtil.DATA_BOTTOM[k][l]>=0){
    13. GameUtil.DATA_BOTTOM[k][l]++;
    14. }
    15. }
    16. }
    17. }
    18. }
    19. }
    20. }
    21. }
    BottomRay.java
    1. package com.ycy;
    2. /**
    3. * 初始化地雷
    4. */
    5. public class BottomRay {
    6. //存放坐标
    7. static int[] rays = new int[GameUtil.RAY_MAX*2];
    8. //地雷坐标
    9. int x,y;
    10. //是否放置 T 表示可以放置 F 不可放置
    11. boolean isPlace = true;
    12. //生成雷
    13. void newRay() {
    14. for (int i = 0; i < GameUtil.RAY_MAX*2 ; i=i+2) {
    15. x= (int) (Math.random()*GameUtil.MAP_W +1);//1-12
    16. y= (int) (Math.random()*GameUtil.MAP_H +1);//1-12
    17. //判断坐标是否存在
    18. for (int j = 0; j < i ; j=j+2) {
    19. if(x==rays[j] && y==rays[j+1]){
    20. i=i-2;
    21. isPlace = false;
    22. break;
    23. }
    24. }
    25. //将坐标放入数组
    26. if(isPlace){
    27. rays[i]=x;
    28. rays[i+1]=y;
    29. }
    30. isPlace = true;
    31. }
    32. for (int i = 0; i < GameUtil.RAY_MAX*2; i=i+2) {
    33. GameUtil.DATA_BOTTOM[rays[i]][rays[i+1]]=-1;
    34. }
    35. }
    36. }
    GameSelect.java
    1. package com.ycy;
    2. import java.awt.*;
    3. /**
    4. * 难度选择类
    5. */
    6. public class GameSelect {
    7. //判断是否点击到难度
    8. boolean hard(){
    9. if(GameUtil.MOUSE_X>100&&GameUtil.MOUSE_X<400){
    10. if(GameUtil.MOUSE_Y>50&&GameUtil.MOUSE_Y<150){
    11. GameUtil.level=1;
    12. GameUtil.state=0;
    13. return true;
    14. }
    15. if(GameUtil.MOUSE_Y>200&&GameUtil.MOUSE_Y<300){
    16. GameUtil.level=2;
    17. GameUtil.state=0;
    18. return true;
    19. }
    20. if(GameUtil.MOUSE_Y>350&&GameUtil.MOUSE_Y<450){
    21. GameUtil.level=3;
    22. GameUtil.state=0;
    23. return true;
    24. }
    25. }
    26. return false;
    27. }
    28. void paintSelf(Graphics g){
    29. g.setColor(Color.black);
    30. g.drawRect(100,50,300,100);
    31. GameUtil.drawWord(g,"简单",220,100,30,Color.black);
    32. g.drawRect(100,200,300,100);
    33. GameUtil.drawWord(g,"普通",220,250,30,Color.black);
    34. g.drawRect(100,350,300,100);
    35. GameUtil.drawWord(g,"困难",220,400,30,Color.black);
    36. }
    37. void hard(int level){
    38. switch (level){
    39. case 1:
    40. GameUtil.RAY_MAX = 10;
    41. GameUtil.MAP_W = 9;
    42. GameUtil.MAP_H = 9;
    43. break;
    44. case 2:
    45. GameUtil.RAY_MAX = 40;
    46. GameUtil.MAP_W = 16;
    47. GameUtil.MAP_H = 16;
    48. break;
    49. case 3:
    50. GameUtil.RAY_MAX = 99;
    51. GameUtil.MAP_W = 30;
    52. GameUtil.MAP_H = 16;
    53. break;
    54. default:
    55. }
    56. }
    57. }
    GameUtil.java
    1. package com.ycy;
    2. import java.awt.*;
    3. /**
    4. * 工具类
    5. * 存放静态参数
    6. * 工具方法
    7. */
    8. public class GameUtil {
    9. //地雷个数
    10. static int RAY_MAX = 100;
    11. //地图的宽
    12. static int MAP_W = 36;
    13. //地图的高
    14. static int MAP_H = 17;
    15. //雷区偏移量
    16. static int OFFSET = 45;
    17. //格子边长
    18. static int SQUARE_LENGTH = 50;
    19. //插旗数量
    20. static int FLAG_NUM = 0;
    21. //鼠标相关
    22. //坐标
    23. static int MOUSE_X;
    24. static int MOUSE_Y;
    25. //状态
    26. static boolean LEFT = false;
    27. static boolean RIGHT = false;
    28. //游戏状态 0 表示游戏中 1 胜利 2 失败 3 难度选择
    29. static int state = 3;
    30. //游戏难度
    31. static int level;
    32. //倒计时
    33. static long START_TIME;
    34. static long END_TIME;
    35. //底层元素 -1 雷 0 空 1-8 表示对应数字
    36. static int[][] DATA_BOTTOM = new int[MAP_W+2][MAP_H+2];
    37. //顶层元素 -1 无覆盖 0 覆盖 1 插旗 2 差错旗
    38. static int[][] DATA_TOP = new int[MAP_W+2][MAP_H+2];
    39. //载入图片
    40. static Image lei = Toolkit.getDefaultToolkit().getImage("imgs/lei.png");
    41. static Image top = Toolkit.getDefaultToolkit().getImage("imgs/top.gif");
    42. static Image flag = Toolkit.getDefaultToolkit().getImage("imgs/flag.gif");
    43. static Image noflag = Toolkit.getDefaultToolkit().getImage("imgs/noflag.png");
    44. static Image face = Toolkit.getDefaultToolkit().getImage("imgs/face.png");
    45. static Image over = Toolkit.getDefaultToolkit().getImage("imgs/over.png");
    46. static Image win = Toolkit.getDefaultToolkit().getImage("imgs/win.png");
    47. static Image[] images = new Image[9];
    48. static {
    49. for (int i = 1; i <=8 ; i++) {
    50. images[i] = Toolkit.getDefaultToolkit().getImage("imgs/num/"+i+".png");
    51. }
    52. }
    53. static void drawWord(Graphics g,String str,int x,int y,int size,Color color){
    54. g.setColor(color);
    55. g.setFont(new Font("仿宋",Font.BOLD,size));
    56. g.drawString(str,x,y);
    57. }
    58. }
    MapBottom.java
    1. package com.ycy;
    2. import java.awt.*;
    3. /**
    4. * 底层地图
    5. * 绘制游戏相关组件
    6. */
    7. public class MapBottom {
    8. BottomRay bottomRay = new BottomRay();
    9. BottomNum bottomNum = new BottomNum();
    10. {
    11. bottomRay.newRay();
    12. bottomNum.newNum();
    13. }
    14. //重置游戏
    15. void reGame(){
    16. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    17. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    18. GameUtil.DATA_BOTTOM[i][j]=0;
    19. }
    20. }
    21. bottomRay.newRay();
    22. bottomNum.newNum();
    23. }
    24. //绘制方法
    25. void paintSelf(Graphics g){
    26. g.setColor(Color.red);
    27. //画竖线
    28. for (int i = 0; i <= GameUtil.MAP_W; i++) {
    29. g.drawLine(GameUtil.OFFSET + i * GameUtil.SQUARE_LENGTH,
    30. 3*GameUtil.OFFSET,
    31. GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
    32. 3*GameUtil.OFFSET+GameUtil.MAP_H*GameUtil.SQUARE_LENGTH);
    33. }
    34. //画横线
    35. for (int i = 0; i <=GameUtil.MAP_H; i++){
    36. g.drawLine(GameUtil.OFFSET,
    37. 3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH,
    38. GameUtil.OFFSET+GameUtil.MAP_W*GameUtil.SQUARE_LENGTH,
    39. 3*GameUtil.OFFSET+i*GameUtil.SQUARE_LENGTH);
    40. }
    41. for (int i = 1; i <= GameUtil.MAP_W ; i++) {
    42. for (int j = 1; j <= GameUtil.MAP_H; j++) {
    43. //雷
    44. if (GameUtil.DATA_BOTTOM[i][j] == -1) {
    45. g.drawImage(GameUtil.lei,
    46. GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
    47. GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
    48. GameUtil.SQUARE_LENGTH - 2,
    49. GameUtil.SQUARE_LENGTH - 2,
    50. null);
    51. }
    52. //数字
    53. if (GameUtil.DATA_BOTTOM[i][j] >=0) {
    54. g.drawImage(GameUtil.images[GameUtil.DATA_BOTTOM[i][j]],
    55. GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 15,
    56. GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 5,
    57. null);
    58. }
    59. }
    60. }
    61. //绘制数字 剩余雷数,倒计时
    62. GameUtil.drawWord(g,""+(GameUtil.RAY_MAX-GameUtil.FLAG_NUM),
    63. GameUtil.OFFSET,
    64. 2*GameUtil.OFFSET,30,Color.red);
    65. GameUtil.drawWord(g,""+(GameUtil.END_TIME-GameUtil.START_TIME)/1000,
    66. GameUtil.OFFSET + GameUtil.SQUARE_LENGTH*(GameUtil.MAP_W-1),
    67. 2*GameUtil.OFFSET,30,Color.red);
    68. switch (GameUtil.state){
    69. case 0:
    70. GameUtil.END_TIME=System.currentTimeMillis();
    71. g.drawImage(GameUtil.face,
    72. GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W/2),
    73. GameUtil.OFFSET,
    74. null);
    75. break;
    76. case 1:
    77. g.drawImage(GameUtil.win,
    78. GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W/2),
    79. GameUtil.OFFSET,
    80. null);
    81. break;
    82. case 2:
    83. g.drawImage(GameUtil.over,
    84. GameUtil.OFFSET + GameUtil.SQUARE_LENGTH * (GameUtil.MAP_W/2),
    85. GameUtil.OFFSET,
    86. null);
    87. break;
    88. default:
    89. }
    90. }
    91. }
    MapTop.java
    1. package com.ycy;
    2. import java.awt.*;
    3. /**
    4. * 顶层地图类
    5. * 绘制顶层组件
    6. * 判断逻辑
    7. */
    8. public class MapTop {
    9. //格子位置
    10. int temp_x;
    11. int temp_y;
    12. //重置游戏
    13. void reGame(){
    14. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    15. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    16. GameUtil.DATA_TOP[i][j]=0;
    17. }
    18. }
    19. }
    20. //判断逻辑
    21. void logic(){
    22. temp_x=0;
    23. temp_y=0;
    24. if(GameUtil.MOUSE_X>GameUtil.OFFSET && GameUtil.MOUSE_Y>3*GameUtil.OFFSET){
    25. temp_x = (GameUtil.MOUSE_X - GameUtil.OFFSET)/GameUtil.SQUARE_LENGTH+1;
    26. temp_y = (GameUtil.MOUSE_Y - GameUtil.OFFSET * 3)/GameUtil.SQUARE_LENGTH+1;
    27. }
    28. if(temp_x>=1 && temp_x<=GameUtil.MAP_W
    29. && temp_y>=1 && temp_y<=GameUtil.MAP_H){
    30. if(GameUtil.LEFT){
    31. //覆盖,则翻开
    32. if(GameUtil.DATA_TOP[temp_x][temp_y]==0){
    33. GameUtil.DATA_TOP[temp_x][temp_y]=-1;
    34. }
    35. spaceOpen(temp_x,temp_y);
    36. GameUtil.LEFT=false;
    37. }
    38. if(GameUtil.RIGHT){
    39. //覆盖则插旗
    40. if(GameUtil.DATA_TOP[temp_x][temp_y]==0){
    41. GameUtil.DATA_TOP[temp_x][temp_y]=1;
    42. GameUtil.FLAG_NUM++;
    43. }
    44. //插旗则取消
    45. else if(GameUtil.DATA_TOP[temp_x][temp_y]==1){
    46. GameUtil.DATA_TOP[temp_x][temp_y]=0;
    47. GameUtil.FLAG_NUM--;
    48. }
    49. else if(GameUtil.DATA_TOP[temp_x][temp_y]==-1){
    50. numOpen(temp_x,temp_y);
    51. }
    52. GameUtil.RIGHT=false;
    53. }
    54. }
    55. boom();
    56. victory();
    57. }
    58. //数字翻开
    59. void numOpen(int x,int y){
    60. //记录旗数
    61. int count=0;
    62. if(GameUtil.DATA_BOTTOM[x][y]>0){
    63. for (int i = x-1; i <=x+1 ; i++) {
    64. for (int j = y-1; j <=y+1 ; j++) {
    65. if(GameUtil.DATA_TOP[i][j]==1){
    66. count++;
    67. }
    68. }
    69. }
    70. if(count==GameUtil.DATA_BOTTOM[x][y]){
    71. for (int i = x-1; i <=x+1 ; i++) {
    72. for (int j = y-1; j <=y+1 ; j++) {
    73. if(GameUtil.DATA_TOP[i][j]!=1){
    74. GameUtil.DATA_TOP[i][j]=-1;
    75. }
    76. //必须在雷区当中
    77. if(i>=1&&j>=1&&i<=GameUtil.MAP_W&&j<=GameUtil.MAP_H){
    78. spaceOpen(i,j);
    79. }
    80. }
    81. }
    82. }
    83. }
    84. }
    85. //失败判定 t 表示失败 f 未失败
    86. boolean boom(){
    87. if(GameUtil.FLAG_NUM==GameUtil.RAY_MAX){
    88. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    89. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    90. if(GameUtil.DATA_TOP[i][j]==0){
    91. GameUtil.DATA_TOP[i][j]=-1;
    92. }
    93. }
    94. }
    95. }
    96. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    97. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    98. if(GameUtil.DATA_BOTTOM[i][j]==-1&&GameUtil.DATA_TOP[i][j]==-1){
    99. GameUtil.state = 2;
    100. seeBoom();
    101. return true;
    102. }
    103. }
    104. }
    105. return false;
    106. }
    107. //失败显示
    108. void seeBoom(){
    109. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    110. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    111. //底层是雷,顶层不是旗,显示
    112. if(GameUtil.DATA_BOTTOM[i][j]==-1&&GameUtil.DATA_TOP[i][j]!=1){
    113. GameUtil.DATA_TOP[i][j]=-1;
    114. }
    115. //底层不是雷,顶层是旗,显示差错旗
    116. if(GameUtil.DATA_BOTTOM[i][j]!=-1&&GameUtil.DATA_TOP[i][j]==1){
    117. GameUtil.DATA_TOP[i][j]=2;
    118. }
    119. }
    120. }
    121. }
    122. //胜利判断 t 表示胜利 f 未胜利
    123. boolean victory(){
    124. //统计未打开格子数
    125. int count=0;
    126. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    127. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    128. if(GameUtil.DATA_TOP[i][j]!=-1){
    129. count++;
    130. }
    131. }
    132. }
    133. if(count==GameUtil.RAY_MAX){
    134. GameUtil.state=1;
    135. for (int i = 1; i <=GameUtil.MAP_W ; i++) {
    136. for (int j = 1; j <=GameUtil.MAP_H ; j++) {
    137. //未翻开,变成旗
    138. if(GameUtil.DATA_TOP[i][j]==0){
    139. GameUtil.DATA_TOP[i][j]=1;
    140. }
    141. }
    142. }
    143. return true;
    144. }
    145. return false;
    146. }
    147. //打开空格
    148. void spaceOpen(int x,int y){
    149. if(GameUtil.DATA_BOTTOM[x][y]==0){
    150. for (int i = x-1; i <=x+1 ; i++) {
    151. for (int j = y-1; j <=y+1 ; j++) {
    152. //覆盖,才递归
    153. if(GameUtil.DATA_TOP[i][j]!=-1){
    154. if(GameUtil.DATA_TOP[i][j]==1){GameUtil.FLAG_NUM--;}
    155. GameUtil.DATA_TOP[i][j]=-1;
    156. //必须在雷区当中
    157. if(i>=1&&j>=1&&i<=GameUtil.MAP_W&&j<=GameUtil.MAP_H){
    158. spaceOpen(i,j);
    159. }
    160. }
    161. }
    162. }
    163. }
    164. }
    165. //绘制方法
    166. void paintSelf(Graphics g){
    167. logic();
    168. for (int i = 1; i <= GameUtil.MAP_W ; i++) {
    169. for (int j = 1; j <= GameUtil.MAP_H; j++) {
    170. //覆盖
    171. if (GameUtil.DATA_TOP[i][j] == 0) {
    172. g.drawImage(GameUtil.top,
    173. GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
    174. GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
    175. GameUtil.SQUARE_LENGTH - 2,
    176. GameUtil.SQUARE_LENGTH - 2,
    177. null);
    178. }
    179. //插旗
    180. if (GameUtil.DATA_TOP[i][j] == 1) {
    181. g.drawImage(GameUtil.flag,
    182. GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
    183. GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
    184. GameUtil.SQUARE_LENGTH - 2,
    185. GameUtil.SQUARE_LENGTH - 2,
    186. null);
    187. }
    188. //差错旗
    189. if (GameUtil.DATA_TOP[i][j] == 2) {
    190. g.drawImage(GameUtil.noflag,
    191. GameUtil.OFFSET + (i - 1) * GameUtil.SQUARE_LENGTH + 1,
    192. GameUtil.OFFSET * 3 + (j - 1) * GameUtil.SQUARE_LENGTH + 1,
    193. GameUtil.SQUARE_LENGTH - 2,
    194. GameUtil.SQUARE_LENGTH - 2,
    195. null);
    196. }
    197. }
    198. }
    199. }
    200. }

  • 相关阅读:
    【win11】 win11环境问题备忘
    python多进程文件处理(二)
    TuckER 论文笔记
    如何成为fpga工程师
    [474]. 一和零
    STM32 CAN/CANFD软件快速配置(HAL库版本)
    Django框架
    如何将内网ip映射到外网?快解析内网穿透
    极智AI | 输入图片BatchSize和分辨率对模型计算量和参数量的影响
    从0搭建Vue3组件库(七):使用 glup 打包组件库并实现按需加载
  • 原文地址:https://blog.csdn.net/chenyu_Yang/article/details/136763124