アットウィキロゴ

1.ゲームの設計


大きなプログラムを作成するにあたって最初に考えなくてはならないのは、やはりどのようなゲームを作成するかです。
ゲームの設計を考えるには様々なやり方 がありますが、昔からの方法の1つとしてペンと紙による設計があります。
どのようなゲームを作成したいか既に決まっている場合は実際にペンで紙に書いてみ ましょう。

下記のメモはこのチュートリアルを作成したプログラマーがFPSゲームを作成する際に書いたメモ書きです。
大まかにでも描いてみると分かり易くなりますね。
#ref error :画像を取得できませんでした。しばらく時間を置いてから再度お試しください。


2.メディアの収集


次はゲームに必要となるメディアを準備していきましょう。
メディアとは3Dワールド、3Dモデル、サウンド、ミュージック、イメージ、画像などのゲームのメインプログラムに追加する素材ファイルのことを指します。
FPSゲームを作成するには、上記であげたメディアのほとんどが必要となります。必要となるメ ディアを自分で集めてももちろん結構です。

例えば、空の背景には天球、ゲームプレイヤーの視点には銃のモデル、また倒すべき敵には敵のモデルなどゲーム作成においてはBSP(Binary Space Partitioning)もメディアの一部であると考えられます。ゲーム中に流れる音楽の巨大ループなどもメディアの一部と考えられます。
炎のイメージを表現するのにパーティクル(粒子)を使用するなどメディアを準備することで、ゲームがより精巧になります。

ダークベーシックプロフェッショナル日本語版には、各種素材をパックにした「ダークマター」や、素材をご自身で作成できる「ゲームスペースライト」が収納されております。アイデア次第で、あなだだけの素晴らしいオリジナルなゲームを作成出来る事でしょう。


3.プログラムの骨組み


ゲームの設計が終了したら、次はゲームプログラムの骨組みについて学習していきましょう。
ほとんどのゲームの基本的な骨組みは同じで、設定ステージ(オブジェクトのロードと準備)、メインループ(ゲームロジックの実行)、クリーンアップステージ(ロードしたメディアの解放)が存在します。

DarkBasic Professionalを終了するとロード済みメディアは自動的に解放されますので、Dark Basic Professionalでゲームを作成する際には、通常、上記の3つのステージの内の最初の2つのステージについてのみ考慮すればよいでしょう。それではまず設定ステージを作成しましょう。

rem TUT3A
rem Initial settings
 sync on :sync rate 100
 backdrop off : hide mouse
rem Load all media for game
 gosub_load_game
rem Setup all objects for game
 gosub_setup_game 

次にゲーム内の要素を制御するメインループと繰り返し行う呼び出しを作成します。

rem TUT3B
rem Game loop
 do
rem Control game elements
 gosub_control_player
 gosub_control_gunandbullet
 gosub_control_enemies
rem Update screen
 sync
rem End loop
 loop 

最後に最初の2ステージで呼び出されるサブルーチンを作成していきましょう。

サブルーチンとはコードブロックのことをさし、どこからでもジャンプしてその サブタスクを実行することができます。

サブタスクとは例えばプレイヤーのロード/コントロール/削除などを行います。サブルーチンには分かり易い名前をつ けて何をするサブルーチンなのか分かるようにしましょう。

rem TUT3C
 _control_player:
 return
 _control_gunandbullet:
 return
  _control_enemies:
 return
 _control_stats:
 return
 _setup_game:
 return
 _load_game:
 return 
上記の例にも、各サブルーチンには内容が分かり易いように名前がつけてあります。現段階では、すべてのサブルーチンにコードが入っていませんが、このチュートリアルの後半で、実際にコードを入力していきましょう。


4.ワールドのロード


ゲームの設計が終了したら、次はゲームプログラムの骨組みについて学習していきましょう。ほとんどのゲームの基本的な骨組みは同じで、設定ステージ(オブ ジェクトのロードと準備)、メインループ(ゲームロジックの実行)、クリーンアップステージ(ロードしたメディアの解放)が存在します。

最初の課題は、ゲームを実行するワールドを作成することです。以前はワールドの作成は非常に複雑で、ゲーム作成者を悩ませることが多かったのですが、BSPコマンドを使用することで、ワールドの作成はとてもシンプルな作業になりました。

簡単なコマンドを実行するだけで、ポリゴン、コリジョン、テクスチャ、シェーダーエフェクト情報を含むBSPワールドをまるごとロードすることができます。

また次のコマンドで天球を作成し、ゲームを実行するワールドに空を作成することができます。

rem TUT4A
rem Load BSP world and sky model
 load bsp "world¥ikzdm1.pk3","ikzdm1.bsp"
 SkyObj=1 : load object "models\sky\am.x",SkyObj  

BSPワールドと空がロードされたら、次はカメラを設定して指定どおりに動くようにしなくてはなりません。

AutoCamが開始時に勝手に移動しないことを確認してください。

rem TUT4B
rem Setup camera
 set camera range 1,10000
 autocam off
rem Setup sky model
 set object SkyObj,1,0,0,0,0,0,0
 scale object SkyObj,20,20,20  
#ref error :画像を取得できませんでした。しばらく時間を置いてから再度お試しください。

BSPのロード中には、ユーザーにロード中であることを知らせるためのテキストを画面に表示する必要があります。

ロードするBSPワールドが大きければ、 ロードに数分かかることもありえますので、画面にこのテキストを表示させることは非常に重要になります。

使い易いゲームをユーザーに提案するためにも、テキストの表示には大きくた見やすいフォントを使用するようにしましょう。

rem TUT4C
rem Select font
 set text font "arial" : set text size 16
 set text to bold : set text transparent
rem Loading prompt
 sync : center text screen width()/2,screen height()/2,"LOADING" : sync  

コードの最初/最後にSYNCコマンドを追加することで、プログラムを初期化して、手動で画面を更新することができます。

作成したテキストを確認するには、テキストの作成後にSYNCを作成する必要があります。



5.プレイヤーの追加


ワールドをロードしたら、次にゲームのプレイヤー(キャラクター)を作成していきましょう。FPSゲームではプレイヤーの視点がカメラになることが基本です。

カメラが動くとその動きがプレイヤーの動きとなります。

rem TUT5A
Rem Trigger player initialisation
 Restart=1  

次にこの値が1に設定された際にプレイヤーをセットアップするコードを準備します。

カメラのBSPコリジョンを使用して3Dワールドのコリジョンを完全自動化することができます。
自動化はスライディングコリジョンだけではなく、早いスピードのコリジョンも可能です。
rem TUT5B
rem In case of restart
 if restart=1
 restart=0
 set bsp collision off 1
 rotate camera 0,0,0
 position camera 2,2,2
 set bsp camera collision 1,0,0.75,0
 endif  

プレイヤーのセットアップ後に制御が可能になります。はじめはプレイヤーの回転、動き、重力を準備しましょう。

rem TUT5C
rem Control player direction
 rotate camera camera angle x(0)+(mousemovey( )/2.0), camera angle y(0)+(mousemovex ( )/2.0),0
rem Conrol player movement
 cx#=camera angle x(0) : cy#=camera angle y(0)
 if upkey( )=1 then xrotate camera 0,0 : move camera 0,0.2 : xrotate camera 0, cx#
 if downkey( )=1 then xrotate camera 0,0 : move camera 0,-0.2 : xrotate camera 0, cx#
 if leftkey( )=1 then yrotate camera 0,cy#-90 : move camera 0.2 : yrotate camera 0, cy#
 if rightkey( )=1 then yrotate camera 0,cy#+90 : move camera 0.2 : yrotate camera 0, cy#
 if wrapcalue(camera angle x(0))>40 and wrapvalue(camera angle x(0))180 then xrotate camera 0,40
 if wrapvalue(camera angle x(0))>180 and wrapvalue(camera angle x(0))280 then xrotate camera 0,280
rem Apply simple gravity to player
 position camera camera position x( ), camera position y(-0.1, camera position z( )  

また、FPSゲームでは常にプレイヤーが画面の中心に位置している必要がありますので、プレイヤーの動きに合わせて空と3Dリスナーの位置を調整する必要があります。

rem TUT5D
rem Player is always focal point of sky
 position object SkyObj, camera position x( ), camera position y( ), camera position z( )
rem position object listener at player for 3D sound
 position listener camera position x( ), camera position y( ), camera position z( )
 rotate listener camera anglex( ), camera angle y( ), camera angle z( )


6.銃の追加


FPSゲームのプレイヤーが銃とその銃に入れる銃弾を持っていなければ、ゲームはすぐに終わってしまいますよね。
通常、FPSゲームの銃は画面下の部分から突き出る形で表示されることが多く、銃弾が発射される方向は画面中央に十字型の印で表示されます。
#ref error :画像を取得できませんでした。しばらく時間を置いてから再度お試しください。

コードの最初の部分では画面を構成するすべてのモデル、サウンド、イメージをロードします。

具体的にあげると銃モデル、銃が発射されたときの音、バックグラウンドミュージック、画面に表示する十字のマークなどです。

rem TUT6A
rem Lad model for gun
 GunObj=2 : load object “models\gun\gun.x”, GunObj
rem Lad all sounds
 GunSnd=1 : load sound “sounds\gun.wav”, GunSnd
 ImpactSnd=2 : load 3dsound “sounds\impact.wav”, ImpactSnd
 DieSnd=101 : load sound “sounds\ingame.wav”, MusicSnd
rem Load music (WAV best for looping)
 MusicSnd=101 : load sound “sounds\ingame.wav”, MusicSnd
 Loop sound MusicSnd : set sound volume MusicSnd, 80
rem Load images
 FireImg=1 : load image “image\fire.bmp”, FireImg
 CrossHairImg=2 : Lad image “images\crossfari.bmp”, CrossHairImg  

メディアをロードした後は、ゲームの開始前にオブジェクトの設定をしましょう。

銃はプレイヤーの視点(カメラ)の一部として画面に固定しなくてはなりません。

銃弾と画面上の十字マークを作成するのも忘れないでおきましょう。

rem TUT6B
rem Setup gun for player
 lock object on GunObj
 scale object GunObj
 scale object GunObj, 2,2,4
 rotate object GunObj, 270,0,0
 position object GunObj, 0.5,-1,2
 disable object zdepth GunObj
rem Create object for bullet
 bulletObj=3 : make object cube BulletObj, 0.1
rem Create simple sprite based crosshair
 sprite 1, 320-16, 240-16, CrossHairImg
 set sprite 1,0,1  

次はユーザーがマウスボタンを押した際に銃が発射するように設定します。銃が銃弾を1発発射すると次の銃弾を発射するまで少し時間がかかります。

次の銃弾を発射するまでのクールダウン時間が必要であるというような筋書きにすればユーザーにとって違和感がないと思います。

rem TUT6C
rem Control gun firing
 if mouseclick( )=1 and bullet=-50
 bullet=100
 play sound GunSnd
 position object BulletObj, camera position x(0),camera position y(0), camera position z(0)
 rotate object BulletObj, camera angle x(0), camera angle y(0), 0
 set bsp object collision 2, BulletObj, 0.1,1
 move object BulletObj, 0.2
 endif   

次は銃弾について設定していきましょう。発射後、銃弾は前に進み、壁にあったときに破壊されるようにしなくてはなりません。

簡単に設定するには前述のコード内のBSPコリジョン設定のビルトインコマンドを使用しましょう。

rem TUT6D
rem Control life of bullet
 if bullet>0
rem If bullet collides with BSP world
 if bsp collision hit(2)=1 or bulletimpact=1
 rem End bullet on wall
 position sound ImpactSnd, object position x(BulletObj), object position y(BulletObj), object position z(BulletObj)
 play sound ImpactSnd
 bulletimpact=0
 bullet=0
 else
rem Move bullet
 dec bullet
 move object BulletObj, 0.5
 endif
rem Bullet dies
 if bullet=0
 set bsp collision off 2
 endif
 else
rem Gun recharge phase
 if bullet>-50 then dec bullet
 endif 


7.敵の追加


FPSゲームには銃で撃つ標的が不可欠です。このチュートリアルではエイリアンを設定することにします。
エイリアンは平和を求めてやってくるかも知れませんが、このゲーム内ではとにかくシューティングのターゲットとして撃ってしまいましょう。

まずは敵のオブジェクトのモデルをロードします。

rem TUT7A
rem Load models for enemies
 EneObj=11
 for ene=EneObj to EneObj+4
 load object “models\enemy\H-Alien Psionic-Idle.x”, ene
 append object “models\enemy\H-Alien Psionic-Die.x”, total object frames(ene)+1
 position object ene,2,2,4
 loop object ene,0,25
 next ene 

次にエイリアンの存在をより現実的なものにするためのサウンドを追加していきましょう。

エイリアンが近づくに従って聞こえてくるエイリアンの息遣いを追加すれば、エイリアンの怖さをより強調することができます。

rem TUT7B
 EnemySnd=11 : load 3dsound “sound\enemy.wav”, EnemySnd
 EnemygunSnd=12 : load 3dsound “sounds\enemygun.wav”, EnemygunSnd
 EnemydieSnd=13 : load 3dsound “sounds\enemydie.wav”, EnemydieSnd  

これで敵のメディアはロードできました。次は敵の動き、回転、重力、そして3Dサウ ンド制御について設定していきましょう。

rem TUT7c
rem Variable for finding closest enemy
 cdist#=9999.99
rem Handle enemies within world
 for ene=EneObj to EneObj+4
rem If enemy alive
 if object visible(ene)=1
rem Kill this enemy
 killenemy=0
rem Move enemy on a slow curve for appearnce of intelligence
 if object angle z(ene)=0
 yrotate object ene, wrapvalue(object angle y(ene)+2)
 endif
 if object angle z(ene)=1
 yrotate object ene, wrapvalue(object angle y(ene)-2)
 endif
 if object angle z(ene)=2
 move object ene, 0.05
 else
 move object ene, 0.02
 endif
rem Switch direction of curve based on a random value
 if rnd(200)=1 then zrotate object ene, rnd(1)
rem Handle gravity for enemy
 position object ene, object position x(ene), object position y(ene)-0.01, object position 
 z(ene)
rem Work out angle and distance between enemy and aplyer
 dx#=camera position x(0)-object position x(ene)
 dy#=camera position y(0)-object position y(ene)
 dz#=camera position z(0)-object position z(ene)
 dist#=ads(sqrt(abs(dx#*dx#)+abs(dy#*dy#)+( dz#*dz#)))
 viewa#=wrapvalue(atanfull(dx#, dz#))
 obja#=wrapvalue(object angle y(ene))
 if viewa#>180 then viewa#=viewa#-360
 if obja#>180 then obja#=obja#-360
rem Closest enemy emits the enemy sound
 if dist#26+25 and object visible(ene)=1
 killenemy=1
 endif
 if killenemy=1
 set bsp collision off 3+(ene-Eneobj)
 hide object ene : dec aliensleft
 killenemy=0
 endif
rem If enemy alive ENDIF
 endif
 next ene 

彼らの息遣いのサウンドを常にバックグランドに小さな音量で流し続け、彼らがプレイヤーに近づいたときにプレイヤーの耳に初めて息遣いが聞こえるように設定すると、エイリアンの気持ち悪さがより際立つと思います。

rem TUT7D
rem Start the enemy presence sound
 loop sound EnemySnd
 scale listener 0.1 


8.ロジックの追加


ロジックとはジャンルに関わらず、すべてのゲームの要となるもので、ゲーム内で起こるすべての事柄をコントロールしています。
今回作成しているゲームでは、ロジックのコードによって、「プレイヤーがエイリアンを殺す」、「エイリアンがプレイヤーを殺す」、 「プレイヤーがゲームに勝つ/負ける」の事柄がコントロールされます。このチュートリアルの目的はゲームを完成させることではありませんので、すべてのロジックを説明することはしませんが、例としてプレイヤーが死んだ後に再びゲームを再スタートするロジックの作り方を説明していきましょう。

ゲームに登場するエイリアンの視界にプレイヤーが入っているとき、エイリアンがプレイヤーに向かって移動するようにすることができます。

rem TUT8A
rem If enemy 'facing player' and 'on similar height' and 'close', zoom in
 if abs(viewa#-obja#)10.0 and abs(dy#)5.0 and dist#30.0
 if object angle z(ene)>2 then play sound EnemygunSnd
 rotate object ene,0,viewa#,2
 set object speed ene,2
 else
 set object speed ene,1
 endif  

プレイヤーと敵(エイリアン)が近づきすぎるとプレイヤーが死ぬように設定する必要があります。

プレイヤーが生き返ったときに、死んだときと同じ位置にエイリアンが居たらプレイヤーはまたすぐに死んでしまいますので、プレイヤーが生き返ったときには敵(エイリアン)をゲーム上から一度削除する必要があります。

rem TUT8B
rem If enemy gets too close to player, player dies
 if dist#2.0
 play sound DieSnd
 for x=0 to 100
 point camera object position x(ene), object position y(ene)+(x/20.0), object position z(ene)
 sync
 next x
 restart=1
 killenemy=1
 endif  

敵に銃弾がヒットすると敵と銃弾の両方が死ぬようにします。

プレイヤーが銃を発射すれば銃弾は再び敵を撃つことができますが、敵であるエイリアンの寿命はその場で終わるようにします。

rem TUT8C
rem If enemy and bullet in same space, enemy dies
 if bullet>0
 if object collision(BulletObj,ene)>0
 play sound EnemydieSnd
 play object ene,26,26+50
 set object speed ene,1
 bulletimpact=1
 endif
 endif  

すべての敵をプレイヤーの前に配置すると、ゲームがすぐに終わってしまいおもしろくありませんので、敵を画面上のいたるところに配置して敵が壁などの障害物を通り抜けできないようにコリジョンを設定するロジックを追加します。

rem TUT8D
rem Place enemies throughout world and set BSP collision for them
 aliensleft=0
 restore EnemyPosData
 for ene=EneObj to EneObj+4
 read ex#,ey#,ez#
 position object ene,ex#,ey#,ez#
 set bsp object collision 3+(ene-EneObj),ene,0.75,0
 yrotate object ene,180 : fix object pivot ene
 inc aliensleft
 next ene 

上記のコードではRESTORE、READコマンドを使用していますので、敵の配置を決める座標のDATAステートメントを準備する必要があります。

敵はプレイヤーに向かって移動しますので、敵の座標はプレイヤーの座標を下に計算されます。

rem TUT8E
rem Enemy position data within level
 EnemyPosData:
 data -9.27,9.98,-2.78
 data -16.54,-0.22,19.18
 data 2.0,9.0,25.0
 data -2.0,-9.0,25.0
 data 2,4.0,10.0


8.ロジックの追加


光沢を追加することでゲームは更に良いものとなります。最新式の車、ステレオ、洗濯機などがよく見えるのはそれらの製品に光沢があるからです。
光沢には6層あります。

オブジェクトに追加した光沢はずっと続きます。このチュートリアルではstatistical shineとparticle bullet shineの2層の光沢を追加することにします。statistical shineを追加するにはレベル内に何匹のエイリアンがいるのか、いつレベルが完了するのか、一番近いエイリアンまでどれくらいの距離があるのかという情報を提供する必要があります。

銃弾の作成

Rem TUT9E
 if particles exist(1)=1 then delete particles 1
 make particles 1, FireImg, 50, 0.5
 set particle emissions 1,10
 set particle speed 1,0.01  

銃弾の制御

rem TUT9C
rem Update particle using bullet object position
 set particle emissions 1,1+(bullet/10)
 rotate particles 1,90-object angle x(BulletObj), object angle y(BulletObj)+180,0
 position particles 1, object position x(BulletObj), object angle y(BulletObj), object position
 z(BulletObj)  

銃弾の方向

rem TUT9D
 set particle emissions 1,0  

以上で終了です。是非お試しください!

タグ:

+ タグ編集
  • タグ:
最終更新:2007年09月19日 21:20