diff --git a/index.html b/index.html
index 0cfff13..189c574 100644
--- a/index.html
+++ b/index.html
@@ -11,6 +11,9 @@
diff --git a/js/Env.js b/js/Env.js
index edb62d0..8ffb798 100644
--- a/js/Env.js
+++ b/js/Env.js
@@ -100,8 +100,9 @@ export class Env {
/**
* Animate all the entities in the environnement
+ * @param {boolean} demo
*/
- animate = () => {
+ animate = (demo) => {
let playerDead = false;
// Retrieve ennemies
@@ -116,7 +117,10 @@ export class Env {
.forEach((player) => {
if (player.animation) {
if (
- !player.animation(ennemies.map((object) => object.data))
+ !player.animation(
+ ennemies.map((object) => object.data),
+ demo
+ )
) {
// If animation returned false, the player died!
playerDead = true;
@@ -143,9 +147,10 @@ export class Env {
/**
* Update the game logic
+ * @param {boolean} demo
*/
- update = () => {
- if (this.animate()) {
+ update = (demo) => {
+ if (this.animate(demo)) {
return true;
}
this.render();
diff --git a/js/Game.js b/js/Game.js
new file mode 100644
index 0000000..9be6de5
--- /dev/null
+++ b/js/Game.js
@@ -0,0 +1,113 @@
+import { Env, TypeEntity } from "./Env.js";
+import { Plane } from "./Plane.js";
+import { Player } from "./Player.js";
+import { Quality } from "./utils.js";
+
+/**
+ * Jump event for the demo
+ */
+export const jumpDemo = new CustomEvent("jumpKey", {
+ detail: {
+ code: "Space",
+ },
+});
+
+/**
+ * Run the game
+ * @param {boolean} demo
+ */
+export const runGame = (demo) => {
+ // THREE.js
+ const env = new Env();
+ document.body.appendChild(env.getDomElement());
+
+ // World
+ const plan = new Plane(
+ window.innerWidth / 50,
+ 10,
+ THREE.Color.NAMES.white,
+ THREE.Color.NAMES.black
+ );
+ env.addToScene(plan);
+
+ // Player
+ const player = new Player(THREE.Color.NAMES.pink);
+ env.addToScene(player, TypeEntity.player);
+
+ if (demo) {
+ addEventListener("jumpKey", (e) => player.controlUser(e.detail));
+ } else {
+ addEventListener("keypress", player.controlUser);
+ }
+
+ // Generate random map
+ env.generateRandomMap(10);
+
+ // GUI
+ const gui = new dat.gui.GUI({ closeOnTop: true });
+ const menu = Quality.buildGUI(env.quality);
+ for (const quality in menu) {
+ gui.add(menu, quality)
+ .listen()
+ .onFinishChange(() => {
+ Quality.update(env.setQuality, menu, quality);
+ });
+ }
+
+ let score = document.getElementById("score");
+ score.style =
+ "position: absolute; \
+ top: 10px; \
+ width: 100%; \
+ display: block; \
+ color: white; \
+ font-size: xx-large;";
+
+ /**
+ * Run the game
+ */
+ const animate = () => {
+ const delta = env.clock.getDelta();
+ const ticks = Math.round(delta / (1 / 120));
+ for (let i = 0; i < ticks; i++) {
+ if (env.update(demo)) {
+ let end = document.createElement("p");
+ end.textContent = "Partie terminée !";
+ end.style =
+ "margin: 0; \
+ position: absolute; \
+ top: 50%; \
+ left: 35%; \
+ font-size: 400%; \
+ color: white;";
+ document.body.appendChild(end);
+
+ let restart = document.createElement("button");
+ restart.textContent = "Cliquez ici pour redémarrer";
+ restart.style =
+ "position: absolute; \
+ top: 60%; \
+ left: 27%; \
+ border: none; \
+ background: none; \
+ color: white; \
+ font-size: 400%;";
+ document.body.appendChild(restart);
+
+ restart.addEventListener("click", () => {
+ location.href = location.href;
+ });
+
+ gui.destroy();
+ return;
+ }
+ }
+
+ score.textContent = `Score : ${Math.floor(env.clock.elapsedTime)}`;
+
+ requestAnimationFrame(animate);
+ };
+
+ // Run it
+ animate();
+};
diff --git a/js/Player.js b/js/Player.js
index 7fbb9ba..e934734 100644
--- a/js/Player.js
+++ b/js/Player.js
@@ -1,5 +1,6 @@
import { Cube } from "./Cube.js";
import { Rotation } from "./utils.js";
+import { jumpDemo } from "./Game.js";
export class Player extends Cube {
constructor(color) {
@@ -14,9 +15,19 @@ export class Player extends Cube {
/**
* Play the player animation
* @param {*} listEnnemies
+ * @param {boolean} demo
* @returns boolean if the player is alive or not
*/
- animation = (listEnnemies) => {
+ animation = (listEnnemies, demo) => {
+ if (demo) {
+ listEnnemies.forEach((ennemy) => {
+ const pos = ennemy.position.x - this.data.position.x;
+ if (pos < Math.random() * 2.8 + 0.2 && pos > 0) {
+ dispatchEvent(jumpDemo);
+ }
+ });
+ }
+
// If we jump
if (this.movementData.state) {
// Rotation
diff --git a/js/main.js b/js/main.js
index 457fb52..72c04ba 100644
--- a/js/main.js
+++ b/js/main.js
@@ -1,104 +1,66 @@
-import { Env, TypeEntity } from "./Env.js";
-import { Plane } from "./Plane.js";
-import { Player } from "./Player.js";
-import { Quality } from "./utils.js";
+import { runGame } from "./Game.js";
window.addEventListener("load", () => main());
+/**
+ * Load the menu
+ */
const main = () => {
- // THREE.js
- const env = new Env();
- document.body.appendChild(env.getDomElement());
+ document.body.style = "background-color: black;";
- // World
- const plan = new Plane(
- window.innerWidth / 50,
- 10,
- THREE.Color.NAMES.white,
- THREE.Color.NAMES.black
- );
- env.addToScene(plan);
-
- // Player
- const player = new Player(THREE.Color.NAMES.pink);
- env.addToScene(player, TypeEntity.player);
- addEventListener("keypress", player.controlUser);
-
- // Generate random map
- env.generateRandomMap(10);
-
- // GUI
- const gui = new dat.gui.GUI({ closeOnTop: true });
- const menu = Quality.buildGUI(env.quality);
- for (const quality in menu) {
- gui.add(menu, quality)
- .listen()
- .onFinishChange(() => {
- Quality.update(env.setQuality, menu, quality);
- });
- }
-
- let score = document.getElementById("score");
- score.style =
- "position: absolute; \
- top: 10px; \
- width: 100%; \
- text-align: center; \
- display: block; \
+ let titleGame = document.createElement("p");
+ titleGame.textContent = "GeometryDash 3D";
+ titleGame.style =
+ "background: none; \
color: white; \
- font-size: xx-large; \
- font-family: sans-serif;";
+ font-size: 400%;";
+ document.body.appendChild(titleGame);
- /**
- * Run the game
- */
- const animate = () => {
- const delta = env.clock.getDelta();
- const ticks = Math.round(delta / (1 / 120));
- for (let i = 0; i < ticks; i++) {
- if (env.update()) {
- let end = document.createElement("p");
- end.textContent = "Partie terminée !";
- end.style =
- "margin: 0; \
- position: absolute; \
- top: 50%; \
- left: 35%; \
- font-size: 400%; \
- font-family: sans-serif; \
- color: white; \
- transform: translate(-50%, -50%) }";
- document.body.appendChild(end);
+ let normalGame = document.createElement("button");
+ normalGame.textContent = "Partie normale";
+ normalGame.style =
+ "position: absolute; \
+ top: 30%; \
+ left: 35%; \
+ border: none; \
+ background: none; \
+ color: white; \
+ font-size: 400%;";
+ document.body.appendChild(normalGame);
- let restart = document.createElement("button");
- restart.textContent = "Cliquez ici pour redémarrer";
- restart.style =
- "margin: 0; \
- position: absolute; \
- top: 60%; \
- left: 27%; \
- border: none; \
- background: none; \
- color: white; \
- font-size: 400%; \
- font-family: sans-serif; \
- transform: translate(-50%, -50%) }";
- document.body.appendChild(restart);
+ let demoGame = document.createElement("button");
+ demoGame.textContent = "Partie démo";
+ demoGame.style =
+ "position: absolute; \
+ top: 40%; \
+ left: 37%; \
+ border: none; \
+ background: none; \
+ color: white; \
+ font-size: 400%;";
+ document.body.appendChild(demoGame);
- restart.addEventListener("click", () => {
- location.href = location.href;
- });
-
- gui.destroy();
- return;
- }
- }
-
- score.textContent = `Score : ${Math.floor(env.clock.elapsedTime)}`;
-
- requestAnimationFrame(animate);
+ const removeMenu = () => {
+ document.body.removeChild(titleGame);
+ document.body.removeChild(normalGame);
+ document.body.removeChild(demoGame);
};
- // Run it
- animate();
+ normalGame.addEventListener(
+ "click",
+ () => {
+ removeMenu();
+ runGame(false);
+ },
+ { once: true }
+ );
+
+ demoGame.addEventListener(
+ "click",
+ () => {
+ removeMenu();
+ runGame(true);
+ },
+ { once: true }
+ );
};