Exemplo n.º 1
0
        /// <summary>
        ///     Makes all necessary calculations to figure out where the current point at this step of the animation is.
        /// </summary>
        /// <param name="gameTime"></param>
        /// <returns></returns>
        public bool Tick(GameTime gameTime)
        {
            if (actor != null && (actor.StatusType & StatusType.Update) == StatusType.Update)
            {
                bool done = Looper.Loop(loopMethod, ref currentTime, ref step, maxTime);

                float timePercent     = (float)currentTime / maxTime;
                float smoothedPercent = Smoother.SmoothValue(smoothing, timePercent);

                Vector3 currentPoint = Vector3.Lerp(isRelative ? Vector3.Zero : start, destination, smoothedPercent);

                FinalOperation finalOperation = PerformOperation(currentPoint, lastPoint);

                process(finalOperation);

                lastPoint = currentPoint;

                currentTime += gameTime.ElapsedGameTime.Milliseconds * step;

                if (done)
                {
                    if (resetAfterDone)
                    {
                        process(target => start);
                    }
                    callback?.Invoke();
                }

                return(done);
            }

            return(false);
        }
        public override void Update(GameTime gameTime, IActor actor)
        {
            tile ??= actor as AttachableTile;
            if (tile == null)
            {
                return;
            }

            Raycaster.HitResult hit;
            if (tile.IsMoving)
            {
                endMoveCallback ??= tile.OnMoveEnd;
                //Check if done moving.
                if (currentMovementTime <= 0)
                {
                    tile.IsMoving       = false;
                    currentMovementTime = 0;
                    startRotation       = rotationQuaternion;
                    endMoveCallback?.Invoke();
                    isDirty = true;
                }

                //The Smoother Replaces Curves as it's easier to have slopes.
                //We count down so it's inverted.
                float currentStep = 1 - Smoother.SmoothValue(Smoother.SmoothingMethod.Smooth,
                                                             (float)currentMovementTime / movementTime);
                Vector3 trans = startPos + diff * currentStep;

                //Invert Lerp percent and get Rotation
                Quaternion quaternion = Quaternion.Slerp(startRotation, rotationQuaternion, currentStep);
                tile.Transform3D.RotationInDegrees = MathHelperFunctions.QuaternionToEulerAngles(quaternion);

                //Check if we have a callback that we must invoke if we collide in the move
                if (onCollideCallback != null)
                {
                    //Raycast to check if there's anything
                    hit = RaycastManager.Instance.Raycast(tile, trans, Vector3.Up, true, 1f);

                    //Invoke callback if we hit something
                    if (hit != null)
                    {
                        onCollideCallback?.Invoke(hit);
                        onCollideCallback = null;
                    }
                }

                //Dont go anywhere we don't want the tile to go
                if (currentMovementTime <= 0)
                {
                    trans = new Vector3((int)Math.Round(trans.X), (int)Math.Round(trans.Y),
                                        (int)Math.Round(trans.Z));
                }

                tile.SetTranslation(trans);
                currentMovementTime -= (int)gameTime.ElapsedGameTime.TotalMilliseconds;
            }
            else
            {
                if (falling && !tile.IsAttached)
                {
                    if (isDirty)
                    {
                        tile.Body.ApplyGravity = true;
                        tile.Body.Immovable    = false;
                        isDirty = false;
                    }

                    tile.Body.Velocity           = Vector3.UnitY * tile.Body.Velocity.Y;
                    tile.Body.Torque             = Vector3.UnitY * tile.Body.Torque.Y;
                    tile.Body.AngularVelocity    = Vector3.UnitY * tile.Body.AngularVelocity.Y;
                    tile.Transform3D.Translation = tile.Body.Position;
                    floored = true;
                }
                else
                {
                    tile.SetTranslation(tile.Transform3D.Translation);
                }

                if (isDirty || falling)
                {
                    hit     = RaycastManager.Instance.Raycast(tile, tile.Transform3D.Translation, Vector3.Down, true, 0.6f);
                    falling = hit == null;
                    if (floored)
                    {
                        EventManager.FireEvent(new PlayerEventInfo {
                            type = PlayerEventType.CheckSouroundings
                        });
                        floored = false;
                    }
                }
            }
        }