Beispiel #1
0
        public override void Draw()
        {
            float x = 300, y = 200;

            x = Mouse.GetX() * 100;
            y = Mouse.GetY() * 100;
            Graphics.Clear(0.7f, 0.7f, 0.7f);

            // draw mouse line (RED)
            Graphics.SetColor(1, 0, 0);
            Graphics.Line(0, 0, x, y);

            // draw ray cast info (GREED)
            Graphics.SetPointSize(10);
            Graphics.SetColor(0, 1, 0);
            foreach (var item in rectList)
            {
                Ray2D ray = new Ray2D(0, 0, x, y);
                if (ray.Intersects(item, out var result))
                {
                    if (m_drawDebugInfo)
                    {
                        Graphics.Points(result.X, result.Y);
                    }
                }
            }

            base.Draw();
        }
Beispiel #2
0
        public bool RayCast(Ray2D ray, out RayCastResult result)
        {
            bool existResult = false;

            result = new RayCastResult();
            Queue <QuadTreeNode> queue = new Queue <QuadTreeNode>();

            queue.Enqueue(this);

            Vector2 hitPoint;

            while (queue.Count != 0)
            {
                var leaf = queue.Dequeue();

                // 当此节点 Zone 与所给 RectangleF 不相交时返回 null
                if (ray.Intersects(leaf.m_zone, out hitPoint) == false)
                {
                    continue;
                }

                // 查看是否与此节点内的 item 有覆盖
                foreach (var item in leaf.managedItems)
                {
                    if (ray.Intersects(item.Zone, out hitPoint) &&
                        (existResult == false || Vector2.DistanceSquared(ray.Original, hitPoint) < Vector2.DistanceSquared(ray.Original, result.Intersection)))
                    {
                        existResult = true;
                        result      = new RayCastResult(hitPoint, item);
                    }
                }

                // 查找子节点
                for (int i = 0; i < 4; i++)
                {
                    if (leaf.childern[i] != null && ray.Intersects(leaf.childern[i].Zone, out hitPoint))
                    {
                        queue.Enqueue(leaf.childern[i]);
                    }
                }
            }

            return(existResult);
        }
Beispiel #3
0
        public LinkedList <RayCastResult> RayCastAll(Ray2D ray)
        {
            var outList = new LinkedList <RayCastResult>();
            Queue <QuadTreeNode> queue = new Queue <QuadTreeNode>();

            queue.Enqueue(this);

            Vector2 castResult;

            while (queue.Count != 0)
            {
                var leaf = queue.Dequeue();

                // 当此节点 Zone 与所给 RectangleF 不相交时返回 null
                if (ray.Intersects(leaf.m_zone, out castResult) == false)
                {
                    continue;
                }

                // 查看是否与此节点内的 item 有覆盖
                foreach (var item in leaf.managedItems)
                {
                    if (ray.Intersects(item.Zone, out castResult))
                    {
                        outList.AddLast(new RayCastResult(castResult, item));
                    }
                }

                // 查找子节点
                for (int i = 0; i < 4; i++)
                {
                    if (leaf.childern[i] != null && ray.Intersects(leaf.childern[i].Zone, out castResult))
                    {
                        queue.Enqueue(leaf.childern[i]);
                    }
                }
            }

            return(outList);
        }
Beispiel #4
0
        public override void Sense()
        {
            base.Sense();
            EndPoints = new List<Vector2>();

                for (int i = 0; i < 3; i++) //3 Feelers
                {
                    float RotationOffset = 0f;
                    if (i == 0) { RotationOffset = -0.4f; }
                    else if (i == 2) { RotationOffset = 0.4f; }

                    //Get Next Position
                    Vector2 Velocity = pHost.Velocity;
                    Velocity.X = (float)Math.Cos(pHost.Rotation + RotationOffset) * (MAX_RANGE + pHost.RotationalVelocity);
                    Velocity.Y = (float)Math.Sin(pHost.Rotation + RotationOffset) * (MAX_RANGE + pHost.RotationalVelocity);
                    Vector2 NextPosition = pHost.Position + Velocity;

                    //Make Ray
                    Ray2D R = new Ray2D(pHost.Position, NextPosition);
                    Boolean HitWall = false;

                    foreach (Actor A in pWorldActors)
                    {
                        if (A is BlockingActor) //If its a wall
                        {
                            //Get Distance
                            float Distance = Vector2.Distance(A.Position, pHost.Position);
                            if (Distance <= MAX_RANGE + 64 + pHost.RotationalVelocity) //In Range
                            {
                                Vector2 HitAt = R.Intersects(A.CollisionRectangle); //Check if it intersects
                                if (HitAt != Vector2.Zero)
                                {
                                    EndPoints.Add(HitAt);
                                    HitWall = true;

                                    DebugInformation += "Feeler(" + (i + 1).ToString() + ") - Touching Wall " + Vector2.Distance(HitAt, pHost.Position).ToString() + "\r\n";
                                }
                            }
                        }
                    }

                        if (!HitWall)
                        {
                            EndPoints.Add(NextPosition);
                            DebugInformation += "Feeler(" + (i + 1).ToString() + ") - Not Touching Wall\r\n";
                        }
                    }
        }
Beispiel #5
0
        public LinkedList <RayCastResult> RayCastAll(Ray2D ray)
        {
            var outList = m_root.RayCastAll(ray);

            Vector2 castResult;

            foreach (var leaf in overFlowLeaf)
            {
                if (ray.Intersects(leaf.Zone, out castResult))
                {
                    outList.AddLast(new RayCastResult(castResult, leaf));
                }
            }

            return(outList);
        }
Beispiel #6
0
        public bool RayCast(Ray2D ray, out RayCastResult result)
        {
            bool existResult = m_root.RayCast(ray, out result);

            // check leaf not in world
            foreach (var leaf in overFlowLeaf)
            {
                if (ray.Intersects(leaf.Zone, out Vector2 hitPoint) &&
                    (existResult == false || Vector2.DistanceSquared(ray.Original, hitPoint) < Vector2.DistanceSquared(ray.Original, result.Intersection)))
                {
                    existResult = true;
                    result      = new RayCastResult(hitPoint, leaf);
                }
            }

            return(existResult);
        }
Beispiel #7
0
        internal static int smethod_0(Ray2D ray, Polyline2D polyline)
        {
            int     num1  = 0;
            int     num2  = polyline.Count + (polyline.Closed ? 1 : 0);
            int     count = polyline.Count;
            Point2D start = polyline[0];

            for (int index = 1; index < num2; ++index)
            {
                Point2D   end = polyline[index % count];
                Segment2D b   = new Segment2D(start, end);
                if (Ray2D.Intersects(ray, b))
                {
                    ++num1;
                }
                start = end;
            }
            return(num1);
        }
Beispiel #8
0
        public void IntersectsBoundingRectangle(Ray2D ray, BoundingRectangle boundingRectangle, bool expectedResult,
                                                Point2 firstExpectedIntersectionPoint, Point2 secondExpectedIntersectionPoint)
        {
            float rayNearDistance, rayFarDistance;
            var   actualResult = ray.Intersects(boundingRectangle, out rayNearDistance, out rayFarDistance);

            Assert.AreEqual(expectedResult, actualResult);

            if (actualResult)
            {
                var firstActualIntersectionPoint = ray.Position + ray.Direction * rayNearDistance;
                Assert.AreEqual(firstExpectedIntersectionPoint, firstActualIntersectionPoint);
                var secondActualIntersectionPoint = ray.Position + ray.Direction * rayFarDistance;
                Assert.AreEqual(secondExpectedIntersectionPoint, secondActualIntersectionPoint);
            }
            else
            {
                Assert.IsTrue(float.IsNaN(rayNearDistance));
                Assert.IsTrue(float.IsNaN(rayFarDistance));
            }
        }
Beispiel #9
0
        internal static bool IsInside(Point2D p, Polyline3D polyline)
        {
            if (polyline == null)
            {
                return(false);
            }
            int     num1     = 0;
            Ray2D   a        = new Ray2D(p, Vector2D.XAxis);
            int     num2     = polyline.Count + (polyline.Closed ? 1 : 0);
            int     count    = polyline.Count;
            Point3D point3D1 = polyline[0];

            for (int index = 1; index < num2; ++index)
            {
                Point3D   point3D2 = polyline[index % count];
                Segment2D b        = new Segment2D(point3D1.X, point3D1.Y, point3D2.X, point3D2.Y);
                if (Ray2D.Intersects(a, b))
                {
                    ++num1;
                }
                point3D1 = point3D2;
            }
            return(num1 % 2 == 1);
        }
        private Vector2 GetArrowScreenBorderPosition(GraphicsContext graphicsContext, Vector2 entityPosition)
        {
            Vector2 direction = entityPosition - CCamera2D.Active.Position;
            Ray2D ray = new Ray2D(graphicsContext.ScreenSize / 2f, Vector2.Normalize(direction)); // ray from screen center to the direction of the drop
            if (!Check.IsValid(ray))
            {
                return -Vector2.One * 10000; // invalid number
            }

            RectangleF screenArea = new RectangleF(graphicsContext.ScreenArea).Inflate(-16);
            Vector2 hitPosition;
            if (ray.Intersects(screenArea.GetSideSegment(Direction2D.Left), out hitPosition) || ray.Intersects(screenArea.GetSideSegment(Direction2D.Right), out hitPosition) ||
                ray.Intersects(screenArea.GetSideSegment(Direction2D.Up), out hitPosition) || ray.Intersects(screenArea.GetSideSegment(Direction2D.Down), out hitPosition))
            {
                return hitPosition;
            }

            throw new InvalidOperationException("");
        }
Beispiel #11
0
        private Segment2D GetLaserSegment(CTransform2D rayStartTransform, EntityWorld entityWorld)
        {
            Ray2D ray = new Ray2D(rayStartTransform);
            RectangleF cameraArea = SkypieaConstants.GetAdjustedCameraArea(CCamera2D.Active);
            Vector2 rayEndPoint;
            if (!ray.Intersects(cameraArea, out rayEndPoint))
            {
                return new Segment2D(-Vector2.One * 1000, -Vector2.One * 1000);
            }

            return new Segment2D(ray.Position, rayEndPoint);
        }
Beispiel #12
0
        /// <summary>
        /// Handles attacking with a ranged weapon.
        /// </summary>
        /// <param name="weapon">The weapon to attack with. Cannot be null.</param>
        /// <param name="target">The target to attack. Can be null.</param>
        void AttackRanged(ItemEntity weapon, Character target)
        {
            if (weapon == null)
            {
                Debug.Fail("Weapon should not be null...");
                return;
            }

            // We can't do anything with ranged attacks if no target is given
            if (target == null)
            {
                TrySend(GameMessage.CannotAttackNeedTarget, ServerMessageType.GUI);
                return;
            }

            Ray2D ray = new Ray2D(this, Position, target.Position, Map.Spatial);

            Vector2 rayCollideWall;

            // FUTURE: Use to create some sort of wasted ammo on a wall or something.  e.g. Grenade item explodes on walls.
            bool hasHitWall = ray.Intersects<WallEntity>(out rayCollideWall);

            if (hasHitWall)
            {
                TrySend(GameMessage.CannotAttackNotInSight, ServerMessageType.GUI);
                return;
            }

            List<ISpatial> rayCollideCharacters;

            // Use IntersectsMany here if you want to damage all characters in the attack path
            bool hasHitCharacter = ray.Intersects<Character>(out rayCollideCharacters);

            if (hasHitCharacter)
            {
                var ammoUsed = false;

                // Check for the needed ammo
                switch (weapon.WeaponType)
                {
                    case WeaponType.Projectile:
                        // Grab projectile ammo out of the inventory first if possible to avoid having to constantly reload
                        var invAmmo = Inventory.FirstOrDefault(x => weapon.CanStack(x.Value));
                        if (invAmmo.Value != null)
                            Inventory.DecreaseItemAmount(invAmmo.Key);
                        else
                            weapon.Destroy();

                        ammoUsed = true;
                        break;

                    case WeaponType.Ranged:
                        // By default, guns won't use ammo. But if you want to require guns to use ammo, you can do so here
                        ammoUsed = true;
                        break;
                }

                if (!ammoUsed)
                    return;

                foreach (var character in rayCollideCharacters)
                {
                    var c = character as Character;

                    if (!Alliance.CanAttack(c.Alliance))
                        continue;

                    // Attack
                    using (var charAttack = ServerPacket.CharAttack(MapEntityIndex, c.MapEntityIndex, weapon.ActionDisplayID))
                    {
                        Map.SendToArea(this, charAttack, ServerMessageType.MapEffect);
                    }

                    OnAttacked();

                    if (Attacked != null)
                        Attacked.Raise(this, EventArgs.Empty);

                    AttackApplyReal(c);
                }
            }
        }