-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 20c4718
Showing
10 changed files
with
690 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
# clang-format version : 16.0.2 | ||
# 从不用tab,使用空格 | ||
UseTab: Never | ||
# 所有的括号都展开到下一行 | ||
BreakBeforeBraces: Allman | ||
# 行的宽限制 | ||
ColumnLimit: 100 | ||
# 参数对齐 | ||
AlignAfterOpenBracket: Align | ||
# 赋值数组左对齐 | ||
AlignArrayOfStructures: Left | ||
# 下面两行要搭配使用 | ||
# 换行运算符对齐 | ||
AlignOperands: AlignAfterOperator | ||
BreakBeforeBinaryOperators: NonAssignment | ||
# 注释对齐 | ||
AlignTrailingComments: | ||
Kind: Always | ||
OverEmptyLines: 0 | ||
# 每个参数占一行,下面两行都是这个意思,一个是声明的一个是用的 | ||
AllowAllArgumentsOnNextLine: false | ||
AllowAllParametersOfDeclarationOnNextLine: false | ||
# 作用域东西太少也不用合并,下面两行都是这个意思 | ||
AllowShortFunctionsOnASingleLine: None | ||
AllowShortLambdasOnASingleLine: None | ||
# 这个是中继返回值的 | ||
AlwaysBreakAfterReturnType : None | ||
# template分行 | ||
AlwaysBreakTemplateDeclarations: Yes | ||
# 参行分行,下面两行都是这个意思 | ||
BinPackArguments: false | ||
BinPackParameters: false | ||
# 要看官网了 | ||
BreakAfterAttributes: Always | ||
# 初始化的时候,值的左右添加空格 | ||
Cpp11BracedListStyle: false | ||
# class 中的 public private 等等将有缩进 | ||
IndentAccessModifiers: true | ||
# case 将有缩进 | ||
IndentCaseLabels: true | ||
# 头文件的等号将有缩进 | ||
IndentPPDirectives: BeforeHash | ||
# requires 分行 | ||
IndentRequiresClause: false | ||
# 缩进的宽度 | ||
IndentWidth: 4 | ||
# namespace 将有缩进 | ||
NamespaceIndentation: All | ||
# obc block 将有缩进 | ||
ObjCBlockIndentWidth: 4 | ||
# constructor init 将单独一行 | ||
# PackConstructorInitializers: Never | ||
# 不同块之间添加一行空白行 | ||
SeparateDefinitionBlocks: Always |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
cmake_minimum_required(VERSION 3.5) | ||
|
||
project(SnakeGame VERSION 0.1 LANGUAGES CXX) | ||
|
||
set(CMAKE_AUTOUIC ON) | ||
set(CMAKE_AUTOMOC ON) | ||
set(CMAKE_AUTORCC ON) | ||
|
||
set(CMAKE_CXX_STANDARD 17) | ||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | ||
|
||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Network) | ||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Network) | ||
|
||
set(PROJECT_SOURCES | ||
main.cpp | ||
GameShowWidget.h | ||
SnakeGameWidget.h | ||
) | ||
|
||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) | ||
qt_add_executable(SnakeGame | ||
MANUAL_FINALIZATION | ||
${PROJECT_SOURCES} | ||
) | ||
# Define target properties for Android with Qt 6 as: | ||
# set_property(TARGET SnakeGame APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR | ||
# ${CMAKE_CURRENT_SOURCE_DIR}/android) | ||
# For more information, see https://doc.qt.io/qt-6/qt-add-executable.html#target-creation | ||
else() | ||
if(ANDROID) | ||
add_library(SnakeGame SHARED | ||
${PROJECT_SOURCES} | ||
) | ||
# Define properties for Android with Qt 5 after find_package() calls as: | ||
# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") | ||
else() | ||
add_executable(SnakeGame | ||
${PROJECT_SOURCES} | ||
) | ||
endif() | ||
endif() | ||
|
||
target_link_libraries(SnakeGame PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Network) | ||
|
||
# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. | ||
# If you are developing for iOS or macOS you should consider setting an | ||
# explicit, fixed bundle identifier manually though. | ||
if(${QT_VERSION} VERSION_LESS 6.1.0) | ||
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.SnakeGame) | ||
endif() | ||
set_target_properties(SnakeGame PROPERTIES | ||
${BUNDLE_ID_OPTION} | ||
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} | ||
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} | ||
MACOSX_BUNDLE TRUE | ||
# WIN32_EXECUTABLE FALSE | ||
WIN32_EXECUTABLE TRUE | ||
) | ||
|
||
include(GNUInstallDirs) | ||
install(TARGETS SnakeGame | ||
BUNDLE DESTINATION . | ||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | ||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} | ||
) | ||
|
||
if(QT_VERSION_MAJOR EQUAL 6) | ||
qt_finalize_executable(SnakeGame) | ||
endif() | ||
|
||
message("QT_VERSION_MAJOR: ${QT_VERSION_MAJOR}") | ||
message("QT_VERSION: ${QT_VERSION}") | ||
message("BUILD_ID_OPTION: ${BUNDLE_ID_OPTION}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
|
||
#pragma once | ||
|
||
#include <QLabel> | ||
#include <QLineEdit> | ||
#include <QMessageBox> | ||
#include <QPushButton> | ||
#include <QStackedWidget> | ||
#include <QVBoxLayout> | ||
#include <QWidget> | ||
#include <qgridlayout.h> | ||
|
||
#include "SnakeGameWidget.h" | ||
|
||
class GameShowWidget : public QWidget | ||
{ | ||
Q_OBJECT; | ||
|
||
public: | ||
GameShowWidget(QWidget *parent = nullptr) : QWidget(parent) | ||
{ | ||
layout = new QVBoxLayout(); | ||
|
||
gameTopLayout = new QHBoxLayout(); | ||
gameScoreNameLabel = new QLabel("得分:"); | ||
gameScoreNumLabel = new QLabel("0"); | ||
gameStartGameButton = new QPushButton("开始游戏"); | ||
gameSettingButton = new QPushButton("游戏设置"); | ||
gameHelpButton = new QPushButton("帮助"); | ||
|
||
// 取消键盘焦点 | ||
gameStartGameButton->setFocusPolicy(Qt::NoFocus); | ||
gameSettingButton->setFocusPolicy(Qt::NoFocus); | ||
gameHelpButton->setFocusPolicy(Qt::NoFocus); | ||
|
||
gameTopLayout->addWidget(gameScoreNameLabel); | ||
gameTopLayout->addWidget(gameScoreNumLabel); | ||
gameTopLayout->addStretch(); | ||
gameTopLayout->addWidget(gameStartGameButton); | ||
gameTopLayout->addWidget(gameSettingButton); | ||
gameTopLayout->addWidget(gameHelpButton); | ||
|
||
gameArea = new SnakeGameWidget(this); | ||
layout->addLayout(gameTopLayout); | ||
layout->addWidget(gameArea); | ||
|
||
connect(gameStartGameButton, | ||
&QPushButton::clicked, | ||
this, | ||
[=]() | ||
{ | ||
QString str = gameStartGameButton->text(); | ||
if (str == "开始游戏") | ||
{ | ||
changeGameMode(0); | ||
} | ||
else | ||
{ | ||
changeGameMode(1); | ||
} | ||
}); | ||
connect(gameHelpButton, | ||
&QPushButton::clicked, | ||
this, | ||
[=]() | ||
{ | ||
QMessageBox::information( | ||
this, | ||
"帮助", | ||
"按方向键控制蛇的移动,吃到食物得分,撞到墙壁或者自己结束游戏\n游戏开始" | ||
"前请调整合适的窗口大小,游戏布局随窗口大小变化\n游戏设置可以设置速度大小"); | ||
}); | ||
|
||
connect(gameSettingButton, | ||
&QPushButton::clicked, | ||
[=]() | ||
{ | ||
changeGameMode(1); | ||
QDialog dialog(this); | ||
|
||
QGridLayout dialogGridLayout; | ||
|
||
QLabel dialogBottomLabel("游戏速度(1-1000):"); | ||
QLineEdit dialogBottomLineEdit; | ||
dialogBottomLineEdit.setText(QString::number(gameArea->getSpeed())); | ||
dialogGridLayout.addWidget(&dialogBottomLabel, 0, 0); | ||
dialogGridLayout.addWidget(&dialogBottomLineEdit, 0, 1); | ||
|
||
QPushButton dialogEnsureButton("确定"); | ||
QPushButton dialogCancelButton("取消"); | ||
dialogGridLayout.addWidget(&dialogEnsureButton, 1, 0); | ||
dialogGridLayout.addWidget(&dialogCancelButton, 1, 1); | ||
|
||
connect(&dialogEnsureButton, | ||
&QPushButton::clicked, | ||
[&]() | ||
{ | ||
bool ok; | ||
int speed = dialogBottomLineEdit.text().toInt(&ok); | ||
if (!ok) | ||
{ | ||
QMessageBox::warning(this, "警告", "速度请输入数字"); | ||
return; | ||
} | ||
|
||
if (!(speed <= 1000 && speed >= 1)) | ||
{ | ||
QMessageBox::warning(this, "警告", "速度范围为1-1000"); | ||
return; | ||
} | ||
gameArea->setSpeed(speed); | ||
dialog.close(); | ||
}); | ||
|
||
connect(&dialogCancelButton, | ||
&QPushButton::clicked, | ||
[&]() | ||
{ | ||
dialog.close(); | ||
}); | ||
|
||
dialog.setLayout(&dialogGridLayout); | ||
|
||
dialog.exec(); | ||
}); | ||
|
||
connect(gameArea, | ||
&SnakeGameWidget::gameOver, | ||
this, | ||
[=]() | ||
{ | ||
changeGameMode(1); | ||
}); | ||
connect(gameArea, | ||
&SnakeGameWidget::getScore, | ||
[=](int score) | ||
{ | ||
gameScoreNumLabel->setText(QString::number(score)); | ||
}); | ||
|
||
setLayout(layout); | ||
} | ||
|
||
~GameShowWidget() | ||
{ | ||
} | ||
|
||
void changeGameMode(int mode = 0) | ||
{ | ||
// qDebug() << "chageGameMode"; | ||
QString str = gameStartGameButton->text(); | ||
// qDebug() << str; | ||
if (mode == 0) | ||
{ | ||
if (str == "开始游戏") | ||
{ | ||
gameStartGameButton->setText("结束游戏"); | ||
gameArea->start(); | ||
gameScoreNumLabel->setText("0"); | ||
} | ||
} | ||
else if (mode == 1) | ||
{ | ||
if (str == "结束游戏") | ||
{ | ||
// qDebug() << gameStartGameButton->text(); | ||
gameStartGameButton->setText("开始游戏"); | ||
gameArea->end(); | ||
|
||
// 吃完全部食物 | ||
QString score = gameScoreNumLabel->text(); | ||
if (score.toInt() | ||
== gameArea->getWidgetAllBlockWidth() * gameArea->getWidgetAllBlockHeight() | ||
- 1) | ||
{ | ||
QMessageBox::warning(this, | ||
"游戏结束", | ||
"恭喜你吃完全部食物!", | ||
QMessageBox::Ok); | ||
} | ||
else | ||
{ | ||
QMessageBox::warning(this, | ||
"游戏结束", | ||
"得分:" + gameScoreNumLabel->text(), | ||
QMessageBox::Ok); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// 键盘监听上下左右 | ||
void keyPressEvent(QKeyEvent *event) | ||
{ | ||
if (event->key() == Qt::Key_Up) | ||
{ | ||
gameArea->setSnakeDirection("u"); | ||
} | ||
else if (event->key() == Qt::Key_Down) | ||
{ | ||
gameArea->setSnakeDirection("d"); | ||
} | ||
else if (event->key() == Qt::Key_Left) | ||
{ | ||
gameArea->setSnakeDirection("l"); | ||
} | ||
else if (event->key() == Qt::Key_Right) | ||
{ | ||
gameArea->setSnakeDirection("r"); | ||
} | ||
} | ||
|
||
private: | ||
QVBoxLayout *layout; | ||
QHBoxLayout *gameTopLayout; | ||
QLabel *gameScoreNameLabel; | ||
QLabel *gameScoreNumLabel; | ||
QPushButton *gameStartGameButton; | ||
QPushButton *gameSettingButton; | ||
SnakeGameWidget *gameArea; | ||
QPushButton *gameHelpButton; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# 介绍 | ||
|
||
## 控制蛇的方向 | ||
|
||
> 使用键盘的上下左右键来控制蛇的方向 | ||
![](img/SnakeDirection.gif) | ||
|
||
## 蛇的活动空间 | ||
|
||
> 蛇的活动空间随着窗口的变化而变化 | ||
![](img/SnakeMoveSpace.gif) | ||
|
||
## 蛇的移动 | ||
|
||
> 通过`游戏设置`可以设置蛇的移动速度(默认:100ms) | ||
![](img/SnakeMoveSpeed.gif) |
Oops, something went wrong.