2.2 パターンの描画方法
ゲームに登場するキャラクタなどの描画方法です。と言っても、コツコツとセルに色を塗る作業ではありませんし、画面上に描画するための特別な方法でもないです。

ワークシート上へゲームに登場するキャラクタを描画するには、あらかじめワークシート上に作っておいた画をコピーして、ワークシート上の好きな場所へ貼付け、早い話がコピペするのです。

なんか期待はずれ…と思った方、世の中そんなもんです(笑)
???.Copy Destination:= でコピペするのが最適
セルのコピー・貼り付けは、???.Copy??? PasteSpecialの2つのメソッドを使って行う高機能コピペ(*1)と、???.Copy Destination:=で行う高速コピペ(*2)があります。

前者は高機能だけどとにかく遅いというメリット・デメリットがあり、後者は高速だけど罫線だけコピーなどの器用な技ができないというというメリット・デメリットがありますが、
シューティングゲームやアクションゲームは何よりもスピードが重視なので、迷わずに後者の???.Copy Destination:=を使います。

'記述例
Range(コピー元).Copy Destination:= Range(貼り付け先)

なお、詳しくはエクセルマクロTips5.7 セルの高速コピー(切取り)貼り付けをどうぞ。

*1:エクセルマクロTips5.5 セルのコピーと貼り付け参照
*2:エクセルマクロTips5.7 セルの高速コピー(切取り)貼り付け参照
コピー元と貼り付け先の指定は数値で
範囲指定は通常、Range("A1:H8")などのように指定することが多いと思いますが、ゲームプログラミングではストレートに行番号や列番号で指定するほうが使いやすいのでCells(R,C)を使って行います。ちなみに、Rの部分が行番号、Cの部分が列番号です。

例えば、R1C1からR16C16の範囲を、R32C32からR47C47の範囲へコピペする場合(右図参照)は次の通りです。

'R1C1〜R16C16をR32C32〜R47C47へコピペする
Range(Cells(1,1),Cells(16,16)).Copy _
    Destination:= Range(Cells(32,32),Cells(47,47))

ちなみに、コピー元と貼付け先の範囲の大きさ(縦横のセル数)は同じ大きさにしてください。それと、RangeCellsを使った範囲指定の方法はエクセルマクロTipsの「5.1 セルや行列を扱うための基本/セルの範囲を指定する場合」もどうぞ。
違いを比べてみよう
というわけで、どれぐらい違うのかを実際に比較してみます。エクセルマクロTips11.6 単純なコピペはDestination:=でにも似たようなネタがあるが気にしちゃいけない(笑)

まずは遅い方(???.Copy??? PasteSpecial)で実験です。次の処理では、「2.1 ワークシートをゲーム画面にする」で描いた怪獣を別な場所へ1000回コピペしています。

実行する場合は、いったんVisual Basic Editorを閉じ「ツール→マクロ→マクロ実行」(またはALT+F8)から実行してください。Visual Basic Editorを表示したままだと、なぜか少し遅くなります。それと、実験はワークシートの表示倍率を10%で行っています。

Sub prcSlowCopyPaste()

    '遅い例

    Dim i As Long

    Debug.Print "START=" & Time

    'R1C1〜R16C16の範囲をR1C21〜R16C26へ
    'CopyとPasteSpecialを使い1000回貼付けます
    For i = 1 To 1000
        Range(Cells(1, 1), Cells(16, 16)).Copy
        Range(Cells(1, 21), Cells(16, 36)).PasteSpecial
    Next

    Debug.Print "END =" & Time

End Sub
 ※このエクセルマクロはワークシート内へ記述するマクロです

処理終了時に、イミディエイトウィンドウ(デバッグウィンドウ)に経過時間を表示しています。何秒かかったでしょうか。オレのPC(Duron 950馬力)では平均で25秒前後でした。しかも、この方法だとコピー元や貼り付け先が選択されてしまい目障りですね。


次に、速い方(???.Copy Destination:=)での実験です。次の処理では、同じく1000回コピペします。違う部分はコピペを行う部分です。

Sub prcFastCopyPaste()

    '速い例

    Dim i As Long

    Debug.Print "START=" & Time

    'R1C1〜R16C16の範囲をR1C21〜R16C26へ
    'Destination:=を使い1000回貼付けます
    For i = 1 To 1000
        Range(Cells(1, 1), Cells(16, 16)).Copy _
            Destination:=Range(Cells(1, 21), Cells(16, 36))
    Next

    Debug.Print "END =" & Time

End Sub
 ※このエクセルマクロはワークシート内へ記述するマクロです

どうでしょう?遅い方では平均で約25秒前後でしたが、速いほうでは平均で約4前後(全てオレのPCでの実測値)でした。遅い方では、1秒間に約40回しかコピペできなかったのが、速いほうでは約250回もコピペできました。しかも、コピー元・先の範囲選択が表示されないのでさらにお得です!

ちなみに、ゲームは速さが求められるからこの方法を使う…と言いましたが、通常のビジネスアプリケーションでもこの方法はお得かも(笑)
でも、やはり限界が…
コピーの速度が3倍ぐらいになっても、大量にコピペしたり、大きな範囲をコピペしたりすると、処理にはそれなりの時間がかかります。つまり、どうあがいても遅いです。

たとえば、上の実験では1秒間に約250回コピーできました。でも、たったの250回です。ゲームでは、短い時間の間に何かと衝突した、自機のビームが発射、得点表示、ボタンが押されたなど様々な処理が入るので、実際は250回よりさらに下回ります。極端な話、はワークシートとVBAだけを使う方法で大量のキャラクタが高速で動き回るようなゲームはムリです。

そんなわけで、ゲームの内容や種類は限定されるけど工夫次第である程度はカバーできるし、何よりもゲームが面白ければそれでいいんじゃないかな(笑)
Copyright(C) 1999-2006 結城圭介。 All rights reserved