private bool HandleCollision(Entity e, CollidableComponent collidable, CollidableComponent other)
        {
            long playerLayer     = this.layerManager.GetBit("Player");
            long asteroidLayer   = this.layerManager.GetBit("Asteroid");
            long projectileLayer = this.layerManager.GetBit("Projectile");
            long borderLayer     = this.layerManager.GetBit("Border");

            if (collidable.CollisionLayer.HasLayer(playerLayer) && other.CollisionLayer.HasLayer(asteroidLayer))
            {
                return(this.CheckAgeAndRespawn(e));
            }
            else if (collidable.CollisionLayer.HasLayer(projectileLayer) && other.CollisionLayer.HasLayer(asteroidLayer))
            {
                //this.ParticleEngine?.SpawnParticles(10, collidable.Collision.CollisionPoint, Color.White);
                return(this.AddScoreAndDestroy(e));
            }
            else if (collidable.CollisionLayer.HasLayer(asteroidLayer) && other.CollisionLayer.HasLayer(projectileLayer))
            {
                return(this.SplitAndOrDestroy(e));
            }
            else if (collidable.CollisionLayer.HasLayer(asteroidLayer) && other.CollisionLayer.HasLayer(borderLayer))
            {
                return(this.RepellFromBorderInward(e, 100));
            }
            else if (collidable.CollisionLayer.HasLayer(playerLayer) && other.CollisionLayer.HasLayer(borderLayer))
            {
                return(this.StopAtBorder(e, collidable, other));
            }

            return(true);
        }
        public override void Update(float elapsedSeconds)
        {
            foreach (Entity e in this.actives.Values)
            {
                CollidableComponent collidable = e.GetComponent <CollidableComponent>();
                System.Diagnostics.Debug.Assert(collidable != null, "CollidableComponent not found");

                for (int i = 0; i < collidable.Collisions.Count; i++)
                {
                    this.HandleCollision(e, collidable, collidable.Collisions[i]);
                }

                collidable.Collisions.Clear();
            }
        }
        private bool StopAtBorder(Entity e, CollidableComponent collidable, CollidableComponent other)
        {
            TransformComponent transform = e.GetComponent <TransformComponent>();
            MotionComponent    motion    = e.GetComponent <MotionComponent>();

            Vector2 penetrationVector = collidable.Collider.PenetrationVector(other.Collider);

            if (!(penetrationVector == Vector2.Zero))
            {
                transform.Position -= penetrationVector;
                Vector2 offsetDirection = Vector2.Normalize(penetrationVector);
                Vector2 offsetMagnitude = new Vector2(Math.Abs(motion.Velocity.X), Math.Abs(motion.Velocity.Y));
                motion.Velocity -= offsetDirection * offsetMagnitude;
            }

            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Checks all entites in the given list whether or not they intersect with each other
        /// </summary>
        /// <param name="entities">The list of entities</param>
        private void CheckCollisions(IReadOnlyList <Entity> entities)
        {
            for (int i = 0; i < entities.Count - 1; i++)
            {
                CollidableComponent collidable1 = entities[i].GetComponent <CollidableComponent>();
                TransformComponent  transform1  = entities[i].GetComponent <TransformComponent>();
                System.Diagnostics.Debug.Assert(collidable1 != null, "CollidableComponent not found");
                System.Diagnostics.Debug.Assert(transform1 != null, "TransformComponent not found");

                //collidable1.Collider.ApplyTransform(transform1.Position, transform1.Rotation, transform1.Scale);
                Rectangle boundingRectangle1 = collidable1.Collider.GetBounds();

                for (int j = i + 1; j < entities.Count; j++)
                {
                    CollidableComponent collidable2 = entities[j].GetComponent <CollidableComponent>();
                    TransformComponent  transform2  = entities[j].GetComponent <TransformComponent>();
                    System.Diagnostics.Debug.Assert(collidable2 != null, "CollidableComponent not found");
                    System.Diagnostics.Debug.Assert(transform2 != null, "TransformComponent not found");

                    // check if collision layers match
                    if (collidable1.CollisionLayer.Matches(collidable2.CollisionMask) || collidable2.CollisionLayer.Matches(collidable1.CollisionMask))
                    {
                        ulong keyPair = this.GetPairedKey(entities[i].EntityId, entities[j].EntityId);
                        // note: the following is necessary if spatial grid is being used
                        if (this.checkedPairs.Add(keyPair)) // check if this pair has already been processed
                        {
                            //collidable2.Collider.ApplyTransform(transform2.Position, transform2.Rotation, transform2.Scale);
                            Rectangle boundingRectangle2 = collidable2.Collider.GetBounds();

                            if (boundingRectangle1.Intersects(boundingRectangle2))         //broadphase, check if objects MAY collide
                            {
                                if (collidable1.Collider.Intersects(collidable2.Collider)) //narrowphase, (add missing colliders (line))
                                {
                                    collidable1.Collisions.Add(collidable2);
                                    collidable2.Collisions.Add(collidable1);
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
0
        private void SpatialHashing()
        {
            this.spatialGrid.Initialize();

            // populate grid and apply transform to colliders
            for (int i = 0; i < this.targets.Count; i++)
            {
                CollidableComponent collidable = this.targets[i].GetComponent <CollidableComponent>();
                TransformComponent  transform  = this.targets[i].GetComponent <TransformComponent>();
                System.Diagnostics.Debug.Assert(collidable != null, "CollidableComponent not found");
                System.Diagnostics.Debug.Assert(transform != null, "TransformComponent not found");

                collidable.Collider.ApplyTransform(transform.Position, transform.Rotation, transform.Scale);
                this.spatialGrid.Add(collidable.Collider.GetBounds(), this.targets[i]);
            }

            //Parallel.For(0, this.spatialGrid.Length, c =>
            //{

            //WIP: still no unique collision check (also, perf. benefit?)
            //desc: loop over entities vs loop over cells
            ////for (int i = 0; i < this.targets.Count; i++)
            ////{
            ////    CollidableComponent collidable = this.targets[i].GetComponent<CollidableComponent>();
            ////    IndexedList<Entity> entities = this.spatialGrid.GetUniqueCellContents(collidable.Collider.GetBounds());
            ////    this.CheckCollision(this.targets[i], entities);
            ////    //this.CheckCollisions(entities);
            ////}

            for (int i = 0; i < this.spatialGrid.CellCount(); i++)
            {
                this.CheckCollisions(this.spatialGrid.GetCellContent(i));
            }

            //});
        }
Beispiel #6
0
        public void Draw(float elapsedSeconds, SpriteBatch spriteBatch)
        {
            if (this.isDebug)
            {
                if (this.UseSpatialHashing)
                {
                    //note: test only
                    Kadro.Physics.PhysicsVisualizer.DrawSpatialGridCells(spriteBatch, this.spatialGrid.GetCells());

                    //todo: move this to another class (maybe even spatialgrid)
                    //for (int i = 0; i < GameConfig.NumCells.X; i++)
                    //{
                    //    spriteBatch.DrawLineSegment(new Vector2(i * GameConfig.CellSize.X, 0), new Vector2(i * GameConfig.CellSize.X, GameConfig.WorldSize.Y), Color.Blue, 1);
                    //}

                    //for (int i = 0; i < GameConfig.NumCells.Y; i++)
                    //{
                    //    spriteBatch.DrawLineSegment(new Vector2(0, i * GameConfig.CellSize.Y), new Vector2(GameConfig.WorldSize.X, i * GameConfig.CellSize.Y), Color.Blue, 1);
                    //}
                }

                for (int i = 0; i < this.targets.Count; i++)
                {
                    CollidableComponent collidable = this.targets[i].GetComponent <CollidableComponent>();
                    TransformComponent  transform  = this.targets[i].GetComponent <TransformComponent>();
                    System.Diagnostics.Debug.Assert(collidable != null, "CollidableComponent not found");
                    System.Diagnostics.Debug.Assert(transform != null, "TransformComponent not found");

                    collidable.Collider.ApplyTransform(transform.Position, transform.Rotation, transform.Scale);
                    collidable.DebugDraw(spriteBatch, 1);
                    spriteBatch.DrawLineSegment(transform.Position, transform.EntityToWorld(VectorExtensions.AngleToVector2(0f) * 20), Color.Green, 1);
                    spriteBatch.DrawLineSegment(transform.Position, transform.Position + Vector2.One, Color.Brown, 1);
                    //collidable.Collider.GetBounds().Draw(spriteBatch, Color.Violet, 1);
                }
            }
        }
 public virtual void OnCollisionExit(CollidableComponent other)
 {
 }