Exemplo n.º 1
0
        public static void Control(PhysicsValues physicsValues, GameDuration elapsedDuration, Entity entity, IEnumerable<Entity> otherEntities)
        {
            // initialize Behavior stores if necessary
            if (!_activeBehavior.ContainsKey(entity))
            {
                Behavior defaultBehavior = InitializeBehaviors(entity);

                _activeBehavior.Add(entity, defaultBehavior);
            }

            Behavior current = _activeBehavior[entity];

            // update the duration the active Behavior has been running
            current.AddToActiveDuration(elapsedDuration);

            // store all relevant data in BehaviorContext
            var context = new BehaviorContext(physicsValues, elapsedDuration, otherEntities);

            // if the minimum running duration of the current Behavior has passed, look for another applicable Behavior
            if (current.ActiveDuration > current.MinimumDuration())
            {
                foreach (Behavior b in _possibleBehaviors[entity])
                {
                    // we only look for *other* Behaviors
                    if (current.Equals(b))
                    {
                        continue;
                    }

                    // determine the other Behavior's current priority
                    var otherPrio = b.DeterminePriority(context);

                    // only consider other Behavior if it's applicable
                    if (otherPrio == BehaviorPriority.NA)
                    {
                        continue;
                    }

                    // switch to other Behavior depending on relation between priorities
                    var currentPrio = current.DeterminePriority(context);
                    if (otherPrio / (currentPrio + otherPrio) > Rng.NextDouble())
                    {
                        // reset the current Behavior, as it might become active again later
                        current.Reset();

                        // change active Behavior to new one
                        _activeBehavior[entity] = b;
                        current = b;

                        ////Console.WriteLine("Entity {0} switched to behavior {1}", entity, b);
                    }
                }
            }

            // let the active Behavior control the entity
            current.Behave(context);
        }
Exemplo n.º 2
0
        public static void MoveEntity(PhysicsValues physicsValues, World world, PositionData positionData, GameDuration elapsedDuration, EntityOffset offset)
        {
            offset.Y -= 0.5 * elapsedDuration.Seconds * physicsValues.Gravity;
            if (MoveY(physicsValues, world, positionData, offset.Y * elapsedDuration.Seconds))
            {
                positionData.IsFalling = false;
            }
            else
            {
                if (!positionData.IsFalling)
                {
                    /* Re-evaluate the fall from the apparent position. */
                    positionData.InternalPos = positionData.Placement.Pos;
                    MoveY(physicsValues, world, positionData, offset.Y * elapsedDuration.Seconds);
                    positionData.IsFalling = true;
                }
            }

            if (positionData.IsFalling)
            {
                offset.Y -= 0.5 * elapsedDuration.Seconds * physicsValues.Gravity;
            }
            else
            {
                if (Math.Abs(offset.Y) > Math.Sqrt(2 * physicsValues.Gravity * physicsValues.TerminalHeight))
                {
                    Respawn(positionData);
                }

                offset.Y = 0;
            }

            if (offset.X != 0 || offset.Z != 0)
            {
                long savedY = positionData.InternalPos.Y;
                if (!positionData.IsFalling && world[(BlockPos)positionData.InternalPos - BlockOffset.UnitY] != 0)
                {
                    // Temporarily move the character up a block so that it can climb up stairs.
                    MoveY(physicsValues, world, positionData, 1);
                }

                EntityPos positionBeforeMovement = positionData.InternalPos;
                double moveX = offset.X * elapsedDuration.Seconds;
                double moveZ = offset.Z * elapsedDuration.Seconds;

                if (offset.X > offset.Z)
                {
                    MoveX(physicsValues, world, positionData, moveX);
                    MoveZ(physicsValues, world, positionData, moveZ);
                }
                else
                {
                    MoveZ(physicsValues, world, positionData, moveZ);
                    MoveX(physicsValues, world, positionData, moveX);
                }

                var moveDelta = positionData.InternalPos - positionBeforeMovement;
                moveX -= moveDelta.X;
                moveZ -= moveDelta.Z;

                if (!positionData.IsFalling)
                {
                    // Attempt to move the character back down to the ground in case we didn't climb a stair.
                    MoveY(physicsValues, world, positionData, (savedY - positionData.InternalPos.Y) / (double)(1L << 32));

                    savedY = positionData.InternalPos.Y;

                    // Attempt to move the caracter down an additional block so that it can walk down stairs.
                    if (!MoveY(physicsValues, world, positionData, -((1L << 32) + 1) / (double)(1L << 32)))
                    {
                        positionData.InternalPos.Y = savedY;
                        positionData.IsFalling = true;
                    }
                }

                // Attempt to continue movement at this new (lower) Y position.
                if (offset.X > offset.Z)
                {
                    if (MoveX(physicsValues, world, positionData, moveX)) offset.X = 0;
                    if (MoveZ(physicsValues, world, positionData, moveZ)) offset.Z = 0;
                }
                else
                {
                    if (MoveZ(physicsValues, world, positionData, moveZ)) offset.Z = 0;
                    if (MoveX(physicsValues, world, positionData, moveX)) offset.X = 0;
                }
            }

            positionData.Velocity = offset;
            SetPositionFromCollisionPosition(physicsValues, world, positionData);
        }
Exemplo n.º 3
0
 public BehaviorContext(PhysicsValues physicsValues, GameDuration elapsedDuration, IEnumerable<Entity> otherEntities)
 {
     PhysicsValues = physicsValues;
     ElapsedDuration = elapsedDuration;
     OtherEntities = otherEntities;
 }