2017-02-11 4 views
1

Я пытаюсь создать простую игру змеи, где змея следует за мышью. Мое тело змеи должно быть polyline. И моя проблема в том, что когда я двигаю мышь слишком быстро или слишком медленно, тело моей змеи становится все длиннее/короче, и я знаю, что это происходит из-за того, что я добавляю новую точку с координатами мыши, а после этого, когда я я подключаю линии к возникновению проблемы. Но я не могу думать о каких-либо более умных решениях.WPF Snake игра, следующая за курсором мыши

public partial class MainWindow : Window 
{ 
    Point mousePos; 
    Polyline polyline; 
    public MainWindow() 
    { 
     InitializeComponent(); 

     polyline = new Polyline(); 
     polyline.Stroke = Brushes.Black; 
     polyline.StrokeThickness = 4; 

     var points = new PointCollection(); 
     for (int i = 0; i < 50; i++) 
     { 
      points.Add(new Point(i, i)); 
     } 
     polyline.Points = points; 
     canvas.Children.Add(polyline); 

    } 
    protected override void OnMouseMove(MouseEventArgs e) 
    { 
     base.OnMouseMove(e); 
     mousePos = e.GetPosition(canvas); 

     polyline.Points.Add(mousePos); 

     for (int i = 0; i < polyline.Points.Count - 1; i++) 
     { 
      polyline.Points[i] = new Point(polyline.Points[i + 1].X, polyline.Points[i + 1].Y); 
     } 

     polyline.Points.RemoveAt(0); 

    } 
} 

ответ

1

Я предлагаю эти несколько модификаций, прокомментированные в коде ниже.

Принцип заключается в том, чтобы создать новую точку, только если расстояние от мыши до последней точки достаточно велико и ограничить смещение, если расстояние далеко.

Point mousePos; 
Polyline polyline; 
double stepSize = 10; // Square size 
double stepSize2; // For precalculation (see below) 

public MainWindow() 
{ 
    InitializeComponent(); 

    polyline = new Polyline(); 
    polyline.Stroke = Brushes.Black; 
    polyline.StrokeThickness = 4; 

    polyline.Points = new PointCollection(); // Starts with an empty snake 
    canvas.Children.Add(polyline); 

    stepSize2 = stepSize * stepSize; // Precalculates the square (to avoid to repeat it each time) 
} 
protected override void OnMouseMove(MouseEventArgs e) 
{ 
    base.OnMouseMove(e); 
    var newMousePos = e.GetPosition(canvas); // Store the position to test 

    if (Dist2(newMousePos, mousePos) > stepSize2) // Check if the distance is far enough 
    { 
     var dx = newMousePos.X - mousePos.X; 
     var dy = newMousePos.Y - mousePos.Y; 

     if (Math.Abs(dx) > Math.Abs(dy)) // Test in which direction the snake is going 
      mousePos.X += Math.Sign(dx) * stepSize; 
     else 
      mousePos.Y += Math.Sign(dy) * stepSize; 

     polyline.Points.Add(mousePos); 

     if (polyline.Points.Count > 50) // Keep the snake lenght under 50 
      polyline.Points.RemoveAt(0); 
    } 
} 

double Dist2(Point p1, Point p2) // The square of the distance between two points (avoids to calculate square root) 
{ 
    var dx = p1.X - p2.X; 
    var dy = p1.Y - p2.Y; 
    return dx * dx + dy * dy; 
} 
+0

Это лучше, чем у меня. –

Смежные вопросы