Avant de commencer ce grand projet, si vous êtes encore débutants avec Three.JS, je vous conseille fortement de maîtriser les concepts de base expliqués dans notre parcours de formation :
Si vous êtes prêts, commençons !
Introduction et présentation du projet
Dans ce grand tutoriel, nous allons développer ensemble, étapes par étapes, un jeu de type Tower Defense avec Three.JS !
Le Tower Defense (souvent abrégée en TD) est un type de jeu vidéo où l’objectif est de défendre une zone contre des vagues successives d’ennemis se déplaçant suivant un itinéraire ou non, en construisant et en améliorant progressivement des tours défensives.
Wikipédia
Ainsi, dans un monde au style 3D orthographique, nous développerons un univers composé d’une route de foret, qui devra être défendue de vagues d’ennemis par des tours.
Le but du jeu sera d’empêcher les ennemis d’arriver au bout du chemin.
Ce tutoriel est disponible au format vidéo !
Lors des différentes phases de développement, nous aborderons les thèmes suivants :
- Bases de Three.JS
- Chargement de modèles 3D
- Animation de modèles 3D
- Raycaster
- Programmation orientée objet et JavaScript de base
Création d’un univers de base
Commençons la première étape de notre projet ! Créons un fichier index.html
:
<head> <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0' /> <style> body { margin: 0; touch-action: none; background-image: -webkit-gradient(linear, 0 0, 100% 100%, color-stop(0, #877fa8), color-stop(100%, #f9ae91)); background-image: -webkit-linear-gradient(135deg, #877fa8, #f9ae91); background-image: -moz-linear-gradient(45deg, #877fa8, #f9ae91); background-image: -ms-linear-gradient(45deg, #877fa8 0, #f9ae91 100%); background-image: -o-linear-gradient(45deg, #877fa8, #f9ae91); background-image: linear-gradient(135deg, #877fa8, #f9ae91); } canvas { width: 100%; height: 100% ; touch-action: none;} </style> <script type="module"></script> </head> <body> </body>
Puis, dans cette base de code, attaquons le concret dans la balise script
!
Commençons par importer Three.JS et MapControls
dans notre projet et créons quelques variables :
<script type="module"> import * as THREE from '../js/build/three.module.js'; import { MapControls } from '../js/examples/jsm/controls/OrbitControls.js'; // Basic Threejs variables var scene; var camera; var renderer; var clock; var controls; [...]
Puis, créons une fonction init
. Cette dernière sera appelée à la fin de notre code JavaScript, ce sera le point d’entrée de notre projet :
<script type="module"> [...] function init() { } init(); </script>
Dans cette fonction, nous initialiserons les variables précédemment crées ainsi que les bases de notre univers Three.JS.
Les acteurs de base
Pour rappel, n’hésitez pas a vous rafraîchir la mémoire sur les concepts de base de Three.JS :
Commençons par les variables clock
et scene
, respectivement de type Clock
et Scene
:
function init() { clock = new THREE.Clock(); scene = new THREE.Scene(); }
Ensuite, notre moteur de rendu 3D renderer
, de type WebGLRenderer
.
Toujours dans la fonction init
:
// ---------------- RENDERER ---------------- renderer = new THREE.WebGLRenderer( { antialias : true , alpha: true} ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); // we add the HTML element to the HTML page
Poursuivons avec l’initialisation de la variable camera
. Dans ce projet nous utiliserons OrthographicCamera
:
// ---------------- CAMERA ---------------- const aspect = window.innerWidth / window.innerHeight; const frustumSize = 10; camera = new THREE.OrthographicCamera( frustumSize * aspect / - 2, frustumSize * aspect / 2, frustumSize / 2, frustumSize / - 2, 1, 1000 ); camera.position.set( -5, 5, -5 ); camera.lookAt(new THREE.Vector3(0,0,0)); scene.add( camera );
Contrôler la caméra
Puis, initialisons une instance de MapControls
pour contrôler la camera. Pour rappel, MapControls
est une classe des add-on officiels de Three.JS :
// ---------------- CAMERA CONTROLS ---------------- controls = new MapControls( camera, renderer.domElement ); controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled controls.dampingFactor = 0.05; controls.screenSpacePanning = false; controls.minDistance = 2; controls.maxDistance = 20; controls.maxPolarAngle = Math.PI / 2;
Si vous souhaitez plus d’informations sur le contrôle de camera de base :
Nos variables de base sont enfin initialisées ! Occupons nous désormais de remplir notre scène.
L’éclairage de la scène
Commençons par l’éclairage de notre scène. Comme vous le savez, l’éclairage de la scène est la plupart du temps indispensable pour que les objets 3D y soient visibles.
Toujours dans notre fonction init
:
// ---------------- LIGHTS ---------------- var ambientLight = new THREE.AmbientLight( 0xcccccc, 0.2 ); scene.add( ambientLight ); const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.6 ); directionalLight.position.set( - 1, 0.9, 0.4 ); scene.add( directionalLight );
Un cube au centre de la scène
Poursuivons le code de notre fonction init
avec la création d’un cube au centre de la scène :
var cube; [...] const material = new THREE.MeshLambertMaterial(); const geometry = new THREE.BoxGeometry( 2, 2, 2 ); cube = new THREE.Mesh( geometry, material ); scene.add( cube );
La boucle principale d’animation
Pour finir, occupons nous de la boucle principale d’animation. Créons une fonction render
basique :
function render() { var delta = clock.getDelta(); //get delta time between two frames var elapsed = clock.elapsedTime; //get elapsed time controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true renderer.render( scene, camera ); // We are rendering the 3D world requestAnimationFrame( render ); // we are calling render() again, to loop }
N’oubliez pas d’appeler render
à la fin de notre fonction init
pour démarrer la boucle principale :
function init() { [...] // ---------------- STARTING THE GAME MAIN LOOP ---------------- render(); }
Résultat final
Téléchargez le code final : Github
Félicitations, vous êtes arrivés à la fin de cette première partie ! Voila l’état de notre projet à l’issue de ce premier article :
Dans la prochaine partie, nous étudierons comment implémenter les fonctionnalités liées à la carte de jeu, restez connectés !
[…] Créer un jeu de Tower Defense avec Three.JS – Partie 1 […]
[…] Créer un jeu de Tower Defense avec Three.JS – Partie 1 […]
[…] Créer un jeu de Tower Defense avec Three.JS – Partie 1 : Les bases […]
[…] Créer un jeu de Tower Defense avec Three.JS – Partie 1 : Les bases […]