0

現在、Objective-C/Cocoa について詳しく学ぶためにローグライクを作成しています。今のところとても楽しんでおり、たくさんのことを学びました。

このコードはorigin、ビューのboundsを移動して、プレイヤーの動きに追従します。コードは完璧に機能します。4 つを使用するよりも良い方法があるかどうかを尋ねただけforです。

また、特に描画と関係がある場合、すべてを 1 つにまとめるよりも個別に行う方がよい場合もいくつか見てきましたが、それnsbezierpathはなぜですか?

編集: 人々は私が何をしているのかを正確に把握するのに苦労していたので、できる限り詳しく説明します.

view30x30 グリッド (0-29,0-29) のタイルで、それぞれ 20x20 です。マップは、必要に応じて大きくすることも小さくすることもできます。

まず、 の とともに を取得[player_ location]します。で割ったのは、タイルのサイズがであるからです。実際にはです。これを行う唯一の理由は、操作を簡単にするためです (20 単位ではなく 1 単位で数える方が簡単です)。4 人が通過し、が の中央 ( ) のタイル内にあることを確認します。プレーヤーが画面の端の 1 つに向かって移動していて、現在のマップの高さ/幅よりも小さい場合、プレーヤーがマップの中央に表示されるように移動します。originboundsview2020,(1,2)(20,40)for[player_ location]15bounds + 15viewbounds.x/y + 30origin

コードは完璧に動作し、が発生setboundsした後に に移動しましたがfor、1 つだけです。に残されているわけではありませdrawRectん。何をする必要があるかを理解しようとするためにここに持っていました。現在は独自の場所にあり、プレイヤーが実際に移動したときにのみ呼び出されます。

新しいコードは次のとおりです。

- (void)keepViewCentered
{
    NSPoint pl = [player_ location];
    NSPoint ll;
    NSPoint location = [self bounds].origin;
    ll.x = location.x / 20;
    ll.y = location.y / 20;
    for ( pl.y = [player_ location].y; pl.y >= ll.y + 15 && ll.y + 30 < [currentMap_ height]; ll.y++ )
    {
        location.y = ll.y * 20;
    }
    for ( pl.x = [player_ location].x; pl.x >= ll.x + 15 && ll.x + 30 < [currentMap_ width]; ll.x++ )
    {
        location.x = ll.x * 20;
    }
    for ( pl.y = [player_ location].y; pl.y <= ll.y + 15 && ll.y >= 0; ll.y-- )
    {
        location.y = ll.y * 20;
    }
    for ( pl.x = [player_ location].x; pl.x <= ll.x + 15 && ll.x >= 0; ll.x-- )
    {
        location.x = ll.x * 20;
    }
    [self setBoundsOrigin: location];
}

動作中の写真がこちら!

図 1: これは 1,1 のプレーヤーです。特にない。 http://sneakyness.com/stackoverflow/SRLbounds1.png

図 2: 3 つの金の部分は、ビューの境界より前にプレーヤーが移動できる距離を表します。原点は、プレーヤーの中心に留まるように移動します。無関係ではありますが、プレイヤーは実際に金を見ることができないことに注意してください。プログラミングの視野は多くの議論の場であり、使用できるアルゴリズムはいくつかありますが、いずれも欠点がなく、Objective-C に移植されていません。現在はただの正方形です。壁とすべてを通して見る。 http://sneakyness.com/stackoverflow/SRLbounds2.png

図 3: プレーヤーを中心に、bounds.origin が異なるビュー。 http://sneakyness.com/stackoverflow/SRLbounds3.png

4

3 に答える 3

1

ここで何をしようとしているのかはわかりませんが、非常に非効率的です。setBoundsOrigin:つまり、最後の呼び出しだけが実際に何かを行っているということです。原点を途中に設定してdrawRect:も、何も動きません。drawRect:これをアニメーションと考えている場合、 の実行全体で 1 つの「フレーム」が描画されます。

あなたは描画ループを担当していないことに注意してください。drawRect:描画が必要であると判断したときに、フレームワークによって呼び出されます。フレームワークに与えることができるさまざまなヒント ( などsetNeedsDisplay:) がありますが、最終的に何かが必要なときに呼び出すのはフレームワークです。

アニメーションが目的の場合は、Core Animation Programming Guideをお読みください。アニメーションを管理するための非常に簡単で効率的な方法について説明します。画面上でのアニメーション化は、Cocoa の大きな強みの 1 つであり、非常に複雑なことを非常に簡単に行うことができます。

于 2009-07-23T23:17:05.217 に答える
0

場合によっては…すべてを1つにまとめるのではなく、別々に行う方がよい…</ p>

はい。メソッドdrawBackgroundTile:、場合によってはdrawItem:メソッドとdrawPlayer:メソッドを用意し、これらをループ内で呼び出しますdrawRect:。これにより、レベルのボード全体が描画されます。これが非レイヤーベースのソリューションです。

もう1つは、Robの回答に対するコメントで述べたように、CoreAnimationを使用することです。次に、全体を斧drawRect:し、ビューにルートレイヤーをホストさせます。ルートレイヤーにはタイルレイヤーが含まれ、その一部にはアイテムとアクター(プレーヤー/モンスター/ペット)レイヤーが含まれます。

何故ですか?

それは適切で、効率的で、読みやすいソリューションだからです。

于 2009-07-24T01:00:13.293 に答える