private RectangleF CheckEntityCollisions(List <Collision> blockEntities, CollisionBox hitbox, RectangleF boundbox, bool pushAway = true, bool solidOnly = true) { foreach (var entity in Parent.Entities.GetAll()) { if (entity == Parent) { continue; } CollisionComponent coll = entity.GetComponent <CollisionComponent>(); if (coll == null) { continue; } IEnumerable <CollisionBox> collToCheck = (solidOnly) ? coll.HitByBoxes(hitbox).Where(box => box.Properties.Blocking) : coll.HitByBoxes(hitbox); foreach (CollisionBox targetBox in collToCheck) { // if he's blocking, check for collision and maybe push me away RectangleF rect = targetBox.BoxAt(coll.PositionSrc.Position); RectangleF adjustrect = rect; adjustrect.X -= Const.PixelEpsilon; adjustrect.Y -= Const.PixelEpsilon; adjustrect.Width += 2 * Const.PixelEpsilon; adjustrect.Height += 2 - Const.PixelEpsilon; RectangleF intersection = RectangleF.Intersect(boundbox, adjustrect); if (intersection.Width != 0 || intersection.Height != 0) { blockEntities.Add(new Collision(hitbox, targetBox, coll)); if (hitbox.PushAway && pushAway) { float vx, vy; MovementComponent mov = entity.GetComponent <MovementComponent>(); vx = MovementSrc.VelocityX; vy = MovementSrc.VelocityY; if (mov != null) { vx -= mov.VelocityX; vy -= mov.VelocityY; } PointF offset = hitbox.GetIntersectionOffset(rect, boundbox, vx, vy, false, false); if (offset.X != 0 || offset.Y != 0) { PositionSrc.Offset(offset.X, offset.Y); boundbox.Offset(offset.X, offset.Y); } } } } } return(boundbox); }
public override void RegisterDependencies(Component component) { if (component is PositionComponent) { position = component as PositionComponent; } else if (component is CollisionComponent) { collision = component as CollisionComponent; } }
public static Effect ParseEffect(XElement node) { Effect effect = entity => {}; List <CollisionBox> rects = new List <CollisionBox>(); HashSet <string> enables = new HashSet <string>(); bool clear = false; foreach (XElement prop in node.Elements()) { switch (prop.Name.LocalName) { case "Enabled": bool b = prop.GetValue <bool>(); effect += entity => { CollisionComponent col = entity.GetComponent <CollisionComponent>(); if (col != null) { col.Enabled = b; } }; break; case "Hitbox": rects.Add(new CollisionBox(prop)); break; case "EnableBox": XAttribute nameAttrEn = prop.RequireAttribute("name"); enables.Add(nameAttrEn.Value); break; case "Clear": clear = true; break; } } if (rects.Count > 0 || enables.Count > 0 || clear) { effect += entity => { HitBoxMessage msg = new HitBoxMessage(entity, rects, enables, clear); entity.SendMessage(msg); } } ; return(effect); } }
public override Component Clone() { CollisionComponent copy = new CollisionComponent { Enabled = Enabled, hitboxes = new List <CollisionBox>() }; foreach (CollisionBox box in hitboxes) { copy.AddBox(box); } return(copy); }
private void ReactForHitbox(List <MapSquare> hitSquares, HashSet <TileProperties> hitTypes, CollisionBox hitbox) { hitbox.SetParent(this); var boundBox = hitbox.BoxAt(PositionSrc.Position); if (hitbox.Environment) { foreach (MapSquare tile in hitSquares) { var tileBox = tile.BlockBox; bool downonly = (!Parent.Container.IsGravityFlipped && tile.Tile.Properties.Climbable); bool uponly = (Parent.Container.IsGravityFlipped && tile.Tile.Properties.Climbable); bool hit = (tile.BlockBox != Rectangle.Empty) ? BlockByIntersection(boundBox, tileBox, uponly, downonly) : boundBox.IntersectsWith(tile.BoundBox); if (hitbox.PushAway && (hit || boundBox.IntersectsWith(tile.BoundBox))) // the environment touched me! { hitTypes.Add(tile.Tile.Properties); } } } // but for entities, we can go ahead and be active aggressors - // inflict our effects on the target entity, not the other way around foreach (var entity in Parent.Entities.GetAll()) { if (entity == Parent) { continue; } CollisionComponent coll = entity.GetComponent <CollisionComponent>(); if (coll == null) { continue; } foreach (CollisionBox targetBox in coll.TargetBoxes(hitbox)) { boundBox = CheckTargetBox(hitbox, boundBox, entity, coll, targetBox); } } }
public override void RegisterDependencies(Component component) { if (component is PositionComponent) position = component as PositionComponent; else if (component is CollisionComponent) collision = component as CollisionComponent; }
private Rectangle CheckTargetBox(CollisionBox hitbox, Rectangle boundBox, IEntity entity, CollisionComponent coll, CollisionBox targetBox) { var rect = targetBox.BoxAt(coll.PositionSrc.Position); if (boundBox.IntersectsWith(rect)) { coll.Touch(hitbox, targetBox); Touch(targetBox, hitbox); CollideWith(entity, hitbox, targetBox); } return(boundBox); }
public Collision(CollisionBox mybox, CollisionBox target, CollisionComponent tgtComp) { myBox = mybox; targetBox = target; targetColl = tgtComp; }
public void SetParent(CollisionComponent parent) { parentComponent = parent; }
// change those last bools into an enum or something else! public Point GetIntersectionOffset(Rectangle tileBox, Rectangle boundBox, float approach_vx, float approach_vy, bool uponly, bool downonly) { int top = -1, bottom = -1, left = -1, right = -1; var intersection = Rectangle.Intersect(boundBox, tileBox); var offset = Point.Empty; if (intersection.Width == 0 && intersection.Height == 0) { return(offset); } if (Math.Abs(intersection.Bottom - boundBox.Bottom) < Const.PixelEpsilon) { bottom = intersection.Height; } if (Math.Abs(intersection.Top - boundBox.Top) < Const.PixelEpsilon) { top = intersection.Height; } if (Math.Abs(intersection.Right - boundBox.Right) < Const.PixelEpsilon) { right = intersection.Width; } if (Math.Abs(intersection.Left - boundBox.Left) < Const.PixelEpsilon) { left = intersection.Width; } if (top > 0 || bottom > 0 || left > 0 || right > 0) { bool vert = CollisionComponent.VerticalApproach(intersection, boundBox, approach_vx, approach_vy); if (vert) { if (downonly) { if (approach_vy > 0 && boundBox.Bottom <= tileBox.Bottom) { offset.Y = -bottom; return(offset); } else { return(Point.Empty); } } else if (uponly) { if (approach_vy < 0 && boundBox.Top >= tileBox.Top) { offset.Y = top; return(offset); } else { return(Point.Empty); } } if (top >= 0) { offset.Y = top; } if (bottom >= 0) { offset.Y = -bottom; } } else { if (uponly || downonly) { return(Point.Empty); } if (left >= 0) { if (approach_vx < 0) { offset.X = left; } } if (right >= 0) { if (approach_vx > 0) { offset.X = -right; } } } } return(offset); }
private RectangleF CheckTargetBox(CollisionBox hitbox, RectangleF boundBox, IEntity entity, CollisionComponent coll, CollisionBox targetBox) { RectangleF rect = targetBox.BoxAt(coll.PositionSrc.Position); if (boundBox.IntersectsWith(rect)) { coll.Touch(hitbox, targetBox); Touch(targetBox, hitbox); CollideWith(entity, hitbox, targetBox); } return boundBox; }
public override Component Clone() { CollisionComponent copy = new CollisionComponent { Enabled = Enabled, hitboxes = new List<CollisionBox>() }; foreach (CollisionBox box in hitboxes) copy.AddBox(box); return copy; }