2022-11-08 10:40:45 +01:00
|
|
|
import { Element } from "./Element.js";
|
2022-11-24 19:45:20 +01:00
|
|
|
import { Quality } from "./utils.js";
|
2022-11-24 21:01:59 +01:00
|
|
|
import { Size } from "./Cone.js";
|
|
|
|
import { Spade } from "./Spade.js";
|
2022-11-08 10:40:45 +01:00
|
|
|
|
2022-11-24 20:16:48 +01:00
|
|
|
export class TypeEntity {
|
|
|
|
static other = 0;
|
|
|
|
static player = 1;
|
|
|
|
static ennemy = 2;
|
|
|
|
}
|
|
|
|
|
2022-11-08 10:40:45 +01:00
|
|
|
export class Env {
|
|
|
|
constructor() {
|
|
|
|
this.scene = new THREE.Scene();
|
|
|
|
this.camera = new THREE.PerspectiveCamera(
|
|
|
|
75,
|
|
|
|
window.innerWidth / window.innerHeight,
|
|
|
|
1,
|
|
|
|
1000
|
|
|
|
);
|
|
|
|
|
2022-11-22 10:40:21 +01:00
|
|
|
this.camera.position.z = 7;
|
2022-11-08 10:40:45 +01:00
|
|
|
|
|
|
|
this.renderer = new THREE.WebGLRenderer();
|
|
|
|
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
|
2022-11-24 19:45:20 +01:00
|
|
|
// Change the default quality of the rendered scene
|
|
|
|
this.setQuality(Quality.medium);
|
2022-11-24 16:03:01 +01:00
|
|
|
|
|
|
|
// Store all elements in the env
|
|
|
|
this.elements = [];
|
|
|
|
|
|
|
|
// Setup renderer for lights
|
|
|
|
this.renderer.shadowMap.enabled = true;
|
|
|
|
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
|
|
|
|
|
|
|
// Add light source
|
|
|
|
const light = new THREE.DirectionalLight(THREE.Color.NAMES.white);
|
|
|
|
// On top : 1, right : 2 and between player (0) and camera (7) : 4
|
|
|
|
light.position.set(2, 1, 4);
|
|
|
|
light.castShadow = true;
|
|
|
|
this.scene.add(light);
|
2022-11-24 18:41:17 +01:00
|
|
|
|
|
|
|
// Clock
|
|
|
|
this.clock = new THREE.Clock();
|
2022-11-08 10:40:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the Canvas element
|
|
|
|
* @returns domElement
|
|
|
|
*/
|
|
|
|
getDomElement = () => this.renderer.domElement;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get current scene
|
|
|
|
* @returns Scene
|
|
|
|
*/
|
|
|
|
getScene = () => this.scene;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get used camera
|
|
|
|
* @returns Camera
|
|
|
|
*/
|
|
|
|
getCamera = () => this.camera;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get current renderer
|
|
|
|
* @returns Render
|
|
|
|
*/
|
|
|
|
getRenderer = () => this.renderer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Change the quality of the render
|
|
|
|
* @param {Quality} quality
|
|
|
|
* @returns
|
|
|
|
*/
|
2022-11-24 19:45:20 +01:00
|
|
|
setQuality = (quality) => {
|
|
|
|
this.quality = quality;
|
|
|
|
|
|
|
|
this.renderer.setSize(
|
|
|
|
window.innerWidth / quality,
|
|
|
|
window.innerHeight / quality,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
};
|
2022-11-08 10:40:45 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Add an element to the scene
|
|
|
|
* @param {Element} element Element
|
2022-11-24 20:16:48 +01:00
|
|
|
* @param {TypeEntity} type Type of the element added
|
2022-11-08 10:40:45 +01:00
|
|
|
*/
|
2022-11-24 20:16:48 +01:00
|
|
|
addToScene = (element, type) => {
|
|
|
|
if (!type) {
|
|
|
|
type = TypeEntity.other;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.elements.push([element, type]);
|
2022-11-08 10:40:45 +01:00
|
|
|
this.scene.add(element.data);
|
|
|
|
};
|
|
|
|
|
2022-11-24 16:03:01 +01:00
|
|
|
/**
|
2022-11-27 17:20:49 +01:00
|
|
|
* Animate all the entities in the environnement
|
2022-11-24 16:03:01 +01:00
|
|
|
*/
|
|
|
|
animate = () => {
|
2022-11-27 18:09:56 +01:00
|
|
|
// Retrieve ennemies
|
|
|
|
const ennemies = this.elements
|
|
|
|
.filter((entityData) => entityData[1] == TypeEntity.ennemy)
|
|
|
|
.map((ennemyData) => ennemyData[0]);
|
|
|
|
|
2022-11-24 21:01:59 +01:00
|
|
|
// Player animation
|
2022-11-24 20:16:48 +01:00
|
|
|
this.elements
|
|
|
|
.filter((entityData) => entityData[1] == TypeEntity.player)
|
|
|
|
.map((playerData) => playerData[0])
|
|
|
|
.forEach((player) => {
|
|
|
|
if (player.animation) {
|
2022-11-27 18:09:56 +01:00
|
|
|
if (
|
|
|
|
!player.animation(ennemies.map((object) => object.data))
|
|
|
|
) {
|
|
|
|
// If animation returned false, the player died!
|
|
|
|
console.log("player died!");
|
|
|
|
// TODO: Stop the game
|
|
|
|
// Destroy the player?
|
|
|
|
// End game
|
|
|
|
}
|
2022-11-24 20:16:48 +01:00
|
|
|
}
|
|
|
|
});
|
2022-11-24 21:01:59 +01:00
|
|
|
|
|
|
|
// Enemy animation
|
2022-11-24 21:33:38 +01:00
|
|
|
ennemies.forEach((ennemy) => {
|
|
|
|
ennemy.data.position.x -= 0.05;
|
|
|
|
if (ennemy.data.position.x <= -10) {
|
|
|
|
ennemy.data.position.x = ennemy.startPos + Math.random() * 20;
|
|
|
|
}
|
|
|
|
});
|
2022-11-24 16:03:01 +01:00
|
|
|
};
|
|
|
|
|
2022-11-08 10:40:45 +01:00
|
|
|
/**
|
|
|
|
* Render the current scene, using the camera
|
|
|
|
* @returns
|
|
|
|
*/
|
|
|
|
render = () => this.renderer.render(this.scene, this.camera);
|
2022-11-24 18:41:17 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the game logic
|
|
|
|
*/
|
|
|
|
update = () => {
|
|
|
|
this.animate();
|
|
|
|
this.render();
|
|
|
|
};
|
2022-11-24 21:01:59 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate a random map of ennemies
|
|
|
|
* @param {number} numberOfEnnemies
|
|
|
|
*/
|
|
|
|
generateRandomMap = (numberOfEnnemies) => {
|
|
|
|
// Distance before the first ennemy hit the player
|
|
|
|
const startDelta = 5;
|
|
|
|
// Simple Spade
|
|
|
|
for (let index = 1; index < numberOfEnnemies + 1; index++) {
|
|
|
|
const spade = new Spade(
|
|
|
|
Math.random() * 0xffffff,
|
2022-11-24 21:33:38 +01:00
|
|
|
Math.round(Math.random()) ? Size.little : Size.big,
|
|
|
|
startDelta + index + Math.random() * 20
|
2022-11-24 21:01:59 +01:00
|
|
|
);
|
|
|
|
|
|
|
|
this.addToScene(spade, TypeEntity.ennemy);
|
|
|
|
}
|
|
|
|
};
|
2022-11-08 10:40:45 +01:00
|
|
|
}
|