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; (row0) { 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_z0) { 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-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-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; }; }