private static PhysicalVector2 GetStartingPosition( Physical.PosRectangle playerPosRectangle, Physical.Orientation.Cardinal orientation, Physical.Rectangle rectangle ) { PhysicalVector2 result = playerPosRectangle.GetCenteredBound(orientation); switch (orientation) { case Physical.Orientation.Cardinal.Left: result.X -= (rectangle.Width / 2); break; case Physical.Orientation.Cardinal.Right: result.X += (rectangle.Width / 2); break; case Physical.Orientation.Cardinal.Up: result.Y -= (rectangle.Height / 2); break; case Physical.Orientation.Cardinal.Down: result.Y += (rectangle.Height / 2); break; } return(result); }
private static void HandleCollision( Ecs.Registry registry, Queue <Entity> toRemove, Entity entity, Comps.Solid solidComp, Comps.Position positionComp, Comps.Shapes.Rectangle rectangleComp, PhysicalVector2 tilePosition, Rectangle tileRectangle ) { if (solidComp.ephemeral) { toRemove.Enqueue(entity); } else { PhysicalVector2 correction = GetMinCorrection( rectangleComp.data, positionComp.data, tileRectangle, tilePosition ); positionComp.data += correction; } }
public static void Run( Ecs.Registry registry, IMap map ) { // To avoid performance costs from doing list intersections, only // query for entities with `Solid` components. // // However, we can assume that all entities with a `Solid` component // also have these components: // - `Position` // - `Shape.Rectangle` List <Entity> entities = registry.GetEntitiesList(typeof(Comps.Solid)); // Queue entities to remove so we aren't removing entities while // iterating over them Queue <Entity> toRemove = new Queue <Entity>(); foreach (Ecs.Entity entity in entities) { var entityRect = registry.GetComponentUnsafe <Comps.Shapes.Rectangle>(entity); var entityPos = registry.GetComponentUnsafe <Comps.Position>(entity); var entityPosRect = new PosRectangle(entityPos.data, entityRect.data); // Check every tile that the rectangle is touching. foreach (int index in OverlappingTiles(map, entityPosRect)) { var gameTile = (GameTile)map.GameLayer.tiles[index]; switch (gameTile.kind) { case GameTile.Kind.Solid: var tilePos = GetTilePosition(map, index); var tileRect = new Rectangle( map.TileWidth, map.TileHeight ); if (CheckCollision( entityRect.data, entityPos.data, tileRect, tilePos )) { var entitySolid = registry.GetComponentUnsafe <Comps.Solid>(entity); HandleCollision( registry, toRemove, entity, entitySolid, entityPos, entityRect, tilePos, tileRect ); } break; } } } ProcessRemoves(toRemove, registry); }
public static Entity Create( Comps.Projectile.Kind kind, Entity owner, Ecs.Registry registry ) { // Assume that `owner` has position and orientation // components var playerPositionComp = registry .GetComponentUnsafe <Comps.Position>(owner); var playerRectangleComp = registry .GetComponentUnsafe <Comps.Shapes.Rectangle>(owner); var playerOrientationComp = registry .GetComponentUnsafe <Comps.Orientations.Cardinal>(owner); var playerPosRectangle = new Physical.PosRectangle( playerPositionComp.data, playerRectangleComp.data ); // Create projectile Physical.Rectangle rectangle = new Physical.Rectangle( 16.0f * 4, 16.0f * 4 ); PhysicalVector2 position = GetStartingPosition( playerPosRectangle, playerOrientationComp.data, rectangle ); var projectileEntity = registry.CreateEntity(); registry.AssignComponent( projectileEntity, new Comps.Shapes.Rectangle { data = rectangle } ); registry.AssignComponent( projectileEntity, new Comps.Position { data = position } ); registry.AssignComponent( projectileEntity, (Comps.Orientations.Cardinal)playerOrientationComp.Clone() ); PhysicalVector2 velocity = playerOrientationComp.data.GetPhysicalVector2() * GetStartingSpeed(kind); registry.AssignComponent( projectileEntity, new Comps.Velocity { data = velocity, decay = 1.0f } ); registry.AssignComponent( projectileEntity, new Comps.Projectile { kind = kind, ownerId = owner.id } ); if (IsDamaging(kind)) { registry.AssignComponent( projectileEntity, new Comps.Damaging { damage = 1, attackerId = owner.id } ); } registry.AssignComponent( projectileEntity, new Comps.Lifetime { ticks = GetLifetime(kind) } ); registry.AssignComponent( projectileEntity, new Comps.Solid { ephemeral = true } ); return(projectileEntity); }