// Cloned by Vaidas Buzas on 2 Dec 2022 from World "Project" by Duarte Martinho
// Please leave this clone trail here.
//----------------------------------------------------------------------------------------------
//--- START SKYBOX -----------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
const SKYBOX_ARRAY = [
"/uploads/duarte/px_skybox.png", // b
"/uploads/duarte/nx_skybox.png", // d
"/uploads/duarte/py_skybox.png", // top
"/uploads/duarte/ny_skybox.png", // bottom
"/uploads/duarte/pz_skybox.png", // a
"/uploads/duarte/nz_skybox.png", // c
];
//----------------------------------------------------------------------------------------------
//--- END SKYBOX -------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
function GameModel() {
var model = {};
model.tableSize = {width:0,depth:0,height:0};
model.goalSize = {width:0.3, depth:0.045};
model.state = 1;
model.difficulty = 0.5;
model.numPucks = 1; //simultaneous pucks
model.camera = 0;
model.soundEnabled = true;
model.playerA = {
score: 0,
paddle: null,
radius: 0
};
model.playerB = {
score: 0,
paddle: null,
radius: 0,
};
model.targetScore = 10;
model.pucks = [];
model.listeners = {};
return model;
}
let Hockey = class {
// constructor() {
// this.projector = new THREE.Projector();
// }
GameScene(gameModel) {
this.init(gameModel);
}
init(model) {
this.model = model;
this.input = {x:0, y:0};
this.ai = null;
// DISABLED FOR NOW initialize audio
// Hockey.Audio.init(model);
//initialize world
// this.loadBackground();
this.loadLight();
this.initInput();
this.loadModels(modelsLoaded);
// console.log(ABHandler.getX);
function modelsLoaded() {
// this.simulation = new Hockey.Physics(this.model);
// this.ai = new Hockey.AI(this.model, this.simulation);
// model.on("goal", function(puck){
// this.onGoal(puck);
// });
// prepareToServe();
// model.setState(1);
}
}
loadBackground() {
var t = THREE.ImageUtils.loadTexture( "/uploads/duarte/floor.jpg" );
t.wrapS = THREE.RepeatWrapping;
t.wrapT = THREE.RepeatWrapping;
var material = new THREE.ShaderMaterial({
uniforms: {
texture: { type: "t", value: t },
innerRadius: { type: "f", value: 0.3 },
outerRadius: { type: "f", value: 0.9}
},
vertexShader: document.getElementById('vs_floor').textContent,
fragmentShader: document.getElementById('fs_floor').textContent
});
var floorPlane = new THREE.PlaneGeometry(7,7);
var floorMesh = new THREE.Mesh( floorPlane, material );
floorMesh.rotation.x = -Math.PI * 0.5;
ABWorld.scene.add(floorMesh);
// Floor
/*var floorPlane = new THREE.PlaneGeometry(7,7);
var material = new THREE.MeshPhongMaterial( { color: 0xffffff, map:THREE.ImageUtils.loadTexture( "images/floor.jpg"), ambient: 0xaaaaaa } );
material.map.repeat.x = 4;
material.map.repeat.y = 4;
material.map.wrapS = THREE.RepeatWrapping;
material.map.wrapT = THREE.RepeatWrapping;
var floorMesh = new THREE.Mesh( floorPlane, material );
floorMesh.rotation.x = -Math.PI * 0.5;
ABWorld.scene.add(floorMesh);
// Cover
var coverPlane = new THREE.PlaneGeometry(7,7);
var coverMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff, map:THREE.ImageUtils.loadTexture( "images/cover.png"), transparent: true } );
var coverMesh = new THREE.Mesh( coverPlane, coverMaterial );
coverMesh.rotation.x = -Math.PI * 0.5;
coverMesh.position.y = 0.1;
ABWorld.scene.add(coverMesh);*/
}
loadSkybox() {
var imagePrefix = "sky/";
var directions = ["posx", "negx", "posy", "negy", "posz", "negz"];
var imageSuffix = ".jpg";
var skyGeometry = new THREE.CubeGeometry( 500, 500, 500 );
var materialArray = [];
for (var i = 0; i < 6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture( imagePrefix + directions[i] + imageSuffix ),
side: THREE.BackSide
}));
var skyMaterial = new THREE.MeshFaceMaterial( materialArray );
var skyBox = new THREE.Mesh( skyGeometry, skyMaterial );
ABWorld.scene.add( skyBox );
}
loadLight() {
ABWorld.scene.add(new THREE.AmbientLight(0x222222));
var light = new THREE.SpotLight( 0xffffff, 0.8 );
light.position.set( 0, 10, 0 );
light.target.position.set( 0, 0, 0 );
ABWorld.scene.add( light );
}
loadModels(callback) {
var hockey = this;
var m = new THREE.MTLLoader();
m.load ( '/uploads/duarte/table.mtl', function ( materials ) {
materials.preload();
var o = new THREE.OBJLoader();
o.setMaterials ( materials );
o.load ( '/uploads/duarte/table.obj', function ( object ) {
var table = object;
var bb = hockey.getCompoundBoundingBox(table);
var tableSize = {width: bb.max.z - bb.min.z,
depth: bb.max.x - bb.min.x,
height: bb.max.y + bb.min.y};
var scale = 25.75/tableSize.width;
tableSize.width*=scale * 0.88;
tableSize.depth*=scale * 0.93;
tableSize.height*=scale * 0.95;
hockey.model.tableSize = tableSize;
table.scale.set(scale,scale,scale);
table.position.set(0,tableSize.height,0);
table.rotation.y = Math.PI/2;
ABWorld.scene.add( table );
});
});
m.load ( '/uploads/duarte/paddle.mtl', function ( materials ) {
materials.preload();
var o = new THREE.OBJLoader();
o.setMaterials ( materials );
o.load ( '/uploads/duarte/paddle.obj', function ( object ) {
paddleLoaded(object);
});
});
m.load ( '/uploads/duarte/puck.mtl', function ( materials ) {
materials.preload();
var o = new THREE.OBJLoader();
o.setMaterials ( materials );
o.load ( '/uploads/duarte/puck.obj', function ( object ) {
puckLoaded(object);
});
});
function paddleLoaded(object) {
var paddle = object;
var model = hockey.model;
var bb = hockey.getCompoundBoundingBox(paddle);
var paddleRadius = model.tableSize.width * 0.05;
var scale = paddleRadius * 2 / (bb.max.x - bb.min.x);
paddle.position.set(0,model.tableSize.height,model.tableSize.depth * 0.25);
paddle.scale.set(scale, scale, scale);
hockey.model.playerA.paddle = paddle;
hockey.model.playerA.radius = paddleRadius;
var paddle2 = paddle.clone();
paddle2.position.z = -model.tableSize.depth * 0.25;
hockey.model.playerB.paddle = paddle2;
hockey.model.playerB.radius = paddleRadius;
ABWorld.scene.add(paddle);
ABWorld.scene.add(paddle2);
}
function puckLoaded(object) {
var puckRadius = hockey.model.playerA.radius * 0.7;
var bb = hockey.getCompoundBoundingBox(object);
var scale = puckRadius * 2 / (bb.max.x - bb.min.x);
object.scale.set(scale, scale, scale);
for (var i = 0; i< hockey.model.numPucks; ++i) {
var puck = i === 0 ? object : object.clone();
puck.position.set(0,hockey.model.tableSize.height,0);
ABWorld.scene.add(puck);
hockey.model.addPuck(puck, puckRadius);
}
callback();
}
}
initInput() {
var hockey = this;
ABHandler.getX = (e) => {
hockey.processInput(e.pageX, e.pageY);
};
// document.addEventListener( 'mousemove', inputHandler, false );
}
processInput(x,y) {
this.input.x = x;
this.input.y = y;
}
getCompoundBoundingBox(object3D) {
var box = null;
object3D.traverse(function (obj3D) {
var geometry = obj3D.geometry;
if (geometry === undefined) return;
geometry.computeBoundingBox();
if (box === null) {
box = geometry.boundingBox;
} else {
box.union(geometry.boundingBox);
}
});
return box;
}
}
const MAXPOS = 5; // length of one side of the arena
const SKYCOLOR = 0xffffcc; // a number, not a string
const LIGHTCOLOR = 0xffffff ;
const startRadiusConst = 40 ; // distance from centre to start the camera at
const maxRadiusConst = 250 ; // maximum distance from camera we will render things
var FOLLOW_Y = 20;
var LOOKAT_Y = -200;
function setLookatFollow() {
// ABWorld.follow.copy(theagent.position);
ABWorld.follow.y = FOLLOW_Y;
ABWorld.follow.x = ABWorld.follow.x + 0;
ABWorld.follow.z = ABWorld.follow.z + 0;
// ABWorld.lookat.copy(theagent.position);
ABWorld.lookat.y = LOOKAT_Y;
// ABWorld.lookat.x = ABWorld.lookat.x + 2;
ABWorld.lookat.z = ABWorld.lookat.z + 10;
}
AB.world.newRun = function()
{
ABWorld.init3d ( startRadiusConst, maxRadiusConst, SKYCOLOR );
var hockey = new Hockey();
var model = GameModel();
gameScene = hockey.GameScene(model);
ABWorld.cameraMove();
setLookatFollow();
};
AB.world.nextStep = function()
{
};