Game
- add vr support - add gamepad support and vr controller (only in vr for that)
This commit is contained in:
@ -25,7 +25,7 @@ urlpatterns = [
|
|||||||
path("multiOnlineGamePage", views.multiOnlineGamePage, name='multiOnlineGamePage'),
|
path("multiOnlineGamePage", views.multiOnlineGamePage, name='multiOnlineGamePage'),
|
||||||
path("waitingGamePage", views.waitingGamePage, name='waitingGamePage'),
|
path("waitingGamePage", views.waitingGamePage, name='waitingGamePage'),
|
||||||
path("profilPage", views.profilPage, name='profilPage'),
|
path("profilPage", views.profilPage, name='profilPage'),
|
||||||
path("game", views.game, name='game'),
|
# path("game", views.game, name='game'),
|
||||||
path("wait_game", views.game, name='wait_game'),
|
path("wait_game", views.game, name='wait_game'),
|
||||||
path("login42", views.login42, name='login42'),
|
path("login42", views.login42, name='login42'),
|
||||||
path("logout", views.logout, name='logout'),
|
path("logout", views.logout, name='logout'),
|
||||||
|
@ -6,13 +6,16 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/18 00:30:31 by edbernar #+# #+# */
|
/* Created: 2024/08/18 00:30:31 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/10/03 14:48:51 by edbernar ### ########.fr */
|
/* Updated: 2024/10/05 01:06:19 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
import { fetchProfile, MotionController } from '/static/javascript/three/examples/jsm/libs/motion-controllers.module.js'
|
||||||
|
import { XRControllerModelFactory } from '/static/javascript/three/examples/jsm/webxr/XRControllerModelFactory.js'
|
||||||
|
import { scene, renderer, isInVrMode } from '/static/javascript/multiOnlineGame/multiOnlineGamePage.js'
|
||||||
|
import { lastSelectedGoal, availableGoals } from '/static/javascript/lobbyPage/3d.js';
|
||||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||||
import { layoutSelected } from '/static/javascript/lobbyPage/main.js'
|
import { layoutSelected } from '/static/javascript/lobbyPage/main.js'
|
||||||
import { lastSelectedGoal, availableGoals } from '/static/javascript/lobbyPage/3d.js';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Explication du code :
|
Explication du code :
|
||||||
@ -45,12 +48,16 @@ import { lastSelectedGoal, availableGoals } from '/static/javascript/lobbyPage/3
|
|||||||
- Ajouter une fonction pour l'animation de point marqué (OK)
|
- Ajouter une fonction pour l'animation de point marqué (OK)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let playerExist = false;
|
let playerExist = false;
|
||||||
let isOnPointAnim = false;
|
let isOnPointAnim = false;
|
||||||
let pressedButton = [];
|
let pressedButton = [];
|
||||||
let mapLength = 0;
|
let mapLength = 0;
|
||||||
const goalAnimation = ["triangle", "cylinder", "star", "box", "rectangle", "ring"];
|
const goalAnimation = ["triangle", "cylinder", "star", "box", "rectangle", "ring"];
|
||||||
let key = null;
|
const controllerModelFactory = new XRControllerModelFactory();
|
||||||
|
let motionController = null;
|
||||||
|
let key = null;
|
||||||
|
let controller1 = null;
|
||||||
|
let controller2 = null;
|
||||||
|
|
||||||
class Player
|
class Player
|
||||||
{
|
{
|
||||||
@ -67,6 +74,8 @@ class Player
|
|||||||
opponent = null;
|
opponent = null;
|
||||||
playerGoalAnimation = null;
|
playerGoalAnimation = null;
|
||||||
opponentGoal = null;
|
opponentGoal = null;
|
||||||
|
controller1 = null;
|
||||||
|
controller2 = null;
|
||||||
|
|
||||||
constructor (object, map, opponent, indexGoalAnimation, goalIdOppenent)
|
constructor (object, map, opponent, indexGoalAnimation, goalIdOppenent)
|
||||||
{
|
{
|
||||||
@ -280,6 +289,7 @@ class Player
|
|||||||
|
|
||||||
update()
|
update()
|
||||||
{
|
{
|
||||||
|
const gamepads = navigator.getGamepads();
|
||||||
const currentTime = Date.now();
|
const currentTime = Date.now();
|
||||||
this.deltaTime = (currentTime - this.previousTime) / 1000;
|
this.deltaTime = (currentTime - this.previousTime) / 1000;
|
||||||
this.previousTime = currentTime;
|
this.previousTime = currentTime;
|
||||||
@ -287,6 +297,23 @@ class Player
|
|||||||
let i;
|
let i;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
for (let i = 0; i< gamepads.length; i++)
|
||||||
|
{
|
||||||
|
if (gamepads[i])
|
||||||
|
{
|
||||||
|
const xAxis = gamepads[i].axes[0];
|
||||||
|
const yAxis = gamepads[i].axes[1];
|
||||||
|
if (!gamepads[i].buttons[0].touched)
|
||||||
|
this.buttonACheck = false;
|
||||||
|
else if (this.buttonACheck == false && gamepads[i].buttons[0].touched)
|
||||||
|
{
|
||||||
|
this.buttonACheck = true;
|
||||||
|
this.buttonAAction = true;
|
||||||
|
}
|
||||||
|
this.joysticksMove(xAxis, yAxis);
|
||||||
|
this.buttonAAction = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
while (i < pressedButton.length)
|
while (i < pressedButton.length)
|
||||||
{
|
{
|
||||||
if (pressedButton[i] == key.up && this.object.position.y < this.limits.up)
|
if (pressedButton[i] == key.up && this.object.position.y < this.limits.up)
|
||||||
@ -336,6 +363,40 @@ class Player
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
if (isInVrMode)
|
||||||
|
{
|
||||||
|
if (controller1.userData.inputSource && controller1.userData.inputSource.gamepad)
|
||||||
|
{
|
||||||
|
const gamepad = controller1.userData.inputSource.gamepad;
|
||||||
|
const [a, b, xAxis, yAxis] = gamepad.axes;
|
||||||
|
|
||||||
|
this.joysticksMove(xAxis, yAxis);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonACheck = false;
|
||||||
|
buttonAAction = false;
|
||||||
|
|
||||||
|
joysticksMove(xAxis, yAxis)
|
||||||
|
{
|
||||||
|
if (yAxis > 0.75 || this.buttonAAction)
|
||||||
|
addKeyInArr({key: key.down})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.down});
|
||||||
|
if (yAxis < -0.75 || this.buttonAAction)
|
||||||
|
addKeyInArr({key: key.up})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.up});
|
||||||
|
if (xAxis > 0.5)
|
||||||
|
addKeyInArr({key: key.right})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.right});
|
||||||
|
if (xAxis < -0.5)
|
||||||
|
addKeyInArr({key: key.left})
|
||||||
|
else
|
||||||
|
remKeyInArr({key: key.left});
|
||||||
}
|
}
|
||||||
|
|
||||||
setCameraPosition(x, y, z)
|
setCameraPosition(x, y, z)
|
||||||
@ -369,6 +430,37 @@ class Player
|
|||||||
}, i * 10);
|
}, i * 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configureVrController()
|
||||||
|
{
|
||||||
|
controller1 = renderer.xr.getController(0);
|
||||||
|
controller2 = renderer.xr.getController(1);
|
||||||
|
|
||||||
|
scene.add(controller1);
|
||||||
|
scene.add(controller2);
|
||||||
|
|
||||||
|
for (let i = 0; i < scene.children.length; i++)
|
||||||
|
{
|
||||||
|
if (scene.children[i].name === 'vrHeadset')
|
||||||
|
{
|
||||||
|
const controllerGrip1 = renderer.xr.getControllerGrip(0);
|
||||||
|
controllerGrip1.add(controllerModelFactory.createControllerModel(controllerGrip1));
|
||||||
|
scene.children[i].add(controllerGrip1);
|
||||||
|
|
||||||
|
const controllerGrip2 = renderer.xr.getControllerGrip(1);
|
||||||
|
controllerGrip2.add(controllerModelFactory.createControllerModel(controllerGrip2));
|
||||||
|
scene.children[i].add(controllerGrip2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
controller1.addEventListener('connected', (event) => {
|
||||||
|
controller1.userData.inputSource = event.data;
|
||||||
|
});
|
||||||
|
|
||||||
|
controller2.addEventListener('connected', (event) => {
|
||||||
|
controller2.userData.inputSource = event.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function addKeyInArr(e)
|
function addKeyInArr(e)
|
||||||
|
@ -6,20 +6,20 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/18 00:53:53 by edbernar #+# #+# */
|
/* Created: 2024/08/18 00:53:53 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/10/03 14:27:34 by edbernar ### ########.fr */
|
/* Updated: 2024/10/04 21:47:35 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
import { availableSkins, lastSelectedGoal } from '/static/javascript/lobbyPage/3d.js';
|
|
||||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
|
||||||
import { OrbitControls } from '/static/javascript/three/examples/jsm/controls/OrbitControls.js'
|
import { OrbitControls } from '/static/javascript/three/examples/jsm/controls/OrbitControls.js'
|
||||||
import { sendRequest } from "/static/javascript/websocket.js";
|
import { availableSkins, lastSelectedGoal } from '/static/javascript/lobbyPage/3d.js';
|
||||||
import { Player } from '/static/javascript/multiOnlineGame/Player.js'
|
import { VRButton } from "/static/javascript/three/examples/jsm/webxr/VRButton.js"
|
||||||
import { Map } from '/static/javascript/multiOnlineGame/Map.js'
|
|
||||||
import { Ball } from '/static/javascript/multiOnlineGame/Ball.js'
|
|
||||||
import { pageRenderer, isMobile } from '/static/javascript/main.js'
|
|
||||||
import { Opponent } from '/static/javascript/multiOnlineGame/Opponent.js'
|
import { Opponent } from '/static/javascript/multiOnlineGame/Opponent.js'
|
||||||
|
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||||
|
import { Player } from '/static/javascript/multiOnlineGame/Player.js'
|
||||||
|
import { pageRenderer, isMobile } from '/static/javascript/main.js'
|
||||||
|
import { Ball } from '/static/javascript/multiOnlineGame/Ball.js'
|
||||||
|
import { Map } from '/static/javascript/multiOnlineGame/Map.js'
|
||||||
|
import { sendRequest } from "/static/javascript/websocket.js";
|
||||||
/*
|
/*
|
||||||
Controls :
|
Controls :
|
||||||
- w : monter
|
- w : monter
|
||||||
@ -49,22 +49,32 @@ Controls :
|
|||||||
- k : recreate et augmente le score de opponent
|
- k : recreate et augmente le score de opponent
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const scoreMax = 5;
|
let scene = null;
|
||||||
|
let map = null;
|
||||||
|
let ball = null;
|
||||||
|
let renderer = null;
|
||||||
|
let player = null;
|
||||||
|
let spotLight = null;
|
||||||
|
let ambiantLight = null;
|
||||||
|
let opponent = null;
|
||||||
|
let interval = null;
|
||||||
|
let intervalPing = null;
|
||||||
|
let debug = false;
|
||||||
|
let lastPingTime = 0;
|
||||||
|
let lastFpsTime = 0;
|
||||||
|
let lastFpsDisplayed = 0;
|
||||||
|
let lastFpsArr = [60];
|
||||||
|
let VrButton = null;
|
||||||
|
let isInVrMode = false;
|
||||||
|
|
||||||
let scene = null;
|
const observer = new MutationObserver((mutationsList) => {
|
||||||
let map = null;
|
mutationsList.forEach((mutation) => {
|
||||||
let ball = null;
|
if (VrButton.innerText == 'VR NOT SUPPORTED')
|
||||||
let renderer = null;
|
document.getElementById('newButtonVr').style.display = 'none';
|
||||||
let player = null;
|
if (mutation.attributeName === 'style')
|
||||||
let spotLight = null;
|
VrButton.style.display = 'none';
|
||||||
let ambiantLight = null;
|
});
|
||||||
let opponent = null;
|
});
|
||||||
let interval = null;
|
|
||||||
let intervalPing = null;
|
|
||||||
let debug = false;
|
|
||||||
let lastPingTime = 0;
|
|
||||||
let lastFpsTime = 0;
|
|
||||||
let lastFpsDisplayed = 0;
|
|
||||||
|
|
||||||
// ------------------- (need to be remove) -------------------- //
|
// ------------------- (need to be remove) -------------------- //
|
||||||
const cameraTmp = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight);
|
const cameraTmp = new THREE.PerspectiveCamera(90, window.innerWidth / window.innerHeight);
|
||||||
@ -75,7 +85,6 @@ class MultiOnlineGamePage
|
|||||||
{
|
{
|
||||||
static create(skin)
|
static create(skin)
|
||||||
{
|
{
|
||||||
console.log(lastSelectedGoal);
|
|
||||||
if (!skin)
|
if (!skin)
|
||||||
skin = {player: 0, opponent: 0};
|
skin = {player: 0, opponent: 0};
|
||||||
const bar1 = createBarPlayer(availableSkins[skin.player]);
|
const bar1 = createBarPlayer(availableSkins[skin.player]);
|
||||||
@ -89,6 +98,8 @@ class MultiOnlineGamePage
|
|||||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||||
renderer.domElement.style.animation = 'fadeOutStartGames 1s';
|
renderer.domElement.style.animation = 'fadeOutStartGames 1s';
|
||||||
renderer.domElement.style.filter = 'brightness(1)';
|
renderer.domElement.style.filter = 'brightness(1)';
|
||||||
|
|
||||||
|
vrMode();
|
||||||
opponent = new Opponent(bar2, map, Math.floor(Math.random() * 100 % 6));
|
opponent = new Opponent(bar2, map, Math.floor(Math.random() * 100 % 6));
|
||||||
player = new Player(bar1, map, opponent, Math.floor(Math.random() * 100 % 6), skin.goalId);
|
player = new Player(bar1, map, opponent, Math.floor(Math.random() * 100 % 6), skin.goalId);
|
||||||
spotLight = new THREE.SpotLight(0xffffff, 10000, 0, 0.2);
|
spotLight = new THREE.SpotLight(0xffffff, 10000, 0, 0.2);
|
||||||
@ -175,6 +186,8 @@ class MultiOnlineGamePage
|
|||||||
|
|
||||||
static dispose()
|
static dispose()
|
||||||
{
|
{
|
||||||
|
observer.disconnect();
|
||||||
|
VrButton = null;
|
||||||
window.removeEventListener('resize', windowUpdater);
|
window.removeEventListener('resize', windowUpdater);
|
||||||
if (interval)
|
if (interval)
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
@ -298,7 +311,6 @@ function loop()
|
|||||||
renderer.render(scene, player.camera);
|
renderer.render(scene, player.camera);
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastFpsArr = [10, 3, 5];
|
|
||||||
|
|
||||||
function showFps()
|
function showFps()
|
||||||
{
|
{
|
||||||
@ -316,4 +328,40 @@ function showFps()
|
|||||||
lastFpsTime = now;
|
lastFpsTime = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { MultiOnlineGamePage, player, opponent, ball, map};
|
function vrMode()
|
||||||
|
{
|
||||||
|
const supportsXR = 'xr' in window.navigator;
|
||||||
|
const newButton = configButton();
|
||||||
|
|
||||||
|
if (!supportsXR)
|
||||||
|
return ;
|
||||||
|
renderer.xr.enabled = true;
|
||||||
|
document.body.appendChild( VRButton.createButton(renderer) );
|
||||||
|
VrButton = document.getElementById('VRButton');
|
||||||
|
observer.observe(VrButton, { attributes: true });
|
||||||
|
if (VrButton.innerText !== 'VR NOT SUPPORTED')
|
||||||
|
document.body.append(newButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
function configButton()
|
||||||
|
{
|
||||||
|
const newButton = document.createElement('button');
|
||||||
|
const cameraGroup = new THREE.Group();
|
||||||
|
|
||||||
|
cameraGroup.name = "vrHeadset";
|
||||||
|
newButton.innerText = "Vr mode";
|
||||||
|
newButton.setAttribute('id', 'newButtonVr');
|
||||||
|
newButton.addEventListener('click', () => {
|
||||||
|
VrButton.click();
|
||||||
|
scene.add(cameraGroup);
|
||||||
|
scene.remove(player.camera);
|
||||||
|
player.configureVrController();
|
||||||
|
cameraGroup.add(player.camera);
|
||||||
|
cameraGroup.position.set(0, 0.5, 7.5);
|
||||||
|
isInVrMode = true;
|
||||||
|
});
|
||||||
|
return (newButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { MultiOnlineGamePage, player, opponent, ball, map, scene, renderer, isInVrMode };
|
@ -150,14 +150,14 @@ function findNodes( motionController, scene ) {
|
|||||||
// If the extents cannot be found, skip this animation
|
// If the extents cannot be found, skip this animation
|
||||||
if ( ! visualResponse.minNode ) {
|
if ( ! visualResponse.minNode ) {
|
||||||
|
|
||||||
console.warn( `Could not find ${minNodeName} in the model` );
|
// console.warn( `Could not find ${minNodeName} in the model` );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! visualResponse.maxNode ) {
|
if ( ! visualResponse.maxNode ) {
|
||||||
|
|
||||||
console.warn( `Could not find ${maxNodeName} in the model` );
|
// console.warn( `Could not find ${maxNodeName} in the model` );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/20 11:23:41 by edbernar #+# #+# */
|
/* Created: 2024/08/20 11:23:41 by edbernar #+# #+# */
|
||||||
/* Updated: 2024/09/29 13:28:28 by edbernar ### ########.fr */
|
/* Updated: 2024/10/04 17:35:50 by edbernar ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
@ -252,4 +252,16 @@ body {
|
|||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#newButtonVr {
|
||||||
|
position: absolute;
|
||||||
|
left: 10px;
|
||||||
|
top: 55px;
|
||||||
|
width: 152px;
|
||||||
|
height: 40px;
|
||||||
|
z-index: 900;
|
||||||
|
padding: 0;
|
||||||
|
color: white;
|
||||||
|
background-color: rgba(0, 0, 0, 0.367);
|
||||||
}
|
}
|
Reference in New Issue
Block a user