Esempio n. 1
0
        public void Update(GameTime gameTime)
        {
            // Update all Derps
            // Use the kill stack to clean up dead derps
            Stack <Derp> killingStack = new Stack <Derp>();

            foreach (KeyValuePair <SortKey, Derp> keyVal in derpsSpeed)
            {
                Derp d = keyVal.Value;

                // Update each
                if (d.alive)
                {
                    d.Update();
                }
                else
                {
                    killingStack.Push(d);
                }
            }

            // Cleaning up
            while (killingStack.Count > 0)
            {
                RemoveDerp(killingStack.Pop());
            }
        }
Esempio n. 2
0
        public int CheckDerpCollision(Derp casting, myVector v, out double t, bool checkBothTeams)
        {
            // t is initialized optimistically to the full distance
            t = 1.0;

            // the id of the derp is -1 if there is no collision
            int ret = -1;

            // For collision we are checking only against our teammates (because we will always attack (and stop moving) before we collide with enemies) <- at least that's the plan
            List <Derp> checkingList;

            if (casting.team == TEAM.HOME)
            {
                checkingList = homeDerps;
            }
            else
            {
                checkingList = awayDerps;
            }

            // I'm making the optimistic assumption that these lists will be sorted because they are sorted every Draw Step
            int myID = checkingList.IndexOf(casting);

            // check derps above me
            for (int i = myID - 1; i >= 0; --i)
            {
                // only check derps near me on the y axis
                if (casting.y - checkingList[i].y > distThreshholdY)
                {
                    break;
                }

                double check_t = Geometry.DerpCircleCast(casting, checkingList[i], v);
                if (check_t < t)
                {
                    t   = check_t;
                    ret = i;
                }
            }

            // check derps below me
            for (int i = myID + 1; i < checkingList.Count; ++i)
            {
                // only check derps near me on the y axis
                if (casting.y - checkingList[i].y > distThreshholdY)
                {
                    break;
                }

                double check_t = Geometry.DerpCircleCast(casting, checkingList[i], v);
                if (check_t < t)
                {
                    t   = check_t;
                    ret = i;
                }
            }

            // If we need to check the enemy team, then we can't do it quite as fast, but just check against them all
            if (checkBothTeams)
            {
                checkingList = (casting.team == TEAM.HOME ? awayDerps : homeDerps);
                foreach (Derp o in checkingList)
                {
                    double check_t = Geometry.DerpCircleCast(casting, o, v);
                    if (check_t < t)
                    {
                        t   = check_t;
                        ret = -1;
                    }
                }
            }

            // the id of the colliding derp
            return(ret);
        }
Esempio n. 3
0
        // Check for a Derp's Circle-Cast across the field
        // This will work like a BFS, starting from the initial position
        // then check all 4 corners around the position to build on the bfs
        public bool CheckFieldCollision(Derp d, myVector v, out double t, out myLineSegment col)
        {
            // initial optimistic setup that there will not be a collision
            bool ret = false;
            t = 1.0;
            col = null;

            // calculate starting point
            int startX = (int)(d.x / BLOCK_WIDTH);
            int startY = (int)(d.y / BLOCK_HEIGHT);

            // Unit Vector in desired direction
            myVector vUnit = new myVector(v.x, v.y);
            vUnit.toUnit();

            // set up the bfs
            Queue<SimpleNode> q = new Queue<SimpleNode>();
            bool[,] vis = new bool[height+1, width+1];

            q.Enqueue(new SimpleNode(startX, startY, 0));
            vis[startY, startX] = true;

            // Create the 4 line segments so we don't have to do quiiite as much object creation in this loop
            myLineSegment[] segs = new myLineSegment[4];
            for (int i = 0; i < 4; ++i)
                segs[i] = new myLineSegment(null, null);

            // BFS
            int[] dx = { 0, 1, 0, -1 };
            int[] dy = { -1, 0, 1, 0 };
            int cur_step = 0;
            while (q.Count > 0)
            {
                SimpleNode cur = q.Dequeue();

                // end early if we had a hit already in a previous step
                if (ret && cur_step != cur.step)
                    break;

                // checking 4 nodes around us
                myPoint p1 = new myPoint(cur.x * BLOCK_WIDTH, cur.y * BLOCK_HEIGHT);
                myPoint p2 = new myPoint((cur.x + 1) * BLOCK_WIDTH, cur.y * BLOCK_HEIGHT);
                myPoint p3 = new myPoint((cur.x + 1) * BLOCK_WIDTH, (cur.y + 1) * BLOCK_HEIGHT);
                myPoint p4 = new myPoint(cur.x * BLOCK_WIDTH, (cur.y + 1) * BLOCK_HEIGHT);
                segs[0].Update(p1, p2);
                segs[1].Update(p2, p3);
                segs[2].Update(p4, p3);
                segs[3].Update(p1, p4);

                for (int i = 0; i < 4; ++i)
                {
                    int nx = cur.x + dx[i];
                    int ny = cur.y + dy[i];

                    if (nx < 0 || nx > width || ny < 0 || ny >= height || vis[ny, nx])
                        continue;

                    double possible_t;
                    if (Geometry.DerpLineSegmentCast(d, v, segs[i], out possible_t))
                    {
                        // We have a hit! If the next zone is safe to move in, then continue the bfs
                        if (gameGrid[ny, nx] != '0')
                        {
                            q.Enqueue(new SimpleNode(nx, ny, cur.step + 1));
                            vis[ny, nx] = true;
                        }
                        // We hit an unnavigable space. Stop the BFS, this is as far as we go
                        else
                        {
                            ret = true;

                            if (Math.Abs(possible_t - t) < 1e-5 && col != null)
                            {
                                // break ties by taking the furthest behind the direction we wish to go
                                // Calculate the center point on the wall, and get the dot product of the vector to that point.
                                // The most negative value is the furthest behind
                                myPoint segMidPoint1 = new myPoint((segs[i].p1.x + segs[i].p2.x) / 2.0, (segs[i].p1.y + segs[i].p2.y) / 2.0);
                                myVector toMidPoint1 = new myVector(segMidPoint1.x - d.x, segMidPoint1.y - d.y);

                                myPoint segMidPoint2 = new myPoint((col.p1.x + col.p2.x) / 2.0, (col.p1.y + col.p2.y) / 2.0);
                                myVector toMidPoint2 = new myVector(segMidPoint2.x - d.x, segMidPoint2.y - d.y);

                                if (vUnit.dot(toMidPoint1) < vUnit.dot(toMidPoint2))
                                {
                                    t = possible_t;
                                    col = new myLineSegment(segs[i].p1.x, segs[i].p1.y, segs[i].p2.x, segs[i].p2.y); // careful... memory bugs
                                }
                            }
                            else if (possible_t < t)
                            {
                                t = possible_t;
                                col = new myLineSegment(segs[i].p1.x, segs[i].p1.y, segs[i].p2.x, segs[i].p2.y); // careful... memory bugs
                            }
                        }
                    }
                }

                // if we are a special diagonal case, then check the cross hit as well
                myLineSegment diag = null;

                char c = gameGrid[cur.y, cur.x];
                if (c == '1' || c == '3')
                    diag = new myLineSegment(p2, p4);

                if (c == '2' || c == '4')
                    diag = new myLineSegment(p1, p3);

                if (diag != null)
                {
                    double possible_t;
                    if (Geometry.DerpLineSegmentCast(d, v, diag, out possible_t))
                    {
                        ret = true;

                        if (Math.Abs(possible_t - t) < 1e-5 && col != null)
                        {
                            // break ties by taking the furthest behind the direction we wish to go
                            // Calculate the center point on the wall, and get the dot product of the vector to that point.
                            // The most negative value is the furthest behind
                            myPoint segMidPoint1 = new myPoint((diag.p1.x + diag.p2.x) / 2.0, (diag.p1.y + diag.p2.y) / 2.0);
                            myVector toMidPoint1 = new myVector(segMidPoint1.x - d.x, segMidPoint1.y - d.y);

                            myPoint segMidPoint2 = new myPoint((col.p1.x + col.p2.x) / 2.0, (col.p1.y + col.p2.y) / 2.0);
                            myVector toMidPoint2 = new myVector(segMidPoint2.x - d.x, segMidPoint2.y - d.y);

                            if (vUnit.dot(toMidPoint1) < vUnit.dot(toMidPoint2))
                            {
                                t = possible_t;
                                col = new myLineSegment(diag.p1.x, diag.p1.y, diag.p2.x, diag.p2.y); // careful... memory bugs
                            }
                        }
                        else if (possible_t < t)
                        {
                            t = possible_t;
                            col = new myLineSegment(diag.p1.x,diag.p1.y, diag.p2.x, diag.p2.y); // careful... memory bugs
                        }
                    }
                }

                cur_step = cur.step;
            }

            return ret;
        }