Old stuff/old_sites/threejs/10_game/js/doors.js
(Deskargatu)
var Doors = function(game_mesh, options)
{
var self=this;
self.game_mesh = game_mesh;
this.mesh = [];
var material;
var depth;
var depth2;
var total_doors=0;
this.cells = [];
this.generated_doors = {};
this.data_doors = {};
this.load= function()
{
var self=this;
depth = (Math.sqrt(3)/2) * options.door_size*1.0;
depth2 = (Math.sqrt(3)/2) * options.door_size * Math.sqrt(3)/2 *1.3;
var texloader = new THREE.TextureLoader();
this.cubeTexture=THREE.ImageUtils.loadTexture('textures/wall.jpg');
this.cubeTexture.wrapS = this.cubeTexture.wrapT = THREE.RepeatWrapping;
this.cubeTexture.repeat.set( 0.1, 0.1 );
return new Promise(function(ok, reject)
{
var ended=0;
var loader = new THREE.JSONLoader();
loader.load( "js/meshes/door.js", function(geometry, mat)
{
self.door_geo = geometry;
self.door_mat = mat;
ended++;
if(ended==2)
{
ok();
}
});
loader.load( "js/meshes/wall.js", function(geometry, mat)
{
self.wall_geo = geometry;
self.door_mat = mat;
ended++;
if(ended==2)
{
ok();
}
});
});
};
this.build = function()
{
var self=this;
self.data_doors= {}
this.num_items_line = Math.floor(Math.sqrt(options.maze_num));
this.half_num = Math.floor(this.num_items_line/2);
var total=0;
self.max_row = 0;
self.max_line = 0;
// Loop to create maze
// Loop lines
for(var row=0; (row<this.num_items_line || total < options.maze_num); row++)
{
self.max_row = row;
for(var line=0; (line<this.num_items_line && total < options.maze_num); line++)
{
if(self.max_line<line) { self.max_line= line ; }
total++;
var cell = self.create_cell({ x: row - this.half_num, y: 1, z:line - this.half_num});
if(!self.generated_doors[row])
{
self.generated_doors[row] = {};
}
self.generated_doors[row][line] = cell;
self.generated_doors[row][line].opened_doors=[];
}
}
// Open/Close some doors
this.maze_doors();
// Loop to really the meshes
// Loop lines
total=0;
for(var row=0; (row<this.num_items_line || total < options.maze_num); row++)
{
for(var line=0; (line<this.num_items_line && total < options.maze_num); line++)
{
var cell = self.create_meshes({num:total, real_x:row, x: row - this.half_num, y: 1, real_z : line, z:line - this.half_num});
total++;
}
}
};
this.get_external_coord = function()
{
var exit_on_x = !!Math.floor(Math.random()*2);
var x = z =0;
if(exit_on_x)
{
x = Math.floor(Math.random()*(this.max_line+1));
z = Math.floor(Math.random()*2) ? 0 : this.max_line;
}
else
{
x = Math.floor(Math.random()*2) ? 0 : this.max_row;
z = Math.floor(Math.random()*(this.max_line+1));
}
return { x: x, z: z};
};
this.maze_doors = function()
{
var coords = this.get_external_coord();
this.start_x = this.end_x = coords.x;
this.start_z = this.end_z = coords.z;
while(this.end_x===this.start_x && this.end_z === this.start_z)
{
coords = this.get_external_coord();
this.end_x = coords.x;
this.end_z = coords.z;
}
this.generated_doors[this.end_x][this.end_z].opened_doors.push(this.end_z ? 0 : 3);
if((!this.end_x || this.end_x==this.max_row) && (this.end_z!=0 && this.end_z!=this.max_line))
{
this.generated_doors[this.end_x][this.end_z].opened_doors.push(this.end_x ? 1 : 4);
}
this.generated_doors[this.start_x][this.start_z].opened_doors.push(this.start_z ? 0 : 3);
if((!this.start_x || this.start_x==this.max_row) && (this.start_z!=0 && this.start_z!=this.max_line))
{
this.generated_doors[this.start_x][this.start_z].opened_doors.push(this.start_x ? 1 : 4);
}
this.maze_doors_next([this.start_x, this.start_z]);
};
this.maze_doors_next = function(opt)
{
var self=this;
var initial_x = opt[0];
var initial_z = opt[1];
this.generated_doors[initial_x][initial_z].used=1;
var next_doors_full = this.near_doors(initial_x, initial_z);
var next_doors_unused=[];
next_doors_full.forEach(function(door)
{
if(!self.generated_doors[door[0]][door[1]].used)
{
next_doors_unused.push(door);
}
});
if(next_doors_unused.length>0)
{
var opened_link = Math.floor(Math.random()*next_doors_unused.length);
var dest_x = next_doors_unused[opened_link][0];
var dest_z = next_doors_unused[opened_link][1];
console.log('link between ',initial_x+'/'+initial_z+' and ',dest_x+'/'+dest_z);
// Fill generated_doors data
// Same row
if(initial_x ==dest_x)
{
// Bottom door
if(initial_z<dest_z)
{
this.generated_doors[initial_x][initial_z].opened_doors.push(0);
this.generated_doors[dest_x][dest_z].opened_doors.push(3);
}
else
{
this.generated_doors[initial_x][initial_z].opened_doors.push(3);
this.generated_doors[dest_x][dest_z].opened_doors.push(0);
}
}
else if(initial_x<dest_x)
{
var pair = !!(initial_x%2===0)
if(initial_z==dest_z)
{
this.generated_doors[initial_x][initial_z].opened_doors.push(pair ? 2 : 1);
this.generated_doors[dest_x][dest_z].opened_doors.push(pair ? 5 : 4);
}
else
{
this.generated_doors[initial_x][initial_z].opened_doors.push(pair ? 1 : 2);
this.generated_doors[dest_x][dest_z].opened_doors.push(pair ? 4 : 5);
}
}
else
{
var pair = !!(initial_x%2===0)
if(initial_z==dest_z)
{
this.generated_doors[initial_x][initial_z].opened_doors.push(pair ? 4 :5);
this.generated_doors[dest_x][dest_z].opened_doors.push(pair ? 1 : 2);
}
else
{
this.generated_doors[initial_x][initial_z].opened_doors.push(pair ? 5 : 4);
this.generated_doors[dest_x][dest_z].opened_doors.push(pair ? 2 : 1);
}
}
this.maze_doors_next(next_doors_unused[opened_link]);
// Visualize path
var geometry = new THREE.BufferGeometry();
var positions = new Float32Array( 2 * 3 ); // 3 vertices per point
geometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );
drawCount = 2; // draw the first 2 points, only
geometry.setDrawRange( 0, drawCount );
var material = new THREE.LineBasicMaterial( { color: Math.random() * 0xffff00 + 0x0000ff, linewidth: 2 } );
// line
line = new THREE.Line( geometry, material );
self.game_mesh.add( line );
var ref = this.cells[initial_x*this.num_items_line + initial_z];
var dest = this.cells[dest_x*this.num_items_line + dest_z];
var positions = line.geometry.attributes.position.array;
positions[0]=(ref.position.x);
positions[1]=(ref.position.y);
positions[2]=(ref.position.z);
positions[3]=(dest.position.x);
positions[4]=(dest.position.y);
positions[5]=(dest.position.z);
}
// Do a maze with the not connected dots too
else
{
for(var x=0; x<=this.max_row; x++)
{
for(var z=0; z<=this.max_line; z++)
{
// Need to link and unused cell with a used cell
if(this.generated_doors[x][z] && !this.generated_doors[x][z].used)
{
next_doors_full = this.near_doors(x, z);
next_doors_used=[];
next_doors_full.forEach(function(door)
{
if(self.generated_doors[door[0]][door[1]].used)
{
next_doors_used.push(door);
}
});
if(next_doors_used.length>0)
{
var connected_door = next_doors_used[Math.floor(Math.random()* next_doors_used.length)];
return this.maze_doors_next(connected_door);
}
}
}
}
}
};
this.near_doors = function(initial_x, initial_z)
{
var next_doors = [];
// Top next door
if(initial_z>0)
{
if(this.generated_doors[initial_x][initial_z-1])
{
next_doors.push([initial_x, initial_z-1]);
}
}
// Bottom next door
if(initial_z<=this.max_line)
{
if(this.generated_doors[initial_x][initial_z+1])
{
next_doors.push([initial_x, initial_z+1]);
}
}
// Left next doors
if(initial_x>0)
{
var pair = !!(initial_x%2===0)
// Pair 2,1 has left next doors: 1,1 and 1,2
if(pair)
{
if(this.generated_doors[initial_x-1][initial_z])
{
next_doors.push([initial_x-1, initial_z]);
}
if(initial_z<this.max_line)
{
if(this.generated_doors[initial_x-1][initial_z+1])
{
next_doors.push([initial_x-1, initial_z+1]);
}
}
}
// Impair 1,1 has 0,0 and 0,1
else
{
if(this.generated_doors[initial_x-1][initial_z])
{
next_doors.push([initial_x-1, initial_z]);
}
if(initial_z-1>-1)
{
if(this.generated_doors[initial_x-1][initial_z-1])
{
next_doors.push([initial_x-1, initial_z-1]);
}
}
}
}
if(initial_x<=this.max_row)
{
var pair = !!(initial_x%2===0)
// Pair 2,1 has left next doors: 1,1 and 1,2
if(pair)
{
if(this.generated_doors[initial_x+1] && this.generated_doors[initial_x+1][initial_z])
{
next_doors.push([initial_x+1, initial_z]);
}
if(initial_z<this.max_line)
{
if(this.generated_doors[initial_x+1] && this.generated_doors[initial_x+1][initial_z+1])
{
next_doors.push([initial_x+1, initial_z+1]);
}
}
}
// Impair 1,1 has 0,0 and 0,1
else
{
if(this.generated_doors[initial_x+1] && this.generated_doors[initial_x+1][initial_z])
{
next_doors.push([initial_x+1, initial_z]);
}
if(initial_z-1>-1)
{
if(this.generated_doors[initial_x+1] && this.generated_doors[initial_x+1][initial_z-1])
{
next_doors.push([initial_x+1, initial_z-1]);
}
}
}
}
return next_doors;
};
/* Memorize the doors created, to avoid creating doble contiguous doors */
this.register_door= function(x, z, i, cell)
{
if(x<0 || z<0)
{
return;
}
if(!this.data_doors[x+'.'+z])
{
this.data_doors[x+'.'+z]={};
}
this.data_doors[x+'.'+z][i] = 1;
var pair= x%2==0;
if(cell)
{
switch(i)
{
case 0: this.register_door(x, z+1, 3, false); break;
case 1: this.register_door(x+1, pair? z : z+1, 4, false); break;
case 2: this.register_door(x+1, pair ? z-1 : z, 5, false); break;
}
}
};
this.get_pos = function(params)
{
var pair = params.x%2 ? depth2 : 0;
var x =params.x * depth *2;
var z =params.z * depth2 *2 + pair;
return { x: x, z: z};
};
this.get_start_pos = function()
{
return this.get_pos({ x: this.start_x - this.half_num, z: this.start_z - this.half_num});
};
this.get_end_pos = function()
{
return this.get_pos({ x: this.end_x - this.half_num, z: this.end_z - this.half_num});
};
this.create_cell = function(params)
{
var self=this;
var pivots=[];
this.fulldepth = options.door_size + options.door_size*2;
var pair = params.x%2 ? depth2 : 0;
var cell = new THREE.Object3D();
var pos = this.get_pos(params);
cell.position.x=pos.x;
cell.position.y=0;
cell.position.z=pos.z;
this.cells.push(cell);
self.game_mesh.add(cell);
return cell;
};
this.create_meshes = function(params)
{
var self=this;
var pivots=[];
this.fulldepth = options.door_size + options.door_size*2;
var total=this.mesh.length;
var cell = this.cells[params.num];
for(var i=0; i<6;i++)
{
if(!this.data_doors[params.x+'.'+params.z] || !this.data_doors[params.x+'.'+params.z][i])
{
this.register_door(params.x, params.z, i, cell);
total_doors++;
pivots[total] = new THREE.Object3D();
cell.add(pivots[total]);
var materials = [];
materials.push(new THREE.MeshLambertMaterial({ map: this.cubeTexture} ));
materials.push(new THREE.MeshLambertMaterial({ map: this.cubeTexture} ));
materials.push(new THREE.MeshLambertMaterial({ map: this.cubeTexture} ));
materials.push(new THREE.MeshLambertMaterial({ map: this.cubeTexture} ));
if(this.generated_doors[params.real_x][params.real_z].opened_doors.indexOf(i)!==-1)
{
this.mesh[total] = new THREE.Mesh( self.door_geo, new THREE.MeshFaceMaterial(materials));
}
else
{
this.mesh[total] = new THREE.Mesh( self.wall_geo, new THREE.MeshFaceMaterial(materials));
}
this.mesh[total].scale.x=options.door_size;
this.mesh[total].scale.y= options.door_size;
this.mesh[total].scale.z= options.door_size;
this.mesh[total].receiveShadow = true;
pivots[total].add( this.mesh[total] );
this.mesh[total].position.set(0, 0, options.door_size);
pivots[total].rotation.y= Math.radians(i*60);
total++;
}
}
self.pivots = pivots;
return cell;
};
}