※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

入門編・12
シューティングゲームもどきを作る

敵キャラを動かす


せっかく敵キャラを作ったのに、動かないのでは面白くありません。
敵キャラが動くようにしましょう。
それぞれが独立して斜め方向に動き、画面端で反射して方向を変えるようにします。
なお、当たり判定はまだ作りません。

敵キャラに必要な要素

斜め方向に動く、ということで、『動く方向』と『スピード』を決めてやる必要があります。
Game_Enemyクラスの持つ変数に、下の二つを追加します。
 attr_accessor   :direct                   # 移動方向。数字キーの位置
 attr_accessor   :speed                    # 移動スピード。
移動方向のようなものも、普通は数字で管理します("左上"というような文字列ではなく)。
ここでは、数字キーと方向を合わせるようにしましょう。つまり、
左上:7、右上:9、左下:1、右下:3
と決めます。別に0,1,2,3と決めてやってもいいのですが、こうしておくと後でちょっと便利です。
そして、初期値を決めてやるために、initializeメソッド内に以下の行を追加します。
   tmp = rand(3)
   case tmp
   when 0
     @direct = 7
   when 1
     @direct = 9
   when 2
     @direct = 1
   when 3
     @direct = 3   
   end
   @speed = 3 + rand(2)
tmpは、一時的に使う変数によく使う名前で、この名前である必要はありません。
場合にもよりますが、通常直後のcase文や複雑な計算式で一瞬答えを置いておきたい時などに使います。
tmp = rand(3)によって、tmpには0,1,2,3のいずれかの数値が入ります。
そして、そのあとcase~whenによって、数値によって方向を決めています(文法はヘルプを参照)。例えば、tmpが0なら方向は7(左上)というように。
乱数で1,3,7,9のどれか、というような決め方は出来ないので、一旦別の変数に乱数を使ってからその変数の値で飛び飛びの値を割り振っています。まあ、RPGのイベントとかでもよく使う手ですかね?
最後の行でspeedを決めています。こちらも乱数で、ちょっと動きが読みづらくしています。speedの値は3,4,5のいずれかになります。

敵キャラを動かす

では、動かしてみましょう。自機の移動をupdate内に書いたのと同様、敵キャラの移動もGame_Enemyのupdate内に記述します。
 #--------------------------------------------------------------------------
 # ● 更新
 #--------------------------------------------------------------------------
 def update
   if @alive == true then 
     move                                    # 移動
     check_wall                              # 壁に当たった場合の判定
   end
 end
moveという移動メソッド、check_wallという壁反射についてのメソッドを追加します。
生きていなければ移動もしなくていいので、if文で生きている時だけ移動するようにしています。
それぞれのメソッドの中身はこんな感じです。
 #--------------------------------------------------------------------------
 # ● 移動
 #--------------------------------------------------------------------------
 def move
   case @direct
   when 1
     @x -= @speed
     @y += @speed
   when 3
     @x += @speed
     @y += @speed    
   when 7
     @x -= @speed
     @y -= @speed
   when 9
     @x += @speed
     @y -= @speed
   end
 end

 #--------------------------------------------------------------------------
 # ● 壁に当たった場合を判定。
 #--------------------------------------------------------------------------
 def check_wall
   if @x < 0 then
     @direct += 2
   end
   if @x > (WND_X-SIZE_X) then
     @direct -= 2
   end
   if @y < 0 then
     @direct -= 6
   end
   if @y > (WND_Y-SIZE_Y) then
     @direct += 6
   end        
 end
moveの方は、@directの値によって移動を行っているだけです。これだけだと、画面のはるか遠くまでぶっ飛んで行ってしまいます。
check_wallでそうならないようにしているわけですが、こちらは少し複雑です。
if文四つで出来ていますが、まず最初のif文を見てみましょう。
   if @x < 0 then
     @direct += 2
   end
敵キャラのx座標が0より小さい時、つまり左端からはみ出している時、方向の値に2を加えます。
2を加えるって何でしょうか?
想像してみましょう。左にぶつかりうるのは、左下に移動中(1)か左上に移動中(7)です。そして、左下に移動中なら反射して右下に移動(3)、左上なら右上(9)に方向転換します。
つまり、1→3、7→9と変化するわけです。どちらも2増えています。これが+2というわけです。
他のif文も同様、これにより壁による反射が実現します。
実行してみましょう。画面を5機のUFOが跳ね回ったら成功です。意外とよけるの難しいですが、当たっても何も起こりません。

実は……

シューティングゲームもどきとは言え、この方法による反射は結構ずさんです。
速度が変わるようなことが起こると、壁にめり込んでしまったりします。
まあ、目標はシューティングゲームではなくRGSSの習得なので、ご容赦を……。
穴のないプログラムを作成されたい方は、別途ゲームのアルゴリズムを扱った本やサイトを参照して下さい。



  • すごくわかりやすいです!!
    わかりやすい講座を探していたのでありがたいです。
    続き楽しみにしています! -- (名無しさん) 2009-04-11 17:41:26
  • コメントありがとうございます。
    こんなに早く反応があるとは……。
    ヘルプの解説を含め、シーンの構造などを説明しているものが
    ほとんどなかったのが不満で、作ってみました。
    本当に実はあんまり分かっていないので、至らないところも
    多いかと思いますが、よろしくお願いします。 -- (管理人) 2009-04-11 18:58:22
  • すいません、『自機を表示する』の記述に誤りがありました。
    updateの中身を書かないと、自機の位置が正しく反映されません。
    記事を修正しておきます。 -- (管理人) 2009-04-14 21:59:20
  • ツクール古参ですがRGSSに四苦八苦でした(^^;)
    が、シーンの基本構造を解説した記事にガチで救われました
    応援してるんで、がんばってください!!続き楽しみです。

    -- (うきぶくろ) 2009-04-27 12:17:15
  • コメントありがとうございます。
    一番書きたかったそのあたりは書いたもののなんだか忙しい+
    自分でもRGSSの解読に手間取っているためになかなか更新できていません。
    どの程度まで書けるか分かりませんがよろしくお願いします。 -- (管理人) 2009-04-28 08:40:35
  • 敵キャラを作成する・2の最後の方に、
    updateの際に敵キャラを扱うスプライトの更新を行うのを忘れていたのを修正しました。
    イタリック体で修正が入っている部分です。 -- (管理人) 2009-05-02 22:10:23
  • UFOが見にくかったので画像に縁取りをつけました。 -- (管理人) 2009-05-04 08:56:56
  • ホントにスゴイと思います。尊敬します。
    大変だと思いますが少しずつでいいんで頑張ってください。 -- (ユウ) 2009-05-12 00:07:40
  • コメントありがとうございます。
    恐らくこれを見て作る側はすぐなんでたいそうもどかしいと思いますが……。
    ところで、今のところはちゃんとこの講座の通りで動くようになっているのでしょうか?
    一応チェックはしてますが、多少ポカはすると思ってたので指摘が無いのがむしろ意外です。 -- (管理人) 2009-05-13 21:11:52
  • 大丈夫です。ちゃんと動いています。
    頑張ってください。続きが楽しみです。 -- (ユウ) 2009-05-18 01:06:59
  • 1段目と言われている部分は『RGSS2』
    2段目と言われている部分は『プリセットのスクリプト』
    と言われると、より解り易い表現なのでは? -- (通行人) 2009-11-05 12:48:40
  • @enemies[i] = Game_Enemy.new(200 + rand(312), rand(384))
    ↑argumentErrorが発生しました。wrong number of arguments(2 for 0)
    どうすればいいでしょうか、頼みます。
    -- (help me!!) 2010-01-05 00:22:50
  • マウス入力はできますぜ。
    Win32とかなんやらをつかって。
    キーボードもできるみたいですが見つかりません。
    探してます。 -- (シャミラ) 2010-03-24 05:28:28
  • 勉強させてもらってます、とても参考になります。
    入門編・10 にあるGame_Ememiesのクラスの
    attr_accessor ;s_enemies ですが、;を:に変えないとエラーを吐きますので
    コピペでやった人は修正した方がよさそうです
    -- (邯鄲) 2010-09-04 17:27:18
  • @enemies[i] = Game_Enemy.new(200 + rand(312), rand(384))
    ↑argumentErrorが発生しました。wrong number of arguments(2 for 0)

    Game_Enemyクラスって最初からありますよね。
    それが原因では? -- (ぽん) 2010-10-03 23:11:42
  • 製作初心者なのでとても助かります!! -- (ありがとうございます!) 2011-02-05 12:44:03
  • セーブ/ロードまわりはMarshalを使ってスクリプトで記述されていますし、
    ファイルの読み書きもRubyと同様にできますから、
    セーブやロードをいじるのはスクリプト操作でできることでは? -- (ななし) 2011-05-20 13:04:19
  • ダンジョンなら3D化できると、下記サイトに書いてありました。 -- (だれかさん) 2011-08-18 07:26:19
  • アルバイトはじめましたd(´∀`*)グッ♪ http://64n.co/ -- (私だ) 2012-01-09 04:49:41
  • 風俗店を探よりココ!!男性は報酬あり!d(´∀`*)→ http://www.44m4.net/ -- (江梨子) 2012-08-20 17:11:02
名前:
コメント:

すべてのコメントを見る