Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
CnsMaple committed Jan 2, 2024
0 parents commit 20c4718
Show file tree
Hide file tree
Showing 10 changed files with 690 additions and 0 deletions.
55 changes: 55 additions & 0 deletions .clang-format
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build
74 changes: 74 additions & 0 deletions CMakeLists.txt
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}")
222 changes: 222 additions & 0 deletions GameShowWidget.h
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;
};
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 介绍

## 控制蛇的方向

> 使用键盘的上下左右键来控制蛇的方向
![](img/SnakeDirection.gif)

## 蛇的活动空间

> 蛇的活动空间随着窗口的变化而变化
![](img/SnakeMoveSpace.gif)

## 蛇的移动

> 通过`游戏设置`可以设置蛇的移动速度(默认:100ms)
![](img/SnakeMoveSpeed.gif)
Loading

0 comments on commit 20c4718

Please sign in to comment.