MC2D v0.0.6 Source Code
目录
- MC2D v0.0.6 Source Code
- Declaration
- main.cpp
- basewidget.h
- basewidget.cpp
- maininterface.h
- maininterface.cpp
- selectworld.h
- selectworld.cpp
- optionwidget.h
- optionwidget.cpp
- createmap.h
- createmap.cpp
- gamewidget.h
- gamewidget.cpp
- Tool.cpp
MC2D v0.0.6 Source Code
Declaration
A Minecraft 2D Version Powered By Qt
main.cpp
#include "Tool.h"
#include "selectworld.h"
#include "maininterface.h"
#include "optionwidget.h"
#include "createmap.h"
#include "gamewidget.h"int main(int argc, char *argv[]) {QApplication a(argc, argv);MainInterface *main_interface = new MainInterface(nullptr, 1280, 720, TITLE);SelectWorld *select_world = new SelectWorld(nullptr, 1280, 720, TITLE);OptionWidget *option_widget = new OptionWidget(nullptr, 1280, 720, TITLE);CreateMap *create_map = new CreateMap(nullptr, 1280, 720, TITLE);GameWidget *game_widget = new GameWidget(30, nullptr, 1280, 720, TITLE);/* Main Interface -> Select Map */QObject::connect(main_interface, &MainInterface::select_world, [=]() {select_world->updateMapList();select_world->Show(main_interface);});/* Select Map -> Main Interface*/QObject::connect(select_world, &SelectWorld::main_interface, [=]() {main_interface->Show(select_world);});/* Select Map -> Create Map */QObject::connect(select_world, &SelectWorld::create_map, [=]() {create_map->Show(select_world);});/* Main Interface -> Option Widget */QObject::connect(main_interface, &MainInterface::option, [=]() {option_widget->Show(main_interface);});/* Option Widget -> Main Interface*/QObject::connect(option_widget, &OptionWidget::main_interface, [=]() {main_interface->Show(option_widget);});/* Create Map -> Select World*/QObject::connect(create_map, &CreateMap::select_world, [=]() {select_world->updateMapList();select_world->Show(create_map);});QObject::connect(select_world, &SelectWorld::game_widget, [=]() {game_widget->startGame();game_widget->Show(select_world);});QObject::connect(option_widget, &OptionWidget::update_setting, [=]() {/* Update Font */if(option_widget->langMode == 1)option_widget->setLang->langs->setCurrentIndex(0);else if(option_widget->langMode == 2)option_widget->setLang->langs->setCurrentIndex(1);else if(option_widget->langMode == 3)option_widget->setLang->langs->setCurrentIndex(2);else if(option_widget->langMode == 4)option_widget->setLang->langs->setCurrentIndex(3);main_interface->updateFont(option_widget->font());select_world->updateFont(option_widget->font());option_widget->updateFont(option_widget->font());create_map->updateFont(option_widget->font());main_interface->updateLang(option_widget->langMode);option_widget->updateLang(option_widget->langMode);select_world->updateLang(option_widget->langMode);create_map->updateLang(option_widget->langMode);});QObject::connect(main_interface, &BaseWidget::GameOver, [=]() {sendInfo("Game has been over");option_widget->saveSetting();exit(0);});QObject::connect(select_world, &BaseWidget::GameOver, [=]() {sendInfo("Game has been over");option_widget->saveSetting();exit(0);});QObject::connect(option_widget, &BaseWidget::GameOver, [=]() {sendInfo("Game has been over");option_widget->saveSetting();exit(0);});QObject::connect(create_map, &BaseWidget::GameOver, [=]() {sendInfo("Game has been over");option_widget->saveSetting();exit(0);});option_widget->loadSetting();/* Start Game (Centered) */main_interface->Show((QApplication::desktop()->width() - 1280) / 2, (QApplication::desktop()->height() - 720) / 2, 0);return a.exec();
}
basewidget.h
#ifndef BASEWIDGET_H
#define BASEWIDGET_H#include "Tool.h"/* A Basic Widget in Game */
class BaseWidget : public QWidget {Q_OBJECT
public:explicit BaseWidget(QWidget *parent = nullptr,int width = 1280,int height = 720,QString title = TITLE);void Show(int x = 0, int y = 0, int mode = 0);void Show(BaseWidget *widget);void Hide();virtual void updateFont(QFont font);void closeEvent(QCloseEvent *event) override;virtual void updateLang(int langMode);int langMode;/* Button Clicked Sound */QSound *buttonSound = new QSound(":/sound/musics/ButtonClicked.wav");signals:void GameOver();void widgetShow();
};#endif // BASEWIDGET_H
basewidget.cpp
#include "basewidget.h"BaseWidget::BaseWidget(QWidget *parent,int width,int height,QString title) {/* Init Widget */this->setWindowIcon(QIcon(":/gui/images/gui/icon.png"));this->setParent(parent);this->resize(width, height);this->setWindowTitle(title);
}void BaseWidget::Show(int x, int y, int mode) {/* Mode == 0 : Normal *//* Mode == 1 : Maximized *//* Mode == 2 : FullScreen */if(!mode) this->move(x, y);switch(mode) {case 0: this->showNormal(); break;case 1: this->showMaximized(); break;case 2: this->showFullScreen(); break;}sendInfo("Widget Has Been Shown");widgetShow();
}void BaseWidget::Show(BaseWidget *widget)
{widget->Hide();if(widget->isMaximized()) this->Show(0, 0, 1);else if(widget->isFullScreen()) this->Show(0, 0, 2);else {this->resize(widget->width(), widget->height());this->Show(widget->x(), widget->y());}widgetShow();
}void BaseWidget::Hide() {this->hide();sendInfo("Widget Has Been Hidden");
}void BaseWidget::updateFont(QFont font)
{setFont(font);
}void BaseWidget::closeEvent(QCloseEvent *event)
{GameOver();
}void BaseWidget::updateLang(int langMode)
{if(langMode == 1) {setWindowTitle(CN_TITLE);} else if(langMode == 2) {setWindowTitle(TITLE);}sendInfo("Lang has been updated");
}
maininterface.h
#ifndef MAININTERFACE_H
#define MAININTERFACE_H#include "basewidget.h"class MainInterface : public BaseWidget
{Q_OBJECT
public:explicit MainInterface(QWidget *parent = nullptr,int width = 1280,int height = 720,QString title = nullptr);void paintEvent(QPaintEvent *event) override;void resizeEvent(QResizeEvent *event) override;void keyPressEvent(QKeyEvent *event) override;void updateFont(QFont font) override;void updateLang(int langMode) override;/* Image */QImage titleImg = QImage(":/gui/images/gui/title.png");QImage bg = QImage(":/gui/images/gui/bg.png");int titleWidth = titleImg.width(), titleHeight = titleImg.height();/* Button */GameButton *SinglePlayer = new GameButton( ("SinglePlayer"), this);GameButton *MultiPlayer = new GameButton( ("MultiPlayer"), this);GameButton *Exit = new GameButton( ("Exit"), this);GameButton *Option = new GameButton( ("Options..."), this);/* Text */QStaticText GameInfoText = QStaticText( ("Minecraft 2D Author: Bili_TianX"));signals:void select_world();void option();
};#endif // MAININTERFACE_H
maininterface.cpp
#include "maininterface.h"MainInterface::MainInterface(QWidget *parent, int width, int height, QString title) : BaseWidget(parent, width, height, title)
{/* Init Buttons */MultiPlayer->setEnabled(false);connect(SinglePlayer, &QPushButton::clicked, [=]() {sendInfo("Player Clicked SinglePlayer Button");buttonSound->play();select_world();});connect(MultiPlayer, &QPushButton::clicked, [=]() {sendInfo("Player Clicked MultiPlayer Button");sendError("MultiPlayer Button is Invalid");buttonSound->play();});connect(Option, &QPushButton::clicked, [=]() {sendInfo("Player Clicked Option Button");buttonSound->play();option();});connect(Exit, &QPushButton::clicked, [=]() {sendInfo("Player Clicked Exit Button");buttonSound->play();GameOver();});
}void MainInterface::paintEvent(QPaintEvent *event)
{QPainter p(this);/* Draw Background */p.drawImage(QRect(0, 0, width(), height()), bg);/* Draw Title */p.drawImage(19 * width() / 160,35 * height() / 288,titleImg.scaled(titleWidth * width() / 1280,titleHeight * height() / 720));/* Draw Text */p.setFont(this->font());p.setPen(QColor(255, 255, 255));p.drawStaticText(QPoint(10, height() - GameInfoText.size().height() - 5), GameInfoText);
}void MainInterface::resizeEvent(QResizeEvent *event)
{/* Update The Buttons Size */SinglePlayer->resize(400 * width() / 1280, 40 * height() / 720);MultiPlayer->resize(400 * width() / 1280, 40 * height() / 720);Option->resize(400 * width() / 1280, 40 * height() / 720);Exit->resize(400 * width() / 1280, 40 * height() / 720);/* Update The Buttons Position */SinglePlayer->move(440 * width() / 1280, 360 * height() / 720); // 360 + 40 * 1MultiPlayer->move(440 * width() / 1280, 440 * height() / 720); // 360 + 40 * 3Option->move(440 * width() / 1280, 520 * height() / 720); // 360 + 40 * 5Exit->move(440 * width() / 1280, 600 * height() / 720); // 360 + 40 * 7
}void MainInterface::keyPressEvent(QKeyEvent *event)
{switch(event->key()) {/* F11 -> Full Screen */case Qt::Key_F11:if(!isFullScreen()) this->showFullScreen();else this->showNormal();break;/* ESC -> Exit Game */case Qt::Key_Escape:GameOver();}
}void MainInterface::updateFont(QFont font)
{setFont(font);SinglePlayer->setFont(font);MultiPlayer->setFont(font);Option->setFont(font);Exit->setFont(font);GameInfoText.prepare(QTransform(), font);
}void MainInterface::updateLang(int langMode)
{this->langMode = langMode;if(langMode == 1) {SinglePlayer->setText("单人游戏");MultiPlayer->setText("多人游戏");Option->setText("选项...");Exit->setText("退出");setWindowTitle(CN_TITLE);GameInfoText.setText("我的世界 2D 作者:B站天下wu双");} else if(langMode == 2) {SinglePlayer->setText("SinglePlayer");MultiPlayer->setText("MultiPlayer");Option->setText("Option...");Exit->setText("Exit");setWindowTitle(TITLE);GameInfoText.setText("Minecraft 2D Author: Bili_TianX");} else if(langMode == 3) {SinglePlayer->setText("單人游戲");MultiPlayer->setText("多人游戲");Option->setText("選項...");Exit->setText("退出");setWindowTitle(TW_TITLE);GameInfoText.setText("我的世界 2D 作者: B站天下wu雙");} else if(langMode == 4) {SinglePlayer->setText("シングルプレイヤー");MultiPlayer->setText("マルチプレイヤー");Option->setText("オプション...");Exit->setText("出口");setWindowTitle(JP_TITLE);GameInfoText.setText("マインクラフト 2D 作者: Bili_TianX");}sendInfo("Lang has been updated");
}
selectworld.h
#ifndef SELECTWORLD_H
#define SELECTWORLD_H#include "basewidget.h"struct MapList : public QListWidget {QListWidgetItem item;MapList(QWidget *parent) : QListWidget(parent) {setStyleSheet("QListWidget{background-color:rgba(0, 0, 0, 0);border:0px;color:white;outline:0px;}""QListWidget::item:selected:!active{color:white;border:2px solid grey;background-color:black;}""QListWidget::item:selected:active{color:white;border:2px solid grey;background-color:black;}""QListWidget::item:hover{color:none;border:none;background:none;}");QScrollBar *qsb = new QScrollBar(this);qsb->setStyleSheet("QScrollBar:vertical {border: none;background: black;}""QScrollBar::handle:vertical {background: rgb(192, 192, 192);border:2px solid grey;}""QScrollBar::add-line:vertical {border: 0px;background: black;height: 20px;subcontrol-position: bottom;subcontrol-origin: margin;}""QScrollBar::sub-line:vertical {border: 0px;background: black;height: 20px;subcontrol-position: top;subcontrol-origin: margin;}""QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {border: none;background: none;}""QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {background: none;}");setVerticalScrollBar(qsb);}
};/* A Widget to Select World */
class SelectWorld : public BaseWidget
{Q_OBJECT
public:explicit SelectWorld(QWidget *parent = nullptr,int width = 1280,int height = 720,QString title = nullptr);void paintEvent(QPaintEvent *event) override;void resizeEvent(QResizeEvent *event) override;void keyPressEvent(QKeyEvent *event) override;void updateFont(QFont font) override;void updateLang(int langMode) override;void updateMapList();/* Images */QImage bg = QImage(":/gui/images/gui/SelectWorld.png");/* Buttons */GameButton *PlaySelectedWorld = new GameButton( ("Play Selected World"), this);GameButton *CreateNewWorld = new GameButton( ("Create New World"), this);GameButton *Rename = new GameButton( ("Rename"), this);GameButton *Delete = new GameButton( ("Delete"), this);GameButton *ReCreate = new GameButton( ("Re-Create"), this);GameButton *Cancel = new GameButton( ("Cancle"), this);/* Text */QStaticText SelectWorldText = QStaticText( ("Select World"));MapList *list = new MapList(this);private:QString getTitle() {switch(langMode) {case 1:return "删除地图";break;case 2:return "Delete Map";break;case 3:return "刪除地圖";break;case 4:return "削除マップ";break;default:return "";};};QString getText(){switch(langMode) {case 1:return QString("确定删除地图 : \"" + list->currentItem()->text() +"\"?");break;case 2:return "Be Sure To Delete The Map : \"" + list->currentItem()->text() +"\"?";break;case 3:return "確定刪除地圖 : \"" + list->currentItem()->text() +"\"?";break;case 4:return "地図を削除するには : \"" + list->currentItem()->text() +"\"?";break;default:return "";};};
signals:void main_interface();void create_map();void game_widget();
};#endif // SELECTWORLD_H
selectworld.cpp
#include "selectworld.h"SelectWorld::SelectWorld(QWidget *parent, int width, int height, QString title) : BaseWidget(parent, width, height, title)
{updateMapList();connect(list, &QListWidget::itemSelectionChanged, [=](){sendInfo(list->currentItem()->text());Delete->setEnabled(true);PlaySelectedWorld->setEnabled(true);});/* Init Buttons */PlaySelectedWorld->setEnabled(false);Rename->setEnabled(false);Delete->setEnabled(false);ReCreate->setEnabled(false);connect(PlaySelectedWorld, &QPushButton::clicked, [=]() {sendInfo("Player Clicked PlaySelectedWorld Button");buttonSound->play();game_widget();});connect(CreateNewWorld, &QPushButton::clicked, [=]() {sendInfo("Player Clicked CreateNewWorld Button");create_map();buttonSound->play();});connect(Delete, &QPushButton::clicked, [=]() {sendInfo("Player Clicked Delete Button");buttonSound->play();if (QMessageBox::Yes == QMessageBox::question(this,getTitle(),getText(),QMessageBox::Yes | QMessageBox::No,QMessageBox::Yes)) {sendInfo("Will be deleted map:" + list->currentItem()->text());QDir dir("saves/"+list->currentItem()->text());dir.removeRecursively();updateMapList();}});connect(Rename, &QPushButton::clicked, [=]() {sendInfo("Player Clicked Rename Button");buttonSound->play();});connect(ReCreate, &QPushButton::clicked, [=]() {sendInfo("Player Clicked ReCreate Button");buttonSound->play();});connect(Cancel, &QPushButton::clicked, [=]() {sendInfo("Player Clicked Cancel Button");buttonSound->play();main_interface();});
}void SelectWorld::paintEvent(QPaintEvent *event)
{QPainter p(this);/* Draw Background */p.drawImage(QRect(0, 0, width(), height()), bg);/* Draw Text */p.setFont(font());p.setPen(QColor(255, 255, 255));p.drawStaticText((width() - SelectWorldText.size().width()) / 2,(140 * height() / 720 - SelectWorldText.size().height() - 5),SelectWorldText);
}void SelectWorld::resizeEvent(QResizeEvent *event)
{/* Update The Buttons Size */int tmpWidth = 190 * width() / 1280, tmpHeight = 40 * height() / 720;PlaySelectedWorld->resize(400 * width() / 1280, 40 * height() / 720);CreateNewWorld->resize(400 * width() / 1280, 40 * height() / 720);Rename->resize(tmpWidth, tmpHeight);Delete->resize(tmpWidth, tmpHeight);ReCreate->resize(tmpWidth, tmpHeight);Cancel->resize(tmpWidth, tmpHeight);/* h - 28 * 2 * h / 144 */list->resize(4 * width() / 7, height() - 56 * height() / 144);/* Update The Buttons Position */PlaySelectedWorld->move(230 * width() / 1280, 600 * height() / 720);CreateNewWorld->move(650 * width() / 1280, 600 * height() / 720);Rename->move(230 * width() / 1280, 660 * height() / 720);Delete->move(440 * width() / 1280, 660 * height() / 720);ReCreate->move(650 * width() / 1280, 660 * height() / 720);Cancel->move(860 * width() / 1280, 660 * height() / 720);list->move((width() - list->width()) / 2, 28 * height() / 144);
}void SelectWorld::keyPressEvent(QKeyEvent *event)
{switch (event->key()) {/* F11 -> Full Screen */case Qt::Key_F11:if(!isFullScreen()) this->showFullScreen();else this->showNormal();break;/* ESC -> Go To Main Interface */case Qt::Key_Escape:main_interface();break;}
}void SelectWorld::updateFont(QFont font)
{setFont(font);PlaySelectedWorld->setFont(font);CreateNewWorld->setFont(font);Rename->setFont(font);Delete->setFont(font);ReCreate->setFont(font);Cancel->setFont(font);list->setFont(font);SelectWorldText.prepare(QTransform(), font);
}void SelectWorld::updateLang(int langMode)
{this->langMode = langMode;if(langMode == 1) {PlaySelectedWorld->setText("进入选中的世界");CreateNewWorld->setText("创建新的世界");Rename->setText("重命名");Delete->setText("删除");ReCreate->setText("重建");Cancel->setText("取消");SelectWorldText.setText("选择世界");setWindowTitle(CN_TITLE);} else if(langMode == 2) {PlaySelectedWorld->setText("Play Selected World");CreateNewWorld->setText("Create New World");Rename->setText("Rename");Delete->setText("Delete");ReCreate->setText("Re-Create");Cancel->setText("Cancel");SelectWorldText.setText("Select World");setWindowTitle(TITLE);} else if(langMode == 3) {PlaySelectedWorld->setText("進入選中的世界");CreateNewWorld->setText("創建新的世界");Rename->setText("重命名");Delete->setText("刪除");ReCreate->setText("重建");Cancel->setText("取消");SelectWorldText.setText("選擇世界");setWindowTitle(TW_TITLE);} else if(langMode == 4) {PlaySelectedWorld->setText("選択された世界を再生する");CreateNewWorld->setText("新しい世界を創造する");Rename->setText("名前の変更");Delete->setText("削除");ReCreate->setText("再作成");Cancel->setText("キャンセル");SelectWorldText.setText("世界を選択");setWindowTitle(JP_TITLE);}
}/* Make Sure the floder is a map */
bool checkMap(QString path) {QFileInfo f1(path + "/map.mc2d"), f2(path + "/setting.mc2d");return f1.isFile() && f2.isFile();
}void SelectWorld::updateMapList()
{list->clear();QDir dir("saves");dir.setFilter(QDir::Dirs);auto fileList = dir.entryInfoList();for(QFileInfo i: fileList) {if(checkMap(i.filePath())) {list->addItem(i.fileName());sendInfo("has been added:" + i.filePath());}}
}
optionwidget.h
#ifndef OPTIONWIDGET_H
#define OPTIONWIDGET_H#include "basewidget.h"struct ChooseLang : public QDialog{QComboBox *langs = new QComboBox;QHBoxLayout *h = new QHBoxLayout();ChooseLang(QWidget *parent = nullptr) : QDialog(parent) {langs->addItem("中文");langs->addItem("English");langs->addItem("繁體中文");langs->addItem("日本語");h->addWidget(langs);this->setLayout(h);this->setFixedSize(250, 50);this->setWindowTitle( ("Choose Language"));}
};class OptionWidget : public BaseWidget
{Q_OBJECT
public:explicit OptionWidget(QWidget *parent = nullptr,int width = 1280,int height = 720,QString title = nullptr);void saveSetting(); // Save Setting From Filevoid loadSetting(); // Load Setting From Filevoid paintEvent(QPaintEvent *event) override;void resizeEvent(QResizeEvent *event) override;void keyPressEvent(QKeyEvent *event) override;void updateFont(QFont font) override;void updateLang(int langMode) override;int langMode = 1; // 1 中文 2 英文/* Widget Background */QImage bg = QImage(":/gui/images/gui/OptionBG.png");/* Widget Text */QStaticText OptionText = QStaticText( ("Options"));/* Widget Button */GameButton *Done = new GameButton( ("Done"), this);GameButton *Font = new GameButton( ("Font..."), this);GameButton *Lang = new GameButton( ("Language"), this);/* Font Select */QFontDialog *SettingFont = new QFontDialog(this);ChooseLang *setLang = new ChooseLang(this);
signals:void main_interface();void update_setting();
};#endif // OPTIONWIDGET_H
optionwidget.cpp
#include "optionwidget.h"OptionWidget::OptionWidget(QWidget *parent, int width, int height, QString title) : BaseWidget(parent, width, height, title)
{/* Init Buttons */connect(Done, &QPushButton::clicked, [=](){sendInfo("Player Clicked Done Button");buttonSound->play();setFont(SettingFont->currentFont());if(setLang->langs->currentIndex() == 0) langMode = 1;else if(setLang->langs->currentIndex() == 1) langMode = 2;else if(setLang->langs->currentIndex() == 2) langMode = 3;else if(setLang->langs->currentIndex() == 3) langMode = 4;update_setting();main_interface();});connect(Font, &QPushButton::clicked, [=]() {sendInfo("Player Clicked Font... Button");buttonSound->play();SettingFont->resize(1024, 768);SettingFont->show();});connect(Lang, &QPushButton::clicked, [=]() {sendInfo("Player Clicked Language Button");setLang->show();});
}void OptionWidget::saveSetting()
{QFile *file = new QFile("settings.json");file->open(QIODevice::WriteOnly);QJsonObject obj;obj.insert("FontFamily", QJsonValue(font().family()));obj.insert("FontSize", QJsonValue(font().pointSize()));obj.insert("Language", QJsonValue(langMode));QJsonDocument doc = QJsonDocument(obj);file->write(doc.toJson());file->close();sendInfo("Setting has been saved");
}void OptionWidget::loadSetting()
{QFile *file = new QFile("settings.json");file->open(QIODevice::ReadOnly);QByteArray b = file->readAll();QJsonParseError *error = new QJsonParseError;QJsonDocument settings = QJsonDocument::fromJson(b, error);if(error->error == QJsonParseError::NoError) {if(settings.isObject()) {QJsonObject obj = settings.object();setFont(QFont(obj["FontFamily"].toString(), obj["FontSize"].toInt()));langMode = obj["Language"].toInt();}} else {sendError("Unable To Load Setting");return;}file->close();update_setting();sendInfo("Setting has been loaded");
}void OptionWidget::paintEvent(QPaintEvent *event)
{QPainter p(this);/* Draw Background */p.drawImage(QRect(0, 0, width(), height()), bg);/* Draw Text */p.setFont(font());p.setPen(QColor(255, 255, 255));p.drawStaticText((width() - OptionText.size().width()) / 2,(OptionText.size().height() * 1.5) * height() / 720,OptionText);
}void OptionWidget::resizeEvent(QResizeEvent *event)
{Done->resize(400 * width() / 1280, 40 * height() / 720);Font->resize(400 * width() / 1280, 40 * height() / 720);Lang->resize(400 * width() / 1280, 40 * height() / 720);Done->move((width() - Done->width()) / 2, height() - Done->height() * 1.5);Font->move((width() / 2 - Font->width()) / 2, 150 * height() / 720);Lang->move(width() / 2 + (width() / 2 - Font->width()) / 2, 150 * height() / 720);
}void OptionWidget::keyPressEvent(QKeyEvent *event)
{switch (event->key()) {/* F11 -> Full Screen */case Qt::Key_F11:if(!isFullScreen()) this->showFullScreen();else this->showNormal();break;/* ESC -> Go To Main Interface */case Qt::Key_Escape:main_interface();break;}
}void OptionWidget::updateFont(QFont font)
{setFont(font);Done->setFont(font);Font->setFont(font);Lang->setFont(font);setLang->setFont(font);setLang->langs->setFont(font);SettingFont->setFont(font);OptionText.prepare(QTransform(), font);SettingFont->setCurrentFont(this->font());
}void OptionWidget::updateLang(int langMode)
{this->langMode = langMode;if(langMode == 1) {Done->setText("完成");Lang->setText("语言...");Font->setText("字体...");setLang->setWindowTitle("选择语言");OptionText.setText("选项");SettingFont->setWindowTitle("选择字体");setWindowTitle(CN_TITLE);} else if(langMode == 2) {Done->setText("Done");Lang->setText("Language...");Font->setText("Font...");setLang->setWindowTitle("Choose Language");OptionText.setText("Options");SettingFont->setWindowTitle("Select Font");setWindowTitle(TITLE);} else if(langMode == 3) {Done->setText("完成");Lang->setText("語言...");Font->setText("字體...");setLang->setWindowTitle("選擇語言");OptionText.setText("選項");SettingFont->setWindowTitle("選擇字體");setWindowTitle(TW_TITLE);} else if(langMode == 4) {Done->setText("了");Lang->setText("言語...");Font->setText("フォント...");setLang->setWindowTitle("言語を選択");OptionText.setText("オプション");SettingFont->setWindowTitle("フォントを選択");setWindowTitle(JP_TITLE);}
}
createmap.h
#ifndef CREATEMAP_H
#define CREATEMAP_H#include "basewidget.h"struct CreatingWorld : QDialog{QProgressBar *pb = new QProgressBar();QVBoxLayout *v = new QVBoxLayout();CreatingWorld(QWidget *parent = nullptr) : QDialog(parent) {v->addWidget(pb);pb->setRange(0, 100);pb->setFormat("Current Progress: %p%");pb->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);setFixedSize(500, 50);setLayout(v);};
};/* A Widget to Create a Map */
class CreateMap : public BaseWidget
{Q_OBJECT
public:explicit CreateMap(QWidget *parent = nullptr,int width = 1280,int height = 720,QString title = nullptr);void paintEvent(QPaintEvent *event) override;void resizeEvent(QResizeEvent *event) override;void keyPressEvent(QKeyEvent *event) override;void updateFont(QFont font) override;void updateLang(int langMode) override;/* Images */QImage bg = QImage(":/gui/images/gui/OptionBG.png");/* Widget Text */QStaticText createText = QStaticText("Create New World");GameLabel *WorldNameLabel = new GameLabel("Will be saved in:", this);GameLabel *Label1 = new GameLabel("World Name", this);GameLineEdit *inputWorldName = new GameLineEdit(this);GameButton *Cancel = new GameButton("Cancel", this);GameButton *CreateNewWorld = new GameButton("Create New World", this);CreatingWorld *cw = new CreatingWorld(this);QString curMapName;
signals:void select_world();
};#endif // CREATEMAP_H
createmap.cpp
#include "createmap.h"CreateMap::CreateMap(QWidget *parent, int width, int height, QString title) : BaseWidget(parent, width, height, title)
{QObject::connect(Cancel, &GameButton::clicked, [=]() {sendInfo("Player Clicked Cancel Button");buttonSound->play();select_world();});QObject::connect(CreateNewWorld, &GameButton::clicked, [=](){sendInfo("Player Clicked CreateNewWorld Button");buttonSound->play();cw->show();Map gameMap = Map(curMapName);/* Step 1: Gen Bedrock */for(int i = 0; i < MapWidth; ++i) {gameMap.MAPP[MapHeight - 1][i] = BLOCK::BEDROCK;cw->pb->setValue(5.0 * i / MapWidth);switch(langMode) {case 1:cw->pb->setFormat(QString("生成基岩中......: %1%").arg(QString::number(5.0 * i / MapWidth, 'f', 2)));break;case 2:cw->pb->setFormat(QString("Generating Bedrock......: %1%").arg(QString::number(5.0 * i / MapWidth, 'f', 2)));break;case 3:cw->pb->setFormat(QString("生成基岩中......: %1%").arg(QString::number(5.0 * i / MapWidth, 'f', 2)));break;case 4:cw->pb->setFormat(QString("岩盤の生成......: %1%").arg(QString::number(5.0 * i / MapWidth, 'f', 2)));break;}QCoreApplication::processEvents();}sendInfo("Bedrock has been generated");/* Step 2: Gen Grass */qsrand(gameMap.seed);int cur = myRand(70, 100);bool isUp = (cur > 85 ? false : true);gameMap.MAPP[cur][0] = BLOCK::GRASSBLOCK;for(int i = 1; i < MapWidth; ++i) {int delta = myRand(0, 1000) & 1;cur = (isUp ? cur + delta : cur - delta);isUp = isUp ^ (myRand(0, 1000) & 1);if(cur > 100) isUp = false;if(cur < 70) isUp = true;gameMap.MAPP[cur][i] = BLOCK::GRASSBLOCK;cw->pb->setValue(5 + 10.0 * i / MapWidth);switch(langMode) {case 1:cw->pb->setFormat(QString("生成草方块中......: %1%").arg(QString::number(5 + 10.0 * i / MapWidth, 'f', 2)));break;case 2:cw->pb->setFormat(QString("Generating GrassBlock......: %1%").arg(QString::number(5 + 10.0 * i / MapWidth, 'f', 2)));break;case 3:cw->pb->setFormat(QString("生成草方塊中......: %1%").arg(QString::number(5 + 10.0 * i / MapWidth, 'f', 2)));break;case 4:cw->pb->setFormat(QString("草の生成......: %1%").arg(QString::number(5 + 10.0 * i / MapWidth, 'f', 2)));break;}QCoreApplication::processEvents();}sendInfo("GrassBlock has been generated");cw->pb->setRange(0, 0);switch(langMode) {case 1:cw->setWindowTitle(QString("保存地图中......"));break;case 2:cw->setWindowTitle(QString("Saving Map......"));break;case 3:cw->setWindowTitle(QString("保存地圖中......"));break;case 4:cw->setWindowTitle(QString("保存マップ......"));break;}QCoreApplication::processEvents();if(!gameMap.createMap()) {sendError("Unable To Create Map");switch(langMode) {case 1:QMessageBox::critical(this, "错误", "无法创建地图!");break;case 2:QMessageBox::critical(this, "Wrong", "Unable To Create Map!");break;case 3:QMessageBox::critical(this, "錯誤", "無法創建地圖!");break;case 4:QMessageBox::critical(this, "エラー", "地図が作成できません!");break;}}QCoreApplication::processEvents();cw->pb->setRange(0, 100);inputWorldName->textChanged("");cw->hide();select_world();});inputWorldName->setMaxLength(20);QObject::connect(inputWorldName, &QLineEdit::textChanged, [=]() {sendInfo("Input World Name Changed");if(inputWorldName->text().length() == 0) CreateNewWorld->setEnabled(false);else CreateNewWorld->setEnabled(true);curMapName = replaceStr(inputWorldName->text(),"\\/:*?\"<>|",'_');sendInfo("world name changed as:" + curMapName);while(!checkName(curMapName)) curMapName += '_';switch(langMode) {case 1:WorldNameLabel->setText("将会被保存为: " + curMapName);break;case 2:WorldNameLabel->setText("Will be saved in: " + curMapName);break;case 3:WorldNameLabel->setText("將會被保存為: " + curMapName);break;case 4:WorldNameLabel->setText("に保存されます: " + curMapName);break;}});
}void CreateMap::paintEvent(QPaintEvent *event)
{QPainter p(this);/* Draw Background */p.drawImage(QRect(0, 0, width(), height()), bg);/* Draw Text */p.setFont(font());p.setPen(QColor(255, 255, 255));p.drawStaticText((width() - createText.size().width()) / 2,(createText.size().height() * 1.5) * height() / 720,createText);
}void CreateMap::resizeEvent(QResizeEvent *event)
{this->inputWorldName->resize(500 * width() / 1280, 55 * height() / 720);this->Cancel->resize(400 * width() / 1280, 40 * height() / 720);this->CreateNewWorld->resize(400 * width() / 1280, 40 * height() / 720);this->inputWorldName->move((width() - inputWorldName->width()) / 2, 150 * height() / 720);this->WorldNameLabel->move((width() - inputWorldName->width()) / 2, 150 * height() / 720 + inputWorldName->height());this->Label1->move((width() - inputWorldName->width()) / 2, 150 * height() / 720 - Label1->height());this->CreateNewWorld->move((width() / 2 - CreateNewWorld->width()) / 2,height() - CreateNewWorld->height() * 1.5);this->Cancel->move(width() / 2 + (width() / 2 - Cancel->width()) / 2,height() - Cancel->height() * 1.5);
}void CreateMap::keyPressEvent(QKeyEvent *event)
{switch (event->key()) {/* F11 -> Full Screen */case Qt::Key_F11:if(!isFullScreen()) this->showFullScreen();else this->showNormal();break;/* ESC -> Go To Main Interface */case Qt::Key_Escape:select_world();break;}
}void CreateMap::updateFont(QFont font)
{setFont(font);createText.prepare(QTransform(), font);inputWorldName->setFont(font);WorldNameLabel->setFont(font);Cancel->setFont(font);CreateNewWorld->setFont(font);
}void CreateMap::updateLang(int langMode)
{this->langMode = langMode;this->langMode = langMode;if(langMode == 1) {createText.setText("创建新的世界");inputWorldName->setText("新的世界");inputWorldName->setPlaceholderText("世界名称");Cancel->setText("取消");CreateNewWorld->setText("创建新的世界");Label1->setText("世界名称");cw->setWindowTitle("创建世界中……");setWindowTitle(CN_TITLE);} else if(langMode == 2) {createText.setText("Create New World");inputWorldName->setPlaceholderText("World Name");inputWorldName->setText("New World");Cancel->setText("Cancel");CreateNewWorld->setText("Create New World");Label1->setText("World Name");cw->setWindowTitle("Creating World……");setWindowTitle(TITLE);} else if(langMode == 3) {createText.setText("創建新的世界");inputWorldName->setPlaceholderText("世界名稱");inputWorldName->setText("新的世界");Cancel->setText("取消");CreateNewWorld->setText("創建新的世界");Label1->setText("世界名稱");cw->setWindowTitle("創建世界中……");setWindowTitle(TW_TITLE);} else if(langMode == 4) {createText.setText("新しい世界を創造する");inputWorldName->setPlaceholderText("世界名");inputWorldName->setText("新世界");Cancel->setText("キャンセル");CreateNewWorld->setText("新しい世界を創造する");cw->setWindowTitle("世界を創る……");Label1->setText("世界名");setWindowTitle(JP_TITLE);}
}
gamewidget.h
#ifndef GAMEWIDGET_H
#define GAMEWIDGET_H#include "basewidget.h"
#include "Tool.h"enum DIR {LEFT, RIGHT, UP, DOWN
};class Entity {public:int x, y;int curHealth, maxHealth;QString name;Entity(QString name, int curHealth, int maxHealth) : name(name), curHealth(curHealth), maxHealth(maxHealth) {};
};class ItemDrop : public Entity {};
class Monster : public Entity {};
class Animal : public Entity {};class Player : public Entity {public:int speed = 10;QImage player_image = PLAYER_FRONT;Player() : Entity("Steve", 20, 20) {};void setPos(int x, int y) {this->x = max(0, x);this->y = max(0, y);};void move(int dir) {switch(dir) {case LEFT:setPos(x, y - speed);player_image = PLAYER_LEFT;break;case RIGHT:setPos(x, y + speed);player_image = PLAYER_RIGHT;break;case DOWN:setPos(x + speed, y);player_image = PLAYER_DOWN;break;case UP:setPos(x - speed, y);player_image = PLAYER_UP;break;}}
};class GameWidget : public BaseWidget
{Q_OBJECT
public:int fps;bool isRunning = false;GameWidget(int fps, QWidget *parent, int width, int height, QString title);Map CurrentMap();void startGame();void quitGame();void run();void paintEvent(QPaintEvent *event) override;void updatePlayerPos();void updateWorld();void resizeEvent(QResizeEvent *event) override;void wait();void keyPressEvent(QKeyEvent *event) override;void keyReleaseEvent(QKeyEvent *event) override;void mousePressEvent(QMouseEvent *event) override;Player player;QSet<int> pressedKeys;
};
#endif // GAMEWIDGET_H
gamewidget.cpp
#include "gamewidget.h"GameWidget::GameWidget(int fps, QWidget *parent, int width, int height, QString title) : fps(fps), BaseWidget(parent, width, height, title)
{player.setPos(0, 0);
}void GameWidget::startGame()
{if(isRunning) return;isRunning = true;run();
}void GameWidget::run() {while(isRunning) {repaint();updatePlayerPos();MySleep(1000 / fps);}
}void GameWidget::paintEvent(QPaintEvent *event)
{QPainter p(this);int y = -(player.x % BLOCK::BLOCK_WIDTH), x = -(player.y % BLOCK::BLOCK_HEIGHT);for(int i = 0; i <= width() / BLOCK::BLOCK_WIDTH + 1; ++i) {for(int j = 0; j <= height() / BLOCK::BLOCK_HEIGHT + 1; ++j) {switch(myRand(BLOCK::AIR, BLOCK::STONE)) {case BLOCK::STONE:p.drawImage(QRect(x + BLOCK::BLOCK_WIDTH * i, y + BLOCK::BLOCK_HEIGHT * j, BLOCK::BLOCK_WIDTH, BLOCK::BLOCK_HEIGHT), BLOCK::STONE_IMAGE);break;case BLOCK::DIRT:p.drawImage(QRect(x + BLOCK::BLOCK_WIDTH * i, y + BLOCK::BLOCK_HEIGHT * j, BLOCK::BLOCK_WIDTH, BLOCK::BLOCK_HEIGHT), BLOCK::DIRT_IMAGE);break;case BLOCK::GRASSBLOCK:p.drawImage(QRect(x + BLOCK::BLOCK_WIDTH * i, y + BLOCK::BLOCK_HEIGHT * j, BLOCK::BLOCK_WIDTH, BLOCK::BLOCK_HEIGHT), BLOCK::GRASSBLOCK_IMAGE);break;case BLOCK::BEDROCK:p.drawImage(QRect(x + BLOCK::BLOCK_WIDTH * i, y + BLOCK::BLOCK_HEIGHT * j, BLOCK::BLOCK_WIDTH, BLOCK::BLOCK_HEIGHT), BLOCK::BEDROCK_IMAGE);break;}}}p.drawImage(QRect((width() - BLOCK::BLOCK_WIDTH) / 2, (height() - BLOCK::BLOCK_HEIGHT * 2) / 2, BLOCK::BLOCK_WIDTH, BLOCK::BLOCK_HEIGHT * 2), player.player_image);
}void GameWidget::updatePlayerPos()
{for(auto i : pressedKeys) {switch(i) {case Qt::Key_W : player.move(UP); break;case Qt::Key_A : player.move(LEFT); break;case Qt::Key_S : player.move(DOWN); break;case Qt::Key_D : player.move(RIGHT); break;}}
}void GameWidget::updateWorld()
{}void GameWidget::resizeEvent(QResizeEvent *event)
{BLOCK::BLOCK_WIDTH = 48 * width() / 1280;BLOCK::BLOCK_HEIGHT = 48 * height() / 720;repaint();
}void GameWidget::keyPressEvent(QKeyEvent *event)
{if(!event->isAutoRepeat()) pressedKeys.insert(event->key());
}void GameWidget::keyReleaseEvent(QKeyEvent *event)
{if(!event->isAutoRepeat()) pressedKeys.remove(event->key());
}void GameWidget::mousePressEvent(QMouseEvent *event)
{sendInfo(QString::number(event->x()) + "-" + QString::number(event->y()));
}void GameWidget::quitGame()
{if(!isRunning) return;isRunning = false;
}
Tool.cpp
#ifndef TOOL_H
#define TOOL_H#include <QDebug>
#include <QTime>
#include <QFont>
#include <QSound>
#include <QStaticText>
#include <QPushButton>
#include <QMouseEvent>
#include <QScrollBar>
#include <QThread>
#include <QTimer>
#include <QLineEdit>
#include <QWidget>
#include <QLabel>
#include <QIcon>
#include <QPainter>
#include <QKeyEvent>
#include <QWidget>
#include <QImage>
#include <QPushButton>
#include <QStaticText>
#include <QPainter>
#include <QKeyEvent>
#include <QIcon>
#include <QPainter>
#include <QWidget>
#include <QImage>
#include <QKeyEvent>
#include <QStaticText>
#include <QFontDialog>
#include <QFile>
#include <QDialog>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QByteArray>
#include <QJsonParseError>
#include <QComboBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QTranslator>
#include <QIcon>
#include <Qt>
#include <QObject>
#include <QDesktopWidget>
#include <QPalette>
#include <QProgressBar>
#include <QDir>
#include <QProgressDialog>
#include <QtGlobal>
#include <QTableView>
#include <QSet>
#include <QTableWidget>
#include <QTableWidgetItem>
#include <QTableWidgetSelectionRange>
#include <QListWidget>
#include <QElapsedTimer>
#include <QListWidgetItem>
#include <QMessageBox>/* Game Title */
static QString TITLE = "Minecraft 2D v0.0.6";
static QString CN_TITLE = "我的世界 2D v0.0.6";
static QString TW_TITLE = "我的世界 2D v0.0.6";
static QString JP_TITLE = "マインクラフト v0.0.6";const static QImage PLAYER_FRONT(":/entity/images/entity/player_front.png");
const static QImage PLAYER_LEFT(":/entity/images/entity/player_left.png");
const static QImage PLAYER_RIGHT(":/entity/images/entity/player_right.png");
const static QImage PLAYER_BACK(":/entity/images/entity/player_back.png");
const static QImage PLAYER_UP(":/entity/images/entity/player_up.png");
const static QImage PLAYER_DOWN(":/entity/images/entity/player_down.png");class GameButton : public QPushButton
{Q_OBJECT
public:explicit GameButton(QString text = nullptr, QWidget *parent = nullptr) : QPushButton(text, parent){this->resize(400, 40);/* Enabled : White *//* Hoverd : Golden *//* Disabled : Grey */this->setStyleSheet("QPushButton{border-image: url(:/gui/images/gui/button_normal.png);color:rgb(255, 255, 255);}""QPushButton::hover{border-image: url(:/gui/images/gui/button_select.png);color:rgb(255, 215, 0);}""QPushButton::disabled{border-image: url(:/gui/images/gui/button_disabled.png);color:rgb(128, 128, 128)};");};
};class GameLineEdit : public QLineEdit
{Q_OBJECT
public:GameLineEdit(QWidget *parent = nullptr) : QLineEdit(parent){setStyleSheet("QLineEdit{border:3px solid grey;""background:black;""color:white}");resize(500, 55);};
};class GameLabel : public QLabel {Q_OBJECT
public:GameLabel(QString text = "", QWidget *parent = nullptr) : QLabel(text, parent) {resize(1000, 50);QPalette pa;pa.setColor(QPalette::WindowText, Qt::gray);setPalette(pa);}
};/* Loggers */
static void sendInfo(QString msg) {QDateTime current_time = QDateTime::currentDateTime();qDebug() << "[" + current_time.toString("yyyy-MM-dd hh:mm:ss") + ("][Info]") + msg;
}static void sendError(QString msg) {QDateTime current_time = QDateTime::currentDateTime();qDebug() << "[" + current_time.toString("yyyy-MM-dd hh:mm:ss") + ("][Error]") + msg;
}static void sendWarning(QString msg) {QDateTime current_time = QDateTime::currentDateTime();qDebug() << "[" + current_time.toString("yyyy-MM-dd hh:mm:ss") + ("][Warning]") + msg;
}static void sendInfo(int num) {sendInfo(QString::number(num));
}/* Easy Function */
static QString replaceStr(QString before, QString after, QChar c) {if(before.length() == 0) {return "(NULL)";}int len = after.length();for(int i = 0; i < len; ++i) {before.replace(after[i], c);}return before;
}static int myRand(int minn, int maxn) {return qrand() % (maxn - minn + 1) + minn;
}static bool checkName(QString mapName) {QDir saves;return !saves.exists("saves/" + mapName);
}static void MySleep(int msec) {QElapsedTimer t;t.start();while(t.elapsed() < msec) QCoreApplication::processEvents();
}static int max(int x, int y) {return x > y ? x : y;
}namespace BLOCK {enum BlockID {AIR, BEDROCK, GRASSBLOCK, DIRT, STONE
};static int BLOCK_WIDTH = 48;
static int BLOCK_HEIGHT = 48;
const static QImage DIRT_IMAGE(":/block/images/blocks/dirt.png");
const static QImage BEDROCK_IMAGE(":/block/images/blocks/bedrock.png");
const static QImage GRASSBLOCK_IMAGE(":/block/images/blocks/grass_block_side.png");
const static QImage STONE_IMAGE(":/block/images/blocks/stone.png");class Block {public:short id; QString name;Block() : id(0), name("") {};Block(short id, QString name) : id(id), name(name) {};virtual void onRightClick(){sendInfo("Block be clicked");};
};
}const int MapWidth = 50000;
const int MapHeight = 150;
const int MapSize = MapWidth * MapHeight;class Map {public:short **MAPP = nullptr;int seed;QString mapName;Map(QString name, int seed = -1) {MAPP = (short **)malloc(sizeof(short *) * MapHeight);for(int i = 0; i < MapHeight; ++i)MAPP[i] = (short *)malloc(sizeof(short) * MapWidth);qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));if(seed == -1) this->seed = qrand();mapName = name;for(int i = 0; i < MapHeight; ++i) {for(int j = 0; j < MapWidth; ++j) {this->MAPP[i][j] = BLOCK::AIR;}}}bool isSameName() {QDir saves;return saves.exists("saves/" + mapName);}bool createMap() {QDir saves;if(!saves.exists("saves")) saves.mkdir("saves");if(isSameName()) return false;saves.mkdir("saves/" + mapName);QFile MapFile("saves/" + mapName + "/map.mc2d");QFile setting("saves/" + mapName + "/setting.mc2d");if(!MapFile.open(QIODevice::WriteOnly | QIODevice::Text)) {return false;}if(!setting.open(QIODevice::WriteOnly | QIODevice::Text)) {return false;}QTextStream out(&MapFile);for(int i = 0; i < MapHeight; ++i) {for(int j = 0; j < MapWidth; ++j) {out << this->MAPP[i][j] << " ";}QCoreApplication::processEvents();out << "\n";}MapFile.close();QJsonObject obj;obj.insert("seed", QJsonValue(seed));obj.insert("MapName", mapName);QJsonDocument doc(obj);setting.write(doc.toJson());setting.close();return true;}
};#endif // LOGGER_H
MC2D v0.0.6 Source Code相关推荐
- import openfire4.0.2 source code in eclipse
[0]README 1)本文旨在给出 导入 openfire4.0.2 源码到 eclipse的具体 steps: 2)小生我导入该version 的 openfire 用了近2 天时间, 比较心酸, ...
- Pyinstaller 打包 torch 后执行失败 OSError: could not get source code
1. 问题现象 系统环境 Python 3.6.9 torch 1.2.0 torchvision 0.4.0 Pyinstaller 4.5.1 Pyinstaller 打包 torch 后执行失败 ...
- Understanding The React Source Code
Understanding The React Source Code - Initial Rendering (Simple Component) I UI updating, in its ess ...
- DevExpress Components16.2.6 Source Code 编译
DevExpress 是一个比较有名的界面控件套件,提供了一系列优秀的界面控件.这篇文章将展示如何在拥有源代码的情况下,对 DevExpress 的程序集进行重新编译. 特别提示:重编译后,已安装好的 ...
- Source Code Collection for Reproducible Research
Source Code Collection for Reproducible Research [ http://www.csee.wvu.edu/~xinl/source.html] " ...
- 【纯技术贴】.NETStandard FreeSql v0.0.9 功能预览
年关将至,首页技术含量文章真是越来越少,理解大家盼着放假过年,哥们我何尝不是,先给大家拜个早年. 兄弟我从11月底发了神经,开启了 ORM 功能库的开发之旅,历时两个月编码和文档整理,目前预览版本更新 ...
- Android Studio: Debug Android SDK Source Code
1>查看当前设备的API Level 如图,设备Android版本为8.0.0. 2>使用SDK Manager下载对应的Source Code 注意: a.勾选右下角的"Sho ...
- Downloading Android Source Code
Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的分布式版本控制软件,它不同于Subversion.CVS这样的集中式版本控制系统.在集中式版本控制系统 ...
- Reverse-engineer Source Code into UML Diagrams
今天同事需要反向生成类图,用PowerDesigner 转了一份,不甚满意,在网上逛了逛,发现在这篇文章挺不错. I have been on several teams where we studi ...
- 一款不错的编程字体Source Code Pro
我以前一直是用的MS自家的是Consolas的字体,这个字体基本上具有编程字体所需的所有要素:等宽.支持ClearType.中文字体大小合适,l和1,o和0很容易区分.非要挑刺的话就是字体比较小,9号 ...
最新文章
- java中的反射(一)
- QT的QFormLayout类的使用
- 【JDBC】各版本jar包下载网址及Tomcat下载
- em算法详细例子及推导_第九章-EM算法
- mvc html传参数乱码,SpringMVC Controller 接收页面传递的中文参数出现乱码
- 简单应用定时器和监听器
- python到底有什么用-Python中的闭包到底有什么用
- 利用javaScript动态增加表格行,删除表格行
- Java网络编程socket实现(demo)
- java动态时钟_Java实现动态模拟时钟
- ArduinoUNO实战-第五章-有源蜂鸣器实验
- 大数据新闻推送你怎么看_“大数据”新闻推送中存在的不足与改进
- 微软借云重振中国市场希望渺茫
- 《加州消费者隐私法案》(CCPA)解读二:CCPA赋予消费者六大权力
- 计算机的诞生以及四个发展阶段,计算机发展历史的四个阶段.docx
- 【JS数组 习题练习】
- Linux登入Oracle数据库修改密码
- Nginx服务器部署
- DB2存储过程使用游标
- left join的基本用法以及on与where的区别
热门文章
- [Err] 1267 - Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT)
- Flink服务的HA配置
- unity动态禁用/启用组件enabled
- Instrument详解
- 【雕爷学编程】Arduino动手做(59)---RS232转TTL串口模块
- 推荐一部烂片《东方华尔街》
- 如何利用碎片化时间形成知识体系
- Unity XR Interaction Toolkit 组件解析(一)Action-based 和 Device-based 的区别
- 解决:win10有提示音,但是播视频没有声音
- android模拟器 adb 命令,安卓模拟器下 使用ADB命令