2

FPS ゲームにカメラの動きを実装しようとしています。ほぼ理解できたと思いますが、まだ解決しなければならない問題がいくつかあります。マウスの動きを次のように設定しました。

protected override void OnLoad(EventArgs e)
{
    Mouse.Move += OnMouseMove;
}

void OnMouseMove(object sender, MouseMoveEventArgs e)
{
    _lookDir.X += e.XDelta * _mouseSensitivity;
    _lookDir.Y -= e.YDelta * _mouseSensitivity;
}

マウスが実際にウィンドウ内にあるときはかなりうまくいくようですが、ウィンドウを離れるとすぐに機能しません。私がしなければならないことは、マウスがウィンドウの外側にあるときにマウスの動きをトリガーしたとしても、デスクトップの境界で同じ問題が発生するため、マウスをウィンドウの内側に制限することだと思います代わりにコーディネートします。

では...どうすればよいでしょうか?マウスをウィンドウ内に固定しますか? 基本的に、マウスの位置を中央に設定し続けるだけですか? もしそうなら...どうすればマウスの位置を設定できますか? 私は Windows を使用していますが、OpenTK が提供する場合は非ネイティブ ソリューションを使用したいと考えています。

4

3 に答える 3

2

私が行った 1 つの実践、および使用された古い Quake ゲーム (および半減期 1) は、すべてのフレームでカーソル位置を画面の中央にリセットし、画面の中央からのデルタを計算することです。

EDIT:カーソルを移動するには、 Cursor.Positionをチェックしてください

于 2012-02-12T00:55:38.023 に答える
1

これは今の私の解決策です...ただし、Windowsに固有です。

protected void ResetCursorPosition()
{
    Cursor.Position = WindowCenter;
    _lastMousePos = Cursor.Position;
}

protected void LockMouse()
{
    _lockMouse = true;
    _origCursorPosition = Cursor.Position;
    CursorVisible = false;
    ResetCursorPosition();
}

protected void UnlockMouse()
{
    _lockMouse = false;
    CursorVisible = true;
    Cursor.Position = _origCursorPosition;
}

void OnMouseDown(object sender, MouseButtonEventArgs e)
{
    if (!_lockMouse) LockMouse();
}

void OnKeyDown(object sender, KeyboardKeyEventArgs e)
{
    if(e.Key == Key.Escape)
    {
        if (_lockMouse) UnlockMouse();
        else Exit();
    }
}

protected override void OnUpdateFrame(FrameEventArgs e)
{
    Title = string.Format("{0} - {1:0.0} FPS", _windowTitle, RenderFrequency);

    float moveSpeed = Keyboard[RunKey] ? 0.9f : 0.4f;

    if (Keyboard[MoveForwardKey])
    {
        _pos.X += (float)Math.Cos(_lookDir.X) * moveSpeed;
        _pos.Z += (float)Math.Sin(_lookDir.X) * moveSpeed;
    }

    if (Keyboard[StrafeLeftKey]) // FIXME: holding W + A gives extra speed (also, perhaps strafing should be slower?)
    {
        _pos.X -= (float) Math.Cos(_lookDir.X + Math.PI / 2) * moveSpeed;
        _pos.Z -= (float) Math.Sin(_lookDir.X + Math.PI / 2) * moveSpeed;
    }

    if (Keyboard[StrafeRightKey])
    {
        _pos.X += (float)Math.Cos(_lookDir.X + Math.PI / 2) * moveSpeed;
        _pos.Z += (float)Math.Sin(_lookDir.X + Math.PI / 2) * moveSpeed;
    }

    if (Keyboard[MoveBackKey])
    {
        _pos.X -= (float)Math.Cos(_lookDir.X) * moveSpeed;
        _pos.Z -= (float)Math.Sin(_lookDir.X) * moveSpeed;
    }

    if(Keyboard[JumpKey])
    {
        _pos.Y += moveSpeed;
    }

    if (Keyboard[CroucKey])
    {
        _pos.Y -= moveSpeed;
    }

    if (_lockMouse)
    {
        var mouseDelta = Cursor.Position - new Size(_lastMousePos);
        if (mouseDelta != Point.Empty)
        {
            _lookDir.X += mouseDelta.X * _mouseSensitivity;
            _lookDir.Y -= mouseDelta.Y * _mouseSensitivity;
            ResetCursorPosition();
        }
    }

    var target = _pos + new Vector3((float)Math.Cos(_lookDir.X), (float)Math.Sin(_lookDir.Y / 2), (float)Math.Sin(_lookDir.X));
    _viewMat = Matrix4.LookAt(_pos, target, _up);
    _projUniform.Mat4(_viewMat * _projMat);
}
于 2012-02-12T19:50:15.830 に答える