var Game = function(opt) { var scene; var lock; var SCREEN_HEIGHT; var SCREEN_HEIGHT; var camera; var renderer; var mazes= {}; var camera_decal_x = -34; var camera_decal_y = 100; var camera_decal_z = 30; // "Main perso view" //var camera_decal_x = -10; //var camera_decal_y = 10; //var camera_decal_z = -10; var clock = new THREE.Clock(); var stats = new Stats(); stats.showPanel( 0 ); // 0: fps, 1: ms, 2: mb, 3+: custom document.body.appendChild( stats.dom ); var start_num_maze = 6; var maze_increment = 1; this.load = function() { var promises = []; this.assets = new Assets(); return this.assets.load(); }; this.init = function() { var self=this; this.load().then(function() { self.init_loaded(); }, function() { alert('Error loading some assets...'); }); }; this.init_loaded= function() { var self=this; this.opt = opt; this.obstacles = []; this.obstacles_with_player = []; this.collision_callbacks = []; this.scene = new THREE.Scene(); // Build basic structures var width = 10000; var height = 10000; var click_ground = new THREE.PlaneGeometry(width, height); var material = new THREE.LineBasicMaterial( { color: 0x555555, opacity:0, transparent:true } ); // Set and add the click_ground this.click_ground = new THREE.Mesh(click_ground, material); this.click_ground.name='click_ground'; this.click_ground.rotation.x = -Math.PI / 2; this.scene.add(this.click_ground); this.camera = new THREE.PerspectiveCamera(45, 1, 0.1, 10000); this.scene.add(this.camera); //this.scene.fog = new THREE.FogExp2( 0x333355, 0.0055 ); this.ambient_light = new THREE.PointLight(); this.ambient_light.intensity=1.0; this.ambient_light.position.set(100, 200, 80); this.scene.add(this.ambient_light); this.renderer = new THREE.WebGLRenderer({ antialias: true}); this.renderer.setClearColor(0x000000, 1); this.renderer.shadowMapEnabled=true; this.renderer.shadowMapSoft=true; window.addEventListener( 'resize', onWindowResize, false ); function onWindowResize(){ self.camera.aspect = window.innerWidth / window.innerHeight; self.camera.updateProjectionMatrix(); self.renderer.setSize( window.innerWidth, window.innerHeight ); } this.container = opt.root; this.setAspect(); this.container.appendChild(this.renderer.domElement); this.start(); this.render(); this.updateCollisionsCache(); }; this.setAspect= function() { var w = this.container.offsetWidth; // Fit the initial visible area's height h = this.container.offsetHeight; // Update the renderer and the camera this.renderer.setSize(w, h); this.camera.aspect = w / h; this.camera.updateProjectionMatrix(); }; this.setFocus = function(object) { this.camera.position.set(object.position.x + camera_decal_x, object.position.y + camera_decal_y, object.position.z + camera_decal_z); this.camera.position.set(object.position.x + camera_decal_x, object.position.y + camera_decal_y, object.position.z + camera_decal_z); this.camera.lookAt(object.position); }; this.start = function() { var self=this; this.direction=0; // Create start path var path = new Path(this, {direction: this.direction, x: 0, z: 0}); path.build(); this.start_path = path; var pos = path.get_start_pos(); var angle = Math.radians(30); pos.x += Math.cos(angle) * 20; pos.z += Math.sin(angle) * 20; this.focus_perso = self.add_character({ x: pos.x, y: 0, z: pos.z, moveable: true, ai: false, game: self }); this.focus_perso.name='main character'; this.enterPath(path); }; this.add_character= function(params) { return new Perso(this, params); }, this.add_key= function(params) { return new Key(this, params); }, this.render = function() { stats.begin(); this.renderer.render(this.scene, this.camera); if(!this.updating) { this.updating=1; var delta = clock.getDelta(); if(delta>0.070 && game.opt.debug_level>10) { console.warn('SLOW RENDERING DELTA: ',delta); delta=0.070; } //delta=0.030; this.focus_perso.update(delta); if(this.current_maze) { this.current_maze.update(delta); } this.setFocus(this.focus_perso.container); this.updating=0; } requestAnimationFrame(this.render_fct); stats.end(); }; this.render_fct = this.render.bind(this); this.getObstacles = function() { return this.obstacles; }; this.getObstaclesWithPlayer = function() { return this.obstacles_with_player; }; this.getCollisionCallbacks = function() { return this.collision_callbacks; } this.generateCollisionCallbacks = function() { if(this.current_maze) { return this.current_maze.getCollisionCallbacks(); } else { var coll = []; for (var i in mazes) { coll = coll.concat(mazes[i].getOutsideCollisionCallbacks()); } return coll; } }; this.callCollisionCallbacks = function(perso,collisions) { if(this.current_maze) { return this.current_maze.callCollisionCallbacks(perso, collisions); } else { if(collisions.length>0) { if(collisions[0].mazeid) { this.inMaze(collisions[0].mazeid, collisions[0].cellid); } } } }; this.enterPath = function(path) { var self=this; this.current_path=path; this.obstacles = this.current_path.getObstacles(); if(!path.next_maze) { var pos = path.get_end_pos(); var maze = new Maze(this, { maze_num: start_num_maze, x: pos.x, z: pos.z }); this.last_maze=maze; start_num_maze+= maze_increment; path.next_maze = maze; maze.start_path = path; mazes[maze.id] = maze; maze.build(); var pos = maze.doors.get_end_pos(); var path = new Path(self, {direction: this.direction, x: pos.x, z: pos.z}); maze.end_path = path; self.end_path = path; path.build(); } } this.leaveMaze = function(id, path) { console.log('leave maze! ',id); var self=this; this.current_maze_id = null; this.current_maze = null; this.current_path = path; this.obstacles=[]; this.obstacles_with_player=[]; this.collision_callbacks = []; if(path){ this.enterPath(path); } }; this.updateCollisionsCache = function() { if(this.current_maze) { this.obstacles = this.current_maze.getObstacles(); this.obstacles_with_player = [].concat(this.obstacles, this.focus_perso.container_mesh); // Debug - no walls //this.obstacles_with_player = [this.focus_perso.container_mesh]; } this.collision_callbacks = this.generateCollisionCallbacks(); }; this.inMaze = function(mazeid, cellid) { if(this.current_maze_id!==mazeid) { console.log('in maze ',mazeid, cellid); this.current_path = null; this.current_maze_id = mazeid; this.current_maze = mazes[mazeid]; this.current_maze.current_cell = cellid; } } };