Package gwlpr.mapshard.entitysystem.systems

Source Code of gwlpr.mapshard.entitysystem.systems.MovementSystem

/**
* For copyright information see the LICENSE document.
*/

package gwlpr.mapshard.entitysystem.systems;

import gwlpr.mapshard.entitysystem.Entity;
import gwlpr.mapshard.entitysystem.EntityManager;
import gwlpr.mapshard.entitysystem.GenericSystem;
import gwlpr.mapshard.entitysystem.Components.*;
import gwlpr.mapshard.entitysystem.events.RotateEvent;
import gwlpr.mapshard.entitysystem.events.MoveEvent;
import gwlpr.mapshard.entitysystem.events.StopMovingEvent;
import gwlpr.mapshard.models.ClientBean;
import gwlpr.mapshard.models.enums.MovementState;
import gwlpr.mapshard.models.enums.MovementType;
import gwlpr.mapshard.views.EntityMovementView;
import gwlpr.protocol.util.Vector2;
import java.util.Collection;
import realityshard.container.events.Event;
import realityshard.container.events.EventAggregator;
import realityshard.container.util.Handle;
import realityshard.container.util.HandleRegistry;


/**
* This system handles movement of entities, without collision.
* Collision handling might be done in a separate system, though it could
* be reasonable to merge both of these systems...
*
* Hint: Make sure to use a unit-vector as the direction of the player
* before calculating anything.
*
* @author _rusty
*/
public class MovementSystem extends GenericSystem
{

    private final static int UPDATEINTERVAL = -1; // use standard server tick interval

    private final EntityManager entityManager;
    private final HandleRegistry<ClientBean> clientRegistry;


    /**
     * Constructor.
     *
     * @param       aggregator
     * @param       entityManager
     * @param       clientRegistry
     */
    public MovementSystem(
            EventAggregator aggregator,
            EntityManager entityManager,
            HandleRegistry<ClientBean> clientRegistry)
    {
        super(aggregator, UPDATEINTERVAL);

        this.entityManager = entityManager;
        this.clientRegistry = clientRegistry;
    }


    /**
     * This is invoked periodically. (Or never, depending on the interval)
     *
     * @param timeDelta
     */
    @Override
    protected void update(int timeDelta)
    {
        // get all moving entities
        Collection<Entity> entities = entityManager.getEntitiesWith(
                Position.class,
                Direction.class,
                Movement.class);

        for (Entity entity : entities)
        {
            // check if entity is not moving
            if (entity.get(Movement.class).moveState != MovementState.MoveKeepDir)
            {
                continue;
            }
           
            // retrieve the components we need
            Position pos = entity.get(Position.class);
            Vector2 dir = entity.get(Direction.class).direction.getUnit();
            Movement move = entity.get(Movement.class);
           
//            // update the position (we simply assume that the client has now reached its future position)
//            pos.position = move.futurePosition;

            // calculate the next future position (the next movement aim)
            // we do not actually change the current position of the agent!
            // formula: posVec + ( dirVec * (speedScal * (0.001 * timeDeltaScal)))
            pos.position = pos.position.add(dir.mul(move.speed * (0.001F * timeDelta)));
        }
    }


    /**
     * Handles movement events.
     * This only concerns entities that just started moving or changed direction.
     *
     * @param moveEvt
     */
    @Event.Handler
    public void onMove(MoveEvent moveEvt)
    {
        // we need to inform the connected clients and
        // set the movement state to moving (if that has not yet happened)
       
        Entity et = moveEvt.getThisEntity();

        // update the entities values
//        et.get(Direction.class).direction = moveEvt.getDirection().getUnit();
        Movement move = et.get(Movement.class);
//        move.moveType = moveEvt.getType(); // use the new movement type here
//        move.moveState = MovementState.Moving;

        // inform the clients
        for (Handle<ClientBean> clientHandle : clientRegistry.getAllHandles())
        {
            EntityMovementView.sendChangeDirection(clientHandle.get().getChannel(), et);
           
            // anything else will be send on server tick. no need to repeat the
            // calculations here
        }
       
        move.moveState = MovementState.MoveKeepDir;
    }


    /**
     * Handles entities that stopped moving.
     * Tells our clients.
     *
     * @param stopMove
     */
    @Event.Handler
    public void onStopMoving(StopMovingEvent stopMove)
    {
        // we need to inform the connected clients and
        // set the movement state to notmoving

        Entity et = stopMove.getThisEntity();
       
        // update the movement component of the entity
        // note that as the entity is not moving anymore,
        // its future position is the position it has already reached!
        // this is necessary because the update movement view will send the future position
       
        Position pos = et.get(Position.class);
        Direction dir = et.get(Direction.class);
        Movement move = et.get(Movement.class);
       
        Vector2 direction1 = pos.position.vecWithEndpoint(move.moveAim);
       
        float angle = direction1.angleTo(dir.direction);
       
        move.moveAim = pos.position;
        move.moveType = MovementType.Stop;
        move.moveState = MovementState.NotMoving;

        // inform the clients
        for (Handle<ClientBean> clientHandle : clientRegistry.getAllHandles())
        {
            EntityMovementView.sendRotateAgent(clientHandle.get().getChannel(), et, (float)Math.cos(angle), (float)Math.sin(angle));
           
            EntityMovementView.sendUpdateMovement(clientHandle.get().getChannel(), et);
        }
    }


    /**
     * Event handler.
     * Rotate event, this signals that an entity changed its direction
     * while not moving.
     *
     * @param rot
     */
    @Event.Handler
    public void onRotate(RotateEvent rot)
    {
        // fetch some entity info
        Entity et = rot.getThisEntity();
       
        // and update the direction
        Direction dir = et.get(Direction.class);
        dir.direction = dir.direction.applyRotation(rot.getCos(), rot.getSin());

        // inform the clients
        for (Handle<ClientBean> clientHandle : clientRegistry.getAllHandles())
        {
            EntityMovementView.sendRotateAgent(clientHandle.get().getChannel(), et, rot.getCos(), rot.getSin());
        }
    }
}
TOP

Related Classes of gwlpr.mapshard.entitysystem.systems.MovementSystem

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.