update report

This commit is contained in:
Mylloon 2022-12-03 01:11:54 +01:00
parent c5b5ce1fa0
commit 503dca347b
Signed by: Anri
GPG key ID: A82D63DFF8D1317F

View file

@ -28,11 +28,17 @@
\tableofcontents \tableofcontents
\clearpage \clearpage
\section{Projet} \section[Projet]{Explication du projet}
% Expliquer ce qu'est geometry dash 3d Le but du projet est de créer un jeu du type
\href{https://fr.wikipedia.org/wiki/Geometry_Dash}{Geometry Dash} en vue 3D.
Geometry Dash est un jeu de plateforme dans lequel le joueur dirige un cube
glissant sur le sol et qui doit sauter pour éviter des obstacles.
Le but de \textbf{ce} jeu est de faire le plus gros score, chaque seconde
passée dans le jeu ajoute 1 point au compteur, le score étant affiché en haut de l'écran.
\section[Rendu 3D]{Rendu 3D avec THREE.JS} \section[Rendu 3D]{Rendu 3D avec THREE.JS}
La \autoref{fig:expls} schématise le rendu complet d'une scène du jeu La \autoref{fig:expls} schématise grossièrement comment est rendu le jeu.
\begin{figure}[h] \begin{figure}[h]
\centering \centering
@ -41,12 +47,180 @@ La \autoref{fig:expls} schématise le rendu complet d'une scène du jeu
\label{fig:expls} \label{fig:expls}
\end{figure} \end{figure}
L'environnement du jeu s'occupe de tout. Elle garde en mémoire la liste des
éléments présents dans le jeu :
\begin{itemize}
\item Joueur (le cube)
\item Ennemis (les piques)
\end{itemize}
Elle lance l'animation de ces derniers chacun son tour dans la fonction
\texttt{animate}, qui est appelée juste avant de rendre la scène (cf. \autoref{cod:envupdate}).
\begin{figure}[h]
\centering
\begin{minipage}{0.3\textwidth}
\begin{minted}[autogobble,linenos]{js}
update = (demo) => {
if (this.animate(demo)) {
return true;
}
this.render();
return false;
};
\end{minted}
\end{minipage}
\caption{fonction \texttt{update}, \texttt{Env.js}}
\label{cod:envupdate}
\end{figure}
\section[Logique]{Logique du jeu} \section[Logique]{Logique du jeu}
Lorsque l'on joue, on a l'impression que le personnage avance sur un plan
infini. Ce n'est pas exactement ce qui se passe.
Le joueur est un cube fixe, il ne fait que sauté et tourné sur lui-même.
Le plan est fixe, ce qui bouge sont les piques ennemis.
\subsection[Génération procédurale]{Génération du terrain}
Le sol est un plan simple sur lequel une texture en dégradé est appliquée,
du blanc (proche de la caméra) au noir. Il y a une lumière pour appuyer l'effet
3D de la scène (il y a donc les ombres des objets projetés sur le sol).
Le monde est généré via la fonction \texttt{generateRandomMap} de la classe
\texttt{Env}. Elle permet de générer $n$ obstacles pour le joueur placés devant
le joueur. Quand les obstacles passent derrière le joueur et sortent de l'écran,
ils sont téléportés devant le joueur en étant déplacé, ils ne sont pas justes
replacés à leur position initiale, créant une carte infinie. La taille du pique est choisie de façon aléatoire.
\begin{figure}[h]
\centering
\begin{minipage}{0.7\textwidth}
\begin{minted}[autogobble,linenos]{js}
const spade = new Spade(
Math.random() * 0xffffff,
Math.round(Math.random()) ? Size.little : Size.big,
startDelta + (index - 1) * 10
);
\end{minted}
\dots lors de l'animation des piques\dots
\begin{minted}[autogobble,linenos,firstnumber=last]{js}
if (ennemy.data.position.x <= -10) {
ennemy.data.position.x = ennemy.startPos + Math.random() * 20;
}
\end{minted}
\end{minipage}
\caption{Création d'un pique et retéléportation lors de la sortie de l'écran, \texttt{Env.js}}
\label{cod:spade}
\end{figure}
\subsection{Saut du joueur} \subsection{Saut du joueur}
TODO! Dans le cas d'un joueur humain, on écoute via \texttt{addEventListener}
l'événement de la touche \textit{espace} pressée. Dans le cas de la démo, on utilise
un évènement interne \textit{nommé \texttt{jumpKey}}.
Les deux événements sont enregistrés et lanceront la fonction de saut.
\begin{figure}[h]
\centering
\begin{minipage}{0.7\textwidth}
\begin{minted}[autogobble,linenos]{js}
if (demo) {
addEventListener("jumpKey", (e) => player.controlUser(e.detail));
} else {
addEventListener("keypress", player.controlUser);
}
\end{minted}
\end{minipage}
\caption{Enregistrement des événements de saut, \texttt{Game.js}}
\label{cod:eventjump}
\end{figure}
La fonction \texttt{controlUser} définit le point de saut maximal ainsi que la
rotation du joueur finale.
\begin{figure}[h]
\centering
\begin{minipage}{0.7\textwidth}
\begin{minted}[autogobble,linenos]{js}
controlUser = (key) => {
if (key.code == "Space" && !this.movementData.state) {
this.movementData.changeRotation(
this.data.rotation.y - Math.PI / 2
);
this.movementData.changeJump(
3 * this.data.position.y + Math.PI / 2
);
this.movementData.changeState();
}
};
\end{minted}
\end{minipage}
\caption{Définition du saut max et de la rotation finale, \texttt{Player.js}}
\label{cod:defjumprot}
\end{figure}
Les coordonnées de transition (le saut et la descente) ainsi que l'angle sont calculées lors de l'animation du joueur, dans la fonction \texttt{animation} de la
classe \texttt{Player}.
\subsubsection[Démo]{Cas de la démonstration}
On vérifie si un ennemi est devant lors de l'animation du joueur, si c'est le
cas alors on saute.
\begin{figure}[h]
\centering
\begin{minipage}{0.7\textwidth}
\begin{minted}[autogobble,linenos]{js}
if (demo) {
listEnnemies.forEach((ennemy) => {
const pos = ennemy.position.x - joueur.position.x;
// Aléatoire entre 0.5 (proche du pique) et 2 (loin du pique)
if (pos > 0 && pos < Math.random() * 1.5 + 0.5) {
// Événement "jumpKey"
dispatchEvent(jumpDemo);
}
});
}
\end{minted}
\end{minipage}
\caption{Vérification IA : saut automatique, \texttt{Player.js}}
\label{cod:ia}
\end{figure}
\subsection{Collisions}
À chaque frame du jeu, le joueur vérifie qu'il n'entre pas en collision avec
les ennemies via du
\href{https://threejs.org/docs/#api/en/core/Raycaster}{ray casting}.
\begin{figure}[h]
\centering
\begin{minipage}{0.7\textwidth}
\begin{minted}[autogobble,linenos]{js}
const rc = new THREE.Raycaster(
this.data.position,
directionVector.normalize()
);
// Contient les éléments en collisions avec le joueur
const collisionResults = rc.intersectObjects(listEnnemies, false);
if (
collisionResults.length > 0 &&
collisionResults[0].distance < directionVector.length()
) {
return true;
}
return false;
\end{minted}
\end{minipage}
\caption{Vérification des collisions, \texttt{Player.js}}
\label{cod:raycast}
\end{figure}
\subsection{Fin de jeu} \subsection{Fin de jeu}
TODO! Le jeu se termine dès que le joueur entre en collision avec un ennemi. Quand
c'est le cas, un menu de fin apparaît au-dessus du jeu, invitant le joueur à
rejouer. Peu importe si c'est une démo ou non.
\newpage \newpage
\appendix \appendix