今天分享一个我用Qt改写的微信打飞机游戏,程序重在设计过程,运用了(抽象)工厂的模式产生不同的对象(子弹,敌军,炸弹...),逻辑处理相对简单,尚未解决的问题是怎么使用Qt实现各种声音的混音效果,这里使用QThread线程里面使用Sound类播放声音,但是效果不佳,如有好的解决方案,望回复指导,程序运行效果如下:

所有类的定义和游戏实现过程都在头文件playplane.h和源文件playplane.cpp中

playplane.h:

#ifndef PLAYPLANE_H
#define PLAYPLANE_H#include <QtGui/QWidget>
#include <QFile>
#include <QDomDocument>
#include <QMessageBox>
#include <QDir>
#include <QSound>
#include <QTimer>
#include <QCursor>
#include <QMouseEvent>
#include <QPainter>
#include <QThread>
#include <QTextCodec>class Entity
{
public:QString Name;int X;int Y;int Width;int Height;int SpeedY;int SpeedX;QImage Image;QString ToString(){return Name;}
};//飞机类
class Plane :public Entity
{
public: int Level;Plane(){this->Name = "";this->X = 0;this->Y = 0;this->Width = 0;this->Height = 0;this->SpeedX = 0;this->SpeedY = 0;this->Image = QImage();this->Level = 1;}Plane(QString name, int x, int y, int width, int height, int speedX,int speedY, QImage bmp){this->Name = name;this->X = x;this->Y = y;this->Width = width;this->Height = height;this->SpeedX = speedX;this->SpeedY = speedY;this->Image = bmp;this->Level = 1;}void LevelUp(){Level++;}
};//子弹类
class Bullet:public Entity
{
public:Bullet(QString name, int x, int y, int width, int height, int speedX, int speedY, QImage bmp){this->Name = name;this->X = x;this->Y = y;this->Width = width;this->Height = height;this->SpeedX = speedX;this->SpeedY = speedY;this->Image = bmp;}
};//敌军类
class Enemy:public Entity
{
public:int HP;Enemy(QString name, int x, int y, int width, int height, int speedX, int speedY, int hp, QImage bmp){this->Name = name;this->X = x;this->Y = y;this->Width = width;this->Height = height;this->SpeedX = speedX;this->SpeedY = speedY;this->HP = hp;this->Image = bmp;}
};//奖励类
class Reward:public Entity
{
public:int StnTimes;int Counter;Reward(QString name, int x, int y, int width, int height, int speedX, int speedY, int stnTimes, QImage bmp){this->Name = name;this->X = x;this->Y = y;this->Width = width;this->Height = height;this->SpeedX = speedX;this->SpeedY = speedY;this->StnTimes = stnTimes;this->Image = bmp;this->Counter = 0;}
};//爆炸效果类
class Explosion
{
public:int X;int Y;int Width;int Height;int StnTimes;int Counter;QList<QImage> Images;Explosion(int x, int y,  int stnTimes,QList<QImage> bmp){this->X = x;this->Y = y;this->StnTimes = stnTimes;this->Images = bmp;this->Counter = 0;}
};//实体构建的工厂类
class EntityFactory
{
public:enum ImgItem { boom_add = 1, bomb_icon = 2, bullet_0 = 3, bullet_1 = 4, bullet_add = 5, enemy_b = 6, enemy_m = 7, enemy_s = 8,   explosion_01 = 9, explosion_02 = 10, explosion_03 = 11, hero_1 = 12, hero_2 = 13, pause_button = 14, resume_button = 15, smoke_01 = 16, smoke_02 = 17 };static QImage image_item[18];static void InitFactory(QString xmlPath);static Plane GenPlane(QString style);static Enemy GenEnemy(QString size,int speedBase,int width);static Bullet GenBullet(QString style,int p_x,int p_y);static Reward GenReward(QString style, int p_x, int p_y);static QImage GetBoomIcon();static Explosion GenExplosion(QString style, int p_x, int p_y);
};class MusicPlay
{
private:QString musicPath;QSound* bells;public:MusicPlay(QString musicPath){this->musicPath = musicPath;bells = new QSound(musicPath);}~MusicPlay(){delete bells;}void Play(){ bells->play();return;}
};class ThreadMusicPlay:public QThread
{
private:QString musicPath;int msec;
public:ThreadMusicPlay(QString musicPath = "",int msec = 100);~ThreadMusicPlay();void setFilePath(QString musicPath,int msec);void run();
};class PlayPlane : public QWidget
{Q_OBJECTpublic:PlayPlane(QWidget *parent = 0, Qt::WFlags flags = 0);~PlayPlane();
public slots:void timedraw();protected:void paintEvent ( QPaintEvent *  );void mouseMoveEvent ( QMouseEvent * );void mousePressEvent ( QMouseEvent *  );void keyPressEvent ( QKeyEvent *  );void leaveEvent ( QEvent *  );void enterEvent ( QEvent *  );private:Plane plane;QTimer t_draw;QList<Enemy> enemy_lsit;QList<Bullet> bullet_lsit;QList<Explosion> explosion_list;QList<Reward> reward_list;int score;int boom_count;bool pause;QImage background;int block_time;int block_interval;int send_time;int send_interval;int reward_time;int reward_interval;int rwd_bullet_stnTime;int backY;bool b_GameOver;MusicPlay* music_shoot;MusicPlay* music_BOMB3;MusicPlay* music_explosion;ThreadMusicPlay threadMusicPlay;};#endif // PLAYPLANE_H

playplane.cpp:

#include "playplane.h"QImage EntityFactory::image_item[18];void EntityFactory::InitFactory(QString xmlPath)
{QFile file(xmlPath);  if (!file.open(QIODevice::ReadOnly | QFile::Text)) {  QMessageBox::warning(NULL,"error","open for read error...");}  QString errorStr;  int errorLine;  int errorColumn;QDomDocument doc;  if (!doc.setContent(&file, false, &errorStr, &errorLine, &errorColumn)) {  QMessageBox::warning(NULL,"error","setcontent error...");file.close();  }  file.close(); QDir filedir(xmlPath);QDomElement root = doc.documentElement();  if (root.tagName() != "TextureAtlas") {  QMessageBox::warning(NULL,"error","root.tagname != TextureAtlas...");}filedir.cdUp();QString imagepath = filedir.path() + "/" + root.attribute("imagePath");QImage bmp = QImage(imagepath);QDomNode node = root.firstChild();  int i = 1;while(!node.isNull())  {  if(node.isElement())  {  QDomElement element = node.toElement();QString name = element.attribute("name");int x = element.attribute("x").toInt();int y = element.attribute("y").toInt();int width = element.attribute("width").toInt();int height = element.attribute("height").toInt();image_item[i++] = bmp.copy(x, y, width, height);    }node = node.nextSibling(); }
}Plane EntityFactory::GenPlane(QString style)
{if (style == "normal"){QImage tempBmp = image_item[(int)ImgItem::hero_1];return Plane("small", 250,500, tempBmp.width(), tempBmp.height(),0, 0, tempBmp);}else if (style == "super"){QImage tempBmp = image_item[(int)ImgItem::hero_2];return Plane("mid", 350, 700, tempBmp.width(), tempBmp.height(), 0,0, tempBmp);}
}Enemy EntityFactory::GenEnemy(QString size,int speedBase,int width)
{if (size == "small"){QImage tempBmp = image_item[(int)ImgItem::enemy_s];return Enemy("small", qrand()%width+50, 0, tempBmp.width(), tempBmp.height(),qrand()%5-2, qrand()%4+2+speedBase,1,tempBmp);}else if (size == "mid"){QImage tempBmp = image_item[(int)ImgItem::enemy_m];return Enemy("mid", qrand()%width + 50, 0, tempBmp.width(), tempBmp.height(), qrand()% 5 - 2, qrand()% 4 + 1+speedBase, 5, tempBmp);}else if (size == "big"){QImage tempBmp = image_item[(int)ImgItem::enemy_b];return Enemy("big", qrand()%width + 50, 0, tempBmp.width(), tempBmp.height(), qrand()% 3 - 1, qrand()% 3 + 1+speedBase, 20, tempBmp);}
}Bullet EntityFactory::GenBullet(QString style,int p_x,int p_y)
{if (style == "red"){QImage tempBmp = image_item[(int)ImgItem::bullet_0];return Bullet("small", p_x, p_y, tempBmp.width(), tempBmp.height(),0, 20, tempBmp);}else if (style == "blue"){QImage tempBmp = image_item[(int)ImgItem::bullet_1];return Bullet("mid", p_x, p_y, tempBmp.width(), tempBmp.height(),0, 20, tempBmp);}
}Reward EntityFactory::GenReward(QString style, int p_x, int p_y)
{if (style == "bullet_add"){QImage tempBmp = image_item[(int)ImgItem::bullet_add];return Reward("bullet_add", p_x, p_y, tempBmp.width(), tempBmp.height(), qrand() % 5 - 2, 3,5000, tempBmp);}else if (style == "boom_add"){QImage tempBmp = image_item[(int)ImgItem::boom_add];return Reward("boom_add", p_x, p_y, tempBmp.width(), tempBmp.height(), qrand() % 5 - 2, 3,5000, tempBmp);}
}QImage EntityFactory::GetBoomIcon()
{return image_item[(int)ImgItem::bomb_icon];
}Explosion EntityFactory::GenExplosion(QString style, int p_x, int p_y)
{if (style == "small"){QList<QImage> tempBmp;tempBmp.append(image_item[(int)ImgItem::explosion_01]);tempBmp.append(image_item[(int)ImgItem::explosion_02]);tempBmp.append(image_item[(int)ImgItem::explosion_03]);tempBmp.append(image_item[(int)ImgItem::explosion_02]);tempBmp.append(image_item[(int)ImgItem::explosion_01]);return Explosion(p_x, p_y, 300, tempBmp);}else if (style == "mid"){QList<QImage> tempBmp;tempBmp.append(image_item[(int)ImgItem::explosion_01]);return Explosion(p_x, p_y, 500, tempBmp);}else if (style == "big"){QList<QImage> tempBmp;tempBmp.append(image_item[(int)ImgItem::explosion_01]);return Explosion(p_x, p_y, 500, tempBmp);}
}ThreadMusicPlay::ThreadMusicPlay(QString musicPath,int msec)
{this->musicPath = musicPath;this->msec = msec;
}
ThreadMusicPlay::~ThreadMusicPlay()
{}
void ThreadMusicPlay::setFilePath(QString musicPath,int msec)
{this->musicPath = musicPath;this->msec = msec;
}
void ThreadMusicPlay::run()
{QSound::play(this->musicPath);this->msleep(msec);
}PlayPlane::PlayPlane(QWidget *parent, Qt::WFlags flags): QWidget(parent, flags)
{score = 0;boom_count = 5;pause = false;block_time = 1;block_interval = 0;send_time = 0;send_interval = 0;reward_time = 1;reward_interval = 0;rwd_bullet_stnTime = 0;backY = 0;EntityFactory::InitFactory("resource/plane.xml");background = QImage("resource/bg_02.jpg");plane = EntityFactory::GenPlane("normal");this->setCursor(Qt::BlankCursor);this->cursor().setPos(QPoint(plane.X + this->x(), plane.Y + this->y()));connect(&t_draw,SIGNAL(timeout()),this,SLOT(timedraw()));t_draw.setInterval(20);send_interval = 100 / t_draw.interval();block_interval = 260 / t_draw.interval();reward_interval = 5000 / t_draw.interval();t_draw.start();music_BOMB3 = new MusicPlay("resource/BOMB3.wav");music_shoot = new MusicPlay("resource/shoot.wav");music_explosion = new MusicPlay("resource/explosion.wav");b_GameOver = false;setMouseTracking(true);
}PlayPlane::~PlayPlane()
{delete music_BOMB3;delete music_shoot;delete music_explosion;
}void PlayPlane::timedraw()
{t_draw.stop();if(pause){update();t_draw.start();return;}//发射子弹if (send_time > send_interval){if (rwd_bullet_stnTime > 0)//双弹未结束{bullet_lsit.push_back(EntityFactory::GenBullet("blue", plane.X - 6, plane.Y - 50));bullet_lsit.push_back(EntityFactory::GenBullet("blue", plane.X + 6, plane.Y - 50));rwd_bullet_stnTime -= t_draw.interval() * send_interval;}else{bullet_lsit.push_back(EntityFactory::GenBullet("red", plane.X, plane.Y - 50));}threadMusicPlay.setFilePath("resource/shoot.wav",100);threadMusicPlay.start();send_time = 0;}//生产敌军if (block_time % block_interval == 0){int speedBase = 0;if (block_interval < 2)speedBase = 1;if (block_interval < 5)speedBase = 2;else if (block_interval < 10)speedBase = 1;if (block_time % (block_interval * 20) == 0){enemy_lsit.push_back(EntityFactory::GenEnemy("big",speedBase,this->width()));}else if(block_time % (block_interval * 10) == 0){enemy_lsit.push_back(EntityFactory::GenEnemy("mid", speedBase,this->width()));}else{enemy_lsit.push_back(EntityFactory::GenEnemy("small", speedBase,this->width()));}}//奖励if (reward_time == reward_interval){if (qrand() % 2 == 0){reward_list.push_back(EntityFactory::GenReward("bullet_add", qrand() %(this->width())+50, 0));}else{reward_list.push_back(EntityFactory::GenReward("boom_add", qrand() %(this->width())+50, 0));}reward_time = 0;}send_time++;block_time++;reward_time++;//飞机提升水平if (send_interval>0 && score > plane.Level * plane.Level * 50000){plane.LevelUp();send_interval--;}//敌军提升水平if (block_interval > 1 && block_time % 300 == 300-1){block_interval--;}//碰撞for (int i = 0; i < enemy_lsit.size(); i++){for (int j = 0; j < bullet_lsit.size(); j++){if (qAbs(bullet_lsit[j].X - enemy_lsit[i].X) < (bullet_lsit[j].Width + enemy_lsit[i].Width) / 2 && qAbs(bullet_lsit[j].Y - enemy_lsit[i].Y) < (bullet_lsit[j].Height + enemy_lsit[i].Height) / 2){enemy_lsit[i].HP--;if (enemy_lsit[i].HP == 0)//explose{//socre ++if (enemy_lsit[i].Name == "small") score += 1000;else if (enemy_lsit[i].Name == "mid") score += 6000;else if (enemy_lsit[i].Name == "big") score += 25000;//add to explosionexplosion_list.push_back(EntityFactory::GenExplosion("small", enemy_lsit[i].X, enemy_lsit[i].Y));threadMusicPlay.setFilePath("resource/explosion.wav",200);threadMusicPlay.start();//remove bothenemy_lsit.removeAt(i);bullet_lsit.removeAt(j);}else{bullet_lsit.removeAt(j);}break;}}}//获取奖励for (int i = 0; i < reward_list.size(); i++){if (qAbs(plane.X - reward_list[i].X) < (plane.Width + reward_list[i].Width) / 2 && qAbs(plane.Y -reward_list[i].Y) < (plane.Height + reward_list[i].Height) / 2){if (reward_list[i].Name == "bullet_add"){rwd_bullet_stnTime += reward_list[i].StnTimes;}else if (reward_list[i].Name == "boom_add"){boom_count++;}reward_list.removeAt(i);}}//飞机碰撞检测for (int i = 0; i < enemy_lsit.size(); i++){bool isCrashed = false;if (qAbs(plane.X - enemy_lsit[i].X) < (plane.Width / 4 + enemy_lsit[i].Width) / 2 && qAbs(plane.Y -enemy_lsit[i].Y) < (plane.Height - 30 + enemy_lsit[i].Height) / 2){isCrashed = true;}if (isCrashed){t_draw.stop();this->setCursor(Qt::ForbiddenCursor);threadMusicPlay.setFilePath("resource/BOMB5.wav",200);threadMusicPlay.start();b_GameOver = true;update();return;}}update();t_draw.start();
}void PlayPlane::paintEvent ( QPaintEvent * e )
{ QPainter painter(this);//背景图painter.drawImage(QRect(0, - this->height() + backY, this->width(),this->height()),background);painter.drawImage(QRect(0, backY, this->width(),this->height()),background);backY += 2;if (backY > this->height())backY = 0;//飞机painter.drawImage(QPoint(plane.X - plane.Width / 2, plane.Y - plane.Height / 2),plane.Image);//子弹for (int i = 0; i < bullet_lsit.size(); i++){painter.drawImage(QPoint(bullet_lsit[i].X - bullet_lsit[i].Width / 2, bullet_lsit[i].Y -bullet_lsit[i].Height / 2),bullet_lsit[i].Image);bullet_lsit[i].Y -= bullet_lsit[i].SpeedY;if (bullet_lsit[i].Y < -40){bullet_lsit.removeAt(i);}}//奖励for (int i = 0; i < reward_list.size(); i++){painter.drawImage(QPoint(reward_list[i].X - reward_list[i].Width / 2, reward_list[i].Y -reward_list[i].Height / 2),reward_list[i].Image);reward_list[i].Y += reward_list[i].SpeedY;reward_list[i].X += reward_list[i].SpeedX;if (reward_list[i].Y > this->height() + 20){reward_list.removeAt(i);}}//炸弹QImage boom_icon = EntityFactory::GetBoomIcon();if (boom_count > 0){painter.drawImage(QPoint(10, this->height() - 40 - boom_icon.height()),boom_icon);QFont font("微软雅黑",18);painter.setFont(font);painter.setPen(Qt::gray);painter.drawText(QPoint(10 + boom_icon.width(),this->height() -15 - boom_icon.height()),"×" + QString::number(boom_count));}//敌军for (int i = 0; i < enemy_lsit.size(); i++){painter.drawImage(QPoint(enemy_lsit[i].X - enemy_lsit[i].Width / 2, enemy_lsit[i].Y -enemy_lsit[i].Height / 2),enemy_lsit[i].Image);enemy_lsit[i].Y += enemy_lsit[i].SpeedY;enemy_lsit[i].X += enemy_lsit[i].SpeedX;if (enemy_lsit[i].X > this->width() || enemy_lsit[i].X < 0){enemy_lsit[i].SpeedX = -enemy_lsit[i].SpeedX;}if (enemy_lsit[i].Y > this->width() + 20){enemy_lsit.removeAt(i);}}//爆炸效果for (int i = 0; i < explosion_list.size(); i++){QImage temp_explose = explosion_list[i].Images[explosion_list[i].Counter / (explosion_list[i].StnTimes /explosion_list[i].Images.size())];painter.drawImage(QPoint(explosion_list[i].X - temp_explose.width() / 2, explosion_list[i].Y -temp_explose.height() / 2),temp_explose);explosion_list[i].Counter += 24;if (explosion_list[i].Counter > explosion_list[i].StnTimes)explosion_list.removeAt(i);}QFont font("微软雅黑",14);painter.setFont(font);painter.setPen(Qt::green);painter.drawText(QPointF(10, 20),"分数:" + QString::number(score));painter.drawText(QPointF(this->width() - 90, 20),"等级:" + (send_interval == 1 ? "满级" : QString::number(plane.Level)));if(b_GameOver){QFont font("微软雅黑",22);painter.setFont(font);painter.setPen(Qt::red);painter.drawText(QPointF(this->width()/2-80, this->height()/2-50),QString("Game Over"));return;}if(pause){QFont font("微软雅黑",22);painter.setFont(font);painter.setPen(Qt::red);painter.drawText(QPointF(this->width()/2-30, this->height()/2-50),QString("暂 停"));return;  }
}void PlayPlane::mouseMoveEvent ( QMouseEvent * e )
{ if(b_GameOver){return;}if (!pause){plane.X = e->x();plane.Y = e->y();}
}void PlayPlane::mousePressEvent ( QMouseEvent * e )
{ if (!pause && e->button() == Qt::RightButton){if (boom_count > 0){boom_count--;for (int i = 0; i < enemy_lsit.size(); i++){//socre ++if (enemy_lsit[i].Name == "small") score += 1000;else if (enemy_lsit[i].Name == "mid") score += 6000;else if (enemy_lsit[i].Name == "big") score += 25000;//add to explosionexplosion_list.push_back(EntityFactory::GenExplosion("small", enemy_lsit[i].X, enemy_lsit[i].Y));}threadMusicPlay.setFilePath("resource/BOMB3.wav",500);threadMusicPlay.start();enemy_lsit.clear();}}
}void PlayPlane::keyPressEvent ( QKeyEvent * e )
{  if(b_GameOver){return;}if (e->key() == ' '){pause = !pause;if(pause){t_draw.stop();this->setCursor(Qt::ForbiddenCursor);update();}else{t_draw.start();this->setCursor(Qt::BlankCursor);this->cursor().setPos(QPoint(plane.X + this->x(), plane.Y + this->y()));}}
}void PlayPlane::leaveEvent ( QEvent * e )
{}void PlayPlane::enterEvent ( QEvent * e )
{ }

main入口:

#include "playplane.h"
#include <QtGui/QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);    QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312"));QTextCodec::setCodecForLocale(QTextCodec::codecForName("GB2312"));QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));PlayPlane w;w.resize(480,600);w.show();return a.exec();
}

微信打飞机升级版(Qt实现)相关推荐

  1. pygame开发PC端微信打飞机游戏

    pygame开发PC端微信打飞机游戏  一.项目简介1. 介绍本项目类似曾经火爆的微信打飞机游戏.游戏将使用Python语言开发,主要用到pygame的API.游戏最终将会以python源文件game ...

  2. swing版本山寨微信打飞机

    闲来无事,顺便想想当前小时候用铅笔画素描的那种感觉,所以山寨着微信的飞机大战画了一个,其实画的还可以把,哈哈哈.... 游戏做的比较粗糙和简陋,希望大家体谅下.j.k.l.i分别控制飞机的左上右下.

  3. 游戏‘微信打飞机’ 第二课

    #include <yzkgame.h> #pragma comment( linker, "/subsystem:\"console\" /entry:\& ...

  4. 游戏‘微信打飞机 第一课

    #include <yzkgame.h> #pragma comment( linker, "/subsystem:\"console\" /entry:\& ...

  5. 案例十三、模仿微信打飞机游戏

    首先实现微信打飞机游戏,首先会有自己和敌机,采用canvas绘图来生成自己和敌人. 1.生成自己,且可以通过左右键来进行左右移动. //生成自己,且可以左右移动 //控制飞机向右移动的函数functi ...

  6. 游戏‘微信打飞机’ 第三课

    #include <yzkgame.h> #pragma comment( linker, "/subsystem:\"console\" /entry:\& ...

  7. 微信打飞机小游戏的尝试

    微信打飞机小游戏的尝试 问题:微信打飞机游戏出现不断跳出的问题 原因:未加return. ​

  8. JS微信打飞机游戏(一)

    模拟微信打飞机游戏,JavaScript+HTML5+css实现,随后版本可能移植到Android和IOS. 首个版本里,仅实现按住键盘移动飞机移动. 不必解释过多,代码里面有注释. <!DOC ...

  9. Python编写微信打飞机小游戏(三)

    如果觉得这篇文章对您有所启发,欢迎关注我的公众号,我会尽可能积极和大家交流,谢谢. Python编写微信打飞机小游戏(一) Python编写微信打飞机小游戏(二) Python编写微信打飞机小游戏(三 ...

最新文章

  1. 数人云CEO王璞:容器正成为软件交付的标准
  2. Leetcode 344. 反转字符串 解题思路及C++实现
  3. java arrays.sort() c_5.4 (Java学习笔记)集合的排序(Collections.sort(),及Arrays.sort())...
  4. node.js require 自动执行脚本 并生成html,nodejs 执行脚本并实时输出
  5. onCreateOptionsMenu
  6. 120万人同时在线考试,这么大的流量如何支撑
  7. 多麦克风做拾音的波束_麦克风丨人声应该用动圈话筒还是电容话筒?
  8. 后台启动_Linux系统后台运行应用三板斧
  9. Typedef声明简介
  10. MySQL vs. MongoDB: Choosing a Data Management Solution
  11. 物理内存管理之zone详解
  12. Java实现:堆排序
  13. 人工智能 一种现代方法 第4章 超越经典搜索
  14. 水晶报表教程:手把手教你制作基本报表
  15. 朋友让帮忙写个理发店的会员信息管理系统...
  16. 计算机毕业设计Java校园约拍系统(源码+系统+mysql数据库+Lw文档)
  17. 爆笑!让你捧腹大笑的标语
  18. 7-3 找零钱***分数 20作者 李祥单位 湖北经济学院
  19. MASM汇编入门:寄存器数据的使用
  20. Codeforces Round #277.5 (Div. 2) A,B,C,D,E,F题解

热门文章

  1. Webservice调用天气接口案例
  2. Word启动时进入“安全模式”解决办法
  3. 如何获得Oracle分区索引类型
  4. Python趣味案例——剪刀石头布小游戏改进版(自由实现三局两胜五局三胜七局四胜。。。)
  5. Halcon快速读取点云的方法
  6. 大数据可以揭示基因密码吗?
  7. 计算机视觉方面的三大国际会议及期刊会议影响因子
  8. python 凯利公式_凯利公式的模拟验证
  9. 4款精美绝伦的优质软件,一个比一个精彩
  10. 【C++】17.map和set的模拟实现