0

ゲーム AI スクリプトを実行するためのファイバー システムを実装していますが、小さな問題が発生しました。

スクリプトで x フレームの待機を示すために yield return x を使用しています。他のイベントが待機するフレーム数を変更できるため、x フレームを計算するロジックをカプセル化したかったのです。私の理想的な解決策は、次のようなものです。

public Boolean removeScript = false;

public IEnumerable update()
{
    while(true)
    {
        shootAtPlayer()
        wait(30)
    }
}

private IEnumerable wait(int x)
{
    yield return removeScript ? -1 : x;
}

wait() は、return 30 を生成するように指示するか、スクリプトが不要になった場合は -1 を返します。イテレータは、スクリプトを削除して -1 の戻り値を処理します。x > 0 の場合、イテレータはフレームごとに return を 0 になるまでデクリメントし、update() を再度呼び出します。

ただし、当然のことながら、wait() からの yield 戻り値は update メソッドに伝達されないため、これは機能しません。これにより、コードが重複し、モジュール性が低下し、コードが読みにくくなります。

public IEnumerable update()
{
    while(true)
    {
        shootAtPlayer()
        yield return removeScript ? -1 : x;
    }
}

これを構造化するためのより良い方法があるかどうか疑問に思っていましたか? または、この場合に役立つ、欠けている言語機能はありますか?

4

1 に答える 1

1

この特定のケースでは、解決策は比較的単純です。Wait()整数のみを返すようにします。

public IEnumerable Update()
{
    while (true)
    {
        ShootAtPlayer();
        yield return Wait(30);
    }
}

private int Wait(int x)
{
    return removeScript ? -1 : x;
}

より複雑なケースでは、 を使用できますがforeach、これにより構文がより冗長になります。

public IEnumerable Update()
{
    while (true)
    {
        ShootAtPlayer();

        foreach (var x in Wait(30))
            yield return x;
    }
}

private IEnumerable Wait(int x)
{
    yield return removeScript ? -1 : x;
}

yield returnご覧のとおり、ファイバーを実装するために(ab) 使用できますがyield return、これを意図したものではないため、うまく機能しません。

この種の非同期継続のために作られたのは、新しいasync-awaitです。これにより、コードはたとえば次のようになります。

public async Task Update()
{
    while (true)
    {
        ShootAtPlayer();
        await Wait(30);
    }
}

private async Task Wait(int x)
{
    await fiber.Wait(removeScript ? -1 : x);
}

最後の注意として、あなたが使用している方法removeScriptは良い考えではないと思います。スクリプトの終了は、魔法の値を返すことによってではなく、Update()メソッドが実際に完了する (列挙型にそれ以上の項目がない、または完了する) ことによって示される必要があります。Task

于 2013-06-04T12:29:22.063 に答える