Exemple #1
0
    // TODO: Criar fisica do Disco
    /// <remarks>Source: http://gamedevelopment.tutsplus.com/tutorials/when-worlds-collide-simulating-circle-circle-collisions--gamedev-769</remarks>
    private static void CheckDiscCollision(BolaState state, TransformTarget target, GameContext context)
    {
        // Circle-circle collision
        var discRadius   = context.Config.Disco.Size.Radius;
        var paddleRadius = context.Config.Bola.Size.Radius;
        var discPos      = context.State.Disco.Transform.Position;
        var bolaPos      = state.Transform.Position;

        var discVelocity   = context.State.Disco.Heading * context.State.Disco.Speed;
        var paddleVelocity = target.Heading * context.Config.Bola.Size.ForwardSpeed;
        var discMass       = context.Config.Disco.Size.Mass;
        var bolaMass       = context.Config.Bola.Size.Mass;

        var dist    = Vector2.Distance(discPos, bolaPos);
        var minDist = discRadius + paddleRadius;

        if (dist < minDist)
        {
            var collisionPoint = Vector2.zero;
            collisionPoint.x = ((discPos.x * paddleRadius) + (bolaPos.x * discRadius)) / (discRadius + paddleRadius);
            collisionPoint.y = ((discPos.y * paddleRadius) + (bolaPos.y * discRadius)) / (discRadius + paddleRadius);

            var discNormal    = (collisionPoint - discPos).normalized;
            var bounceHeading = -Vector2.Reflect(paddleVelocity, discNormal).normalized;

            var newDiscVelocity = Vector2.zero;
            newDiscVelocity.x = (discVelocity.x * (discMass - bolaMass) + (2 * bolaMass * paddleVelocity.x)) / (discMass + bolaMass);
            newDiscVelocity.y = (discVelocity.y * (discMass - bolaMass) + (2 * bolaMass * paddleVelocity.y)) / (discMass + bolaMass);

            context.State.Disco.Heading = (newDiscVelocity + bounceHeading).normalized;
            context.State.Disco.Speed   = Mathf.Max(context.State.Disco.Speed, newDiscVelocity.magnitude * context.Config.Bola.DiscBounceFactor);
        }
    }
Exemple #2
0
    private static void StepTransform(float deltaTime, GameContext context, TransformTarget target)
    {
        var state = context.State.Disco;

        var angleOffset = 0f;

        target.Heading     = state.Heading;
        target.Distance    = deltaTime * state.Speed;
        target.AngleOffset = angleOffset;
    }
Exemple #3
0
    public static void ResolveTarget(int playerId, GameContext context, TransformTarget target)
    {
        var state = context.State.GetBola(playerId);

        while (target.Distance > NearZero)
        {
            MoveToTarget(playerId, context, target);
            CheckDiscCollision(state, target, context);
        }
    }
Exemple #4
0
    public static TransformTarget StepTarget(float deltaTime, GameContext context)
    {
        var state  = context.State.Disco;
        var target = new TransformTarget();

        state.Speed *= context.Config.Disco.DragFactor;

        StepTransform(deltaTime, context, target);

        return(target);
    }
    public static void ResolveTarget(GameContext context, TransformTarget target)
    {
        var state = context.State.Disco;

        while (target.Distance > NearZero)
        {
            MoveToTarget(context, target);
        }

        state.Speed = Mathf.Min(state.Speed, context.Config.Disco.MaxSpeed);
    }
    public static TransformTarget StepTarget(float deltaTime, int playerId, GameContext context)
    {
        var state  = context.State.GetBola(playerId);
        var target = new TransformTarget();

        StepPercentOrbit(deltaTime, playerId, context);

        if (state.Mode == BolaState.MovementMode.Normal)
        {
            UpdateOrbitDirection(playerId, context);
        }

        UpdateOrbitOrigin(playerId, context);

        StepTransform(deltaTime, playerId, context, target);

        return(target);
    }
Exemple #7
0
    private static void MoveToTarget(int playerId, GameContext context, TransformTarget target)
    {
        var state = context.State.GetBola(playerId);
        var trans = state.Transform;

        var nextPos = trans.Position + target.Heading * target.Distance;
        var nextRot = trans.Rotation + target.AngleOffset;

        Line    collisionWall;
        Vector2 collisionPoint;

        var collided = BoxPhysics.CheckPointCollision(context.Config.BolaBox, trans.Position, nextPos, out collisionWall, out collisionPoint);

        if (collided)
        {
            // Calculate partial position offset
            var collisionPosAmount = Mathf.Max(0f, Vector2.Distance(trans.Position, collisionPoint) - NearZero);
            var collisionPosTarget = trans.Position + target.Heading * collisionPosAmount;

            // Apply partial position offset
            target.Distance -= collisionPosAmount;
            trans.Position   = collisionPosTarget;

            // Calculate partial rotation offset
            var bounceDistPercentage = collisionPosAmount / target.Distance;
            var bounceRotAmount      = bounceDistPercentage * target.AngleOffset;

            // Reflect rotation against wall + apply partial rotation offset
            target.Heading      = Vector2.Reflect(nextPos - trans.Position, collisionWall.Normal).Rotate(bounceRotAmount).normalized;
            target.AngleOffset -= bounceRotAmount;
            trans.Rotation      = Vector2.up.SignedAngle(target.Heading);
        }
        else
        {
            target.Distance    = 0f;
            target.AngleOffset = 0f;
            trans.Position     = nextPos;
            trans.Rotation     = nextRot;
        }
    }
    private static void StepTransform(float deltaTime, int playerId, GameContext context, TransformTarget target)
    {
        var state = context.State.GetBola(playerId);
        var trans = state.Transform;

        var posOffset   = Vector2.zero;
        var angleOffset = 0f;

        // Adicionar orbita
        {
            var orbitDist    = deltaTime * context.Config.Bola.Size.OrbitSpeed * state.PercentOrbit;
            var orbitDegrees = MathUtility.CircleArcDistanceToAngleOffset(orbitDist, context.Config.Bola.Size.OrbitRadius);

            if (state.Direction == Direction.CW)
            {
                orbitDegrees *= -1;
            }

            var orbitDest      = trans.Position.RotateAround(state.OrbitOrigin, orbitDegrees);
            var orbitPosOffset = (orbitDest - trans.Position);

            posOffset   += orbitPosOffset;
            angleOffset += orbitDegrees;
        }

        // Adicionar aceleraçao
        {
            var forwardDir       = MathUtility.ToHeading(trans.Rotation);
            var forwardDist      = deltaTime * context.Config.Bola.Size.ForwardSpeed * (1 - state.PercentOrbit);
            var forwardPosOffset = forwardDir * forwardDist;

            posOffset += forwardPosOffset;
        }

        target.Heading     = posOffset.normalized;
        target.Distance    = posOffset.magnitude;
        target.AngleOffset = angleOffset;
    }
    private static void MoveToTarget(GameContext context, TransformTarget target)
    {
        var state = context.State.Disco;

        if (state.IsInGoal)
        {
            target.Distance = 0f;
            return;
        }

        var trans = state.Transform;

        var nextPos = trans.Position + target.Heading * target.Distance;

        Line collisionWall  = default;
        var  collisionPoint = Vector2.zero;

        var collided = false;

        if (state.IsHeadingTowardGoal)
        {
            if (context.Config.DiscoBox.Bounds.Contains(nextPos))
            {
                state.IsHeadingTowardGoal = false;
            }
        }

        // TODO:Mudar a colisao para o ObjectoController.
        if (!state.IsHeadingTowardGoal)
        {
            collided = BoxPhysics.CheckPointCollision(context.Config.DiscoBox, trans.Position, nextPos, out collisionWall, out collisionPoint);
        }

        if (collided && !state.IsHeadingTowardGoal)
        {
            var halfGoalSize = context.Config.Size.GoalWidth / 2 - context.Config.Disco.Size.Radius; // HACK
            var inGoalX      = collisionPoint.x > -halfGoalSize && collisionPoint.x < halfGoalSize;

            if (inGoalX)
            {
                collided = false;
                state.IsHeadingTowardGoal = true;
            }
        }

        if (collided)
        {
            // Calculate partial position offset
            var collisionPosAmount = Mathf.Max(0f, Vector2.Distance(trans.Position, collisionPoint) - NearZero);
            var collisionPosTarget = trans.Position + target.Heading * collisionPosAmount;

            // Apply partial position offset
            target.Distance -= collisionPosAmount;
            trans.Position   = collisionPosTarget;

            // Reflect heading against wall
            target.Heading = Vector2.Reflect(target.Heading, collisionWall.Normal).normalized;
            state.Heading  = target.Heading;

            state.Speed *= context.Config.Disco.WallBounceFactor;
        }
        else
        {
            target.Distance    = 0f;
            target.AngleOffset = 0f;
            trans.Position     = nextPos;
        }

        if (state.IsHeadingTowardGoal)
        {
            var goalLineY = context.Config.DiscoBox.Bounds.max.y + context.Config.Disco.Size.Radius * 2;
            if (Mathf.Abs(trans.Position.y) > goalLineY)
            {
                state.IsInGoal = true;
            }
        }
    }