add light, shadow, animation, player, jump

This commit is contained in:
Mylloon 2022-11-24 16:03:01 +01:00
parent 65a8411801
commit c1dd1a1b48
Signed by: Anri
GPG key ID: A82D63DFF8D1317F
6 changed files with 160 additions and 6 deletions

View file

@ -1,12 +1,15 @@
import { Element } from "./Element.js";
export class Cube extends Element {
constructor() {
constructor(color) {
super();
this.data = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshBasicMaterial({ color: 0x00ff00 })
new THREE.MeshBasicMaterial({ color: color })
);
// Create shadows
this.data.castShadow = true;
}
}

View file

@ -1,8 +1,16 @@
export class Element {
constructor() {
this.data = undefined;
// Rotate everything on X by this factor to give some perspective
this.gameRotation = 2;
}
/**
* Animation of the element
*/
animation = () => {};
/**
* Rotate the element
*/

View file

@ -28,6 +28,20 @@ export class Env {
window.innerHeight / this.quality,
false
);
// 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);
}
/**
@ -66,9 +80,21 @@ export class Env {
* @param {Element} element Element
*/
addToScene = (element) => {
this.elements.push(element);
this.scene.add(element.data);
};
/**
* Animate all the elements in the environnement
*/
animate = () => {
this.elements.forEach((element) => {
if (element.animation) {
element.animation();
}
});
};
/**
* Render the current scene, using the camera
* @returns

View file

@ -11,7 +11,7 @@ export class Plane extends Element {
this.data = new THREE.Mesh(
new THREE.PlaneGeometry(width, height),
new THREE.MeshBasicMaterial({
new THREE.MeshPhongMaterial({
color: color1,
side: THREE.DoubleSide,
map: textureGradient(
@ -23,6 +23,9 @@ export class Plane extends Element {
})
);
this.data.rotation.x = 2;
this.data.rotation.x = this.gameRotation;
// Shadows
this.data.receiveShadow = true;
}
}

View file

@ -1,6 +1,6 @@
import { Env } from "./Env.js";
import { Cube } from "./Cube.js";
import { Plane } from "./Plane.js";
import { Joueur } from "./player.js";
window.addEventListener("load", () => main());
@ -17,9 +17,14 @@ const main = () => {
);
env.addToScene(plan);
const joueur = new Joueur(THREE.Color.NAMES.red);
env.addToScene(joueur);
addEventListener("keypress", joueur.controlUser);
const animate = () => {
requestAnimationFrame(animate);
env.animate();
env.render();
};

109
js/player.js Normal file
View file

@ -0,0 +1,109 @@
import { Cube } from "./Cube.js";
class Rotation {
constructor(position) {
this.default = position.clone();
this.state = false;
this.rotation = 0;
this.jump = 0;
this.rotationVelocity = 0.05;
this.jumpVelocity = 0.1;
this.lastJump = 0;
}
/**
* Change the state of the animation and update the latest jump time
* @param {number} time
*/
changeState = (time) => {
this.state = !this.state;
if (time) {
this.lastJump = time;
}
};
/**
* Change the final rotation
* @param {number} rotation
*/
changeRotation = (rotation) => {
this.rotation = rotation;
};
/**
* Change the final position
* @param {number} jump
*/
changeJump = (jump) => {
this.jump = jump;
};
/**
* Return the state of the jump
* @returns boolean representing if the object is going up or down
*/
falling = () => {
return this.jump == this.default.y;
};
}
export class Joueur extends Cube {
constructor(color) {
super(color);
this.data.position.y = 0.5;
this.data.rotation.x = this.gameRotation;
this.movementData = new Rotation(this.data.position);
}
animation = () => {
// If we jump
if (this.movementData.state) {
// Rotation
this.data.rotation.y -= this.movementData.rotationVelocity;
// If we're falling (2nd part of the jump)
if (this.movementData.falling()) {
// Gravity!
this.data.position.y -= this.movementData.jumpVelocity;
} else {
// If we're jumping (1st part of the jump) : jumping
this.data.position.y += this.movementData.jumpVelocity;
// Check if the jump stop and we need to goes down
if (this.data.position.y >= this.movementData.jump) {
this.movementData.changeJump(this.movementData.default.y);
}
}
// End of the rotation
if (this.data.rotation.y <= this.movementData.rotation) {
// Force the final rotation
this.data.rotation.y = this.movementData.rotation;
// Force the end of the jump
this.data.position.y = this.movementData.default.y;
// End
this.movementData.changeState();
}
}
};
controlUser = (key) => {
const now = Date.now();
if (
key.code == "Space" &&
!this.movementData.state &&
now - this.movementData.lastJump > 400
) {
this.movementData.changeRotation(
this.data.rotation.y - Math.PI / 2
);
this.movementData.changeJump(this.data.position.y + Math.PI / 2);
this.movementData.changeState(now);
}
};
}