Tfe

Ongi etorri tfe-ren webgunera...

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