Package framework.collision

Source Code of framework.collision.CollisionComponent$CollisionStoppedEvent

package framework.collision;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import main.L;

import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Vector2f;

import framework.component.Component;
import framework.component.ComponentSystem;
import framework.component.filter.ComponentFilter;
import framework.component.filter.ComponentPathFilter;
import framework.component.filter.SpacialFilter;
import framework.component.list.MultiTypeComponentList;
import framework.component.list.SingleTypeComponentList;
import framework.component.path.RelativeComponentPath;
import framework.event.Event;
import framework.event.EventListener;
import framework.event.EventSender;
import framework.event.EventSystem;
import framework.event.filter.EventSenderComponentFilter;
import framework.event.util.ValueChangedEvent;
import framework.io.CustomInputStream;
import framework.rendering.RenderableComponent;
import framework.spacial.OrientationComponent;
import framework.spacial.OrientationComponent.OrientationChangedEvent;
import framework.spacial.PositionComponent;

public class CollisionComponent extends RenderableComponent implements EventListener{

  private CollisionMask mask;
  private boolean ignoreCollisions = false;

  private HashSet<CollisionComponent> inContactWith = new HashSet<CollisionComponent>();

  public CollisionComponent(CollisionMask mask){
    super();
    this.mask = mask;
    RelativeComponentPath posPath = new RelativeComponentPath(PositionComponent.class.getName(), this, 1, new int[]{0});
    ComponentFilter posFilter = new ComponentPathFilter(posPath);
    EventSystem.getInstance().registerEventListener(this, "PositionChanged", new EventSenderComponentFilter(posFilter));

    RelativeComponentPath orientPath = new RelativeComponentPath(OrientationComponent.class.getName(), this, 1, new int[]{0});
    ComponentFilter orientFilter = new ComponentPathFilter(orientPath);
    EventSystem.getInstance().registerEventListener(this, "OrientationChanged", new EventSenderComponentFilter(orientFilter));
  }

  public CollisionComponent(CustomInputStream in, int baseID, byte versionNum) throws IOException {
    super(in, baseID, versionNum);
  }


  @Override
  public boolean allowSameTypedSiblings() {
    return true;
  }

  @Override
  protected byte getDataFormatVersion() {
    return 0;
  }

  @Override
  public void onEvent(Event e) {
    if(e != null && !ignoreCollisions){
      if(e.getType().equals("PositionChanged") && e.getSender() != null){
        checkForCollisions((PositionComponent) e.getSender());
      }else if (e.getType().equals("OrientationChanged")){
        OrientationChangedEvent o = (OrientationChangedEvent) e;
        mask.rotate(o.getDelta());
        checkForCollisions();
      }
    }
  }

  private void checkForCollisions(){
    checkForCollisions((PositionComponent) getSiblingByType(PositionComponent.class.getName()));
  }

  private void checkForCollisions(PositionComponent pos) {
    if(pos != null && pos.getVector() != null && this.mask != null){

      checkOldCollisionsAreStillHappening(pos.getVector());

      MultiTypeComponentList allComps = ComponentSystem.getInstance().getAllComponents();
      SingleTypeComponentList allCollisComps = allComps.getComponentsOfType(CollisionComponent.class.getName());
      if(allCollisComps != null){
        SpacialFilter filter = new SpacialFilter(pos.getVector(), getMask());
        Collection<Component> allColliding = allCollisComps.getComponents(filter);
        if(allColliding != null){
          for(Component comp:allColliding){
            if(!comp.equals(this)){
              CollisionComponent c = (CollisionComponent) comp;
              if(!isInContactWith(c, false)){
                inContactWith.add(c);
                c.getAllComponentsInContact().add(this);
                EventSystem.getInstance().pushEvent(new CollisionStartedEvent(this, c));
                EventSystem.getInstance().pushEvent(new CollisionStartedEvent(c, this));
              }
              EventSystem.getInstance().pushEvent(new CollisionEvent(this,c));
              EventSystem.getInstance().pushEvent(new CollisionEvent(c, this));
            }
          }
        }
      }
    }else{
      inContactWith.clear();
    }
  }



  private void checkOldCollisionsAreStillHappening(Vector2f thisOrigin) {
    ArrayList<CollisionComponent> toRemove = new ArrayList<CollisionComponent>();
    for(CollisionComponent c:inContactWith){
      if(!isCollision(thisOrigin,c)){
        toRemove.add(c);
      }
    }
    for(CollisionComponent c:toRemove){
      inContactWith.remove(c);
      c.getAllComponentsInContact().remove(this);
      EventSystem.getInstance().pushEvent(new CollisionStoppedEvent(this, c));
      EventSystem.getInstance().pushEvent(new CollisionStoppedEvent(c, this));
    }
  }

  private boolean isCollision(Vector2f thisOrigin, CollisionComponent otherComp){
    SpacialFilter filter = new SpacialFilter(thisOrigin, this.mask);
    return filter.isValidComponent(otherComp);
  }

  public boolean isCollision(Vector2f thisOrigin, Vector2f otherOrigin, CollisionMask otherMask) {
    return mask == null ? false : mask.isCollision(thisOrigin, otherOrigin, otherMask);
  }

  public float getMaxWidth() {
    return mask != null ? mask.getMaxWidth() : 0;
  }

  public float getMaxHeight() {
    return mask != null ? mask.getMaxHeight() : 0;
  }

  public CollisionMask getMask() {
    return mask;
  }

  public void setMask(CollisionMask mask) {
    this.mask = mask;
    EventSystem.getInstance().pushEvent(new MaskChangedEvent(this, this.mask, mask));
    checkForCollisions();
  }

  public Set<CollisionComponent> getAllComponentsInContact(){
    return inContactWith;
  }

  public boolean isInContactWith(CollisionComponent collisComp, boolean recheckCollisions){
    if(recheckCollisions){
      checkForCollisions();
    }
    return inContactWith.contains(collisComp);
  }

  public class MaskChangedEvent extends ValueChangedEvent<CollisionMask>{
    public MaskChangedEvent(EventSender sender, CollisionMask from,
        CollisionMask to) {
      super(sender, from, to);
    }

    @Override
    protected String getEventTypeID() {
      return "MaskChanged";
    }
  }

  public static class CollisionEvent extends Event{
    private final CollisionComponent collidedWith;
    public CollisionEvent(CollisionComponent sender, CollisionComponent collidedWith) {
      super(sender);
      this.collidedWith = collidedWith;
    }
    @Override
    protected String getEventTypeID() {
      return "Collision";
    }
    public CollisionComponent getCollidedWith() {
      return collidedWith;
    }
  }

  public static class CollisionStartedEvent extends CollisionEvent{
    public CollisionStartedEvent(CollisionComponent sender, CollisionComponent collidedWith) {
      super(sender, collidedWith);
    }
    @Override
    protected String getEventTypeID() {
      return "CollisionStarted";
    }
  }

  public static class CollisionStoppedEvent extends CollisionEvent{
    public CollisionStoppedEvent(CollisionComponent sender, CollisionComponent finishedCollidingWith) {
      super(sender, finishedCollidingWith);
    }
    @Override
    protected String getEventTypeID() {
      return "CollisionStopped";
    }
  }

  @Override
  public void onSiblingAdded(Component sibling) {
    super.onSiblingAdded(sibling);
    if(sibling.isType(OrientationComponent.class)){
      mask.rotate(((OrientationComponent) sibling).getValue());
    }
  }

  public boolean isIgnoringCollision() {
    return ignoreCollisions;
  }

  public void setIgnoreCollisions(boolean ignoreCollision) {
    this.ignoreCollisions = ignoreCollision;
  }

  @Override
  public void draw(Graphics g, int x, int y) {
    g.setColor(Color.white);
    if(getMask() != null){
      getMask().renderForDebug(g, new Vector2f(x, y));
    }
  }

  @Override
  public int getRenderDepth() {
    return RenderableComponent.ALWAYS_ON_TOP;
  }
 
  @Override
  public void setOffsetFromOrigin(Vector2f offsetFromOrigin) {
    super.setOffsetFromOrigin(offsetFromOrigin);
    if(mask != null){
      mask.setRelativePositionOfOrigin(offsetFromOrigin);
    }
  }
}
TOP

Related Classes of framework.collision.CollisionComponent$CollisionStoppedEvent

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.