mirror of
https://github.com/kuhyx/engineer-thesis-WUT.git
synced 2026-07-04 15:43:19 +02:00
feat: added images for controls
This commit is contained in:
parent
5b89acd621
commit
39c9bedb1a
@ -10,6 +10,7 @@
|
|||||||
\usepackage{fontspec}
|
\usepackage{fontspec}
|
||||||
\usepackage{anyfontsize}
|
\usepackage{anyfontsize}
|
||||||
\usepackage{graphicx}
|
\usepackage{graphicx}
|
||||||
|
\usepackage{subcaption}
|
||||||
\usepackage{geometry}
|
\usepackage{geometry}
|
||||||
\usepackage{leading}
|
\usepackage{leading}
|
||||||
\usepackage[nottoc]{tocbibind}
|
\usepackage[nottoc]{tocbibind}
|
||||||
@ -1180,6 +1181,238 @@ namespace textures {
|
|||||||
}
|
}
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\section{Game class}
|
||||||
|
Game class defined in game.h and game.cpp is the main and biggest class in the project, it brings together all other classes and functionalities of the engine.
|
||||||
|
|
||||||
|
\subsubsection{Includes}
|
||||||
|
\begin{lstlisting}[style=C++Style]
|
||||||
|
#include "./constants.hpp"
|
||||||
|
#include "./filesystem.h"
|
||||||
|
#include "./game_level.h"
|
||||||
|
#include "./game_object.h"
|
||||||
|
#include "./post_processor.h"
|
||||||
|
#include "./resource_manager.h"
|
||||||
|
#include "./sprite_renderer.h"
|
||||||
|
#include "./text_renderer.h"
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\paragraph{Constructor}
|
||||||
|
Constructor initializes game window size, empties clicked keys, sets game state to game menu, sets initial level map and retrieves max turns from constants file
|
||||||
|
\begin{lstlisting}[style=C++Style]
|
||||||
|
Game::Game(ScreenDimensions screen)
|
||||||
|
: State(GAME_MENU),
|
||||||
|
Keys(),
|
||||||
|
KeysProcessed(),
|
||||||
|
Width(screen.width),
|
||||||
|
Height(screen.height),
|
||||||
|
Level(0),
|
||||||
|
MaxTurns(constants::MAX_TURNS),
|
||||||
|
Turns(0)
|
||||||
|
{}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\subsection{Game initialization}
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\begin{tikzpicture}[node distance=2cm]
|
||||||
|
\useasboundingbox (-5,0) rectangle (5, -11); % Set a custom bounding box
|
||||||
|
\node (start) [startstop] {Init game};
|
||||||
|
|
||||||
|
\node (pro2) [process, below of=start] {Configure Shaders};
|
||||||
|
\draw [arrow] (start) -- (pro2);
|
||||||
|
\node (pro3) [process, below of=pro2] {Load Textures};
|
||||||
|
\draw [arrow] (pro2) -- (pro3);
|
||||||
|
|
||||||
|
\node (pro4) [process, below of=pro3] {Render Controls};
|
||||||
|
\draw [arrow] (pro3) -- (pro4);
|
||||||
|
|
||||||
|
\node (pro5) [process, below of=pro4] {Load Levels};
|
||||||
|
\draw [arrow] (pro4) -- (pro5);
|
||||||
|
|
||||||
|
\node (close) [startstop, below of=pro5] {Finish};
|
||||||
|
\draw [arrow] (pro5) -- (close);
|
||||||
|
|
||||||
|
\end{tikzpicture}
|
||||||
|
\caption{Initialization logic}
|
||||||
|
\label{fig:main_function_logic}
|
||||||
|
\end{figure}
|
||||||
|
We will describe each step below
|
||||||
|
|
||||||
|
\paragraph{Shaders}
|
||||||
|
Two shaders are used throughout the project, one for rendering sprites (gem tiles) and one for generating post processes (for example shaking the map when tiles get matched) \\
|
||||||
|
More on the shaders usage later when we will be discussing postProcessor and Shader clasess
|
||||||
|
|
||||||
|
\begin{lstlisting}[style=C++Style]
|
||||||
|
void Game::loadShaders() {
|
||||||
|
ResourceManager::LoadShader("sprite.vs", "sprite.fs", "sprite");
|
||||||
|
ResourceManager::LoadShader("post_processing.vs", "post_processing.fs", "postprocessing");
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\paragraph{Textures}
|
||||||
|
Textures names are first defined in the constans file, then the game object invokes resource manager to go through texture paths and load them
|
||||||
|
\begin{lstlisting}[style=C++Style]
|
||||||
|
void Game::loadTextures() {
|
||||||
|
const auto *begin = std::begin(textures::textures);
|
||||||
|
const auto *end = std::end(textures::textures);
|
||||||
|
|
||||||
|
for (auto it = begin; it != end; ++it) {
|
||||||
|
ResourceManager::LoadTexture(FileSystem::getPath(it->path).c_str(),
|
||||||
|
it->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
|
||||||
|
\paragraph{Setting controls}
|
||||||
|
After loading sprite renderers, postprocesses and text, we set instances of classes using loaded resources.
|
||||||
|
\begin{lstlisting}[style=C++Style]
|
||||||
|
void Game::renderSpecificControls() {
|
||||||
|
// set render-specific controls
|
||||||
|
Renderer =
|
||||||
|
std::make_unique<SpriteRenderer>(ResourceManager::GetShader("sprite"));
|
||||||
|
Effects = std::make_unique<PostProcessor>(
|
||||||
|
ResourceManager::GetShader("postprocessing"), this->Width, this->Height);
|
||||||
|
Text =
|
||||||
|
std::make_unique<TextRenderer>(TextRenderer(this->Width, this->Height));
|
||||||
|
Text->Load(FileSystem::getPath("resources/fonts/OCRAEXT.TTF"), text::OCRAEXT_FONT_SIZE);
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\paragraph{Levels}
|
||||||
|
Levels are loaded automatically from the levels folder, game assumes that every file with extension ".lvl" is a level file and adds it to an array of levels
|
||||||
|
\begin{lstlisting}[style=C++Style]
|
||||||
|
void Game::loadLevels() {
|
||||||
|
const std::string path = "../../resources/levels/";
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator(path)) {
|
||||||
|
if (entry.is_regular_file() && entry.path().extension() == ".lvl") {
|
||||||
|
GameLevel level;
|
||||||
|
level.Load(entry.path().c_str(), this->Width, this->Height);
|
||||||
|
this->Levels.push_back(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->Level = 0;
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\subsection{Game update}
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\begin{tikzpicture}[node distance=2cm]
|
||||||
|
\useasboundingbox (-5,0) rectangle (5, -13); % Set a custom bounding box
|
||||||
|
\node (start) [startstop] {Update};
|
||||||
|
|
||||||
|
\node (pro2) [process, below of=start] {Update Tiles};
|
||||||
|
\draw [arrow] (start) -- (pro2);
|
||||||
|
\node (dec1) [decision, below of=pro2, yshift=-1cm] {Points reached?};
|
||||||
|
\draw [arrow] (pro2) -- (dec1);
|
||||||
|
|
||||||
|
\node (stopLost) [startstop, left of=dec1, xshift=-2cm] {Game Won};
|
||||||
|
\draw [arrow] (dec1) -- node[anchor=north] {yes} (stopLost);
|
||||||
|
|
||||||
|
\node (dec2) [decision, below of=pro4, yshift=-1cm] {Turns exceeded?};
|
||||||
|
\draw [arrow] (dec1) -- node[anchor=west]{no} (dec2);
|
||||||
|
% Arrow from 'Closed?' decision node to 'Main Loop' node
|
||||||
|
\draw [arrow] (dec2.east) -- ++(2,0) |- node[anchor=south] {no} (start);
|
||||||
|
|
||||||
|
\node (stopWon) [startstop, below of=dec2, yshift=-1cm] {Game Lost};
|
||||||
|
\draw [arrow] (dec2) -- node[anchor=west]{yes} (stopWon);
|
||||||
|
|
||||||
|
\end{tikzpicture}
|
||||||
|
\caption{Game updates logic}
|
||||||
|
\label{fig:main_function_logic}
|
||||||
|
\end{figure}
|
||||||
|
Game is ended either when the player exceeds maximum move limit (game lost) or when points limit is reached (game won), otherwise the game continues, notice how first we check for win condition then for loss condition, this makes the gameplay a little bit more satisfying and fair.
|
||||||
|
|
||||||
|
\subsection{Controls}
|
||||||
|
Game allows to move through the grid to highlight a tile, then after clicking "enter" a tile is selected, then by using arrows or WSAD keys user can highlight the tile that will be swapped when again "enter" gets clicked
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\begin{tikzpicture}[node distance=2cm]
|
||||||
|
\useasboundingbox (-5,0) rectangle (5, -7); % Set a custom bounding box
|
||||||
|
\node (start) [startstop] {Highight tile (WSAD or arrow keys)};
|
||||||
|
\node (pro2) [process, below of=start] {Select tile (ENTER)};
|
||||||
|
\draw [arrow] (start) -- (pro2);
|
||||||
|
\node (pro3) [process, below of=pro2] {Highlight tile to swap (WSAD or arrow keys)};
|
||||||
|
\draw [arrow] (pro2) -- (pro3);
|
||||||
|
\node (stop) [startstop, below of=pro3] {Swap tile (ENTER)};
|
||||||
|
\draw [arrow] (pro3) -- (stop);
|
||||||
|
\end{tikzpicture}
|
||||||
|
\caption{User controls}
|
||||||
|
\label{fig:main_function_logic}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
All of input processing is taken care by game class, and then relied to game level class.
|
||||||
|
\begin{lstlisting}[style=C++Style]
|
||||||
|
void Game::handleActiveGame() {
|
||||||
|
if (this->State == GAME_ACTIVE) {
|
||||||
|
this->moveLeft();
|
||||||
|
this->moveRight();
|
||||||
|
this->moveUp();
|
||||||
|
this->moveDown();
|
||||||
|
this->selectPiece();
|
||||||
|
this->unselectPiece();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
\begin{figure}[htp]
|
||||||
|
\centering
|
||||||
|
\begin{subfigure}[b]{0.45\textwidth}
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.45]{images/controlsSelect.png}
|
||||||
|
\caption{View of highlighted tile}
|
||||||
|
\label{fig:highlighted_tile}
|
||||||
|
\end{subfigure}
|
||||||
|
\hfill
|
||||||
|
\begin{subfigure}[b]{0.45\textwidth}
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.45]{images/controlsSelectGreen.png}
|
||||||
|
\caption{View of selected tile}
|
||||||
|
\label{fig:selected_tile}
|
||||||
|
\end{subfigure}
|
||||||
|
|
||||||
|
\caption{Tile selection views}
|
||||||
|
\label{fig:tile_selection}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\begin{figure}[H]
|
||||||
|
\centering
|
||||||
|
\begin{subfigure}[b]{0.45\textwidth}
|
||||||
|
\includegraphics[scale=0.45]{images/controlsSwapLeft.png}
|
||||||
|
\caption{Left tile is set to be swapped when enter key will be hit}
|
||||||
|
\label{fig:swap_left}
|
||||||
|
\end{subfigure}
|
||||||
|
\hfill
|
||||||
|
\begin{subfigure}[b]{0.45\textwidth}
|
||||||
|
\includegraphics[scale=0.45]{images/controlsSwapRight.png}
|
||||||
|
\caption{Right tile is set to be swapped when enter key will be hit}
|
||||||
|
\label{fig:swap_right}
|
||||||
|
\end{subfigure}
|
||||||
|
|
||||||
|
\vspace{10pt}
|
||||||
|
|
||||||
|
\begin{subfigure}[b]{0.45\textwidth}
|
||||||
|
\includegraphics[scale=0.45]{images/controlsSwapUp.png}
|
||||||
|
\caption{Upper tile is set to be swapped when enter key will be hit}
|
||||||
|
\label{fig:swap_up}
|
||||||
|
\end{subfigure}
|
||||||
|
\hfill
|
||||||
|
\begin{subfigure}[b]{0.45\textwidth}
|
||||||
|
\includegraphics[scale=0.45]{images/controlsSwapDown.png}
|
||||||
|
\caption{Down tile is set to be swapped when enter key will be hit}
|
||||||
|
\label{fig:swap_down}
|
||||||
|
\end{subfigure}
|
||||||
|
|
||||||
|
\caption{Tile swap controls}
|
||||||
|
\label{fig:tile_swaps}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\subsection{Rendering}
|
||||||
|
|
||||||
|
|
||||||
\subsection{Dependency Management}
|
\subsection{Dependency Management}
|
||||||
There are several libraries: OpenGL, GLFW, stb\_image and freetype being integrated into engine, they are simply included at the top of any files that need them.
|
There are several libraries: OpenGL, GLFW, stb\_image and freetype being integrated into engine, they are simply included at the top of any files that need them.
|
||||||
|
|
||||||
@ -1440,7 +1673,6 @@ Using multiple different libraries and integrating them with our game engine was
|
|||||||
|
|
||||||
\subsection{Time management}
|
\subsection{Time management}
|
||||||
Lastly, probably the biggest challenge was managing time for this thesis. Finishing it required a lot of determination, setting barriers and working every day to ensure that the thesis is finished on time. Thankfully past experiences helped in guiding through this task that could be compared to colossus.
|
Lastly, probably the biggest challenge was managing time for this thesis. Finishing it required a lot of determination, setting barriers and working every day to ensure that the thesis is finished on time. Thankfully past experiences helped in guiding through this task that could be compared to colossus.
|
||||||
\chapter{References}
|
|
||||||
|
|
||||||
\chapter{Appendices}
|
\chapter{Appendices}
|
||||||
|
|
||||||
|
|||||||
BIN
Thesis/images/controlsSelect.png
Normal file
BIN
Thesis/images/controlsSelect.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 452 KiB |
BIN
Thesis/images/controlsSelectGreen.png
Normal file
BIN
Thesis/images/controlsSelectGreen.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 447 KiB |
BIN
Thesis/images/controlsSwapDown.png
Normal file
BIN
Thesis/images/controlsSwapDown.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 445 KiB |
BIN
Thesis/images/controlsSwapLeft.png
Normal file
BIN
Thesis/images/controlsSwapLeft.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 440 KiB |
BIN
Thesis/images/controlsSwapRight.png
Normal file
BIN
Thesis/images/controlsSwapRight.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 445 KiB |
BIN
Thesis/images/controlsSwapUp.png
Normal file
BIN
Thesis/images/controlsSwapUp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 443 KiB |
Loading…
Reference in New Issue
Block a user