Old stuff/old_sites/threejs/15_die/js/perso.js
(Deskargatu)
var Perso = function(game, options)
{
var self=this;
self.id=game.getNewId();
self.move_speed= game.opt.debug_level > 1 ? 2.00 : 1.00;
self.weapon_range = 15;
self.weapon_attack_damage = 10;
self.is_dying=false;
self.is_dead=false;
self.max_life=game.opt.debug_level>1 ? 10000 : 100;
self.life=self.max_life;
self.is_attacking=false;
self.is_moving=false;
var move_action_weight=0;
this.build = function()
{
this.game = game;
this.options=options;
this.bind();
this.create();
this.update_life();
if(options.moveable)
{
this.moveable();
}
};
this.bind = function()
{
this.life_value = document.querySelector('.life_value');
};
this.create =function()
{
var self=this;
this.container = new THREE.Object3D();
this.game.scene.add(this.container);
// Cube simulating perso, for collision detection
var cube_material = new THREE.MeshPhongMaterial( { color: 0xbbbbff, wireframe:game.opt.debug_level>1, transparent:true, visible: game.opt.debug_level>1 } );
var cube_geo = new THREE.BoxGeometry(7,7,7);
this.container_mesh = new THREE.Mesh(cube_geo, cube_material);
this.container_mesh.rotation.x = Math.radians(90);
this.container_mesh.rotation.z = Math.radians(45);
this.container_mesh.position.y=1;
this.container_mesh.name='p';
this.container.add(this.container_mesh);
this.container.position.x = this.options.x;
this.container.position.y = 0;
this.container.position.z = this.options.z;
var materials = game.assets.perso_mat;
for ( var i = 0; i < materials.length; i ++ ) {
var m = materials[ i ];
m.skinning = true;
m.morphTargets = true;
}
this.mesh = new THREE.SkinnedMesh( game.assets.perso_geo, new THREE.MultiMaterial(materials));
this.mesh.castShadow=true;
this.mesh.scale.x=25;
this.mesh.scale.y=25;
this.mesh.scale.z=25;
this.container.add(this.mesh);
this.mesh.receiveShadow = true;
//this.mesh.castShadow = true;
this.mesh.position.x = 0;
this.mesh.position.y = 1;
this.mesh.position.z = 0;
this.mixer = new THREE.AnimationMixer( this.mesh );
this.attackingClip = game.assets.perso_geo.animations[3];
this.walkingClip = game.assets.perso_geo.animations[2];
this.iddlingClip = game.assets.perso_geo.animations[1];
this.dyingClip = game.assets.perso_geo.animations[4];
this.attack_action = this.mixer.clipAction(this.attackingClip, null ).setDuration(0.5);
this.attack_action.setLoop(THREE.LoopOnce, 0);
this.attack_action.clampWhenFinished = true;
this.mixer.addEventListener('finished', this.end_attack.bind(this));
this.dying_action = this.mixer.clipAction(this.dyingClip, null ).setDuration(0.7);
this.dying_action.setLoop(THREE.LoopOnce, 0);
this.dying_action.clampWhenFinished = true;
this.move_action = this.mixer.clipAction(this.walkingClip, null ).setDuration(0.45);
this.idle_action = this.mixer.clipAction(this.iddlingClip, null ).setDuration(5);
this.move_action.play();
this.idle_action.play();
this.attack_action.setEffectiveWeight(0);
this.move_action.setEffectiveWeight(0);
this.idle_action.setEffectiveWeight(1);
};
this.attacked=function(from)
{
if(!this.is_dying)
{
this.life= Math.max(0,this.life-from.weapon_attack_damage);
this.update_life();
if(this.life===0)
{
this.die();
}
}
};
this.update_life = function()
{
this.life_value.innerHTML = this.life;
};
this.attack=function()
{
if(!this.is_attacking)
{
this.is_attacking=true;
this.click_target.attacked(this);
this.move_action.setEffectiveWeight(0);
this.idle_action.setEffectiveWeight(0);
this.attack_action.setEffectiveWeight(1);
this.attack_action.stop();
this.attack_action.play();
}
};
this.die = function()
{
var self=this;
// Already dead?
if(this.is_dying)
{
return;
}
this.is_dying=true;
self.move_action.setEffectiveWeight(0);
self.idle_action.setEffectiveWeight(0);
self.attack_action.setEffectiveWeight(0);
self.dying_action.setEffectiveWeight(1);
self.dying_action.stop();
self.dying_action.play();
game.zoomInCircle(function()
{
game.reload();
console.log('really dead here');
});
window.setTimeout(function()
{
self.is_dead=true;
game.updateCollisionsCache();
}, 700);
};
this.end_attack=function()
{
if(!this.is_dying)
{
this.is_attacking=false;
this.attack_action.setEffectiveWeight(0);
this.move_weight_destination=0;
this.update_weight(true);
}
};
this.mouseEvent= function(event, moving_mouse)
{
// No action if dead
if(this.is_dying || this.is_dead) { return false; }
if(this.click_target && !this.click_target.is_dying && this.mouse_clicked)
{
if(!this.is_attacking)
{
var distance = this.container.position.distanceTo(this.click_target.container.position);
if(distance<this.weapon_range)
{
this.attack(this.click_target);
}
}
return this.click_target.container.position;
}
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
mouse.x = ( event.clientX / this.game.renderer.domElement.width ) * 2 - 1;
mouse.y = - ( event.clientY / this.game.renderer.domElement.height ) * 2 + 1;
raycaster.setFromCamera( mouse, this.game.camera );
var objects;
if(!this.mouse_clicked)
{
objects = game.getHovers();
}
else
{
objects = game.getHoversWithClickGround();
}
var intersects = raycaster.intersectObjects(objects);
if ( intersects.length > 0 ) {
if(intersects[0].object.object)
{
if(this.mouse_clicked)
{
this.click_target = intersects[0].object.object;
}
if(this.last_hover_id!== intersects[0].object.id)
{
if(this.last_hover_object)
{
this.last_hover_object.unhover();
this.last_hover_object=null;
}
intersects[0].object.object.hover();
this.last_hover_object = intersects[0].object.object;
this.last_hover_id = this.last_hover_object.id;
}
}
else
{
this.last_hover_id = '';
if(this.last_hover_object)
{
this.last_hover_object.unhover();
this.last_hover_object=null;
}
}
if(this.mouse_clicked)
{
this.move_collision = intersects[0];
return intersects[0].point;
}
}
else
{
this.last_hover_id = '';
if(this.last_hover_object)
{
this.last_hover_object.unhover();
this.last_hover_object=null;
}
}
return null;
}
this.lookAt= function(pos)
{
pos.y=0;
this.container.lookAt(pos);
}
this.reload = function(pos)
{
this.is_dead=false;
this.is_dying=false;
this.is_attacking=false;
this.is_moving=false;
this.move_destination=null;
this.life = this.max_life;
this.update_life();
this.container.position.x = pos.x;
this.container.position.z = pos.z;
this.move_weight_destination=null;
this.move_action.setEffectiveWeight(0);
this.dying_action.setEffectiveWeight(0);
this.idle_action.setEffectiveWeight(1);
move_action_weight=0;
};
this.mouseMoveCallback= function(event)
{
var pos = this.mouseEvent(event, true);
if(pos && this.mouse_clicked)
{
this.lookAt(pos);
this.moveTo(pos);
}
}
this.mouseDownCallback= function(event)
{
var pos = this.mouseEvent(event,false);
if(pos)
{
this.lookAt(pos);
this.moveTo(pos);
}
}
this.updateMovingStatus = function(destination)
{
this.is_moving=!!destination;
var weight = destination ? 1 : 0;
// Actually moving...
if(move_action_weight!=weight)
{
this.move_weight_destination = weight;
}
this.move_destination = destination;
};
this.moveTo= function(pos)
{
// Check if there is something between us and the destination
var originPoint = this.container.position;
var obstacles = game.getStaticObstacles();
var localVertex = pos.clone();
var globalVertex = localVertex.sub(originPoint);
var collision=false;
var current_pos = this.container.position;
if(current_pos.equals(pos))
{
return;
}
this.move_vector = pos.clone().sub(this.container.position).normalize();
this.move_vector_alt1 = this.move_vector.clone().applyAxisAngle(new THREE.Vector3(0,1,0), Math.radians(70));
this.move_vector_alt2 = this.move_vector.clone().applyAxisAngle(new THREE.Vector3(0,1,0), Math.radians(-70));
this.move_vector.multiplyScalar(this.move_speed);
this.move_vector_alt1.multiplyScalar(this.move_speed);
this.move_vector_alt2.multiplyScalar(this.move_speed);
this.updateMovingStatus(pos);
};
this.move_step= function()
{
if(this.mouse_clicked)
{
this.mouseMoveCallback(this.last_mouse_event);
}
if(this.is_moving)
{
game.assets.step_sound.play();
var moving=0;
// Collision callbacks (keys / etc)
var originPoint = this.container.position;
var all_obstacles = game.getMovingAndStaticObstacles();
var obstacles_with_callbacks = game.getCollisionCallbacks();
var objects=[];
for (var vertexIndex = 0; vertexIndex < this.container_mesh.geometry.vertices.length; vertexIndex++)
{
var localVertex = this.container_mesh.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( this.container_mesh.matrix );
var directionVector = globalVertex.sub( this.container_mesh.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize(),0 , game.opt.door_size );
var collisionResults = ray.intersectObjects(obstacles_with_callbacks);
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
{
objects.push(collisionResults[0].object);
}
}
game.callCollisionCallbacks(this,objects);
// Moving if far enough
var distance= this.container.position.clone().sub(this.move_destination).length();
if(Math.abs(distance) > 2)
{
var originPoint = this.container.position.clone();
originPoint.add(this.move_vector);
var new_distance= originPoint.clone().sub(this.move_destination).length();
if(new_distance<distance)
{
var collision=false;
// Check collision with items that are moving and static ones
for (var vertexIndex = 0; vertexIndex < this.container_mesh.geometry.vertices.length; vertexIndex++)
{
var localVertex = this.container_mesh.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( this.container_mesh.matrix );
var directionVector = globalVertex.sub( this.container_mesh.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize(),0 , game.opt.door_size );
var collisionResults = ray.intersectObjects(all_obstacles);
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
{
collision=true;
}
}
if(collision)
{
var originPoint = this.container.position.clone();
originPoint.add(this.move_vector_alt1);
var distance_alt1= originPoint.clone().sub(this.move_destination).length();
if(distance_alt1<distance)
{
var collision_alt1= false;
// Check collision with items that are moving and static ones
for (var vertexIndex = 0; vertexIndex < this.container_mesh.geometry.vertices.length; vertexIndex++)
{
var localVertex = this.container_mesh.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( this.container_mesh.matrix );
var directionVector = globalVertex.sub( this.container_mesh.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize(),0 , game.opt.door_size );
var collisionResults = ray.intersectObjects(all_obstacles);
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
{
collision_alt1=true;
}
}
if(!collision_alt1)
{
moving++;
this.container.position.add(this.move_vector_alt1);
}
}
var collision_alt2=false;
var originPoint = this.container.position.clone();
originPoint.add(this.move_vector_alt2);
var distance_alt2= originPoint.clone().sub(this.move_destination).length();
if(distance_alt2<distance)
{
// Check collision with items that are moving and static ones
for (var vertexIndex = 0; vertexIndex < this.container_mesh.geometry.vertices.length; vertexIndex++)
{
var localVertex = this.container_mesh.geometry.vertices[vertexIndex].clone();
var globalVertex = localVertex.applyMatrix4( this.container_mesh.matrix );
var directionVector = globalVertex.sub( this.container_mesh.position );
var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize(),0 , game.opt.door_size );
var collisionResults = ray.intersectObjects(all_obstacles);
if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() )
{
collision_alt2=true;
}
}
if(!collision_alt2)
{
moving++;
this.container.position.add(this.move_vector_alt2);
}
}
}
if(!collision)
{
moving++;
this.container.position.add(this.move_vector);
}
}
}
if(!moving)
{
game.assets.step_sound.pause();
this.updateMovingStatus(null);
}
}
};
this.update_weight = function(force)
{
if(this.move_weight_destination!==null && !this.is_attacking)
{
var c = this.move_action.getEffectiveWeight();
var dest;
if(c>this.move_weight_destination)
{
var dest = Math.max(0,c-0.08);
this.move_action.setEffectiveWeight(dest);
this.idle_action.setEffectiveWeight(1-dest);
move_action_weight=dest;
}
else if(c<this.move_weight_destination)
{
var dest = Math.min(1,c+0.08);
this.move_action.setEffectiveWeight(dest);
this.idle_action.setEffectiveWeight(1-dest);
move_action_weight=dest;
}
else if(force)
{
this.move_action.setEffectiveWeight(this.move_weight_destination);
this.idle_action.setEffectiveWeight(1-this.move_weight_destination);
move_action_weight=this.move_weight_destination;
}
else
{
this.move_weight_destination=null;
}
move_action_weight=c;
}
};
this.moveable = function()
{
var self=this;
this.mouse_clicked=false;
// Moveable perso has a light
document.addEventListener( 'mousemove', this.move.bind(this));
document.addEventListener( 'mouseup', this.mouseup.bind(this));
document.addEventListener( 'mousedown', this.mousedown.bind(this));
};
this.move = function(e) {
this.last_mouse_event=e;
self.mouseMoveCallback(e);
};
this.mouseup = function(e) {
this.click_target = null;
this.last_mouse_event=e;
self.mouse_clicked=false;
e.stopPropagation();
return false;
};
this.mousedown = function(e) {
this.click_target = null;
this.last_mouse_event=e;
self.mouse_clicked=true;
e.stopPropagation();
self.mouseDownCallback(e);
return false;
};
this.update= function(delta)
{
this.mixer.update(delta);
this.delta=delta;
if(!this.is_dying && !this.is_attacking)
{
this.move_step();
}
this.update_weight();
};
this.build();
};