예제 #1
0
        /// <summary>
        ///     Führt die Berechnung rund um die Sichtbarkeit durch
        /// </summary>
        private void UpdateVisibles()
        {
            // Remake the visibles map
            visiblesMap.Clear();
            foreach (VisibleProperty visible in visibles.Values)
            {
                visiblesMap.Add(visible, visible.Item.Position, visible.VisibilityRadius);
            }

            // Durchläuft alle sehenden Elemente
            foreach (SightingProperty sighting in viewers.Values)
            {
                var visibleItems = new List <VisibleProperty>();

                // Run through all visible elements in the vincinity
                foreach (VisibleProperty visible in visiblesMap.FindAll(sighting.Item.Position, sighting.ViewRange))
                {
                    // Skip, falls es das selbe Item ist.
                    if (visible.Item == sighting.Item)
                    {
                        continue;
                    }

                    float max = sighting.ViewRange + visible.VisibilityRadius;

                    // Umgang mit der Distanz
                    // TODO: Berücksichtigung von Richtung und Öffnungswinkel
                    if (Item.GetDistance(sighting.Item, visible.Item) <= max)
                    {
                        // Neues Element erspäht
                        if (!sighting.VisibleItems.Contains(visible))
                        {
                            sighting.AddVisibleItem(visible);
                            visible.AddSightingItem(sighting);
                        }

                        // Aufruf für jedes sichtbare Element pro Runde
                        sighting.NoteVisibleItem(visible);
                        visibleItems.Add(visible);
                    }
                }

                // Durchläuft alle bisher sichtbaren Items um zu sehen ob die
                // Aktualität des Visible-Eintrags noch stimmt.
                foreach (VisibleProperty visible in sighting.VisibleItems.ToArray())
                {
                    if (!visibleItems.Contains(visible))
                    {
                        sighting.RemoveVisibleItem(visible);
                        visible.RemoveSightingItem(sighting);
                    }
                }
            }
        }
예제 #2
0
        private void UpdateSniffer()
        {
            // Remake the smellables map
            smellablesMap.Clear();
            foreach (SmellableProperty smellable in smellables.Values)
            {
                smellablesMap.Add(smellable, smellable.Item.Position, smellable.SmellableRadius);
            }

            // Durchläuft alle riechenden Elemente
            foreach (SnifferProperty sniffer in sniffers.Values)
            {
                var smellableItems = new List <SmellableProperty>();

                // Durchläuft alle riechbaren Elemente, sucht in einem "nullradius" nach riechenden Elementen.
                // Diese haben einen bestimmten Radius und können somit die riechenden Elemente überdecken.
                foreach (SmellableProperty smellable in smellablesMap.FindAll(sniffer.Item.Position, 0f))
                {
                    // Skip, falls es das selbe Item ist.
                    if (smellable.Item == sniffer.Item)
                    {
                        continue;
                    }

                    // Umgang mit der Distanz
                    if (Item.GetDistance(sniffer.Item, smellable.Item) <= smellable.SmellableRadius)
                    {
                        // Hinzufügen, falls bisher nicht gerochen
                        if (!sniffer.SmellableItems.Contains(smellable))
                        {
                            smellable.AddSnifferItem(sniffer);
                            sniffer.AddSmellableItem(smellable);
                        }

                        // Aufruf für jedes aktuell riechbare Element
                        sniffer.NoteSmellableItem(smellable);
                        smellableItems.Add(smellable);
                    }
                }

                // Durchläuft alle bisher riechbaren Items um zu sehen ob die
                // Aktualität des Smellable-Eintrags noch stimmt.
                foreach (SmellableProperty smellable in sniffer.SmellableItems.ToArray())
                {
                    if (!smellableItems.Contains(smellable))
                    {
                        sniffer.RemoveSmellableItem(smellable);
                        smellable.RemoveSnifferItem(sniffer);
                    }
                }
            }
        }
예제 #3
0
        public override void Update()
        {
            // Positionen updaten
            foreach (PhysicsUnit item in _cluster.Values)
            {
                if (!item.Update())
                {
                    KillUnit(item);
                }
            }

            // Kollisionen auflösen
            _mipmap.Clear();
            foreach (PhysicsUnit item in _collidables)
            {
                if (item.CanCollide)
                {
                    _mipmap.Add(item, item.Position, item.Radius);
                }
            }

            // Kollisionen finden
            foreach (PhysicsUnit collidable1 in _collidables)
            {
                HashSet <PhysicsUnit> hits = _mipmap.FindAll(collidable1.Position, collidable1.Radius);
                foreach (PhysicsUnit collidable2 in hits)
                {
                    // Kollision mit sich selbst überspringen
                    if (collidable2 == collidable1)
                    {
                        continue;
                    }

                    // TODO: Prüfen, ob diese Item-Kombination schon mal dran war

                    // Auf Kollision prüfen
                    if (Item.GetDistance(collidable1.Item, collidable2.Item) > collidable1.Radius + collidable2.Radius)
                    {
                        continue;
                    }

                    // Kollision auflösen
                    collidable1.Collide(collidable2);
                }
            }

            // Drops behandeln
            Vector2 size = Engine.Map.GetSize();

            foreach (PhysicsUnit item in _collidables)
            {
                if (item.Position.X < 0 ||
                    item.Position.Y < 0 ||
                    item.Position.X > size.X ||
                    item.Position.Y > size.Y)
                {
                    KillUnit(item);
                }
            }

            // Carrier <-> Portable Abstände checken
            foreach (PhysicsUnit item in _cluster.Values)
            {
                item.CheckPortableDistance();
            }
        }