public override void UpdateFrame() { var keyboardState = WindowContext.Current.Window.KeyboardState; if (keyboardState.IsKeyDown(Key.R)) { Reset(); } if (StartMovement) { var speed = Speed; if (keyboardState[Key.ControlLeft]) { speed = speed * 0.1f; } var delta = (float)Application.Current.UpdateCounter.Elapsed.TotalMilliseconds / 1000.0f; var movement = direction * speed * delta; var updatedPosition = gfx.RelativeTranslation + new Vector3(movement.X, movement.Y, 0); var collision = false; var ballRadius = gfx.RelativeScale.X / 2; if (updatedPosition.X + ballRadius > WorldSize.X / 2 || updatedPosition.X - ballRadius < -WorldSize.X / 2) { Reset(); return; } if (updatedPosition.Y + ballRadius > WorldSize.Y / 2 || updatedPosition.Y - ballRadius < -WorldSize.Y / 2) { direction.Y = -direction.Y; collision = true; } bool firstPlayCollision = FirstPlayer.CollidesWithBall(updatedPosition.Xy, ballRadius); bool secondPlayerCollision = SecondPlayer.CollidesWithBall(updatedPosition.Xy, ballRadius); if (firstPlayCollision || secondPlayerCollision) { if ((firstPlayCollision && direction.X < 0) || (secondPlayerCollision && direction.X > 0)) { var player = firstPlayCollision ? FirstPlayer : SecondPlayer; direction.X = -direction.X; collision = true; var normalizedBounds = player.Bounds; normalizedBounds.Center = Vector2.Zero; var translatedDiff = player.Bounds.Center.Y; var translatedBallPos = gfx.RelativeTranslation.Y - translatedDiff; var scaledPaddleCollisionPos = translatedBallPos / player.Bounds.HalfSize.Y; // 0..1 scaledPaddleCollisionPos *= 0.5f; var posY = AxMath.SinNorm(scaledPaddleCollisionPos / 4f); var posX = AxMath.CosNorm(scaledPaddleCollisionPos / 4f); var pos = new Vector2(posX, posY).Normalized(); var newDirX = AxMath.SetSign(pos.X, direction.X); //var newDirY = AxMath.SetSign(pos.Y, direction.Y); direction = new Vector2(newDirX, pos.Y); } } if (collision) { AudioManager.Default.PlayAsync("Audio/collision.rack.json"); } else { gfx.RelativeTranslation = updatedPosition; } } }