Site
- Add multi online game Django - add somes paths
This commit is contained in:
@ -3,10 +3,10 @@
|
||||
# ::: :::::::: #
|
||||
# Game.py :+: :+: :+: #
|
||||
# +:+ +:+ +:+ #
|
||||
# By: tomoron <tomoron@student.42.fr> +#+ +:+ +#+ #
|
||||
# By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ #
|
||||
# +#+#+#+#+#+ +#+ #
|
||||
# Created: 2024/09/13 16:20:58 by tomoron #+# #+# #
|
||||
# Updated: 2024/09/15 13:33:31 by tomoron ### ########.fr #
|
||||
# Updated: 2024/09/15 14:44:14 by edbernar ### ########.fr #
|
||||
# #
|
||||
# **************************************************************************** #
|
||||
|
||||
@ -48,16 +48,10 @@ class Game:
|
||||
self.p1 = socket
|
||||
else:
|
||||
self.p2 = socket
|
||||
print("set game to self")
|
||||
socket.game = self
|
||||
if(self.p2 != None and self.p1 != None):
|
||||
data = json.dumps({"type":"game", "content":{
|
||||
"action" : 1,
|
||||
"id": socket.id,
|
||||
"username": socket.username
|
||||
}})
|
||||
self.p1.sync_send(data)
|
||||
self.p2.sync_send(data)
|
||||
self.p1.sync_send({"type":"game", "content":{"action":1,"id":self.p2.id,"username":self.p2.username}})
|
||||
self.p2.sync_send({"type":"game", "content":{"action":1,"id":self.p1.id,"username":self.p1.username}})
|
||||
except Exception as e:
|
||||
socket.sendError("invalid request", 9005, e)
|
||||
|
||||
|
@ -1,3 +1 @@
|
||||
<body>
|
||||
<p id="score"></p>
|
||||
</body>
|
||||
<p id="score"></p>
|
@ -22,6 +22,7 @@ urlpatterns = [
|
||||
path("homePage",views.homePage, name='homePage'),
|
||||
path("lobbyPage", views.lobbyPage, name='lobbyPage'),
|
||||
path("multiLocalGamePage", views.multiLocalGamePage, name='multiLocalGamePage'),
|
||||
path("multiOnlineGamePage", views.multiOnlineGamePage, name='multiOnlineGamePage'),
|
||||
path("waitingGamePage", views.waitingGamePage, name='waitingGamePage'),
|
||||
path("game", views.game, name='game'),
|
||||
path("wait_game", views.game, name='wait_game'),
|
||||
|
@ -37,6 +37,13 @@ def multiLocalGamePage(request):
|
||||
return(HttpResponse("you are not logged in",status=403))
|
||||
return render(request, "multiLocalGamePage.html", {})
|
||||
|
||||
def multiOnlineGamePage(request):
|
||||
if(request.method != "POST"):
|
||||
return index(request)
|
||||
if(not request.session.get("logged_in", False)):
|
||||
return(HttpResponse("you are not logged in",status=403))
|
||||
return render(request, "multiOnlineGamePage.html", {})
|
||||
|
||||
def waitingGamePage(request):
|
||||
if(request.method != "POST"):
|
||||
return index(request)
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 187 KiB |
@ -6,10 +6,11 @@
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/25 00:00:21 by edbernar #+# #+# */
|
||||
/* Updated: 2024/09/14 21:36:06 by edbernar ### ########.fr */
|
||||
/* Updated: 2024/09/15 15:48:43 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
import { MultiOnlineGamePage } from "/static/javascript/multiOnlineGame/multiOnlineGamePage.js"
|
||||
import { multiLocalGamePage } from "/static/javascript/multiLocalGame/multiLocalGamePage.js"
|
||||
import { WaitingGamePage } from "/static/javascript/waitingGame/main.js"
|
||||
import { LobbyPage } from "/static/javascript/lobbyPage/main.js";
|
||||
@ -23,6 +24,7 @@ class Page
|
||||
{url:'/lobby', servUrl: '/lobbyPage', class: LobbyPage, name: 'lobbyPage', title: 'PTME - Lobby'},
|
||||
{url:'/game', servUrl: '/multiLocalGamePage', class: multiLocalGamePage, name: 'multiLocalGamePage', title: 'PTME - Game'},
|
||||
{url:'/wait_game', servUrl: '/waitingGamePage', class: WaitingGamePage, name: 'waitingGamePage', title: 'PTME - Wait for a game'},
|
||||
{url:'/game', servUrl: '/multiOnlineGamePage', class: MultiOnlineGamePage, name: 'multiOnlineGamePage', title: 'PTME - Game'},
|
||||
]
|
||||
|
||||
constructor()
|
||||
|
@ -0,0 +1,129 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Ball.js :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/20 17:02:47 by edbernar #+# #+# */
|
||||
/* Updated: 2024/09/15 14:56:07 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||
|
||||
class Ball
|
||||
{
|
||||
object = null;
|
||||
centerPos = {};
|
||||
limits = {};
|
||||
interval = null;
|
||||
|
||||
constructor(scene, map)
|
||||
{
|
||||
this.object = this.#createBall();
|
||||
this.centerPos = map.centerPos;
|
||||
this.centerPos.y += this.object.geometry.parameters.radius;
|
||||
this.limits = map.playerLimits;
|
||||
this.resetPosBall();
|
||||
scene.add(this.object);
|
||||
}
|
||||
|
||||
#createBall()
|
||||
{
|
||||
const geometry = new THREE.SphereGeometry(0.15);
|
||||
const material = new THREE.MeshPhysicalMaterial({ color: 0xff5555 });
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
mesh.receiveShadow = true;
|
||||
mesh.castShadow = true;
|
||||
mesh.position.set(this.centerPos.x, this.centerPos.y, this.centerPos.z);
|
||||
return (mesh);
|
||||
}
|
||||
|
||||
resetPosBall()
|
||||
{
|
||||
this.setPosition(this.centerPos.x, this.centerPos.y, this.centerPos.z);
|
||||
}
|
||||
|
||||
setPosition(x, y, z)
|
||||
{
|
||||
this.object.position.set(x, y, z);
|
||||
}
|
||||
|
||||
changeGravity(ballIsOnJumper)
|
||||
{
|
||||
let diffTop = this.limits.up - this.object.position.y;
|
||||
let diffBot = this.object.position.y - this.limits.down;
|
||||
let speed = 0.15;
|
||||
const slower = speed / 3;
|
||||
|
||||
if (diffBot > diffTop)
|
||||
speed *= -1;
|
||||
if (this.interval)
|
||||
clearInterval(this.interval);
|
||||
this.interval = setInterval(() => {
|
||||
this.object.position.y += speed;
|
||||
if ((speed > 0 && this.object.position.y >= this.limits.up)
|
||||
|| (speed < 0 && this.object.position.y <= this.limits.down))
|
||||
{
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
if (speed > 0)
|
||||
this.setPosition(this.object.position.x, this.limits.up, this.object.position.z);
|
||||
else
|
||||
this.setPosition(this.object.position.x, this.limits.down, this.object.position.z);
|
||||
ballIsOnJumper.can = true;
|
||||
}
|
||||
speed -= speed * slower;
|
||||
}, 10);
|
||||
}
|
||||
|
||||
/*---------------- FUNCTION FOR TEST ----------------*/
|
||||
initMoveBallTmp()
|
||||
{
|
||||
console.warn("Don't forget to remove function initMoveBallTmp");
|
||||
const speedBallTmp = 0.1;
|
||||
let warn = false;
|
||||
|
||||
document.addEventListener('keypress', (e) => {
|
||||
if (!this.object && !warn)
|
||||
{
|
||||
console.warn("EventListener in initMoveBallTmp() is still here");
|
||||
warn = true;
|
||||
return ;
|
||||
}
|
||||
if (e.key == '4')
|
||||
this.object.position.x -= speedBallTmp;
|
||||
if (e.key == '6')
|
||||
this.object.position.x += speedBallTmp;
|
||||
if (e.key == '8')
|
||||
this.object.position.z -= speedBallTmp;
|
||||
if (e.key == '2')
|
||||
this.object.position.z += speedBallTmp;
|
||||
if (e.key == '9')
|
||||
this.changeGravity();
|
||||
});
|
||||
}
|
||||
/*---------------------------------------------------*/
|
||||
|
||||
dispose()
|
||||
{
|
||||
if (this.interval)
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
if (this.object)
|
||||
{
|
||||
if (this.object.geometry)
|
||||
this.object.geometry.dispose();
|
||||
if (this.object.material)
|
||||
this.object.material.dispose();
|
||||
if (this.object.texture)
|
||||
this.object.texture.dispose();
|
||||
}
|
||||
this.object = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export { Ball };
|
@ -0,0 +1,620 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Map.js :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/20 14:52:55 by hubourge #+# #+# */
|
||||
/* Updated: 2024/09/15 15:24:37 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
import { GLTFLoader } from '/static/javascript/three/examples/jsm/loaders/GLTFLoader.js';
|
||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||
import { Video } from '/static/javascript/multiOnlineGame/Video.js';
|
||||
|
||||
let loader = null;
|
||||
let scene = null;
|
||||
let videoList = [];
|
||||
let interval2 = null;
|
||||
let videoCanvas = null;
|
||||
let videoCanvasTexture = null;
|
||||
let materialCanvas = null;
|
||||
let textureLoaderPlane = null;
|
||||
let texturePlane = null;
|
||||
let ctx = null;
|
||||
|
||||
let path = [
|
||||
{name: 'goal', onChoice: true, src:'/static/video/multiOnlineGamePage/goal2.webm'},
|
||||
{name: 'easteregg', onChoice: true, src:'/static/video/multiOnlineGamePage/easteregg.webm'},
|
||||
{name: 'outstanding', onChoice: true, src:'/static/video/multiOnlineGamePage/outstanding.webm'},
|
||||
{name: 'ping', onChoice: false, src:'/static/video/multiOnlineGamePage/pingpong.mp4'},
|
||||
{name: 'catch', onChoice: false, src:'/static/video/multiOnlineGamePage/catch.mp4'},
|
||||
{name: 'fortnite', onChoice: false, src:'/static/video/multiOnlineGamePage/fortnite.mp4'},
|
||||
]
|
||||
let spacingImages = [
|
||||
100 * 2.33 * 10 - (100 * 2.33), // 2 images
|
||||
100 * 2.33 * 5 - (100 * 2.33), // 4 images
|
||||
100 * 2.33 * 2.5 - (100 * 2.33), // 8 images
|
||||
100 * 2.33 * 1.25 - (100 * 2.33), // 16 images
|
||||
];
|
||||
|
||||
class Map
|
||||
{
|
||||
arrObject = [];
|
||||
ballObject = null;
|
||||
mapLength = 0;
|
||||
banner = null;
|
||||
centerPos = {
|
||||
x: -1,
|
||||
y: -1,
|
||||
z:-1
|
||||
};
|
||||
playerLimits = {
|
||||
up : 3,
|
||||
down: 0.3,
|
||||
left: -3,
|
||||
right: 3,
|
||||
};
|
||||
ballIsOnJumper = {
|
||||
can: true
|
||||
};
|
||||
|
||||
dispose()
|
||||
{
|
||||
videoList.forEach(elem => {
|
||||
elem.video.pause();
|
||||
elem.video.src = '';
|
||||
elem.video.removeAttribute('src');
|
||||
elem.video.load();
|
||||
})
|
||||
videoList = null;
|
||||
videoCanvas.remove();
|
||||
if (videoCanvasTexture)
|
||||
videoCanvasTexture.dispose();
|
||||
if (materialCanvas)
|
||||
materialCanvas.dispose();
|
||||
videoCanvas = null;
|
||||
textureLoaderPlane = null;
|
||||
loader = null;
|
||||
if (texturePlane)
|
||||
texturePlane.dispose();
|
||||
this.arrObject.forEach(elem => {
|
||||
if (elem.mesh instanceof THREE.Group)
|
||||
{
|
||||
elem.mesh.children.forEach(child => {
|
||||
if (child.geometry)
|
||||
child.geometry.dispose();
|
||||
if (child.material)
|
||||
child.material.dispose();
|
||||
if (child.texture)
|
||||
child.texture.dispose();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (elem.mesh.geometry)
|
||||
elem.mesh.geometry.dispose();
|
||||
if (elem.mesh.material)
|
||||
elem.mesh.material.dispose();
|
||||
if (elem.mesh.texture)
|
||||
elem.mesh.texture.dispose();
|
||||
}
|
||||
scene.remove(elem.mesh);
|
||||
});
|
||||
this.arrObject = null;
|
||||
if (interval2)
|
||||
clearInterval(interval2);
|
||||
scene = null;
|
||||
}
|
||||
|
||||
constructor(sceneToSet, length, obstacles)
|
||||
{
|
||||
loader = new GLTFLoader();
|
||||
scene = sceneToSet;
|
||||
|
||||
this.centerPos.x = 0;
|
||||
this.centerPos.y = 0.15;
|
||||
this.centerPos.z = -length / 2 + length / 2;
|
||||
this.mapLength = length;
|
||||
scene.add(this.#createPlanes(7.5, length, -(Math.PI / 2), "planeBottom", true, '/static/img/multiOnlineGamePage/pastel.jpg'));
|
||||
scene.add(this.#createPlanes(7.5, length, (Math.PI / 2), "planeTop", false, '/static/img/multiOnlineGamePage/pastel.jpg'));
|
||||
scene.add(this.#createWall(-3.5, 0.4, -length/2, "wallLeft"));
|
||||
scene.add(this.#createWall(3.5, 0.4, -length/2, "wallRight"));
|
||||
if (obstacles)
|
||||
this.#generateObstacle();
|
||||
};
|
||||
|
||||
#createPlanes(x, y, rot, name, isBottom, visual)
|
||||
{
|
||||
let geometryPlane = null;
|
||||
let materialPlane = null;
|
||||
let meshPlane = null;
|
||||
|
||||
for (let i = 0; i < this.arrObject.length; i++)
|
||||
{
|
||||
if (this.arrObject[i].name == name)
|
||||
throw Error("Name already exist.");
|
||||
}
|
||||
geometryPlane = new THREE.PlaneGeometry(x, y);
|
||||
if (typeof(visual) == 'string')
|
||||
{
|
||||
textureLoaderPlane = new THREE.TextureLoader();
|
||||
texturePlane = textureLoaderPlane.load(visual);
|
||||
materialPlane = new THREE.MeshPhysicalMaterial({ map: texturePlane });
|
||||
}
|
||||
else if (typeof(visual) == 'number')
|
||||
materialPlane = new THREE.MeshPhysicalMaterial({ color: visual });
|
||||
else
|
||||
materialPlane = new THREE.MeshPhysicalMaterial();
|
||||
meshPlane = new THREE.Mesh(geometryPlane, materialPlane);
|
||||
meshPlane.rotateX(rot);
|
||||
if (isBottom)
|
||||
meshPlane.position.set(0, 0.15, 0);
|
||||
else
|
||||
meshPlane.position.set(0, 3.15, 0);
|
||||
this.arrObject.push({mesh: meshPlane, name: name, type: "plane"});
|
||||
meshPlane.receiveShadow = true;
|
||||
return (meshPlane);
|
||||
};
|
||||
|
||||
changePlane(texture)
|
||||
{
|
||||
console.log(this.arrObject);
|
||||
for (let i = 0; i < this.arrObject.length; i++)
|
||||
{
|
||||
if (this.arrObject[i].name == "planeBottom" || this.arrObject[i].name == "planeTop")
|
||||
{
|
||||
if (this.arrObject[i].mesh.material)
|
||||
this.arrObject[i].mesh.material.dispose();
|
||||
if (typeof(texture) == 'string')
|
||||
{
|
||||
let textureLoader = new THREE.TextureLoader();
|
||||
texture = textureLoader.load(texture);
|
||||
this.arrObject[i].mesh.material.map = texture;
|
||||
}
|
||||
else if (typeof(texture) == 'number')
|
||||
this.arrObject[i].mesh.material.color.set(texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#createWall(x, y, z, name)
|
||||
{
|
||||
let geometryWall = null;
|
||||
let materialWall = null;
|
||||
let meshWall = null;
|
||||
|
||||
for (let i = 0; i < this.arrObject.length; i++)
|
||||
{
|
||||
if (this.arrObject[i].name == name)
|
||||
throw Error("Name already exist.");
|
||||
}
|
||||
|
||||
geometryWall = new THREE.BoxGeometry(0.05, 0.5, 0.75);
|
||||
materialWall = new THREE.MeshPhysicalMaterial();
|
||||
meshWall = new THREE.Mesh(geometryWall, materialWall);
|
||||
meshWall.position.set(x, y, z);
|
||||
materialWall.transparent = true;
|
||||
materialWall.opacity = 0.5;
|
||||
this.arrObject.push({mesh: meshWall, name: name, type: "wall"});
|
||||
return (meshWall);
|
||||
};
|
||||
|
||||
#createGravityChanger(x, y, z, name, typeName, onTop)
|
||||
{
|
||||
let geometry1 = null;
|
||||
let material1 = null;
|
||||
let ring1 = null;
|
||||
let geometry2 = null;
|
||||
let material2 = null;
|
||||
let ring2 = null;
|
||||
let geometry3 = null;
|
||||
let material3 = null;
|
||||
let ring3 = null;
|
||||
let geometry4 = null;
|
||||
let material4 = null;
|
||||
let circle1 = null;
|
||||
let geometry5 = null;
|
||||
let material5 = null;
|
||||
let circle2 = null;
|
||||
let geometry6 = null;
|
||||
let material6 = null;
|
||||
let collider = null;
|
||||
let groupJumper = null;
|
||||
|
||||
for (let i = 0; i < this.arrObject.length; i++)
|
||||
{
|
||||
if (this.arrObject[i].name == name)
|
||||
throw Error("Name already exist.");
|
||||
}
|
||||
|
||||
geometry1 = new THREE.TorusGeometry(1, 0.1, 12, 24);
|
||||
material1 = new THREE.MeshPhysicalMaterial({color: 0x00ff00});
|
||||
ring1 = new THREE.Mesh(geometry1, material1);
|
||||
ring1.rotateX(-Math.PI / 2);
|
||||
ring1.position.set(0, 0, 0);
|
||||
ring1.scale.set(0.2, 0.2, 0.2);
|
||||
material1.transparent = true;
|
||||
material1.opacity = 0.75;
|
||||
|
||||
geometry2 = new THREE.TorusGeometry(1, 0.1, 12, 24);
|
||||
material2 = new THREE.MeshPhysicalMaterial({color: 0x00ff00});
|
||||
ring2 = new THREE.Mesh(geometry2, material2);
|
||||
ring2.rotateX(-Math.PI / 2);
|
||||
ring2.position.set(0, 0 + 0.1, 0);
|
||||
ring2.scale.set(0.18, 0.18, 0.18);
|
||||
material2.transparent = true;
|
||||
material2.opacity = 0.65;
|
||||
|
||||
geometry3 = new THREE.TorusGeometry(1, 0.1, 12, 24);
|
||||
material3 = new THREE.MeshPhysicalMaterial({color: 0x00ff00});
|
||||
ring3 = new THREE.Mesh(geometry3, material3);
|
||||
ring3.rotateX(-Math.PI / 2);
|
||||
ring3.position.set(0, 0 + 0.2, 0);
|
||||
ring3.scale.set(0.16, 0.16, 0.16);
|
||||
material3.transparent = true;
|
||||
material3.opacity = 0.35;
|
||||
|
||||
geometry4 = new THREE.CircleGeometry(0.2, 24);
|
||||
material4 = new THREE.MeshPhysicalMaterial({color: 0xaaffaa});
|
||||
circle1 = new THREE.Mesh(geometry4, material4);
|
||||
circle1.rotateX(-Math.PI / 2);
|
||||
circle1.position.set(0, 0 - 0.048, 0);
|
||||
|
||||
geometry5 = new THREE.CircleGeometry(0.24, 24);
|
||||
material5 = new THREE.MeshPhysicalMaterial({color: 0x00ff00});
|
||||
circle2 = new THREE.Mesh(geometry5, material5);
|
||||
circle2.rotateX(-Math.PI / 2);
|
||||
circle2.position.set(0, 0 - 0.049, 0);
|
||||
|
||||
geometry6 = new THREE.CylinderGeometry(0.15, 0.15, 0.35);
|
||||
material6 = new THREE.MeshPhysicalMaterial({color: 0x00ff00});
|
||||
collider = new THREE.Mesh(geometry6, material6);
|
||||
collider.position.set(0, 0 + 0.1, 0);
|
||||
material6.transparent = true;
|
||||
material6.opacity = 0.1;
|
||||
|
||||
groupJumper = new THREE.Group();
|
||||
groupJumper.add(ring1);
|
||||
groupJumper.add(ring2);
|
||||
groupJumper.add(ring3);
|
||||
groupJumper.add(circle1);
|
||||
groupJumper.add(circle2);
|
||||
groupJumper.add(collider);
|
||||
|
||||
// Set groupJumper position groud / top
|
||||
for (let i = 0; i < groupJumper.children.length && onTop; i++)
|
||||
groupJumper.children[i].position.set(x, y - 0.1, z);
|
||||
for (let i = 0; i < groupJumper.children.length && !onTop; i++)
|
||||
groupJumper.children[i].position.set(x, y, z);
|
||||
|
||||
let distanceY = [-0.04, -0.14, -0.24, 0.048, 0.049, -0.125];
|
||||
let rotate = [0, 0, 0, 1, 1, 0];
|
||||
|
||||
// Set distance between each object
|
||||
for (let i = 0; i < groupJumper.children.length; i++)
|
||||
{
|
||||
if (onTop)
|
||||
{
|
||||
if (rotate[i])
|
||||
groupJumper.children[i].rotateX(Math.PI);
|
||||
groupJumper.children[i].position.set(groupJumper.children[i].position.x, groupJumper.children[i].position.y + distanceY[i], groupJumper.children[i].position.z);
|
||||
}
|
||||
else
|
||||
groupJumper.children[i].position.set(groupJumper.children[i].position.x, groupJumper.children[i].position.y - distanceY[i], groupJumper.children[i].position.z);
|
||||
}
|
||||
|
||||
this.arrObject.push({mesh: groupJumper, name: name, type: typeName});
|
||||
scene.add(groupJumper);
|
||||
};
|
||||
|
||||
#createWallObstacle(x, y, size, onTop)
|
||||
{
|
||||
let geometryWallObs = null;
|
||||
let materialWallObs = null;
|
||||
let meshWallObs = null;
|
||||
|
||||
geometryWallObs = new THREE.BoxGeometry(size, 0.5, 0.1);
|
||||
materialWallObs = new THREE.MeshPhysicalMaterial({color: 0xaaaafe});
|
||||
meshWallObs = new THREE.Mesh(geometryWallObs, materialWallObs);
|
||||
if (onTop)
|
||||
meshWallObs.position.set(x, this.playerLimits.up - 0.1, y);
|
||||
else
|
||||
meshWallObs.position.set(x, 0.4, y);
|
||||
return (meshWallObs);
|
||||
}
|
||||
|
||||
/* Todo (Hugo) :
|
||||
- Faire une zone Player banner (importer un model blender)
|
||||
- Faire une zone pour les pub (ok)
|
||||
- Effet gros pixel (ok)
|
||||
- Effet de lumière en 2d (essayer shader ou filtre)
|
||||
- Preparer differents events (ok)
|
||||
*/
|
||||
putVideoOnCanvas(nbImage, vNameNb)
|
||||
{
|
||||
this.#clearVideoCanvas();
|
||||
if (nbImage <= 0)
|
||||
return ;
|
||||
|
||||
let startIndex = 0;
|
||||
let nbVideos = 1;
|
||||
path.sort(() => Math.random() - 0.5);
|
||||
|
||||
// Create the canvas for the video
|
||||
videoCanvas = document.createElement('canvas');
|
||||
ctx = videoCanvas.getContext('2d');
|
||||
videoCanvas.width = 100 * 2.33 * 20;
|
||||
videoCanvas.height = 100;
|
||||
|
||||
// Get the number of videos to display
|
||||
if (vNameNb && typeof(vNameNb) == 'number')
|
||||
nbVideos = vNameNb;
|
||||
if (vNameNb && typeof(vNameNb) == 'string')
|
||||
startIndex = getIndex(vNameNb);
|
||||
|
||||
function getIndex(vNameNb)
|
||||
{
|
||||
for (let i = 0; i < path.length; i++)
|
||||
{
|
||||
if (path[i].name == vNameNb)
|
||||
return (i);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
// Fill the videoList with the videos
|
||||
for (let i = startIndex; i < (nbVideos + startIndex); i++)
|
||||
{
|
||||
if (path[i].onChoice == true && !(vNameNb && typeof(vNameNb) == 'string'))
|
||||
{
|
||||
startIndex++;
|
||||
continue ;
|
||||
}
|
||||
let videoTmp = null;
|
||||
if (Math.random() < 0.99)
|
||||
videoTmp = new Video(path[i].src).video;
|
||||
else
|
||||
videoTmp = new Video(path[getIndex('easteregg')].src).video;
|
||||
videoTmp.addEventListener('loadeddata', () => {
|
||||
videoTmp.play();
|
||||
drawVideoOnCanvas();
|
||||
});
|
||||
videoList.push({video: videoTmp, imageWidth: 100 * 2.33, imageHeight: 100});
|
||||
}
|
||||
|
||||
// Draw the video on the canvas
|
||||
function drawVideoOnCanvas()
|
||||
{
|
||||
if (videoCanvas)
|
||||
{
|
||||
ctx.clearRect(0, 0, videoCanvas.width, videoCanvas.height);
|
||||
if (nbVideos == 0)
|
||||
return ;
|
||||
let nbDraw = 0;
|
||||
let vIndex = 0;
|
||||
let y = 0;
|
||||
for (let x = 0; x < videoCanvas.width; x += (videoList[vIndex].imageWidth + spacingImages[nbImage]))
|
||||
{
|
||||
ctx.drawImage(videoList[vIndex].video, x, y, videoList[vIndex].imageWidth, videoList[vIndex].imageHeight);
|
||||
nbDraw++;
|
||||
if (nbVideos > 1)
|
||||
vIndex++;
|
||||
if (vIndex >= nbVideos)
|
||||
vIndex = 0;
|
||||
if (!(videoList && videoList[vIndex]))
|
||||
break ;
|
||||
}
|
||||
if (videoCanvasTexture)
|
||||
videoCanvasTexture.needsUpdate = true;
|
||||
requestAnimationFrame(drawVideoOnCanvas);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the material and the banner
|
||||
videoCanvasTexture = new THREE.CanvasTexture(videoCanvas);
|
||||
videoCanvasTexture.wrapS = THREE.RepeatWrapping;
|
||||
videoCanvasTexture.wrapT = THREE.RepeatWrapping;
|
||||
videoCanvasTexture.repeat.set(-1, 1);
|
||||
materialCanvas = new THREE.MeshBasicMaterial({ map: videoCanvasTexture, side: THREE.BackSide , transparent: true});
|
||||
|
||||
// Load the banner
|
||||
loader.load( '/static/models3D/multiOnlineGame/banner.glb', (gltf) => {
|
||||
this.banner = gltf.scene.children[0];
|
||||
gltf = null;
|
||||
this.banner.material = materialCanvas;
|
||||
this.banner.position.y += 1.7;
|
||||
this.banner.rotation.x = (Math.PI);
|
||||
this.banner.rotation.y += -0.15;
|
||||
scene.add(this.banner);
|
||||
interval2 = setInterval(() => {
|
||||
this.banner.rotation.y += 0.001;
|
||||
}, 10);
|
||||
}, undefined, function ( error ) {
|
||||
console.error( error );
|
||||
} );
|
||||
}
|
||||
|
||||
#clearVideoCanvas()
|
||||
{
|
||||
if (videoCanvas)
|
||||
{
|
||||
videoCanvas.remove();
|
||||
videoCanvas = null;
|
||||
}
|
||||
if (videoList)
|
||||
{
|
||||
videoList.forEach(elem => {
|
||||
elem.video.pause();
|
||||
elem.video.src = '';
|
||||
elem.video.removeAttribute('src');
|
||||
elem.video.load();
|
||||
})
|
||||
}
|
||||
videoList = [];
|
||||
if (videoCanvasTexture)
|
||||
{
|
||||
videoCanvasTexture.dispose();
|
||||
videoCanvasTexture = null;
|
||||
}
|
||||
if (materialCanvas)
|
||||
{
|
||||
materialCanvas.dispose();
|
||||
materialCanvas = null;
|
||||
}
|
||||
if (interval2)
|
||||
{
|
||||
clearInterval(interval2);
|
||||
interval2 = null;
|
||||
}
|
||||
scene.remove(this.banner);
|
||||
}
|
||||
|
||||
#animationGravityChanger(group, onTop)
|
||||
{
|
||||
let geometryGC = new THREE.TorusGeometry(1.5, 0.05, 12, 24);
|
||||
let materialGC = new THREE.MeshPhysicalMaterial({color: 0x00ff00});
|
||||
let ringGC = new THREE.Mesh(geometryGC, materialGC);
|
||||
let landmarkGC = group.children[0];
|
||||
let speed = 0.1;
|
||||
let interval = null;
|
||||
|
||||
ringGC.rotateX(-Math.PI / 2);
|
||||
ringGC.position.set(landmarkGC.position.x, landmarkGC.position.y, landmarkGC.position.z);
|
||||
ringGC.scale.set(0.2, 0.2, 0.2);
|
||||
materialGC.transparent = true;
|
||||
scene.add(ringGC);
|
||||
|
||||
interval = setInterval(() => {
|
||||
if (onTop)
|
||||
ringGC.position.y -= speed;
|
||||
else
|
||||
ringGC.position.y += speed;
|
||||
materialGC.opacity -= 0.02;
|
||||
speed *= 0.90;
|
||||
if (materialGC.opacity == 0)
|
||||
clearInterval(interval);
|
||||
}, 10);
|
||||
}
|
||||
|
||||
#generateObstacle()
|
||||
{
|
||||
const wallPos = [
|
||||
{ x: 1, y: 0, z: 1, onTop: false},
|
||||
{ x: 1, y: 0, z: 1, onTop: true},
|
||||
{ x: -1, y: 0, z: 1, onTop: false},
|
||||
{ x: -1, y: 0, z: 1, onTop: true}
|
||||
];
|
||||
for (let i = 0; i < wallPos.length; i++)
|
||||
{
|
||||
if (Math.random() < 0.5)
|
||||
scene.add(this.#createWallObstacle(wallPos[i].x, wallPos[i].y, wallPos[i].z, wallPos[i].onTop));
|
||||
}
|
||||
|
||||
const type = "gravityChanger";
|
||||
const typeNameBottom = "jumperBottom";
|
||||
const typeNameTop = "jumperTop";
|
||||
const jumperPos = [
|
||||
{ x: -1.5, y: 0.2, z: this.mapLength / 4, type: type, typeName: typeNameBottom, onTop: false},
|
||||
{ x: -1.5, y: 3.2, z: this.mapLength / 4, type: type, typeName: typeNameTop, onTop: true},
|
||||
{ x: 1.5, y: 0.2, z: this.mapLength / 4, type: type, typeName: typeNameBottom, onTop: false},
|
||||
{ x: 1.5, y: 3.2, z: this.mapLength / 4, type: type, typeName: typeNameTop, onTop: true},
|
||||
{ x: -1.5, y: 0.2, z: -this.mapLength / 4, type: type, typeName: typeNameBottom, onTop: false},
|
||||
{ x: -1.5, y: 3.2, z: -this.mapLength / 4, type: type, typeName: typeNameTop, onTop: true},
|
||||
{ x: 1.5, y: 0.2, z: -this.mapLength / 4, type: type, typeName: typeNameBottom, onTop: false},
|
||||
{ x: 1.5, y: 3.2, z: -this.mapLength / 4, type: type, typeName: typeNameTop, onTop: true}
|
||||
];
|
||||
for (let i = 0; i < jumperPos.length; i++)
|
||||
{
|
||||
if (Math.random() < 0.5)
|
||||
{
|
||||
this.#createGravityChanger(jumperPos[i].x, jumperPos[i].y, jumperPos[i].z, jumperPos[i].type + i, jumperPos[i].typeName, jumperPos[i].onTop);
|
||||
if (i % 2 == 0)
|
||||
i++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
update(ball)
|
||||
{
|
||||
for (let i = 0; this.arrObject && i < this.arrObject.length; i++)
|
||||
{
|
||||
if (this.arrObject[i].name == "wallLeft")
|
||||
{
|
||||
// Move the wall with the ball position
|
||||
if (ball.object.position.z < this.mapLength / 2 - 0.35 && ball.object.position.z > -this.mapLength / 2 + 0.35)
|
||||
this.arrObject[i].mesh.position.z = ball.object.position.z;
|
||||
if (ball.object.position.y > 0.4 + 0.1 && ball.object.position.y < 3.2)
|
||||
this.arrObject[i].mesh.position.y = ball.object.position.y - 0.1;
|
||||
|
||||
// Change the opacity of the wall
|
||||
let diff = ball.object.position.x - this.arrObject[i].mesh.position.x - 0.1;
|
||||
if (diff > 2)
|
||||
this.arrObject[i].mesh.material.opacity = 0;
|
||||
else
|
||||
this.arrObject[i].mesh.material.opacity = 1 - (diff / 2);
|
||||
}
|
||||
if (this.arrObject[i].name == "wallRight")
|
||||
{
|
||||
// Move the wall with the ball position
|
||||
if (ball.object.position.z < this.mapLength / 2 - 0.35 && ball.object.position.z > -this.mapLength / 2 + 0.35)
|
||||
this.arrObject[i].mesh.position.z = ball.object.position.z;
|
||||
if (ball.object.position.y > 0.4 + 0.1 && ball.object.position.y < 3.2)
|
||||
this.arrObject[i].mesh.position.y = ball.object.position.y - 0.1;
|
||||
|
||||
// Change the opacity of the wall
|
||||
let diff = this.arrObject[i].mesh.position.x - ball.object.position.x - 0.1;
|
||||
if (diff > 2)
|
||||
this.arrObject[i].mesh.material.opacity = 0;
|
||||
else
|
||||
this.arrObject[i].mesh.material.opacity = 1 - (diff / 2);
|
||||
}
|
||||
if (this.arrObject[i].type == 'jumperBottom')
|
||||
{
|
||||
const cylinder = this.arrObject[i].mesh.children[5];
|
||||
const distance = ball.object.position.distanceTo(cylinder.position);
|
||||
const speed = 0.1;
|
||||
|
||||
// Detect if the ball is on the jumper
|
||||
if (distance < 0.25 && this.ballIsOnJumper.can)
|
||||
{
|
||||
this.ballIsOnJumper.can = false;
|
||||
ball.changeGravity(this.ballIsOnJumper);
|
||||
this.#animationGravityChanger(this.arrObject[i].mesh, false);
|
||||
}
|
||||
|
||||
// Gravity changer animation
|
||||
for (let j = 0; j < 3; j++)
|
||||
{
|
||||
this.arrObject[i].mesh.children[j].rotation.x = Math.sin(Date.now() * 0.001 + (j - 2) * 5) * 0.1 + Math.PI / 2;
|
||||
this.arrObject[i].mesh.children[j].rotation.y = Math.sin(Date.now() * 0.001 + (j - 2) * 5) * 0.1 + Math.cos(Date.now() * 0.001) * 0.1;;
|
||||
}
|
||||
}
|
||||
if (this.arrObject[i].type == 'jumperTop')
|
||||
{
|
||||
const cylinder = this.arrObject[i].mesh.children[5];
|
||||
const distance = ball.object.position.distanceTo(cylinder.position);
|
||||
const speed = 0.1;
|
||||
|
||||
// Detect if the ball is on the jumper
|
||||
if (distance < 0.4 && this.ballIsOnJumper.can)
|
||||
{
|
||||
this.ballIsOnJumper.can = false;
|
||||
ball.changeGravity(this.ballIsOnJumper);
|
||||
this.#animationGravityChanger(this.arrObject[i].mesh, true);
|
||||
}
|
||||
|
||||
// Gravity changer animation
|
||||
for (let j = 0; j < 3; j++)
|
||||
{
|
||||
this.arrObject[i].mesh.children[j].rotation.x = Math.sin(Date.now() * 0.001 + (j - 2) * 5) * 0.1 + Math.PI / 2;
|
||||
this.arrObject[i].mesh.children[j].rotation.y = Math.sin(Date.now() * 0.001 + (j - 2) * 5) * 0.1 + Math.cos(Date.now() * 0.001) * 0.1;;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export { Map };
|
@ -0,0 +1,44 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Opponent.js :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/21 10:34:49 by edbernar #+# #+# */
|
||||
/* Updated: 2024/09/15 14:56:35 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
let opponentExist = false;
|
||||
|
||||
class Opponent
|
||||
{
|
||||
object = null;
|
||||
speed = 0.1;
|
||||
interval = null;
|
||||
limits = {};
|
||||
player = null;
|
||||
|
||||
constructor (object, map)
|
||||
{
|
||||
if (opponentExist)
|
||||
throw Error("Opponent is already init.");
|
||||
opponentExist = true;
|
||||
this.object = object;
|
||||
this.limits = map.limits;
|
||||
this.object.position.set(0, 0.3, -map.mapLength / 2 + 0.2);
|
||||
}
|
||||
|
||||
dispose()
|
||||
{
|
||||
opponentExist = false;
|
||||
}
|
||||
|
||||
update()
|
||||
{
|
||||
//en attente du serveur
|
||||
}
|
||||
}
|
||||
|
||||
export { Opponent };
|
@ -0,0 +1,302 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Player.js :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/18 00:30:31 by edbernar #+# #+# */
|
||||
/* Updated: 2024/09/15 14:57:56 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||
|
||||
/*
|
||||
Explication du code :
|
||||
- Un seul joueur peut etre instancié, sinon ça throw une erreur
|
||||
- Lorsqu'une touche est pressée, celle-ci sera ajoutée à la variable "pressedButton"
|
||||
Exemple : w et a sont pressées -> pressedButton = ['w', 'a']
|
||||
- Les lignes avec cleanup sont l'êquivalent d'un destructeur en CPP
|
||||
- Pour appliquer des actions sur les touches, il suffit de faire ça dans la fonction
|
||||
update en regardant si la touche voulue est dans la variable "pressedButton"
|
||||
- Par défaut, la caméra est accrochée, si on veut qu'elle ne bouge plus, il faut
|
||||
modifier "cameraFixed" à true (se fait avec la touche 'm' en jeu)
|
||||
- Si on utilise une touche qui ne sera utilisée que pour un appui simple, il faudra la
|
||||
mettre dans 'addEventListerner('keypress') et pas dans update() pour eviter les
|
||||
problèmes de touche non détecté
|
||||
- La variable "limits" sert à délimiter les mouvements de la barre
|
||||
*/
|
||||
|
||||
/*
|
||||
Todo (Eddy) :
|
||||
- Ajouter une camera sur l'object (OK)
|
||||
- Faire une fonction pour changer le mode de la camera (fix ou accrochée) (OK)
|
||||
- Ajouter une rotation quand la caméra est fixe (OK)
|
||||
- Corriger bug quand changement de caméra (camera qui se remet au dessus
|
||||
quand on repasse au dessus alors qu'elle devrait être en dessous vu que la
|
||||
barre est en haut). Mais peut etre faire ça quand la barre aura des mouvements
|
||||
définis sur la hauteur. (OK)
|
||||
- Ajouter les mouvements définis sur l'axe y (OK)
|
||||
- Faire une fonction qui change de camera quand il y a un but avec un fondu en noir (OK)
|
||||
- Ajouter un zoom sur la camera de la fonction pointAnimation (OK)
|
||||
- Ajouter une fonction pour l'animation de point marqué (OK)
|
||||
*/
|
||||
|
||||
let playerExist = false;
|
||||
let isOnPointAnim = false;
|
||||
let pressedButton = [];
|
||||
|
||||
class Player
|
||||
{
|
||||
object = null;
|
||||
camera = null;
|
||||
speed = 4;
|
||||
cameraFixed = false;
|
||||
interval = null;
|
||||
limits = {};
|
||||
previousTime = Date.now();
|
||||
deltaTime = 1;
|
||||
|
||||
constructor (object, map)
|
||||
{
|
||||
if (playerExist)
|
||||
throw Error("Player is already init.");
|
||||
playerExist = true;
|
||||
isOnPointAnim = false;
|
||||
pressedButton = [];
|
||||
this.object = object;
|
||||
this.limits = map.playerLimits;
|
||||
this.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 10000);
|
||||
this.object.position.set(0, this.limits.down, map.mapLength / 2 - 0.2);
|
||||
this.setCameraPosition(
|
||||
this.object.position.x,
|
||||
this.object.position.y + 0.7,
|
||||
this.object.position.z + 1.5
|
||||
);
|
||||
document.addEventListener('keydown', addKeyInArr);
|
||||
document.addEventListener('keyup', remKeyInArr);
|
||||
document.addEventListener('keypress', simplePressKey);
|
||||
}
|
||||
|
||||
dispose()
|
||||
{
|
||||
playerExist = false;
|
||||
isOnPointAnim = false;
|
||||
document.removeEventListener('keydown', addKeyInArr);
|
||||
document.removeEventListener('keyup', remKeyInArr);
|
||||
document.removeEventListener('keypress', simplePressKey);
|
||||
pressedButton = [];
|
||||
if (this.interval)
|
||||
clearInterval(interval);
|
||||
}
|
||||
|
||||
pointAnimation(map)
|
||||
{
|
||||
const tmpCamera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 10000);
|
||||
const tmp = this.camera;
|
||||
let interval = null;
|
||||
const startColor = this.object.material.color.clone();
|
||||
let hue = 0;
|
||||
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeIn 0.199s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(0)';
|
||||
setTimeout(() => {
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeOut 0.199s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(1)';
|
||||
}, 300)
|
||||
setTimeout(() => {
|
||||
tmpCamera.position.set(this.limits.left, this.limits.up / 2 + 0.5, map.centerPos.z);
|
||||
isOnPointAnim = true;
|
||||
this.camera = tmpCamera;
|
||||
interval = setInterval(() => {
|
||||
tmpCamera.lookAt(this.object.position);
|
||||
hue += 0.01;
|
||||
if (hue > 1)
|
||||
hue = 0;
|
||||
this.object.material.color.setHSL(hue, 1, 0.5);
|
||||
tmpCamera.fov -= 0.05;
|
||||
tmpCamera.updateProjectionMatrix();
|
||||
}, 10);
|
||||
setTimeout(() => {
|
||||
clearInterval(interval);
|
||||
document.getElementsByTagName('canvas')[0].style.animation = null;
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeIn 0.19s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(0)';
|
||||
setTimeout(() => {
|
||||
this.camera = tmp;
|
||||
this.object.material.color.copy(startColor);
|
||||
isOnPointAnim = false;
|
||||
if (!this.cameraFixed)
|
||||
{
|
||||
this.setCameraPosition(
|
||||
this.object.position.x,
|
||||
this.object.position.y - (this.object.position.y >= this.limits.up ? 0.7 : -0.7),
|
||||
this.object.position.z + 2
|
||||
);
|
||||
}
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeOut 0.199s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(1)';
|
||||
}, 200);
|
||||
}, 4000);
|
||||
}, 200)
|
||||
}
|
||||
|
||||
pointOpponentAnimation(map, oppponentObject)
|
||||
{
|
||||
const tmpCamera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 10000);
|
||||
const tmp = this.camera;
|
||||
let interval = null;
|
||||
const startColor = oppponentObject.material.color.clone();
|
||||
let hue = 0;
|
||||
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeIn 0.199s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(0)';
|
||||
setTimeout(() => {
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeOut 0.199s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(1)';
|
||||
}, 300)
|
||||
setTimeout(() => {
|
||||
tmpCamera.position.set(this.limits.left, this.limits.up / 2 + 0.5, map.centerPos.z);
|
||||
isOnPointAnim = true;
|
||||
this.camera = tmpCamera;
|
||||
interval = setInterval(() => {
|
||||
tmpCamera.lookAt(oppponentObject.position);
|
||||
console.log(tmpCamera.position)
|
||||
hue += 0.01;
|
||||
if (hue > 1)
|
||||
hue = 0;
|
||||
oppponentObject.material.color.setHSL(hue, 1, 0.5);
|
||||
tmpCamera.fov -= 0.05;
|
||||
tmpCamera.updateProjectionMatrix();
|
||||
}, 10);
|
||||
setTimeout(() => {
|
||||
clearInterval(interval);
|
||||
document.getElementsByTagName('canvas')[0].style.animation = null;
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeIn 0.19s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(0)';
|
||||
setTimeout(() => {
|
||||
this.camera = tmp;
|
||||
oppponentObject.material.color.copy(startColor);
|
||||
isOnPointAnim = false;
|
||||
if (!this.cameraFixed)
|
||||
{
|
||||
this.setCameraPosition(
|
||||
this.object.position.x,
|
||||
this.object.position.y - (this.object.position.y >= this.limits.up ? 0.7 : -0.7),
|
||||
this.object.position.z + 2
|
||||
);
|
||||
}
|
||||
document.getElementsByTagName('canvas')[0].style.animation = 'fadeOut 0.199s';
|
||||
document.getElementsByTagName('canvas')[0].style.filter = 'brightness(1)';
|
||||
}, 200);
|
||||
}, 4000);
|
||||
}, 200)
|
||||
}
|
||||
|
||||
update()
|
||||
{
|
||||
const currentTime = Date.now();
|
||||
this.deltaTime = (currentTime - this.previousTime) / 1000;
|
||||
this.previousTime = currentTime;
|
||||
|
||||
let i;
|
||||
|
||||
i = 0;
|
||||
while (i < pressedButton.length)
|
||||
{
|
||||
if (pressedButton[i] == 'w' && this.object.position.y < this.limits.up)
|
||||
{
|
||||
if (this.interval)
|
||||
clearInterval(this.interval);
|
||||
this.interval = setInterval(() => {
|
||||
this.object.position.y += this.speed / 40;
|
||||
if (!this.cameraFixed && !isOnPointAnim)
|
||||
this.camera.position.y += (this.speed / 80);
|
||||
if (this.object.position.y >= this.limits.up)
|
||||
{
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
if (pressedButton[i] == 's' && this.object.position.y > this.limits.down)
|
||||
{
|
||||
if (this.interval)
|
||||
clearInterval(this.interval);
|
||||
this.interval = setInterval(() => {
|
||||
this.object.position.y -= this.speed / 40;
|
||||
if (!this.cameraFixed && !isOnPointAnim)
|
||||
this.camera.position.y -= (this.speed / 80);
|
||||
if (this.object.position.y <= this.limits.down)
|
||||
{
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
this.object.position.y = this.limits.down;
|
||||
}
|
||||
}, 5);
|
||||
}
|
||||
if (pressedButton[i] == 'd' && this.object.position.x < this.limits.right)
|
||||
{
|
||||
this.object.position.x += this.speed * this.deltaTime;
|
||||
if (!this.cameraFixed && !isOnPointAnim)
|
||||
this.camera.position.x += this.speed * this.deltaTime;
|
||||
}
|
||||
if (pressedButton[i] == 'a' && this.object.position.x > this.limits.left)
|
||||
{
|
||||
this.object.position.x -= this.speed * this.deltaTime;
|
||||
if (!this.cameraFixed && !isOnPointAnim)
|
||||
this.camera.position.x -= this.speed * this.deltaTime;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
setCameraPosition(x, y, z)
|
||||
{
|
||||
this.camera.position.set(x, y, z);
|
||||
}
|
||||
};
|
||||
|
||||
function addKeyInArr(e)
|
||||
{
|
||||
let i;
|
||||
|
||||
i = 0;
|
||||
while (i < pressedButton.length && e.key != pressedButton[i])
|
||||
i++;
|
||||
if (i == pressedButton.length)
|
||||
pressedButton.push(e.key);
|
||||
}
|
||||
|
||||
function remKeyInArr(e)
|
||||
{
|
||||
let i;
|
||||
|
||||
i = 0;
|
||||
while (i < pressedButton.length && e.key != pressedButton[i])
|
||||
i++;
|
||||
if (i != pressedButton.length)
|
||||
pressedButton.splice(i, 1);
|
||||
}
|
||||
|
||||
function simplePressKey(e)
|
||||
{
|
||||
if (e.key == 'm' && !isOnPointAnim)
|
||||
{
|
||||
this.cameraFixed = !this.cameraFixed;
|
||||
if (!this.cameraFixed)
|
||||
{
|
||||
this.setCameraPosition(
|
||||
this.object.position.x,
|
||||
this.object.position.y - (this.object.position.y >= this.limits.up ? 0.7 : -0.7),
|
||||
this.object.position.z + 1.5
|
||||
);
|
||||
this.camera.rotation.set(0, 0, 0);
|
||||
}
|
||||
else
|
||||
this.setCameraPosition(0, 1.5, this.object.position.z + 3);
|
||||
}
|
||||
}
|
||||
|
||||
export { Player, playerExist };
|
@ -0,0 +1,27 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* Video.js :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/26 18:57:00 by hubourge #+# #+# */
|
||||
/* Updated: 2024/09/15 15:01:30 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
class Video
|
||||
{
|
||||
video = null;
|
||||
|
||||
constructor(path)
|
||||
{
|
||||
this.video = document.createElement('video');
|
||||
this.video.src = path;
|
||||
this.video.muted = true;
|
||||
this.video.autoplay = true;
|
||||
this.video.loop = true;
|
||||
}
|
||||
}
|
||||
|
||||
export { Video };
|
@ -0,0 +1,167 @@
|
||||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* multiOnlineGamePage.js :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/18 00:53:53 by edbernar #+# #+# */
|
||||
/* Updated: 2024/09/15 15:07:29 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
import * as THREE from '/static/javascript/three/build/three.module.js'
|
||||
import { Player } from '/static/javascript/multiOnlineGame/Player.js'
|
||||
import { Map } from '/static/javascript/multiOnlineGame/Map.js'
|
||||
import { Ball } from '/static/javascript/multiOnlineGame/Ball.js'
|
||||
import { Opponent } from '/static/javascript/multiOnlineGame/Opponent.js'
|
||||
|
||||
/*
|
||||
Controls :
|
||||
- w : monter
|
||||
- s : descendre
|
||||
- a : gauche
|
||||
- d : droite
|
||||
|
||||
- g : animation de point
|
||||
- h : animation de point pour l'adversaire
|
||||
- c : switch entre la vue du joueur et la vue de la caméra
|
||||
- q : lancer animation sur les jumpers
|
||||
|
||||
- 8 : avance la balle
|
||||
- 2 : recule la balle
|
||||
- 4 : balle vers la gauche
|
||||
- 6 : balle vers ladroite
|
||||
- 9 : inversion gravite
|
||||
|
||||
- p : clear video
|
||||
- o : goal video
|
||||
- i : outstanding video
|
||||
- u : 16 video
|
||||
- y : 8 video
|
||||
- t : 4 video
|
||||
*/
|
||||
|
||||
let scene = null;
|
||||
let map = null;
|
||||
let ball = null;
|
||||
let renderer = null;
|
||||
let player = null;
|
||||
let spotLight = null;
|
||||
let ambiantLight = null;
|
||||
let opponent = null;
|
||||
|
||||
class MultiOnlineGamePage
|
||||
{
|
||||
static create()
|
||||
{
|
||||
const bar1 = createBarPlayer(0xed56ea);
|
||||
const bar2 = createBarPlayer(0xf3e11e);
|
||||
|
||||
document.body.setAttribute('style', '');
|
||||
scene = new THREE.Scene()
|
||||
map = new Map(scene, 13, true);
|
||||
renderer = new THREE.WebGLRenderer({antialias: true});
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
||||
renderer.domElement.style.animation = 'fadeOutStartGames 1s';
|
||||
renderer.domElement.style.filter = 'brightness(1)';
|
||||
player = new Player(bar1, map);
|
||||
spotLight = new THREE.SpotLight(0xffffff, 10000, 0, 0.2);
|
||||
spotLight.castShadow = true;
|
||||
ambiantLight = new THREE.AmbientLight(0xffffff, 0.5);
|
||||
ball = new Ball(scene, map);
|
||||
opponent = new Opponent(bar2, map);
|
||||
|
||||
scene.add(player.object);
|
||||
scene.add(opponent.object);
|
||||
scene.add(ambiantLight);
|
||||
spotLight.position.set(0, 100, 0);
|
||||
scene.add(spotLight);
|
||||
scene.background = new THREE.Color(0x1a1a1a);
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
document.body.appendChild(renderer.domElement);
|
||||
ball.initMoveBallTmp();
|
||||
map.ballObject = ball.object;
|
||||
|
||||
|
||||
document.addEventListener('keypress', (e) => {
|
||||
if (e.key == 'g')
|
||||
player.pointAnimation(map);
|
||||
if (e.key == 'h')
|
||||
player.pointOpponentAnimation(map, opponent.object);
|
||||
if (e.key == 'c')
|
||||
debug = !debug;
|
||||
if (e.key == 'p')
|
||||
map.putVideoOnCanvas(0, null);
|
||||
if (e.key == 'o')
|
||||
map.putVideoOnCanvas(3, 'goal');
|
||||
if (e.key == 'i')
|
||||
map.putVideoOnCanvas(3, 'outstanding');
|
||||
if (e.key == 'u')
|
||||
map.putVideoOnCanvas(3, 3);
|
||||
if (e.key == 'y')
|
||||
map.putVideoOnCanvas(2, 3);
|
||||
if (e.key == 't')
|
||||
map.putVideoOnCanvas(1, 3);
|
||||
})
|
||||
|
||||
renderer.setAnimationLoop(loop)
|
||||
}
|
||||
|
||||
static dispose()
|
||||
{
|
||||
if (renderer)
|
||||
renderer.dispose();
|
||||
renderer = null;
|
||||
if (map)
|
||||
map.dispose();
|
||||
map = null;
|
||||
if (ball)
|
||||
ball.dispose();
|
||||
ball = null;
|
||||
if (player)
|
||||
player.dispose();
|
||||
player = null;
|
||||
if (opponent)
|
||||
opponent.dispose();
|
||||
opponent = null;
|
||||
if (scene)
|
||||
{
|
||||
scene.children.forEach(child => {
|
||||
if (child.geometry)
|
||||
child.geometry.dispose();
|
||||
if (child.material)
|
||||
child.material.dispose();
|
||||
if (child.texture)
|
||||
child.texture.dispose();
|
||||
scene.remove(child);
|
||||
});
|
||||
}
|
||||
scene = null;
|
||||
}
|
||||
}
|
||||
|
||||
function createBarPlayer(color)
|
||||
{
|
||||
const geometry = new THREE.BoxGeometry(1, 0.1, 0.1);
|
||||
const material = new THREE.MeshPhysicalMaterial({color: color});
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
|
||||
mesh.castShadow = true;
|
||||
return (mesh);
|
||||
}
|
||||
|
||||
function changeBarColor(bar, color)
|
||||
{
|
||||
bar.material.color.set(color);
|
||||
}
|
||||
|
||||
function loop()
|
||||
{
|
||||
player.update();
|
||||
map.update(ball);
|
||||
renderer.render(scene, player.camera);
|
||||
}
|
||||
|
||||
export { MultiOnlineGamePage };
|
@ -6,7 +6,7 @@
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/15 12:00:01 by edbernar #+# #+# */
|
||||
/* Updated: 2024/09/15 12:46:12 by edbernar ### ########.fr */
|
||||
/* Updated: 2024/09/15 14:23:31 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -15,6 +15,7 @@ import { pageRenderer } from '/static/javascript/main.js'
|
||||
|
||||
function typeGame(content)
|
||||
{
|
||||
console.log("New action game : " + content.action);
|
||||
if (content.action == 1)
|
||||
{
|
||||
if (pageRenderer.actualPage == WaitingGamePage)
|
||||
|
@ -6,7 +6,7 @@
|
||||
/* By: edbernar <edbernar@student.42angouleme. +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 21:20:45 by edbernar #+# #+# */
|
||||
/* Updated: 2024/09/15 12:57:52 by edbernar ### ########.fr */
|
||||
/* Updated: 2024/09/15 14:53:22 by edbernar ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
@ -45,14 +45,16 @@ class WaitingGamePage
|
||||
|
||||
static dispose()
|
||||
{
|
||||
const returnButton = document.getElementById('returnToLobbyButton');
|
||||
|
||||
if (intervalPoints)
|
||||
clearInterval(intervalPoints);
|
||||
intervalPoints = null;
|
||||
if (timeout)
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
returnButton.removeEventListener('click', returnToLobby);
|
||||
|
||||
if (returnButton)
|
||||
returnButton.removeEventListener('click', returnToLobby);
|
||||
}
|
||||
|
||||
static showOpponent(username)
|
||||
@ -63,7 +65,18 @@ class WaitingGamePage
|
||||
if (intervalPoints)
|
||||
clearInterval(intervalPoints);
|
||||
intervalPoints = null;
|
||||
sentence.innerText = "Match found";
|
||||
sentence.style.animation = 'anim3 0.5s';
|
||||
sentence.style.opacity = 0;
|
||||
setTimeout(() => {
|
||||
sentence.innerText = "Your opponent is " + username;
|
||||
sentence.style.animation = 'animShowMenuDiv 0.5s';
|
||||
sentence.style.opacity = 1;
|
||||
setTimeout(() => {
|
||||
document.body.style.animation = 'anim3 0.5s';
|
||||
document.body.style.opacity = 0;
|
||||
pageRenderer.changePage("multiOnlineGamePage");
|
||||
}, 1000);
|
||||
}, 500);
|
||||
document.body.removeChild(returnButton);
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user