Esempio n. 1
0
 public DoubleDestructibleLineSegment(Vec2 start, Vec2 end, uint color = 0xffffffff, uint lineWidth = 1)
 {
     SideA = new DestructibleLineSegment(start, end, 0xffff0000, lineWidth);
     SideB = new DestructibleLineSegment(end, start, 0xff0000ff, lineWidth);
     AddChild(SideA);
     AddChild(SideB);
     StartCollider = new CircleCollider(0, start, true);
     EndCollider   = new CircleCollider(0, end, true);
     AddChild(StartCollider);
     AddChild(EndCollider);
 }
        public void Step()
        {
            if (Dead)
            {
                return;
            }
            var g = (MyGame)game;

            OldPosition = Position;
            Position   += Velocity * Time.deltaTime;

            var lineCollision = FindEarliestLineCollision();

            if (lineCollision != null)
            {
                if (bouncesLeft <= 0)
                {
                    Dead = true;
                }
                else
                {
                    bouncesLeft--;
                    ResolveCollision(lineCollision);
                }
            }

            // Destructible collisions
            //// LINES
            var linesToAdd = new List <DoubleDestructibleLineSegment>();

            foreach (var destructibleLine in g.DestructibleLines)
            {
                var(line1, line2) = CollisionUtils.BulletLineCollision(this, destructibleLine);
                if (line1 == null && line2 == null)
                {
                    continue;
                }
                destructibleLine.ShouldRemove = true;
                if (line1 != null)
                {
                    linesToAdd.Add(line1);
                }
                if (line2 != null)
                {
                    linesToAdd.Add(line2);
                }

                if (bouncesLeft <= 0)
                {
                    Dead = true;
                }
                else
                {
                    bouncesLeft--;
                }
            }

            linesToAdd.ForEach(line => {
                g.DestructibleLines.Add(line);
                g.AddChild(line);
            });

            //// CHUNKS
            foreach (var destructibleChunk in g.DestructibleChunks)
            {
                if (!CollisionUtils.BulletChunkCollision(this, destructibleChunk))
                {
                    continue;
                }
                destructibleChunk.ShouldRemove = true;
                Dead = true;
                break;
            }

            //// BLOCKS
            var chunksToAdd = new List <DestructibleChunk>();

            foreach (var destructibleBlock in g.DestructibleBlocks)
            {
                if (!CollisionUtils.BulletBlockCollision(this, destructibleBlock))
                {
                    continue;
                }
                destructibleBlock.ShouldRemove = true;
                var chunks = DestructibleBlock.Destruct(destructibleBlock);
                chunksToAdd.AddRange(chunks);
                Dead = true;
                break;
            }

            chunksToAdd.ForEach(chunk => {
                g.DestructibleChunks.Add(chunk);
                g.AddChild(chunk);
            });

            var availableTanks = new List <Tank>();

            availableTanks.AddRange(g.Enemies.Select(enemy => enemy.Tank));
            availableTanks.Add(g.Player.Tank);
            availableTanks.Remove(parentTank);
            var validColliders = availableTanks.SelectMany(tank => tank.Colliders);

            foreach (var circleCollider in validColliders)
            {
                var colliderParent = circleCollider.parent as Tank;
                var(worldPosition, worldOldPosition)     = CircleCollider.LocalToWorldCoords(circleCollider.Position, circleCollider.OldPosition, colliderParent.Position, colliderParent.OldPosition);
                var(rotatedPosition, rotatedOldPosition) = CircleCollider.ApplyRotation(worldPosition, colliderParent.Position, worldOldPosition, colliderParent.OldPosition, colliderParent.rotation);

                var collisionInfo = CollisionUtils.CircleCircleCollision(Position, OldPosition, Velocity * Time.deltaTime, Radius, rotatedPosition, circleCollider.Radius);
                if (collisionInfo == null)
                {
                    continue;
                }

                Dead = true;
                colliderParent.AIRef.Dead = true;
                break;
            }

            UpdateScreenPosition();
        }