TonyuSystem動作軽量化法
プログラムの動作確認はしてないので参考程度に。
1.当たり判定を数フレームに1回に
アクション,シューティングゲーム等の当たり判定処理は通常毎フレーム行うが、
実はこれ、毎フレーム行う必要はない。
大抵の場合2,3フレームに一回で十分。
当たり判定の処理を減らすことでアクション,シューティング等、
多数のオブジェクトを使用し当たり判定を行うゲームの大幅な軽量化が見込める。
実はこれ、毎フレーム行う必要はない。
大抵の場合2,3フレームに一回で十分。
当たり判定の処理を減らすことでアクション,シューティング等、
多数のオブジェクトを使用し当たり判定を行うゲームの大幅な軽量化が見込める。
<効果>
当たり判定を2フレーム毎にすれば、当たり判定に要する処理量は1/2、
3フレーム毎にすれば、1/3となる。
<例:シューティングの当たり判定の軽量化>
Tonyu公式ページの「チュートリアル→シューティングゲーム→敵を破壊する」の最下部のプログラムを例に改良すると、//Befor while (y<$screenHeight) { y=y+2; for (t in $chars) { if ( t is Tama && crashTo(t) ) die(); } if (crashTo($myChar)) $myChar.die(); update(); }
//After while (y<$screenHeight) { y=y+2; if($frameCount%2==0){ //(←追加部分)2フレーム毎に当たり判定を行う for (t in $chars) { if ( t is Tama && crashTo(t) ) die(); } } if (crashTo($myChar)) $myChar.die(); update(); }
2.オブジェクト毎に$charsに相当する配列を作成
通常、全てのオブジェクトは、オブジェクト配列$charsのみに自動で格納・管理される。
このオブジェクト配列を必要に応じて複数作成することで
動作の軽量化が見込める場合がある。
例えばシューティングゲーム。
シューティングゲームは多くの場合、弾同士また敵同士の当たり判定は必要ない。
オブジェクト配列を複数使用することで、この判定をなくす事が可能。
このオブジェクト配列を必要に応じて複数作成することで
動作の軽量化が見込める場合がある。
例えばシューティングゲーム。
シューティングゲームは多くの場合、弾同士また敵同士の当たり判定は必要ない。
オブジェクト配列を複数使用することで、この判定をなくす事が可能。
なお、この方法を使用する際には、特定オブジェクトに対する管理を手動で行う必要がある。
特定オブジェクトに対する管理とは、
下の例で言うと、弾オブジェクト生成時に配列$tamaCharsに追加する処理、
弾オブジェクトの消滅時に配列$tamaCharsから取り除く処理である。
このような処理を行う必要があるため、上級者向けの方法である。
特定オブジェクトに対する管理とは、
下の例で言うと、弾オブジェクト生成時に配列$tamaCharsに追加する処理、
弾オブジェクトの消滅時に配列$tamaCharsから取り除く処理である。
このような処理を行う必要があるため、上級者向けの方法である。
<効果>(下の例の場合)
弾20個,機体10個の場合、全体の当たり判定の処理量(for(t in xx)ループ回数)は、
- 通常法 :10オブジェクト×(10+20)回=300回
- 軽量化法:10オブジェクト×20回 =200回
(注:弾に対する当たり判定処理を機体側で行う)
<例:シューティングの当たり判定の軽量化(1の例を流用)>
弾のオブジェクトを格納する配列($tamaCharsとする)を用意する。while (y<$screenHeight) { y=y+2; for (t in $tamaChars) { //(←変更部分)弾に対してのみ当たり判定を行う if ( crashTo(t) ) die(); } if (crashTo($myChar)) $myChar.die(); update(); }
と、ここまで書いて気付いた。これあんまり意味ないです。 弾幕系ゲームで弾同士の判定をなくせれば軽くなると思い書いたのだけど、 ここに書いた様なややこしい事しなくても、 機体側で弾に対する当たり判定処理を行えば弾同士の判定は行われません。 つまり、それだけで良い。 まあ、それに加えてここに書いたこともやれば、ある程度軽くなります。
3.メニュー表示などにパネルを使用する
RPGなどにあるメニュー。
このメニューの描画には、いくつもの文字や画像の描画処理が必要になり、
draw系関数で毎フレーム描画する方法では処理がかなり重くなる場合がある。
そこでパネルを使用する。
パネルは一度描画すれば、描画されたものは消えないため、
(パネルの上書きやパネル自体が消滅しない限り)
メニューの様に持続的に表示されるものを効率よく表示することが出来る。
うまく使えばかなりの軽量化が可能。
このメニューの描画には、いくつもの文字や画像の描画処理が必要になり、
draw系関数で毎フレーム描画する方法では処理がかなり重くなる場合がある。
そこでパネルを使用する。
パネルは一度描画すれば、描画されたものは消えないため、
(パネルの上書きやパネル自体が消滅しない限り)
メニューの様に持続的に表示されるものを効率よく表示することが出来る。
うまく使えばかなりの軽量化が可能。
<効果>
未知数
<例>//Befor menu=new Array(); menu.add("< メニュー >"); menu.add("名前:nanasi"); menu.add("Lv:1"); menu.add("HP:20"); while(1){ fillRect(0,0,120,100,$clWhite,1); for(i=0;i<menu.size();i++){ drawText(10,10+20*i,menu.get(i),$clBlack,15); } update(); }
//After menu=new Array(); //(略) resize(120,100); panel.fillRect(0,0,getWidth(),getHeight(),$clWhite); for(i=0;i<menu.size();i++){ panel.drawText(10,10+20*i,menu.get(i),$clBlack,15); } wait(); //dieしない様に止めておく