zoukankan      html  css  js  c++  java
  • java学习之坦克大战游戏

      总结:由于这几天快过年比较忙然后没怎么写,写代码途中一些经验总结现在给忘记了。这次的小项目感觉比上次写的思路清楚了点。没有之前第一次写那么逻辑混乱,结构也搞的比之前的要好,添加功能比较容易。学习了之前的经验,操作对象的方法由对象本身提供。不过这次小项目还有不足和不完善之处,有些可以做的功能没有实现,比如游戏存档,这里应该可以用下对象的序列化,还有游戏难度的设置也可以写个文件弄出来。要过年了,到处走亲戚没什么心思写了,这里只能留个尾巴了。

      前言:之前的及时通信项目完成后感觉线程方面和对java的运用还不是很熟悉,在另外一个学习视频中看到一个做坦克游戏的项目视频,便想自己试着做做看,先看视频把游戏规则什么的都搞清楚。然后开始一步一步实现。

    主要功能步骤如下

    * 1、画出坦克
    * 2、我的坦克可以上下移动
    * 3、可以发射子弹,子弹连发(或者最多5发)
    * 4、当我的坦克击中敌人坦克时,敌人坦克消失(或者爆炸效果)
    * 5、我被击中也显示爆炸效果。
    * 6、游戏开始和游戏介绍选项

    这次游戏界面没有进行设计,直接在一个frame上放个panel。

    游戏设计仿mvc 这里不做详细介绍了直接上代码

    model包

    package com.gh.model;
    /**
     * 爆炸类
     * 考虑到同时爆炸定义个类
     * @author ganhang
     *
     */
    public class Bomb {
        private int x;
        private int y;//坐标
        public boolean islive=true;
        private int time=9;//炸弹生命
        public Bomb() {
            super();
        }
        public Bomb(int x, int y) {
            super();
            this.x = x;
            this.y = y;
        }
        public int getX() {
            return x;
        }
        public void setX(int x) {
            this.x = x;
        }
        public int getY() {
            return y;
        }
        public void setY(int y) {
            this.y = y;
        }
        public int getTime() {
            return time;
        }
        //生命递减
        public void livedown(){
            if(time>0){
                time--;
            }else{
                islive=false;
            }
        }
    }
    Bomb
     1 package com.gh.model;
     2 /**
     3  * 子弹类,
     4  * 因为多个子弹同时运动所以需要个内部类做线程
     5  * @author ganhang
     6  *
     7  */
     8 public class Bullet {
     9     private int x;
    10     private int y;
    11     private int speed;
    12     private int drect;
    13     public boolean islive=true;
    14     public Bullet(int x, int y, int speed, int drect) {
    15         super();
    16         this.x = x;
    17         this.y = y;
    18         this.speed = speed;
    19         this.drect = drect;
    20         new Thread(new BulletThread()).start();
    21     }
    22     public Bullet() {
    23         super();
    24     }
    25 
    26     public int getX() {
    27         return x;
    28     }
    29 
    30     public void setX(int x) {
    31         this.x = x;
    32     }
    33 
    34     public int getY() {
    35         return y;
    36     }
    37 
    38     public void setY(int y) {
    39         this.y = y;
    40     }
    41 
    42     class BulletThread implements Runnable {
    43         @Override
    44         public void run() {
    45             while (true) {
    46                 try {
    47                     Thread.sleep(50);
    48                 } catch (Exception e) {
    49                     e.printStackTrace();
    50                 }
    51                 switch (drect) {//判断方向坐标移动
    52                 case 0:
    53                     y-=speed;
    54                     break;
    55                 case 1:
    56                     x+=speed;
    57                     break;
    58                 case 2:
    59                     y+=speed;
    60                     break;
    61                 case 3:
    62                     x-=speed;
    63                     break;
    64                 }
    65                 if (x < 0 || y < 0 || x > 500 || y > 500||!islive) {
    66                     islive=false;
    67                     break;
    68                 }
    69             }
    70         }
    71     }
    72 }
    Bullet
    package com.gh.model;
    
    /**
     * 地图坐标标记
     * 防止敌方坦克重叠
     * @author ganhang
     *
     */
    public class Map {
        public int[][] location=new int[500][500];
        public Map() {
            for (int i = 0; i < 500; i++) {
                for (int j = 0; j <500; j++) {
                    location[i][j]=0;
                }
            }
        }
    }
    Map

    坦克类,刚才上传发现点问题暂时没改

      1 package com.gh.model;
      2 
      3 import java.util.Vector;
      4 /**
      5  * 坦克类
      6  * 每个坦克就是一个线程,
      7  * 这里自己坦克并没有启动线程
      8  * @author ganhang
      9  *
     10  */
     11 public class Tank implements Runnable {
     12     private int x = 0;
     13     private int y = 0;// 坐标
     14     private int drect = 0;// 方向 0向上,1向右,2向下,3向左;
     15     private int type = 0;// 坦克类型 0表示自己
     16     private int speed = 3;// 速度
     17     public Vector<Bullet> mybs = new Vector<Bullet>();// 子弹集
     18     private Bullet myBullet;// 子弹
     19     public boolean islive = true;
     20     private Map map;
     21     public boolean start = true;
     22     public Map getMap() {
     23         return map;
     24     }
     25 
     26     public void setMap(Map map) {
     27         this.map = map;
     28     }
     29 
     30     public Tank(int x, int y, int drect, int type) {
     31         super();
     32         this.x = x;
     33         this.y = y;
     34         this.drect = drect;
     35         this.type = type;
     36     }
     37 
     38     public Tank() {
     39         super();
     40     }
     41 
     42     public Bullet getMyBullet() {
     43         return myBullet;
     44     }
     45 
     46     public int getSpeed() {
     47         return speed;
     48     }
     49 
     50     public void setSpeed(int speed) {
     51         this.speed = speed;
     52     }
     53 
     54     public int getX() {
     55         return x;
     56     }
     57 
     58     public int getDrect() {
     59         return drect;
     60     }
     61 
     62     public void setDrect(int drect) {
     63         this.drect = drect;
     64     }
     65 
     66     public int getType() {
     67         return type;
     68     }
     69 
     70     public void setType(int type) {
     71         this.type = type;
     72     }
     73 
     74     public void setX(int x) {
     75         this.x = x;
     76     }
     77 
     78     public int getY() {
     79         return y;
     80     }
     81 
     82     public void setY(int y) {
     83         this.y = y;
     84     }
     85 
     86     public void moveUp() {
     87         if (y - speed < 0)
     88             y = 0;
     89         else {
     90             y -= speed;
     91              map.location[x][y]=1;//标记此坦克坐标在地图上防止其他坦克过来占用导致重叠
     92 //             这里只标记了坦克坐标那一个点,会有bug,部分坦克还是有重叠现象,
     93 //             这里可以遍历整个坦克坐标(x到x+20,y到y+30)设置标记。
     94 //             for(int i=x;i<x+20;i++){
     95 //                 for (int j = y; j < y+30; j++) {
     96 //                     map.location[x][y]=1;
     97 //                }
     98 //             }
     99         }
    100     }
    101 
    102     public void moveDown() {
    103         if (y + speed > 470)
    104             y = 470;
    105         else {
    106             y += speed;
    107              map.location[x][y]=1;
    108         }
    109     }
    110 
    111     public void moveRight() {
    112         if (x + speed > 470)
    113             x = 470;
    114         else {
    115             x += speed;
    116              map.location[x][y]=1;
    117         }
    118     }
    119 
    120     public void moveLeft() {
    121         if (x - speed < 0)
    122             x = 0;
    123         else {
    124             x -= speed;
    125              map.location[x][y]=1;
    126         }
    127     }
    128 
    129     public void shot() {
    130         switch (drect) {
    131         case 0:
    132             myBullet = new Bullet(x + 10, y, 5, 0);
    133             mybs.add(myBullet);
    134             break;
    135         case 1:
    136             myBullet = new Bullet(x + 30, y + 10, 5, 1);
    137             mybs.add(myBullet);
    138             break;
    139         case 2:
    140             myBullet = new Bullet(x + 10, y + 30, 5, 2);
    141             mybs.add(myBullet);
    142             break;
    143         case 3:
    144             myBullet = new Bullet(x, y + 10, 5, 3);
    145             mybs.add(myBullet);
    146             break;
    147         }
    148     }
    149 
    150     @Override
    151     public void run() {
    152         while (islive) {
    153             if (start) {
    154                 int step;
    155                 int s;
    156                 try {
    157                     switch (drect) {
    158                     case 0:
    159                         step = (int) (Math.random() * 30);
    160                         for (int i = 0; i < step; i++) {
    161                             moveUp();
    162                             if (y <= 0)
    163                                 break;// 撞墙跳出循环
    164                             if (y >= 30)// 仿数组越界
    165                                 if (map.location[x][y - 30] == 1 || map.location[x][y - 20] == 1) {
    166                                     map.location[x][y - 30] = 0;//这里没分开判断
    167                                     map.location[x][y - 20] = 0;
    168                                     break;
    169                                 }
    170                             Thread.sleep(80);
    171                         }
    172                         break;
    173                     case 1:
    174                         step = (int) (Math.random() * 30);
    175                         for (int i = 0; i < step; i++) {
    176                             moveRight();
    177                             if (x >= 500)
    178                                 break;
    179                             if (x < 470)
    180                                 if (map.location[x + 20][y] == 1 || map.location[x + 30][y] == 1) {
    181                                     map.location[x + 20][y] = 0;
    182                                     map.location[x + 30][y] = 0;
    183                                     break;
    184                                 }
    185                             Thread.sleep(80);
    186                         }
    187                         break;
    188                     case 2:
    189                         step = (int) (Math.random() * 30);
    190                         for (int i = 0; i < step; i++) {
    191                             moveDown();
    192                             if (y >= 500)
    193                                 break;
    194                             if (y < 470)
    195                                 if (map.location[x][y + 30] == 1 || map.location[x][y + 20] == 1) {
    196                                     map.location[x][y + 30] = 0;
    197                                     map.location[x][y + 20] = 0;
    198                                     break;
    199                                 }
    200                             Thread.sleep(80);
    201                         }
    202                         break;
    203                     case 3:
    204                         step = (int) (Math.random() * 30);
    205                         for (int i = 0; i < step; i++) {
    206                             moveLeft();
    207                             if (x <= 0)
    208                                 break;
    209                             if (x >= 30)
    210                                 if (map.location[x - 20][y] == 1 || map.location[x - 30][y] == 1) {
    211                                     map.location[x - 20][y] = 0;
    212                                     map.location[x - 30][y] = 0;
    213                                     break;
    214                                 }
    215                             Thread.sleep(80);
    216                         }
    217                         break;
    218                     }
    219                 } catch (InterruptedException e) {
    220                     e.printStackTrace();
    221                 }
    222                 drect = (int) (Math.random() * 4);// 随机方向
    223                 s = (int) (Math.random() * 10);
    224                 if (s > 8) {
    225                     shot();
    226                 }
    227             }
    228         }
    229     }
    230 }
    Tank

    view包

      1 package com.gh.view;
      2 
      3 import java.awt.Color;
      4 import java.awt.Graphics;
      5 import java.awt.Image;
      6 import java.awt.Toolkit;
      7 import java.util.Vector;
      8 
      9 import javax.swing.JOptionPane;
     10 import javax.swing.JPanel;
     11 
     12 import com.gh.model.Bomb;
     13 import com.gh.model.Bullet;
     14 import com.gh.model.Map;
     15 import com.gh.model.Tank;
     16 
     17 /**
     18  * 游戏显示面板
     19  * 
     20  * @author ganhang
     21  *
     22  */
     23 
     24 public class Mypanel extends JPanel implements Runnable {
     25     public Tank mytank = null;// 我的坦克
     26     Tank ek = null;
     27     Image img;
     28     Vector<Tank> eks = new Vector<Tank>();//地方坦克集
     29     Vector<Bomb> bs = new Vector<Bomb>();//爆炸集合
     30     Map map = new Map();
     31 
     32     public Mypanel() {
     33         mytank = new Tank(200, 200, 0, 0);
     34         mytank.setMap(map);
     35         // 创建敌人坦克
     36         for (int i = 0; i < 17; i++) {
     37             ek = new Tank(i * 30, 10, 2, 1);
     38             eks.add(ek);
     39             ek.setMap(map);
     40             new Thread(ek).start();
     41         }
     42         img = Toolkit.getDefaultToolkit().getImage(this.getClass().getResource("/1.png"));
     43     }
     44 
     45     @Override
     46     public void paint(Graphics g) {
     47         super.paint(g);
     48         // 画背景
     49         g.fillRect(0, 0, 500, 500);
     50         // 画自己的坦克
     51         if (mytank.islive)
     52             drawTank(mytank.getX(), mytank.getY(), g, mytank.getDrect(), mytank.getType());
     53         // 画自己的子弹
     54         for (int i = 0; i < mytank.mybs.size(); i++) {// 循环时删除集合时,不要用foreach,用for
     55             Bullet b = new Bullet();
     56             b = mytank.mybs.get(i);
     57             if (b.islive) {
     58                 g.setColor(Color.white);
     59                 g.fill3DRect(b.getX(), b.getY(), 2, 2, false);
     60             } else
     61                 mytank.mybs.remove(b);
     62         }
     63         // 画敌人坦克
     64         for (int i = 0; i < eks.size(); i++) {
     65             Tank ek = new Tank();
     66             ek = eks.get(i);
     67             if (ek.islive)
     68                 drawEnemyTank(ek.getX(), ek.getY(), ek.getDrect(), g);
     69             // 画敌人子弹
     70             for (int j = 0; j < ek.mybs.size(); j++) {
     71                 Bullet eb = new Bullet();
     72                 eb = ek.mybs.get(j);
     73                 if (eb.islive) {
     74                     g.setColor(Color.green);
     75                     g.fill3DRect(eb.getX(), eb.getY(), 2, 2, false);
     76                 } else
     77                     ek.mybs.remove(eb);
     78             }
     79         }
     80         // 画爆炸,这里有个bug第一次爆炸没有爆炸效果图出来,检查原因是只一闪而过
     81         // 添加休眠好了点,不过影响后面爆炸效果,不明白为什么第一次画得快些
     82         for (int i = 0; i < bs.size(); i++) {
     83             // System.out.println(bs.size());
     84             Bomb bb = bs.get(i);
     85             if (bb.islive) {
     86                 if (bb.getTime() > 6) {
     87                     try {
     88                         Thread.sleep(50);
     89                     } catch (Exception e) {
     90                         e.printStackTrace();
     91                     }
     92                     g.drawImage(img, bb.getX(), bb.getY(), 30, 30, this);
     93                 } else if (bb.getTime() > 3) {
     94                     g.drawImage(img, bb.getX(), bb.getY(), 15, 15, this);
     95                 } else if (bb.getTime() > 0) {
     96                     g.drawImage(img, bb.getX(), bb.getY(), 1, 1, this);
     97                 }
     98             }
     99             bb.livedown();
    100             if (bb.getTime() == 0)
    101                 bs.remove(bb);
    102         }
    103     }
    104 
    105     public boolean isHitEnemy(Bullet b, Tank ek) {
    106         if (ek.getDrect() == 0 || ek.getDrect() == 2) {
    107             // 坦克竖着时宽20,高30
    108             if (b.getX() >= ek.getX() && b.getX() <= ek.getX() + 20 && b.getY() >= ek.getY()
    109                     && b.getY() <= ek.getY() + 30) {
    110                 b.islive = false;
    111                 ek.islive = false;
    112                 Bomb bb = new Bomb(ek.getX(), ek.getY());
    113                 bs.add(bb);
    114                 return true;
    115             }
    116             return false;
    117         } else {// 横着宽30,高20;
    118             if (b.getX() >= ek.getX() && b.getX() <= ek.getX() + 30 && b.getY() >= ek.getY()
    119                     && b.getY() <= ek.getY() + 20) {
    120                 ek.islive = false;
    121                 b.islive = false;
    122                 Bomb bb = new Bomb(ek.getX(), ek.getY());
    123                 bs.add(bb);
    124                 return true;
    125             }
    126             return false;
    127         }
    128     }
    129 
    130     public void drawEnemyTank(int x, int y, int drect, Graphics g) {
    131         drawTank(x, y, g, drect, 1);
    132     }
    133 
    134     public void drawTank(int x, int y, Graphics g, int drect, int type) {
    135         switch (type) {
    136         case 0:
    137             g.setColor(Color.cyan);
    138             break;
    139         case 1:
    140             g.setColor(Color.GREEN);
    141         default:
    142             break;
    143         }
    144         switch (drect) {
    145         case 0:
    146             // 坦克向上时宽20,高30
    147             g.fill3DRect(x, y, 5, 30, false);
    148             g.fill3DRect(x + 15, y, 5, 30, false);
    149             g.fill3DRect(x + 5, y + 9, 10, 15, false);
    150             g.drawLine(x + 10, y + 14, x + 10, y);
    151             break;
    152         case 1:
    153             // 坦克向右时宽30,高20
    154             g.fill3DRect(x, y, 30, 5, false);
    155             g.fill3DRect(x, y + 15, 30, 5, false);
    156             g.fill3DRect(x + 7, y + 5, 15, 10, false);
    157             g.drawLine(x + 13, y + 10, x + 30, y + 10);
    158             break;
    159         case 2:
    160             g.fill3DRect(x, y, 5, 30, false);
    161             g.fill3DRect(x + 15, y, 5, 30, false);
    162             g.fill3DRect(x + 5, y + 7, 10, 15, false);
    163             g.drawLine(x + 10, y + 12, x + 10, y + 30);
    164             break;
    165         case 3:
    166             g.fill3DRect(x, y, 30, 5, false);
    167             g.fill3DRect(x, y + 15, 30, 5, false);
    168             g.fill3DRect(x + 8, y + 5, 15, 10, false);
    169             g.drawLine(x, y + 10, x + 13, y + 10);
    170             break;
    171         }
    172     }
    173 
    174     @Override
    175     public void run() {
    176         while (true) {
    177             try {
    178                 Thread.sleep(50);// 画板刷新频率
    179             } catch (InterruptedException e) {
    180                 e.printStackTrace();
    181             }
    182             // 判断自己坦克的子弹是否击中敌人坦克
    183             for (int i = 0; i < mytank.mybs.size(); i++) {
    184                 Bullet mb = new Bullet();
    185                 mb = mytank.mybs.get(i);
    186                 if (mb.islive) {
    187                     for (int j = 0; j < eks.size(); j++) {
    188                         Tank ek = new Tank();
    189                         ek = eks.get(j);
    190                         if (ek.islive) {
    191                             isHitEnemy(mb, ek);
    192                         }
    193                     }
    194                 }
    195             }
    196             // 判断敌方坦克 的子弹是否击中我方坦克
    197             for (int i = 0; i < eks.size(); i++) {
    198                 Tank et = new Tank();
    199                 et = eks.get(i);
    200                 for (int j = 0; j < et.mybs.size(); j++) {// 这里写错ek查到死。。。
    201                     Bullet etb = new Bullet();
    202                     etb = et.mybs.get(j);
    203                     if (etb.islive) {
    204                         isHitEnemy(etb, mytank);
    205                     }
    206                 }
    207             }
    208             this.repaint();// 刷新
    209             if (!mytank.islive) {
    210                 JOptionPane.showMessageDialog(this, "你被GG");
    211                 mytank.islive = true;
    212             }
    213         }
    214     }
    215 }
    Mypanel

    开始游戏类

     1 package com.gh.view;
     2 
     3 import java.awt.EventQueue;
     4 /**
     5  * 1、画出坦克
     6  * 2、我的坦克可以上下移动
     7  * 3、可以发射子弹,子弹连发(或者最多5发)
     8  * 4、当我的坦克击中敌人坦克时,敌人坦克消失(或者爆炸效果)
     9  * 5、我被击中也显示爆炸效果。
    10  * 6、游戏开始选项
    11  * @author ganhang
    12  *
    13  */
    14 public class TankGame {
    15     private JFrame frame;
    16     /**
    17      * Launch the application.
    18      */
    19     public static void main(String[] args) {
    20         EventQueue.invokeLater(new Runnable() {
    21             public void run() {
    22                 try {
    23                     TankGame window = new TankGame();
    24                     window.frame.setVisible(true);
    25                 } catch (Exception e) {
    26                     e.printStackTrace();
    27                 }
    28             }
    29         });
    30     }
    31 
    32     /**
    33      * Create the application.
    34      */
    35     public TankGame() {
    36         initialize();
    37     }
    38 
    39     /**
    40      * Initialize the contents of the frame.
    41      */
    42     private void initialize() {
    43         frame = new JFrame();
    44         frame.setTitle("u5766u514Bu5927u6218");
    45         frame.setBounds(450, 70, 600, 600);
    46         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    47 
    48         JMenuBar menuBar = new JMenuBar();
    49         frame.setJMenuBar(menuBar);
    50         
    51         JMenu mnNewMenu = new JMenu("u9009u9879");
    52         mnNewMenu.setFont(new Font("微软雅黑", Font.PLAIN, 13));
    53         menuBar.add(mnNewMenu);
    54         
    55         JMenuItem mntmNewMenuItem = new JMenuItem("开始游戏");
    56         mntmNewMenuItem.addActionListener(new ActionListener() {
    57             public void actionPerformed(ActionEvent e) {
    58                 Mypanel mp = new Mypanel();
    59                 Thread t=new Thread(mp);
    60                 t.start();
    61                 frame.getContentPane().add(mp, BorderLayout.CENTER);
    62                 frame.addKeyListener(new KeyListen(mp));
    63                 frame.setVisible(true);
    64             }
    65         });
    66         
    67         mntmNewMenuItem.setFont(new Font("微软雅黑", Font.PLAIN, 12));
    68         mnNewMenu.add(mntmNewMenuItem);
    69         
    70         JMenu mnNewMenu_1 = new JMenu("u6E38u620Fu8BF4u660E");
    71         mnNewMenu_1.setFont(new Font("微软雅黑", Font.PLAIN, 13));
    72         menuBar.add(mnNewMenu_1);
    73         
    74         JMenuItem mntmNewMenuItem_1 = new JMenuItem("u5173u4E8Eu6E38u620F");
    75         mntmNewMenuItem_1.addActionListener(new ActionListener() {
    76             public void actionPerformed(ActionEvent e) {
    77                 JOptionPane.showMessageDialog(frame, "上:W, 下:A ,左:S, 右:D ,射击:空格
     Made by Ganhang");;
    78             }
    79         });
    80         mntmNewMenuItem_1.setFont(new Font("微软雅黑", Font.PLAIN, 12));
    81         mnNewMenu_1.add(mntmNewMenuItem_1);
    82 
    83     }
    84 
    85 }
    TankGame

    control包 这里放的事件监听主要业务逻辑在画板类和模型类里写了

     1 package com.gh.control;
     2 
     3 import java.awt.event.KeyEvent;
     4 import java.awt.event.KeyListener;
     5 
     6 import com.gh.view.Mypanel;
     7 
     8 /**
     9  * 事件监听
    10  * 这里有个控制最大发射子弹数
    11  * @author ganhang
    12  */
    13 public class KeyListen implements KeyListener{
    14     private Mypanel mp=null;
    15     
    16     public KeyListen(Mypanel mp) {
    17         super();
    18         this.mp = mp;
    19     }
    20     @Override
    21     public void keyTyped(KeyEvent e) {
    22         
    23     }
    24     
    25     @Override
    26     public void keyPressed(KeyEvent e) {
    27         //方向键监听
    28         if(e.getKeyCode()==KeyEvent.VK_W){
    29             mp.mytank.setDrect(0);
    30             mp.mytank.moveUp();
    31         }else if(e.getKeyCode()==KeyEvent.VK_S){
    32             mp.mytank.setDrect(2);
    33             mp.mytank.moveDown();
    34         }else if(e.getKeyCode()==KeyEvent.VK_D){
    35             mp.mytank.setDrect(1);
    36             mp.mytank.moveRight();
    37         }else if(e.getKeyCode()==KeyEvent.VK_A){
    38             mp.mytank.setDrect(3);
    39             mp.mytank.moveLeft();
    40         }
    41         //发射子弹监听
    42         if(e.getKeyCode()==KeyEvent.VK_SPACE){
    43             if(mp.mytank.mybs.size()<5)
    44             mp.mytank.shot();
    45         }
    46         mp.repaint();
    47     }
    48     @Override
    49     public void keyReleased(KeyEvent e) {
    50         // TODO Auto-generated method stub
    51         
    52     }
    53 }
    KeyListen

     github:https://github.com/ganhang/My_TankGame

    想到什么再更吧。。

  • 相关阅读:
    【LeetCode】119. Pascal's Triangle II
    随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比[转]
    linux下一些可用库
    malloc分配的内存空间是连续的吗
    语言模型训练网站
    relocation 错误
    undefined reference to `dlopen'
    静态库之间有依赖关系顺序很重要
    C++引用详解
    malloc原理和内存碎片[转]
  • 原文地址:https://www.cnblogs.com/ganhang-acm/p/5183616.html
Copyright © 2011-2022 走看看