public bool Cross(DataBallState comeFrom, ref DataBallState resultBounce) { var increment = comeFrom.Speed * comeFrom.DeltaTime; var next = comeFrom.Position + increment; var paddlePos = Composition.ControllerSim.GetLocalPaddleReflectorPos(); var bounce = paddlePos.y + Composition.ControllerSim.BallRadius; // positives var distanceNoBounce = comeFrom.Position.y - next.y; var distanceBounce = comeFrom.Position.y - bounce; distanceNoBounce = distanceNoBounce > 0f ? distanceNoBounce : 0f; distanceBounce = distanceBounce > 0f ? distanceBounce : 0f; if (distanceBounce < distanceNoBounce) { // no zero here, cause: zero is vertical movement (both are positives and is upper) var factor = distanceBounce / distanceNoBounce; var bouncePos = new Vector2( comeFrom.Position.x + increment.x * factor, comeFrom.Position.y + distanceBounce); resultBounce.Position = bouncePos; resultBounce.Speed = new Vector2( comeFrom.Speed.x, -comeFrom.Speed.y); resultBounce.DeltaTime = comeFrom.DeltaTime / (1f - factor); Debug.Log($"bouncing {GetType().Name}"); return(true); } return(false); }
public bool Cross(DataBallState comeFrom, ref DataBallState resultBounce) { var increment = comeFrom.Speed * comeFrom.DeltaTime; var next = comeFrom.Position + increment; var bounce = -.5f * Composition.DataMeta.CourtRatio + Composition.ControllerSim.BallRadius; // positives var distanceNoBounce = comeFrom.Position.x - next.x; var distanceBounce = comeFrom.Position.x - bounce; distanceNoBounce = distanceNoBounce > 0f ? distanceNoBounce : 0f; distanceBounce = distanceBounce > 0f ? distanceBounce : 0f; if (distanceBounce < distanceNoBounce) { // no zero here, cause: zero is vertical movement (both are positives and is upper) var factor = distanceBounce / distanceNoBounce; resultBounce.Position = new Vector2( comeFrom.Position.x - distanceBounce, comeFrom.Position.y + increment.y * factor); resultBounce.Speed = new Vector2( -comeFrom.Speed.x, comeFrom.Speed.y); resultBounce.DeltaTime = comeFrom.DeltaTime / (1f - factor); Debug.Log($"bouncing {GetType().Name}"); return(true); } return(false); }
private bool FindBounce(ref DataBallState bounce, IObstacle[] obstacles) { var index = 0; for (; index < obstacles.Length && !obstacles[index].Cross(bounce, ref bounce); index++) { } return(index != obstacles.Length); }
public bool Bounce(DataBallState comeFrom, ref DataBallState resultBounce) { var increment = comeFrom.Speed * comeFrom.DeltaTime; var next = comeFrom.Position + increment; resultBounce.Position = next; resultBounce.Speed = comeFrom.Speed; resultBounce.DeltaTime = 0f; Debug.Log($"bouncing {GetType().Name}"); return(true); }
public bool Bounce(DataBallState comeFrom, ref DataBallState resultBounce) { var increment = comeFrom.Speed * comeFrom.DeltaTime; var next = comeFrom.Position + increment; var paddlePos = Composition.ControllerSim.GetRemotePaddleReflectorPos(); var bounce = paddlePos.y - Composition.ControllerSim.BallRadius; // positives var distanceNoBounce = next.y - comeFrom.Position.y; var distanceBounce = bounce - comeFrom.Position.y; distanceNoBounce = distanceNoBounce > 0f ? distanceNoBounce : 0f; distanceBounce = distanceBounce > 0f ? distanceBounce : 0f; if (distanceBounce < distanceNoBounce) { // no zero here, cause: zero is vertical movement (both are positives and is upper) var factor = distanceBounce / distanceNoBounce; // more resources //var bouncePos = comeFrom.Position + increment * factor; var bouncePos = new Vector2( comeFrom.Position.x + increment.x * factor, comeFrom.Position.y + distanceBounce); // more resources //var paddleBoundDistance = (paddlePos - bouncePos).magnitude; var paddleBoundDistance = bouncePos.x > paddlePos.x ? bouncePos.x - paddlePos.x : paddlePos.x - bouncePos.x; if (paddleBoundDistance < Composition.ControllerSim.Frame.PaddleRemoteReflectorHalfSize) { resultBounce.Position = bouncePos; resultBounce.Speed = new Vector2( comeFrom.Speed.x, -comeFrom.Speed.y); resultBounce.DeltaTime = comeFrom.DeltaTime * (1f - factor); //var screenBouncePos = ((Vector3)bouncePos + Vector3.up * Composition.ControllerSim.BallRadius) * Composition.ModelScaleFactor; //var screenPaddlePos = (Vector3)paddlePos * Composition.ModelScaleFactor; //Debug.DrawLine(screenPaddlePos, screenBouncePos, Color.magenta, 20f); Debug.Log($"bouncing {GetType().Name}"); return(true); } } return(false); }
public ControllerSimPhase(DataFrameState stateFrame, DataBallState stateBall, IObstacle[] obstacles) { Debug.Log("predicting"); var maxPath = Mathf.Sqrt(1f + Composition.DataMeta.CourtRatio) * 2f; var currentSpeed = stateBall.Speed.magnitude; stateBall.DeltaTime = maxPath / currentSpeed; var bounce = stateBall; if (FindBounce(ref bounce, obstacles)) { _timeTarget = DateTime.FromBinary(stateFrame.Time) + TimeSpan.FromSeconds(bounce.DeltaTime); _targetBallPos = bounce.Position; _targetBallSpeed = bounce.Speed; Debug.DrawLine(_targetBallPos, stateBall.Position, Color.red, 20f); } else { throw new Exception("undef"); } }
public void Update(IControllerInput controllerInput) { DataFrameState lastRemote; lock (_framesRemote) { lastRemote = _framesRemote[_indexCurrent]; } var paddleLocalMovement = controllerInput.IsMovingLeft ? -1f : 0f; paddleLocalMovement += controllerInput.IsMovingRight ? 1f : 0f; var leftBound = -.5f * Composition.DataMeta.CourtRatio; var rightBound = .5f * Composition.DataMeta.CourtRatio; var lastLocalDelta = _frame.Time; Composition.NetState.SetTimeStamp(ref _frame); var bufferedDeltaTime = (float)(DateTime.FromBinary(_frame.Time) - DateTime.FromBinary(lastRemote.Time)).TotalSeconds; var simDeltaTime = (float)(DateTime.FromBinary(_frame.Time) - DateTime.FromBinary(lastLocalDelta)).TotalSeconds; // update paddle local _frame.PaddleLocalSpeed = Composition.DataMeta.PaddleSpeed * paddleLocalMovement; _frame.PaddleLocalPosition += Frame.PaddleLocalSpeed * simDeltaTime; var leftPaddleLocalBound = _frame.PaddleLocalPosition - _frame.PaddleLocalReflectorHalfSize; var rightPaddleLocalBound = _frame.PaddleLocalPosition + _frame.PaddleLocalReflectorHalfSize; // limit _frame.PaddleLocalPosition = leftBound > leftPaddleLocalBound ? leftBound + _frame.PaddleLocalReflectorHalfSize : Frame.PaddleLocalPosition; _frame.PaddleLocalPosition = rightBound < rightPaddleLocalBound ? rightBound - _frame.PaddleLocalReflectorHalfSize : Frame.PaddleLocalPosition; // update paddle remote _frame.PaddleRemoteSpeed = lastRemote.PaddleRemoteSpeed; _frame.PaddleRemotePosition = lastRemote.PaddleRemotePosition; _frame.PaddleRemotePosition += lastRemote.PaddleRemoteSpeed * bufferedDeltaTime; var leftPaddleRemoteBound = _frame.PaddleRemotePosition - _frame.PaddleRemoteReflectorHalfSize; var rightPaddleRemoteBound = _frame.PaddleRemotePosition + _frame.PaddleRemoteReflectorHalfSize; // limit _frame.PaddleRemotePosition = leftBound > leftPaddleRemoteBound ? leftBound + _frame.PaddleRemoteReflectorHalfSize : Frame.PaddleRemotePosition; _frame.PaddleRemotePosition = rightBound < rightPaddleRemoteBound ? rightBound - _frame.PaddleRemoteReflectorHalfSize : Frame.PaddleRemotePosition; // update ball var ballSpeed = new Vector2(Frame.BallSpeedX, Frame.BallSpeedY); var ballPosition = new Vector2(Frame.BallPositionX, Frame.BallPositionY); // debug if (simDeltaTime < bufferedDeltaTime) { ((Vector3)ballPosition * Composition.ModelScaleFactor).DebugDrawPoint(Color.yellow, .01f, 20f); } // - init bounce calc buffers _bouncedTotal = 0; _bounced = _bounced ?? new IObstacle[_bouncers.Length]; _frameBallTrail = _frameBallTrail ?? new DataBallState[_bouncers.Length + 1]; _frameBallTrail[_bouncedTotal] = new DataBallState { Position = ballPosition, Speed = ballSpeed, DeltaTime = simDeltaTime, }; // - calc bounce for (var index = 0; index < _bouncers.Length; index++) { // exclude obstacle been bounced var indexBounced = 0; for (; indexBounced < _bouncedTotal; indexBounced++) { if (ReferenceEquals(_bouncers[index], _bounced[indexBounced])) { break; } } if (indexBounced != _bouncedTotal) { continue; } // check bounce (default should the last one) if (_bouncers[index].Bounce(_frameBallTrail[_bouncedTotal], ref _frameBallTrail[_bouncedTotal + 1])) { _bounced[_bouncedTotal] = _bouncers[index]; index = 0; _bouncedTotal++; } } // - calc out, with default move //for(var index = 0; index < _finishers.Length; index++) //{ // if(_finishers[index].Bounce(_frameBallTrail[indexTrail], ref _frameBallTrail[indexTrail + 1])) // { // indexTrail++; // } //} _frame.BallPositionX = _frameBallTrail[_bouncedTotal].Position.x; _frame.BallPositionY = _frameBallTrail[_bouncedTotal].Position.y; _frame.BallSpeedX = _frameBallTrail[_bouncedTotal].Speed.x; _frame.BallSpeedY = _frameBallTrail[_bouncedTotal].Speed.y; //_phase = // _phase ?? // new ControllerSimPhase( // _frame, // _frameBallTrail[_bouncedTotal], // _bouncers); //if(!_phase.ApplyCorrection(ref _frame)) //{ // _phase = new ControllerSimPhase( // _frame, // _frameBallTrail[_bouncedTotal], // _bouncers); //} }
public bool Cross(DataBallState comeFrom, ref DataBallState resultBounce) { return(Bounce(comeFrom, ref resultBounce)); }