Пример #1
0
 public void Tick()
 {
     currentTick += 1;
     // Call OnCreate on each new entity.
     while (new_entities.Count != 0)
     {
         var e = new_entities[new_entities.Count - 1];
         new_entities.RemoveAt(new_entities.Count - 1);
         e.OnCreate();
         _entities.Add(e);
         eventListener.EntityCreated(e);
     }
     // OnTick.
     foreach (var e in entities)
     {
         e.OnTick();
     }
     // Perform collision detection.
     for (var i = 0; i < colliders.Count; i += 1)
     {
         var ci    = colliders[i];
         var i_bot = ci.entity.position.y;
         var i_top = i_bot + ci.height;
         for (var j = i + 1; j < colliders.Count; j += 1)
         {
             var cj       = colliders[j];
             var j_bot    = cj.entity.position.y;
             var j_top    = j_bot + cj.height;
             var size     = ci.radius + cj.radius;
             var dist_sqr = map.DistanceSqr(ci.entity.position, cj.entity.position);
             if (dist_sqr > size * size)
             {
                 continue;
             }
             if (DReal.Max(i_bot, j_bot) > DReal.Min(i_top, j_top))
             {
                 continue;
             }
             ci.entity.OnCollision(cj.entity);
             cj.entity.OnCollision(ci.entity);
         }
     }
     // Call OnDestroy on each dead entity.
     while (dead_entities.Count != 0)
     {
         var e = dead_entities[dead_entities.Count - 1];
         dead_entities.RemoveAt(dead_entities.Count - 1);
         if (new_entities.Contains(e))
         {
             new_entities.Remove(e);
         }
         else
         {
             e.OnDestroy();
             _entities.Remove(e);
             eidToEntityMap.Remove(e.eid);
             eventListener.EntityDestroyed(e);
         }
     }
 }
Пример #2
0
        public List <DVector3> BuildPath(DVector3 origin, DVector3 dest)
        {
            var orig_dest = dest;

            origin = new DVector3(((int)origin.x / granularity) * granularity, 0, ((int)origin.z / granularity) * granularity);
            dest   = new DVector3(((int)dest.x / granularity) * granularity, 0, ((int)dest.z / granularity) * granularity);

            var open_set   = new List <DVector3>();
            var closed_set = new HashSet <DVector3>();
            var g_score    = new Dictionary <DVector3, DReal>();
            var f_score    = new Dictionary <DVector3, DReal>();
            var came_from  = new Dictionary <DVector3, DVector3>();

            var ops = 0;

            var origin_reach = Reachability(origin);
            var dest_reach   = Reachability(dest);

            UnityEngine.Debug.Log(string.Format("Gen path from {0}/{1} to {2}/{3}", origin, origin_reach, dest, dest_reach));

            if (!passable(dest) || origin_reach != dest_reach)
            {
                return(null);
            }

            open_set.Add(origin);
            g_score[origin] = 0;
            f_score[origin] = map.DistanceSqr(origin, dest);
            while (open_set.Count != 0)
            {
                ops += 1;
                if (ops > 1000)
                {
                    UnityEngine.Debug.Log("Path too long!");
                    return(null);
                }
                var current = remove_best(open_set, f_score);
                if (current == dest)
                {
                    var path = new List <DVector3>();
                    while (came_from.ContainsKey(current))
                    {
                        // Try to path through the middle of the map square.
                        path.Add(current + new DVector3(1, 1, 1) * (DReal)granularity / 2);
                        current = came_from[current];
                    }
                    path.Reverse();
                    if (path.Count != 0)
                    {
                        path.RemoveAt(path.Count - 1);
                    }
                    path.Add(orig_dest);
                    return(path);
                }
                closed_set.Add(current);
                foreach (var n in neighbors(current))
                {
                    if (!passable(n))
                    {
                        continue;
                    }
                    if (closed_set.Contains(n))
                    {
                        continue;
                    }
                    if (!open_set.Contains(n))
                    {
                        open_set.Add(n);
                        g_score.Add(n, DReal.MaxValue);
                        f_score.Add(n, DReal.MaxValue);
                    }
                    var tentative_g_score = g_score[current] + map.DistanceSqr(current, n);
                    if (tentative_g_score >= g_score[n])
                    {
                        continue;
                    }
                    came_from[n] = current;
                    g_score[n]   = tentative_g_score;
                    f_score[n]   = tentative_g_score + map.DistanceSqr(dest, n);
                }
            }
            return(null);
        }