シューティングゲームを作るに当たって、何をして、何を作ればいいのでしょうか。
上記画像は下記サイトで公開されている素材を本プロジェクトのスタッフが改造して作ったものです。
一般的なシューティングゲームでは、ゲームを遊ぶ人、すなわちプレイヤーが自機を操作して、敵を倒すというものです。
自機を操作するというのは、プレイヤーがボタンを押すと画面上の味方が上下左右に動いたり、弾を発射したりするというものです。 また、敵の攻撃を受けたら爆発したりします。
つまり、自機の要件は以下のようになります。
ほかにもたくさん要件はあります。 順番にその要件を確認しながら、自機と敵を作ってみましょう。
チュートリアルで用意したサンプルのコピーをここでも使います。
とりあえず、自分が動かす機体のグラフィックが必要です。 ダイコンでは以下のフォーマットが使えます。
BMP, PNM (PPM/PGM/PBM), XPM, LBM, PCX, GIF, JPEG, PNG, TGA, TIFF
また、透過色を使う場合はpngかgifのように、そのファイルフォーマット自身が透過色をサポートしている必要があります。
したがって、BMPやJPEGは透過色を扱えません。(特定の色を透過色に指定することもできません。)
(*BMPでも適切なフォーマットで保存すれば透過色を扱えるようです。)
( 自機 32x32 png )
上の画像ファイルをダウンロードしてsampleディレクトリに入れてください。 それから、sample.xmlを以下のように書き直します。 「ここから」〜「ここまで」のところが前回のチュートリアルから新しく書き加えた部分です。
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="sample.xsl"?> <!-- ダイコン: STGスクリプトインタープリタ サンプルスクリプト このスクリプトは画面にロゴを表示します。 --> <シューティング> <ウィンドウ 名前="メインウィンドウ"> <幅>320</幅> <高さ>240</高さ> </ウィンドウ> <場面> <背景><画像>logo.jpg</画像></背景> <ラベル> <文字>はろーわーるど!</文字> <横位置>100</横位置> <縦位置>100</縦位置> <色><赤>10</赤><緑>168</緑><青>10</青></色> </ラベル> <!-- ここから --> <オブジェクト 名前="自機"> <画像>ownfighter.png</画像> </オブジェクト> <!-- ここまで --> </場面> </シューティング>
Windowsならdaikon-launcher.exe を起動して、さきほど書き換えたsample.xml を開いてください。 linux なら"daikon sample.xml" を実行してみてください。( daikon-launcher を起動してsample.xmlを開いても構いません。) 下図のように、左上に自機が表示されたら成功です。
自機を矢印キー(ボタン)で動かせるようにしてみましょう。 まずは、上下に動くようにしてみます。 前回書いたスクリプトの<オブジェクト>のところを以下のように書き加えてください。
<オブジェクト 名前="自機"> <画像>ownfighter.png</画像> <キー登録> <名前>上移動</名前> <キー>上</キー> <押したとき> <移動><縦推進力>-1</縦推進力></移動> </押したとき> </キー登録> <キー登録> <名前>下移動</名前> <キー>下</キー> <押したとき> <移動><縦推進力>1</縦推進力></移動> </押したとき> </キー登録> </オブジェクト>これによって、矢印キーの上下を押すと、画面の中の自機も上下に動くようになりました。 今の段階では画面から少しはみだしただけで、自機が消滅してしまいますが、その設定に関しては後述します。
上のスクリプトでは、<キー登録>によってどのキーが押されたとき(離されたとき)に、何をするのかを登録しています。 <名前>は他の登録とかぶらないようにしてください。名前がかぶると以前の登録を上書きします。
<キー>でどのキーをチェックするのか指定します。どのようなキーが指定できるのかはスクリプトリファレンスを参照してください。
<押したとき>で、キーを押したときに実行するアクションシーケンスというものを記述します。 (同様に、<離したとき>も記述できます。)
<移動><縦推進力>1</縦推進力></移動> というのは、毎フレームごとに下方向に1ずつ加速することを表しています。 もっと速く動きたい場合はこの数値を増やしてみるといいでしょう。 <縦推進力>と<横推進力>を同時に指定することで斜めに動くこともできます。
さて、左右にも動けるようにしてみましょう。 <オブジェクト>を以下のように文を書き足してください。
<オブジェクト 名前="自機"> <!-- 省略 --> <キー登録> <名前>右移動</名前> <キー>右</キー> <押したとき> <移動><横推進力>1</横推進力></移動> </押したとき> </キー登録> <キー登録> <名前>左移動</名前> <キー>左</キー> <押したとき> <移動><横推進力>-1</横推進力></移動> </押したとき> </キー登録> </オブジェクト>
さっそくスクリプトを起動してみましょう。 自機が上下左右に動いたら成功です。
上の例で自機は矢印キーで画面の中を自由自在に動くことができますが、 画面の外に出たら最後、二度と戻って来ません。
自機が画面の外へ飛び出してもまた画面の中に戻って来るようにするためには、 「活動可能エリアの拡大」と「境界線の設置」というものを行います。
自機には活動可能エリアが定められていて、そのエリアの外へ出るとシステムによって消去されます。 画面に表示されているエリアは(0, 0) - (画面の幅, 画面の高さ) の範囲です。 デフォルトの活動可能エリアもまた、(0, 0) - (画面の幅, 画面の高さ) と、表示エリアと同じになっています。
以下のコードを追加すると自機が画面の外に出てもすぐには消去されなくなります。
<オブジェクト 名前="自機"> <!-- 省略 --> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> </オブジェクト>
これにより、画面の外に出ても(-400, -400)-(画面の幅+400, 画面の高さ+400) までのエリアに居る限り、 自機は消滅しません。 ( 各境界は画面の上端、左端、下端、右端を基準に決定します。)
しかしながら、自機が自由に画面の外に出てしまってはゲームになりません。 最悪どこに居るのかわからなくなって、画面の中に戻れなくなることも考えられます。 そこで、境界線を設置して、自機が画面の中から飛び出さないようにします。
この境界線というのは一般的なシューティングでいうところの「障害物」のような取扱いになります。 つまり「当たり判定」をきっちり行う必要があるので、 まずは以下のスクリプトを追加して、自機の当たり判定を設定します。
<オブジェクト 名前="自機"> <!-- 省略 --> <種類>自機</種類> <幅>32</幅> <高さ>32</高さ> </オブジェクト>
次に、以下のスクリプトで場面に境界線を追加します。
<シューティング> <場面> <オブジェクト 名前="自機"> <!-- 省略 --> </オブジェクト> <境界線 名前="上の境界線"> <横位置>-1000</横位置> <縦位置>-1000</縦位置> <幅>2320</幅> <高さ>1000</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <境界線 名前="下の境界線"> <横位置>-1000</横位置> <縦位置>240</縦位置> <幅>2320</幅> <高さ>1000</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <境界線 名前="左の境界線"> <横位置>-1000</横位置> <縦位置>-1000</縦位置> <幅>1000</幅> <高さ>2240</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <境界線 名前="右の境界線"> <横位置>320</横位置> <縦位置>-1000</縦位置> <幅>1000</幅> <高さ>2240</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <場面> </シューティング>
これでスクリプトを起動すると、自機を画面の外に出そうとしても出れなくなっているはずです。 ( 実際にはスポンジにめりこもうとしているような感触です。)
また、境界線の「弾性」の数値を大きくすると、境界線が硬くなります。 大きくしすぎると、境界線に触れただけで自機が跳ね飛ばされるようになります。 ( 自機の移動速度がとてつもなく速いと、この境界線を突き抜けてしまう可能性があるので、適切な「大きさ」と「弾性」を指定するようにしてください。)
(捕捉: <種類>には自機/敵/地形/自機弾/敵弾/地形弾/すりぬけ/自機専用地形/敵専用地形 のいずれかを設定することができます。 )
まだまだ自機に設定することはあるかもしれませんが、次は敵を作ってみます。
自機と同じように、敵にもグラフィックが必要です。
上の画像もsampleダウンロードしてサンプルフォルダに入れてください。
スクリプトは自機と同じものがほとんどそのまま使えます。 以下のスクリプトを追加してください。
<シューティング> <場面> <オブジェクト 名前="自機"> <!-- 省略 --> </オブジェクト> <!-- 省略 --> <オブジェクト 名前="敵"> <画像>enemyfighter.png</画像> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> <種類>敵</種類> <幅>32</幅> <高さ>32</高さ> <横位置>250</横位置> <縦位置>150</縦位置> </オブジェクト> <場面> </シューティング>
自機と違う点は以下の三点です。
( 考えようによっては、二人で協力プレイとか、二人対戦プレイなどもできるかもしれません。)
実際にスクリプトを起動してみると、以下の図のようになります。
ちなみに、実際に敵に体当りしてみると、お互いに反動で跳ね飛ばされます。
シューティングゲームでは敵とのぶつかりあい(または撃ち合い)で、お互いのライフを削ります。 そして、最終的にライフが0になったら爆発するのが基本です。 「どきゃーん!!!」という効果音とともに、火花が飛び散ります。
まず自機と敵はどれだけライフがあって、ぶつかり合うことで相手にどれだけのダメージを与えるのかを決める必要があります。 そのためには<ライフ>タグと<ダメージ量>タグを使います。 とりあえず、自機のライフを3、ぶつかったときに相手に与えるダメージ量を1とするので、自機オブジェクトに以下の文を 書き加えてください。
</オブジェクト 名前="自機"> <!-- 省略 --> <ライフ>3</ライフ> <ダメージ量>1</ダメージ量> </オブジェクト>
これで設定完了です。 次に敵のライフとダメージ量を設定します。
</オブジェクト 名前="敵"> <!-- 省略 --> <ライフ>2</ライフ> <ダメージ量>1</ダメージ量> </オブジェクト>
ダイコンでは、「破壊されたら『爆発オブジェクト』を発射する」という方法で爆発を表現します。 そのためにまず、爆発オブジェクトを作ります。
爆発オブジェクトは爆音を鳴らしながら、爆発のアニメーションを表示します。
以下の画像と音をダウンロードしてsampleフォルダに入れてください。
( ダイコンでアニメーションをするときは、このようにコマを横に並べます。 )
以下のように、<場面>の外に爆発オブジェクトを定義します。 以下の文章を書き加えてください。
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="sample.xsl"?> <!-- 省略 --> <シューティング> <ウィンドウ 名前="メインウィンドウ"> <幅>320</幅> <高さ>240</高さ> </ウィンドウ> <!-- ***** ここから書き加える *****--> <オブジェクト 名前="爆発"> <画像>bomb.png</画像> <種類>すりぬけ</種類> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> <コマ幅>96</コマ幅> <コマ高>96</コマ高> <コマ間隔>4</コマ間隔> <横表示位置>-48</横表示位置> <縦表示位置>-48</縦表示位置> <アクションシーケンス> <効果音><ファイル>bomb.ogg</ファイル></効果音> <停止>32</停止> <自滅/> </アクションシーケンス> </オブジェクト> <!-- ***** ここまで *****--> <場面> <!-- 省略 --> <オブジェクト 名前="自機"> <!-- 省略 --> </オブジェクト> <オブジェクト 名前="敵"> <!-- 省略 --> </オブジェクト> </場面> </シューティング>
上のスクリプトでは、<コマ幅>、<コマ高>でアニメーションするコマの大きさを指定します。 そして、<コマ間隔>によって何フレームごとに次のコマを表示するのかを指定します。
<種類>で「すりぬけ」を指定することによって、自機や敵とぶつからないようにしています。
<縦表示位置>、<横表示位置>を指定することで表示する画像の位置をオブジェクトの座標からずらすことができます。
<アクションシーケンス>では毎フレームごとに実行するコマンドを記述します。 上の例では効果音を鳴らした後、32フレーム停止してから自滅するようにプログラムしています。
それでは、以下のスクリプトを追加して、自機と敵がライフ0になれば爆発するようにします。
<オブジェクト 名前="自機"> <!-- 省略 --> <被破壊リアクション> <発射> <オブジェクト名>爆発</オブジェクト名> </発射> </被破壊リアクション> </オブジェクト> <オブジェクト 名前="敵"> <!-- 省略 --> <被破壊リアクション> <発射> <オブジェクト名>爆発</オブジェクト名> </発射> </被破壊リアクション> </オブジェクト>
<被破壊リアクション>はライフが0になったときに実行されるコマンドです。 ただし、実際には1フレーム分しか実行されません。 ( つまり、3フレーム停止してから、発射するなどということはできません。)
実際にスクリプトを起動してみて、敵と衝突したときに敵が爆発すれば成功です。 ( 2回衝突しなければいけないと思った方もいらっしゃるかもしれませんが、ダメージ量による設定では、 接触している間は毎フレームごとにダメージを与えます。2フレーム接触しただけで相手が爆発するので 1回しか衝突していないように見えます。)
体当りだけで敵を倒すゲームも無いわけではありませんが、シューティングゲームなので弾を撃ってみたいと思います。 弾を撃つためには、 - 弾のオブジェクトを作る - キーが押されたら、自機から弾を発射するようにする
の2工程が必要です。
作業を簡略化するため、弾には自機のグラフィックを流用します。 以下のようにスクリプトを書き加えてください。
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="sample.xsl"?> <!-- 省略 --> <シューティング> <ウィンドウ 名前="メインウィンドウ"> <幅>320</幅> <高さ>240</高さ> </ウィンドウ> <オブジェクト 名前="自機の弾"> <画像>ownfighter.png</画像> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> <種類>自機弾</種類> <幅>32</幅> <高さ>32</高さ> <ダメージ量>1</ダメージ量> <アクションシーケンス> <進路維持>100000</進路維持> </アクションシーケンス> </オブジェクト> <場面> <!-- 省略 --> </場面> </シューティング>
ダイコンの世界では、各オブジェクトは「減衰率」というものを持っており、 何もしなければその場に停止しようとする力が働きます。 ( 実際には毎フレームの終わりにオブジェクトの速度を減衰率で除算します。 ) <進路維持>は、そういった力を無視して、指定したフレーム数の間、速度を維持し続けます。
次は「スペース」を押したら弾を発射するようにキーを登録します。 以下のスクリプトを追加してください。
<オブジェクト 名前="自機"> <!-- 省略 --> <キー登録> <名前>弾を撃つ</名前> <キー>スペース</キー> <押したとき> <発射> <オブジェクト名>自機の弾</オブジェクト名> <縦位置>-16</縦位置> <横初速度>2</横初速度> </発射> <停止>10</停止> </押したとき> </オブジェクト>
これで、自機はスペースを押すことで、弾を発射できるようになりました。
オブジェクトの座標は画像の左上になります。 発射されるオブジェクトの基準座標は発射するオブジェクトの中心です。 そのまま発射すると、弾が自機から半分下にずれた状態で発射されます。 これを修正するために、縦位置で上に16ドットずらしています。
敵をもっと増やしてみましょう。 今回は新しい概念「継承」を使います。
以下のスクリプトを追加してください。
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="sample.xsl"?> <!-- 省略 --> <シューティング> <ウィンドウ 名前="メインウィンドウ"> <幅>320</幅> <高さ>240</高さ> </ウィンドウ> <!-- 省略 --> <場面> <!-- 省略 --> <オブジェクト 継承="敵"> <横位置>150</横位置> <縦位置>50</縦位置> </オブジェクト> </場面> </シューティング>
実行すると、もう一機の敵が登場します。 この継承によって、"敵"という名前のオブジェクトの設定をそのままコピーすることができます。 上の例では"敵"というオブジェクトをコピーした上で、登場位置を上書きしています。 こうすることによって、同じことを何度もコピーする手間が省けます。
次は、時間差をつけてもう9機くらい登場させてみましょう。 下のスクリプトを追加してください。
<!-- 省略 --> <場面> <!-- 省略 --> <時間>100</時間> <オブジェクト 継承="敵"> <横位置>80</横位置> <縦位置>200</縦位置> </オブジェクト> </場面>
<時間>タグによって、100フレーム間を置いてから、 次の<オブジェクト>タグによって、もう一機敵が登場します。
これを繰り返せば、どんどん敵を配置していけるわけです。
今のままでは敵は自分から動こうとしません。 そこで、自機を追尾するようにしてみましょう。
敵オブジェクトの所に、以下のスクリプトを追加してください。
<オブジェクト 名前="敵"> <!-- 省略 --> <アクションシーケンス> <追尾> <種類>自機</種類> <速度>0.2</速度> <時間>10</時間> </追尾> <進路維持>150</進路維持> <停止>10</停止> </アクションシーケンス> </オブジェクト>
これを起動するといきなり敵が自機を襲うようになります。 実際にスクリプトを動かしてみて確認してください。 <追尾>では、10フレームの間、毎フレームごとに0.2ずつ加速しながら10フレーム自機に向けて加速します。 ( FCSみたいに、追尾対象の動きを予測するなんてスマートなことはできません。)
アクションシーケンスでは他にもいくつかコマンドがあります。 詳しくは[スクリプトリファレンス」を参照してください。
チュートリアル/自機と敵を作るは以上でおしまいです。 最後に、スクリプトの完成形を載せておきますので、必要であれば参考にしてください。
<?xml version="1.0" encoding="utf-8"?> <?xml-stylesheet type="text/xsl" href="sample.xsl"?> <!-- ダイコン: STGスクリプトインタープリタ サンプルスクリプト このスクリプトは画面にロゴを表示します。 --> <シューティング> <ウィンドウ 名前="メインウィンドウ"> <幅>320</幅> <高さ>240</高さ> </ウィンドウ> <オブジェクト 名前="自機の弾"> <画像>ownfighter.png</画像> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> <種類>自機弾</種類> <幅>32</幅> <高さ>32</高さ> <ダメージ量>1</ダメージ量> <アクションシーケンス> <進路維持>100000</進路維持> </アクションシーケンス> </オブジェクト> <オブジェクト 名前="爆発"> <画像>bomb.png</画像> <種類>すりぬけ</種類> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> <コマ幅>96</コマ幅> <コマ高>96</コマ高> <コマ間隔>4</コマ間隔> <横表示位置>-48</横表示位置> <縦表示位置>-48</縦表示位置> <アクションシーケンス> <効果音><ファイル>bomb.ogg</ファイル></効果音> <停止>32</停止> <自滅/> </アクションシーケンス> </オブジェクト> <場面> <背景><画像>logo.jpg</画像></背景> <ラベル> <文字>はろーわーるど!</文字> <横位置>100</横位置> <縦位置>100</縦位置> <色><赤>10</赤><緑>168</緑><青>10</青></色> </ラベル> <オブジェクト 名前="自機"> <画像>ownfighter.png</画像> <キー登録> <名前>上移動</名前> <キー>上</キー> <押したとき> <移動><縦推進力>-1</縦推進力></移動> </押したとき> </キー登録> <キー登録> <名前>下移動</名前> <キー>下</キー> <押したとき> <移動><縦推進力>1</縦推進力></移動> </押したとき> </キー登録> <キー登録> <名前>右移動</名前> <キー>右</キー> <押したとき> <移動><横推進力>1</横推進力></移動> </押したとき> </キー登録> <キー登録> <名前>左移動</名前> <キー>左</キー> <押したとき> <移動><横推進力>-1</横推進力></移動> </押したとき> </キー登録> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> <種類>自機</種類> <幅>32</幅> <高さ>32</高さ> <ダメージ量>1</ダメージ量> <ライフ>3</ライフ> <被破壊リアクション> <発射> <オブジェクト名>爆発</オブジェクト名> </発射> </被破壊リアクション> <キー登録> <名前>弾を撃つ</名前> <キー>スペース</キー> <押したとき> <発射> <オブジェクト名>自機の弾</オブジェクト名> <縦位置>-16</縦位置> <横初速度>2</横初速度> </発射> <停止>10</停止> </押したとき> </キー登録> </オブジェクト> <境界線 名前="上の境界線"> <横位置>-1000</横位置> <縦位置>-1000</縦位置> <幅>2320</幅> <高さ>1000</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <境界線 名前="下の境界線"> <横位置>-1000</横位置> <縦位置>240</縦位置> <幅>2320</幅> <高さ>1000</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <境界線 名前="左の境界線"> <横位置>-1000</横位置> <縦位置>-1000</縦位置> <幅>1000</幅> <高さ>2240</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <境界線 名前="右の境界線"> <横位置>320</横位置> <縦位置>-1000</縦位置> <幅>1000</幅> <高さ>2240</高さ> <種類>自機専用地形</種類> <弾性>1</弾性> </境界線> <オブジェクト 名前="敵"> <画像>enemyfighter.png</画像> <上境界>-400</上境界> <左境界>-400</左境界> <下境界>400</下境界> <右境界>400</右境界> <種類>敵</種類> <幅>32</幅> <高さ>32</高さ> <横位置>250</横位置> <縦位置>150</縦位置> <被破壊リアクション> <発射> <オブジェクト名>爆発</オブジェクト名> </発射> </被破壊リアクション> <ライフ>2</ライフ> <ダメージ量>1</ダメージ量> <アクションシーケンス> <追尾> <種類>自機</種類> <速度>0.2</速度> <時間>10</時間> </追尾> <進路維持>150</進路維持> <停止>10</停止> </アクションシーケンス> </オブジェクト> <オブジェクト 継承="敵"> <横位置>150</横位置> <縦位置>50</縦位置> </オブジェクト> <時間>100</時間> <!-- 1機目 --> <オブジェクト 継承="敵"> <横位置>80</横位置> <縦位置>200</縦位置> </オブジェクト> <時間>100</時間> <!-- 2機目 --> <オブジェクト 継承="敵"> <横位置>10</横位置> <縦位置>100</縦位置> </オブジェクト> <時間>100</時間> <!-- 3機目 --> <オブジェクト 継承="敵"> <横位置>280</横位置> <縦位置>150</縦位置> </オブジェクト> <時間>100</時間> <!-- 4機目 --> <オブジェクト 継承="敵"> <横位置>160</横位置> <縦位置>120</縦位置> </オブジェクト> <時間>100</時間> <!-- 5機目 --> <オブジェクト 継承="敵"> <横位置>300</横位置> <縦位置>220</縦位置> </オブジェクト> <時間>100</時間> <!-- 6機目 --> <オブジェクト 継承="敵"> <横位置>80</横位置> <縦位置>180</縦位置> </オブジェクト> <時間>100</時間> <!-- 7機目 --> <オブジェクト 継承="敵"> <横位置>280</横位置> <縦位置>20</縦位置> </オブジェクト> <時間>100</時間> <!-- 8機目 --> <オブジェクト 継承="敵"> <横位置>30</横位置> <縦位置>10</縦位置> </オブジェクト> <時間>100</時間> <!-- 9機目 --> <オブジェクト 継承="敵"> <横位置>180</横位置> <縦位置>100</縦位置> </オブジェクト> </場面> </シューティング>
[PageInfo]
LastUpdate: 2009-02-24 15:17:29, ModifiedBy: karasimiso
[Permissions]
view:all, edit:members, delete/config:members