// private int _lastTime; private void MainPage_Loaded(object sender, RoutedEventArgs e){ // , CompositionTarget.Rendering += _gameLoopUpdate; _lastTime = Environment.TickCount; } private void _gameLoopUpdate(object sender, EventArgs e){ int currentTime = Environment.TickCount; int frameTime = currentTime - _lastTime; _lastTime = currentTime; // }
<Grid Margin="12" Background="#FF084E0F"/> <Viewbox IsHitTestVisible="False" Margin="12"> <TextBlock TextWrapping="Wrap" Text=" " Foreground="#FF00228D" RenderTransformOrigin="0.5,0.5" Margin="10,0" Width="129" Height="16"> <TextBlock.RenderTransform> <CompositeTransform Rotation="-35"/> </TextBlock.RenderTransform> </TextBlock> </Viewbox> <Canvas x:Name="ContentPanel" Margin="12"> <TextBlock x:Name="tbInfo" Text="TextBlock" Foreground="White" FontSize="16" /> <Image x:Name="car" Width="70" Source="car.png" Height="35" /> </Canvas>
Dimensional problems with animation.
There are several problems that can arise when working with animation due to the size of animated objects:
- When the width or height dimensions are set in Auto , the change of the rotation center is not taken into account, respectively, there may be problems with the rotation animation. Set dimensions in absolute units.
- At start, ActualWidth and ActualHeight are equal to zero, because Not a single object has been drawn yet. Consider this in calculations.
// . , // , . // public sealed class KeyHandler { private bool[] isPressed = new bool[256]; private UserControl targetCanvas = null; public void ClearKeyPresses(){ for (int i = 0; i < 256; i++){ isPressed[i] = false; } } public void ClearKey(Key k){ isPressed[(int) k] = false; } public void Attach(UserControl target){ ClearKeyPresses(); targetCanvas = target; target.KeyDown += new KeyEventHandler(target_KeyDown); target.KeyUp += new KeyEventHandler(target_KeyUp); target.LostFocus += new RoutedEventHandler(target_LostFocus); } public void Detach(UserControl target){ target.KeyDown -= new KeyEventHandler(target_KeyDown); target.KeyUp -= new KeyEventHandler(target_KeyUp); target.LostFocus -= new RoutedEventHandler(target_LostFocus); ClearKeyPresses(); } private void target_KeyDown(object sender, KeyEventArgs e){ isPressed[(int) e.Key] = true; } private void target_KeyUp(object sender, KeyEventArgs e){ isPressed[(int) e.Key] = false; } private void target_LostFocus(object sender, EventArgs e){ ClearKeyPresses(); } public bool IsKeyPressed(Key k){ int v = (int) k; if (v < 0 || v > 82) return false; return isPressed[v]; } public bool IsKeyPressed(Key[] keys){ foreach (Key k in keys){ if (this.IsKeyPressed(k)) return true; } return false; } }
// private KeyHandler _keyHandler = new KeyHandler(); // private RotateTransform _rotateHelper = new RotateTransform(); // private TranslateTransform _translateTransform = new TranslateTransform(); private RotateTransform _rotateTransform = new RotateTransform();
Because Transformations animate an object relative to its starting position. Make sure that the car object (our machine) is not set to Canvas.Top and Canvas.Left .
public MainPage(){ InitializeComponent(); this.Loaded += MainPage_Loaded; // var tg = new TransformGroup(); tg.Children.Add(_rotateTransform); tg.Children.Add(_translateTransform); car.RenderTransform = tg; // _translateTransform.X = 50; _translateTransform.Y = 50; car.MouseLeftButtonDown += car_MouseLeftButtonDown; // _keyHandler.Attach(this); }
// void car_MouseLeftButtonDown(object sender, MouseButtonEventArgs e){ _speedPerSecond += 300; }
private void MainPage_Loaded(object sender, RoutedEventArgs e){ // , System.Windows.Browser.HtmlPage.Plugin.Focus(); // , CompositionTarget.Rendering += _gameLoopUpdate; _lastTime = Environment.TickCount; }
// private Point _direction = new Point(1, 0); // private double _speedPerSecond ; // / , >1 ,<1 private double _accelerationRatioPerSec = 0.60; // private int _lastTime;
private void _gameLoopUpdate(object sender, EventArgs e){ int currentTime = Environment.TickCount; int frameTime = currentTime - _lastTime; _lastTime = currentTime; // // double delta = (double)frameTime / 1000; // double xCurrentPos = _translateTransform.X; double yCurrentPos = _translateTransform.Y; double currentAngle = _rotateTransform.Angle; // double addToSpeedPerSec = 300; if (_keyHandler.IsKeyPressed(Key.Up)){ _speedPerSecond += addToSpeedPerSec*delta; } if (_keyHandler.IsKeyPressed(Key.Down)){ _speedPerSecond -= addToSpeedPerSec * delta; } // double targetAngle = currentAngle; double coefAngle = .5; if (_keyHandler.IsKeyPressed(Key.Right)){ targetAngle += _speedPerSecond * coefAngle*delta; } if (_keyHandler.IsKeyPressed(Key.Left)){ targetAngle -= _speedPerSecond * coefAngle * delta; } // _rotateHelper.CenterX = car.ActualWidth / 2; _rotateHelper.CenterY = car.ActualHeight / 2; _rotateHelper.Angle = targetAngle; // _rotateHelper.CenterX = 0; _rotateHelper.CenterY = 0; _direction = _rotateHelper.Transform(new Point(1, 0)); // _speedPerSecond += (_speedPerSecond*_accelerationRatioPerSec - _speedPerSecond)*delta; // , double stepPerFrame = _speedPerSecond * delta; // double xTargetPos = xCurrentPos + _direction.X * stepPerFrame; double yTargetPos = yCurrentPos + _direction.Y * stepPerFrame; // Rect borderRect = _rotateHelper.TransformBounds(new Rect(0, 0, car.ActualWidth, car.ActualHeight)); borderRect.X = borderRect.X + xTargetPos; borderRect.Y = borderRect.Y + yTargetPos; // if (isInContentPanel(borderRect)){ //// _translateTransform.X = xTargetPos; _translateTransform.Y = yTargetPos; _rotateTransform.Angle = targetAngle; } else{ // , _speedPerSecond = 0; } // tbInfo.Text = string.Format("Speed:{0:F1}", _speedPerSecond); } // , private bool isInContentPanel(Rect shapeBorder){ if (0 <= shapeBorder.Left && shapeBorder.Right <= ContentPanel.ActualWidth) if (0 <= shapeBorder.Top && shapeBorder.Bottom <= ContentPanel.ActualHeight) return true; return false; }
Source: https://habr.com/ru/post/125037/
All Articles