private bool IsAroundCollider(ITransformComponent transform, IMoverComponent mover, CollidableComponent collider) { foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true)) { if (entity == transform.Owner) { continue; // Don't try to push off of yourself! } if (!entity.TryGetComponent <CollidableComponent>(out var otherCollider)) { continue; } // TODO: Item check. var touching = ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 || (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) && // Ensure collision true; // !entity.HasComponent<ItemComponent>(); // This can't be an item if (touching) { return(true); } } return(false); }
public override void Initialize() { base.Initialize(); collidableComponent = Owner.GetComponent <CollidableComponent>(); collidableComponent.OnBump += OnBump; }
public void TerminateEntity() { // Arrange. int entityID = 76; CollidableComponent collidable = new CollidableComponent(entityID); PositionComponent position = new PositionComponent(entityID, 43f, 0f); Texture2DRenderComponent texture = new Texture2DRenderComponent(entityID, 7, null); componentManager .RegisterType <CollidableComponent, CollidableComponentCR>() .RegisterType <PositionComponent, PositionCR>() .RegisterType <Texture2DRenderComponent, Texture2DRenderCR>() .SetComponent(collidable) .SetComponent(position) .SetComponent(texture); // Act. ((IComponentTerminator)componentManager).TerminateEntity(entityID); // Assert. Assert.IsTrue(!componentManager.ContainsComponent <CollidableComponent>(entityID) && !componentManager.ContainsComponent <PositionComponent>(entityID) && !componentManager.ContainsComponent <Texture2DRenderComponent>(entityID)); }
public override void Initialize() { base.Initialize(); collidableComponent = Owner.GetComponent <CollidableComponent>(); spriteComponent = Owner.GetComponent <SpriteComponent>(); }
public override void OnRemove() { collidableComponent = null; spriteComponent = null; base.OnRemove(); }
public override void Initialize() { base.Initialize(); collidableComponent = Owner.GetComponent <CollidableComponent>(); _appearance = Owner.GetComponent <AppearanceComponent>(); }
public override void OnRemove() { collidableComponent = null; _appearance = null; base.OnRemove(); }
public void InitComponent(int entityID) { // Arrange. CollidableComponent component; // Act. component = new CollidableComponent(entityID); // Assert. Assert.AreEqual(entityID, component.EntityID); }
public void Equals_ShouldBeEqual(int entityID) { // Arrange. CollidableComponent component1; CollidableComponent component2; // Act. component1 = new CollidableComponent(entityID); component2 = new CollidableComponent(entityID); // Assert. Assert.IsTrue(component1 == component2); }
public void Equals_ShouldNotBeEqual(int entity1, int entity2) { // Arrange. CollidableComponent component1; CollidableComponent component2; // Act. component1 = new CollidableComponent(entity1); component2 = new CollidableComponent(entity2); // Assert. Assert.IsFalse(component1 == component2); }
/// <summary> /// Send an event, if the object is entering a collision. /// </summary> /// <param name="collider"> /// The <see cref="Collider"/> collider of the trigger object, reported by Unity. /// </param> public void OnTriggerEnter(Collider collider) { CollidableComponent collidee = collider.GetComponent <CollidableComponent>(); if (collidee == null) { return; } int entityId = this.GetComponent <EntityComponent>().EntityId; CollisionEventData data = new CollisionEventData(entityId, collidee.EntityId, collider); this.Game.EventManager.FireEvent( new HelGamesEvent( CollisionEvents.TriggerEntered, data)); }
/// <summary> /// Send an event, if the object is entering a collision. /// </summary> /// <param name="collisionInfo"> /// The <see cref="Collision"/> collision information, reported by Unity. /// </param> public void OnCollisionExit(Collision collisionInfo) { CollidableComponent collidee = collisionInfo.collider.GetComponent <CollidableComponent>(); if (collidee == null) { return; } int entityId = this.GetComponent <EntityComponent>().EntityId; CollisionEventData data = new CollisionEventData(entityId, collidee.EntityId, collisionInfo); this.Game.EventManager.FireEvent( new HelGamesEvent( CollisionEvents.CollisionLeft, data)); }
public Monsters(string name, Vector2 pos) : base(pos) { Sprite = GFX.SpriteBank.Create(name); Collider = new Hitbox(Sprite.Width, Sprite.Height); Add(Sprite); Tag = GAccess.HittableTag; AddTag(GAccess.MonsterTag); StateMachine = new StateMachine(2); StateMachine.State = StIdle; // detect area DetectAreaCollider = new CollidableComponent(true, false, true); float detectAreaColliderWidth = Sprite.Width * 3; float detectAreaColliderHeight = Sprite.Width * 3; DetectAreaCollider.Collider = new Hitbox(detectAreaColliderWidth, detectAreaColliderHeight, -detectAreaColliderWidth / 2 + Sprite.Width / 2, -detectAreaColliderHeight / 2 + Sprite.Height / 2); Add(DetectAreaCollider); Depth = 1; }
private IEnumerable <Manifold> FindCollisionsFor(CollidableComponent a, List <(EntityUid, EntityUid)> combinations,
public override void OnRemove() { collidableComponent.OnBump -= OnBump; collidableComponent = null; spriteComponent = null; }
private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null) { if (physics.Controller == null) { // Set up controller physics.SetController <MoverController>(); } var weightless = !transform.Owner.HasComponent <MovementIgnoreGravityComponent>() && _physicsManager.IsWeightless(transform.GridPosition); if (weightless && collider != null) { // No gravity: is our entity touching anything? var touching = IsAroundCollider(transform, mover, collider); if (!touching) { return; } } if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner) && !weightless) { (physics.Controller as MoverController)?.StopMoving(); } else { if (weightless) { (physics.Controller as MoverController)?.Push(mover.VelocityDir, mover.CurrentPushSpeed); transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); return; } (physics.Controller as MoverController)?.Move(mover.VelocityDir, mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed); transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); // Handle footsteps. if (_mapManager.GridExists(mover.LastPosition.GridID)) { // Can happen when teleporting between grids. var distance = transform.GridPosition.Distance(_mapManager, mover.LastPosition); mover.StepSoundDistance += distance; } mover.LastPosition = transform.GridPosition; float distanceNeeded; if (mover.Sprinting) { distanceNeeded = StepSoundMoveDistanceRunning; } else { distanceNeeded = StepSoundMoveDistanceWalking; } if (mover.StepSoundDistance > distanceNeeded) { mover.StepSoundDistance = 0; if (!mover.Owner.HasComponent <FootstepSoundComponent>()) { return; } if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) && inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) && item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier)) { modifier.PlayFootstep(); } else { PlayFootstepSound(transform.GridPosition); } } }
public override void Update(GameTime gameTime) { // Var to store collision event data. IList <CollisionEvent> collisionEvents = new List <CollisionEvent>(); // Get running worlds. IReadOnlyList <IWorld> worlds = worldManager.GetWorldsInState(WorldState.Running); // Run through running worlds and check for collisions. foreach (IWorld world in worlds) { // Store component manager. IComponentManager componentManager = world.ComponentManager; // Check if the world has the required component registries. if (!componentManager.ContainsRegistry <CollidableComponent>() || !componentManager.ContainsRegistry <HitboxCollisionComponent>() || !componentManager.ContainsRegistry <PositionComponent>() || !componentManager.ContainsRegistry <TransformComponent>()) { continue; } // Get component registries. IComponentRegistry <CollidableComponent> collidableComponents = (IComponentRegistry <CollidableComponent>)componentManager.GetRegistry <CollidableComponent>(); IComponentRegistry <HitboxCollisionComponent> hitboxCollisionComponents = (IComponentRegistry <HitboxCollisionComponent>)componentManager.GetRegistry <HitboxCollisionComponent>(); IComponentRegistry <PositionComponent> positionComponents = (IComponentRegistry <PositionComponent>)componentManager.GetRegistry <PositionComponent>(); IComponentRegistry <TransformComponent> transformComponents = (IComponentRegistry <TransformComponent>)componentManager.GetRegistry <TransformComponent>(); // Iterate hitbox collision components. for (int i = 0; i < hitboxCollisionComponents.Count; i++) { // Get components. HitboxCollisionComponent hitbox = hitboxCollisionComponents[i]; PositionComponent position = positionComponents.Get(hitbox.EntityID); TransformComponent transform = transformComponents.Get(hitbox.EntityID); // Iterate collidable components and calculate collision. for (int j = 0; j < collidableComponents.Count; j++) { // Get components for collidable entity. CollidableComponent collidable = collidableComponents[j]; PositionComponent collidablePosition = positionComponents.Get(collidable.EntityID); TransformComponent collidableTransform = transformComponents.Get(collidable.EntityID); // Create hitboxes. Rectangle entityA = new Rectangle((int)position.X, (int)position.Y, transform.Width, transform.Height); Rectangle entityB = new Rectangle((int)collidablePosition.X, (int)collidablePosition.Y, collidableTransform.Width, collidableTransform.Height); // Perform collision detection. if (entityA.Intersects(entityB)) { // Entities collided. collisionEvents.Add(new CollisionEvent(hitbox.EntityID, collidable.EntityID, world.ID)); } } } } // An entity can be both a collider and a collidable, so filter out any events where this is true. // We could check this before performing the collision detection but we want to avoid // branch predictions in the hot path as much as possible. collisionEvents = collisionEvents.Where(x => x.Collidable != x.Collider).ToList(); // Emit events. foreach (CollisionEvent collisionEvent in collisionEvents) { eventManager.Emit(collisionEvent); } }
public override void Run() { // If there is no state, setup world. if (State == WorldState.None) { // Create ball. int ballID = EntityManager.CreateEntity(); // Load texture. Texture2D ballTexture = ContentManager.Load <Texture2D>("square"); // Create components. HitboxCollisionComponent ballHitbox = new HitboxCollisionComponent(ballID); PhysicsComponent ballPhysics = new PhysicsComponent(ballID, 0, 0, 0, 0, 1, 150, 150); PositionComponent ballPosition = new PositionComponent(ballID, (engine.ScreenWidth / 2) - (ballTexture.Width / 2), (engine.ScreenHeight / 2) - (ballTexture.Height / 2)); Texture2DRenderComponent ballRender = new Texture2DRenderComponent(ballID, 1, ballTexture); TransformComponent ballTransform = new TransformComponent(ballID, ballTexture.Height, 0, 1, ballTexture.Width); // Add components. ComponentManager .SetComponent(ballHitbox) .SetComponent(ballPhysics) .SetComponent(ballPosition) .SetComponent(ballRender) .SetComponent(ballTransform); // Emit ball create event. EventManager.Emit(new BallCreateEvent(ballID)); // Create player one paddle. int paddleAID = EntityManager.CreateEntity(); // Load texture. Texture2D paddleATexture = ContentManager.Load <Texture2D>("paddle"); // Create components. CollidableComponent paddleACollidable = new CollidableComponent(paddleAID); PhysicsComponent paddleAPhysics = new PhysicsComponent(paddleAID, 0, 0, 0, 0, 1, 0, 0); PositionComponent paddleAPosition = new PositionComponent(paddleAID, 0, (engine.ScreenHeight / 2) - (paddleATexture.Height / 2)); Texture2DRenderComponent paddleARender = new Texture2DRenderComponent(paddleAID, 2, paddleATexture); TransformComponent paddleATransform = new TransformComponent(paddleAID, paddleATexture.Height, 0, 1, paddleATexture.Width); // Add components. ComponentManager .SetComponent(paddleACollidable) .SetComponent(paddleAPhysics) .SetComponent(paddleAPosition) .SetComponent(paddleARender) .SetComponent(paddleATransform); // Emit paddle create event. EventManager.Emit(new PaddleCreateEvent(paddleAID, 1)); // Create player two paddle. int paddleBID = EntityManager.CreateEntity(); // Load texture. Texture2D paddleBTexture = ContentManager.Load <Texture2D>("paddle"); // Create components. CollidableComponent paddleBCollidable = new CollidableComponent(paddleBID); PhysicsComponent paddleBPhysics = new PhysicsComponent(paddleBID, 0, 0, 0, 0, 1, 0, 0); PositionComponent paddleBPosition = new PositionComponent(paddleBID, (engine.ScreenWidth - paddleBTexture.Width), (engine.ScreenHeight / 2) - (paddleBTexture.Height / 2)); Texture2DRenderComponent paddleBRender = new Texture2DRenderComponent(paddleBID, 2, paddleBTexture); TransformComponent paddleBTransform = new TransformComponent(paddleBID, paddleBTexture.Height, 0, 1, paddleBTexture.Width); // Add components. ComponentManager .SetComponent(paddleBCollidable) .SetComponent(paddleBPhysics) .SetComponent(paddleBPosition) .SetComponent(paddleBRender) .SetComponent(paddleBTransform); // Emit paddle create event. EventManager.Emit(new PaddleCreateEvent(paddleBID, 2)); } base.Run(); }
private void FindCollisionsFor(CollidableComponent a, PhysicsComponent aPhysics, HashSet <(EntityUid, EntityUid)> combinations)
public override void Run() { // If there is no state, setup world. if (State == WorldState.None) { // Initialise random number generator. Random random = new Random(); // Var to hold IDs of created balls. int[] ballIDs = new int[Pong.BallCount]; // Create balls. for (int i = 0; i < ballIDs.Length; i++) { // Create ball. int ballID = EntityManager.CreateEntity(); // Load texture. Texture2D ballTexture = ContentManager.Load <Texture2D>("square"); // Create components. HitboxCollisionComponent ballHitbox = new HitboxCollisionComponent(ballID); PhysicsComponent ballPhysics = new PhysicsComponent(ballID, 0, 0, 0, 0, 1, 150, 150); PositionComponent ballPosition = new PositionComponent(ballID, random.Next(200, engine.ScreenWidth - 201) - (ballTexture.Width / 2), random.Next(150, engine.ScreenHeight - 151) - (ballTexture.Height / 2)); Texture2DRenderComponent ballRender = new Texture2DRenderComponent(ballID, 1, ballTexture); TransformComponent ballTransform = new TransformComponent(ballID, ballTexture.Height, 0, 0.35f, ballTexture.Width); // Add components. ComponentManager .SetComponent(ballHitbox) .SetComponent(ballPhysics) .SetComponent(ballPosition) .SetComponent(ballRender) .SetComponent(ballTransform); // Add ID to array. ballIDs[i] = ballID; } // Emit ball create event. EventManager.Emit(new BallCreateEvent(ballIDs)); // Create player one paddle. int paddleAID = EntityManager.CreateEntity(); // Load texture. Texture2D paddleATexture = ContentManager.Load <Texture2D>("paddle"); // Create components. CollidableComponent paddleACollidable = new CollidableComponent(paddleAID); PhysicsComponent paddleAPhysics = new PhysicsComponent(paddleAID, 0, 0, 0, 0, 1, 0, 0); PositionComponent paddleAPosition = new PositionComponent(paddleAID, 0, (engine.ScreenHeight / 2) - (paddleATexture.Height / 2)); Texture2DRenderComponent paddleARender = new Texture2DRenderComponent(paddleAID, 2, paddleATexture); TransformComponent paddleATransform = new TransformComponent(paddleAID, paddleATexture.Height, 0, 1, paddleATexture.Width); // Add components. ComponentManager .SetComponent(paddleACollidable) .SetComponent(paddleAPhysics) .SetComponent(paddleAPosition) .SetComponent(paddleARender) .SetComponent(paddleATransform); // Emit paddle create event. EventManager.Emit(new PaddleCreateEvent(paddleAID, 1)); // Create player two paddle. int paddleBID = EntityManager.CreateEntity(); // Load texture. Texture2D paddleBTexture = ContentManager.Load <Texture2D>("paddle"); // Create components. CollidableComponent paddleBCollidable = new CollidableComponent(paddleBID); PhysicsComponent paddleBPhysics = new PhysicsComponent(paddleBID, 0, 0, 0, 0, 1, 0, 0); PositionComponent paddleBPosition = new PositionComponent(paddleBID, (engine.ScreenWidth - paddleBTexture.Width), (engine.ScreenHeight / 2) - (paddleBTexture.Height / 2)); Texture2DRenderComponent paddleBRender = new Texture2DRenderComponent(paddleBID, 2, paddleBTexture); TransformComponent paddleBTransform = new TransformComponent(paddleBID, paddleBTexture.Height, 0, 1, paddleBTexture.Width); // Add components. ComponentManager .SetComponent(paddleBCollidable) .SetComponent(paddleBPhysics) .SetComponent(paddleBPosition) .SetComponent(paddleBRender) .SetComponent(paddleBTransform); // Emit paddle create event. EventManager.Emit(new PaddleCreateEvent(paddleBID, 2)); } base.Run(); }
public override void Update(GameTime gameTime) { // Var to store collision event data. IList <CollisionEvent> collisionEvents = new List <CollisionEvent>(); // Get running worlds. IReadOnlyList <IWorld> worlds = worldManager.GetWorldsInState(WorldState.Running); // Run through running worlds and check for collisions. foreach (IWorld world in worlds) { // Store component manager. IComponentManager componentManager = world.ComponentManager; // Check if the world has the required component registries. if (!componentManager.ContainsRegistry <CircleCollisionComponent>() || !componentManager.ContainsRegistry <CollidableComponent>() || !componentManager.ContainsRegistry <PositionComponent>() || !componentManager.ContainsRegistry <TransformComponent>()) { continue; } // Get component registries. IComponentRegistry <CircleCollisionComponent> circleCollisionComponents = (IComponentRegistry <CircleCollisionComponent>)componentManager.GetRegistry <CircleCollisionComponent>(); IComponentRegistry <CollidableComponent> collidableComponents = (IComponentRegistry <CollidableComponent>)componentManager.GetRegistry <CollidableComponent>(); IComponentRegistry <PositionComponent> positionComponents = (IComponentRegistry <PositionComponent>)componentManager.GetRegistry <PositionComponent>(); IComponentRegistry <TransformComponent> transformComponents = (IComponentRegistry <TransformComponent>)componentManager.GetRegistry <TransformComponent>(); // Iterate circle collision components. for (int i = 0; i < circleCollisionComponents.Count; i++) { // Get components. CircleCollisionComponent circle = circleCollisionComponents[i]; PositionComponent position = positionComponents.Get(circle.EntityID); TransformComponent transform = transformComponents.Get(circle.EntityID); // Iterate collidable components and calculate collision. for (int j = 0; j < collidableComponents.Count; j++) { // Get components for collidable entity. CollidableComponent collidable = collidableComponents[j]; PositionComponent collidablePosition = positionComponents.Get(collidable.EntityID); TransformComponent collidableTransform = transformComponents.Get(collidable.EntityID); // Calculate the radius of the entities. float rA = (transform.Scale * transform.Width) / 2; float rB = (collidableTransform.Scale * collidableTransform.Width) / 2; // Check if the distance between the two entities is less than the radii. if (Vector2.Distance(new Vector2(position.X, position.Y), new Vector2(collidablePosition.X, collidablePosition.Y)) < (rA + rB)) { // Entities collided. collisionEvents.Add(new CollisionEvent(circle.EntityID, collidable.EntityID, world.ID)); } } } } // An entity can be both a collider and a collidable, so filter out any events where this is true. // We could check this before performing the collision detection but we want to avoid // branch predictions in the hot path as much as possible. collisionEvents = collisionEvents.Where(x => x.Collidable != x.Collider).ToList(); // Emit events. foreach (CollisionEvent collisionEvent in collisionEvents) { eventManager.Emit(collisionEvent); } }
public PhysShapeList(CollidableComponent owner) { _owner = owner; }
private void UpdateKinematics(ITransformComponent transform, IMoverComponent mover, PhysicsComponent physics, CollidableComponent collider = null) { bool weightless = false; var tile = _mapManager.GetGrid(transform.GridID).GetTileRef(transform.GridPosition).Tile; if ((!_mapManager.GetGrid(transform.GridID).HasGravity || tile.IsEmpty) && collider != null) { weightless = true; // No gravity: is our entity touching anything? var touching = false; foreach (var entity in _entityManager.GetEntitiesInRange(transform.Owner, mover.GrabRange, true)) { if (entity.TryGetComponent <CollidableComponent>(out var otherCollider)) { if (otherCollider.Owner == transform.Owner) { continue; // Don't try to push off of yourself! } touching |= ((collider.CollisionMask & otherCollider.CollisionLayer) != 0x0 || (otherCollider.CollisionMask & collider.CollisionLayer) != 0x0) && // Ensure collision !entity.HasComponent <ItemComponent>(); // This can't be an item } } if (!touching) { return; } } if (mover.VelocityDir.LengthSquared < 0.001 || !ActionBlockerSystem.CanMove(mover.Owner)) { if (physics.LinearVelocity != Vector2.Zero) { physics.LinearVelocity = Vector2.Zero; } } else { if (weightless) { physics.LinearVelocity = mover.VelocityDir * mover.CurrentPushSpeed; transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); return; } physics.LinearVelocity = mover.VelocityDir * (mover.Sprinting ? mover.CurrentSprintSpeed : mover.CurrentWalkSpeed); transform.LocalRotation = mover.VelocityDir.GetDir().ToAngle(); // Handle footsteps. if (_mapManager.GridExists(mover.LastPosition.GridID)) { // Can happen when teleporting between grids. var distance = transform.GridPosition.Distance(_mapManager, mover.LastPosition); mover.StepSoundDistance += distance; } mover.LastPosition = transform.GridPosition; float distanceNeeded; if (mover.Sprinting) { distanceNeeded = StepSoundMoveDistanceRunning; } else { distanceNeeded = StepSoundMoveDistanceWalking; } if (mover.StepSoundDistance > distanceNeeded) { mover.StepSoundDistance = 0; if (!mover.Owner.HasComponent <FootstepSoundComponent>()) { return; } if (mover.Owner.TryGetComponent <InventoryComponent>(out var inventory) && inventory.TryGetSlotItem <ItemComponent>(EquipmentSlotDefines.Slots.SHOES, out var item) && item.Owner.TryGetComponent <FootstepModifierComponent>(out var modifier)) { modifier.PlayFootstep(); } else { PlayFootstepSound(transform.GridPosition); } } }