按照鼠标光标的WPF Snake游戏

时间:2017-02-11 11:30:59

标签: c# wpf game-physics

我正在尝试创建一个简单的蛇游戏,其中蛇跟随鼠标。我的蛇体必须是polyline。我的问题是,当我移动鼠标太快或太慢时,我的蛇的身体变得越来越短,我知道这是因为我正在用鼠标坐标添加新点,之后我我连线问题发生了。但我想不出任何更聪明的解决方案。

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 个答案:

答案 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;
}