calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
<< November 2019 >>

categories

archives

シューティングゲームの当たり判定を高速化

0
    ゲームを作る上で大きな課題の一つとして「当たり判定を如何に高速化できるか」というのがあります。今回は当たり判定を配列に置き換えて高速化する、という手法を思い付いたのでやってみました。

    先ずはデモをご覧下さい。

    デモはこちら

    敵は弾が当たると白く光り、5回弾が当たると爆発するようになってます。


    よくある手法として、弾をある1つのスプライトにすべて配置し、敵一つ一つに対して、弾のスプライト(全体)とhitTestする事によって当たっているか、否かを判定する方法があります。この方法は非常に高速に当たり判定を処理できますが、どの弾と当たったか、を判定できないので、当たった球を消せない、という欠点があります。

    では、弾一つ一つと敵一つ一つをそれぞれ当たり判定しようとすると、これは膨大な量の判定を行わなければならなくなり、デモのような沢山の弾・沢山の敵が出現するシステムでは非常に重くなってしまいます。
    単純な例として、敵が100匹、弾が100発画面上にあったら、100×100=10000回の判定が毎回必要になってしまいます。

    そこで、座標を大きなマス目に置き換え、それぞれのマス目内で判定を行います。デモでは背景にマス目がありますが、これが当たり判定を行っている単位です。
    意外とマス目は大きく感じますが、当たり判定にはそれ程違和感がありません。これは弾が速いのと、「敵に弾があたる」という行為自体、判定が広くても潜在的に不満は起こらない為だと思います。(これが自機の当たり判定となると、もっとシビアにやらないと不満が出ます。)

    具体的な判定ロジックとしては、

    ・縦横の二次配列Aを用意(初期化)する。(マス目の数に合わせた配列、デモは15×15)
    ・画面に表示されている敵の座標からマス目座標を算出し(※1)、配列Aに敵(の参照)を当てていく。
    (配列位置が重複した場合も特に気にせす上書きしちゃう)
    ・画面に表示されている弾一つ一つに対し、マス目座標で配列Aに敵がいるか判定(配列A[x][y]!=undefinedかどうか)、いたら当たり処理を行う。

    この方法ですと、配列作成で15回ループ、敵を配列代入で100回ループ、弾当たり判定100回ループ、で215回のループで全ての判定が行えます(しかも実際の当たり判定処理は100回のみ)。マシンスペックによっては215回でも重いでしょうけど、10000回判定と比べると雲泥の差です。

    ※1例えばマス目の大きさが40x30で、敵の座標が(300,100)だったら、マス目座標は、(300/40, 100/30)で、(8,4)といった具合。

    コメント
    ちょくちょく来てます。
    このデモ

    やべw
    楽しい〜
    • 旅人
    • 2009/09/15 10:30 AM
    勉強になります!
    • 東京犬☆
    • 2010/05/06 12:44 PM
    少しむつかしいけど
    頑張ってみます!
    • ジョッテル
    • 2012/07/11 2:10 PM
    管理者の承認待ちコメントです。
    • -
    • 2018/04/19 1:13 AM
    コメントする








       
    この記事のトラックバックURL
    トラックバック