シューティングゲームの作り方4


1. 画像を表示する
2. 方向キーで画像を移動する
3. 自機クラスを作る
4. シーンクラスを作る

5. 弾を撃つ
6. 敵を作る
7. 当たり判定を作る

8. 敵に弾を撃たせる
9. 耐久力を持たせる
10. 敵を爆発させる
11. スコアを表示する

12. 背景を表示する
13. 表示優先順位を決める
14. 背景をスクロールさせる
15. 背景を多重スクロールさせる
16. 地面に当たり判定を付ける

17. タイトル画面を作る
18. スコアランキング画面を作る
19. ネームエントリー画面を作る
20. ランキングデータを読み書きする


12. 背景を表示する

シューティングの基本システムはほぼ完成しましたので、
ここらで背景にも目を向けて見ましょうか。
ただ1枚絵を表示するだけならもう簡単ですね。

まずは画像を用意します。1画面フルに使うので大きさは640*480です。
ここに貼るには大きいのでリンクだけ。back.png

では背景クラスを作ります。
class Stg_background < Sprite
  def initialize
    super()
    self.bitmap = RPG::Cache.picture("back") 
  end
end

終了ー。
あとはシーンクラスに背景クラス生成の命令を書き込むだけです。
@background1 = Stg_background.new

はい、ここでちょっと待った。
この1文を書く場所をいろいろと変えてみてください。
例えば"@player = Stg_player.new"の後に書いたなら…

自機が表示されない!

そう、背景画像が自機の上に表示されてしまうわけです。
そろそろ表示優先順位について考えてみましょう。



メニューへ


13. 表示優先順位を決める

表示優先順位とは画像が重なった時、どの画像を手前に表示するかを決める優先度のことです。
とくに指定しなければ後に表示した画像ほど手前に表示されます。
現在のままだと一番手前の画像が、ある敵だったり、ある敵の弾だったり、
ある自機の弾だったり、ころころ変わってしまいます。
同じ種類のオブジェクトは同じくらいの優先度で統一したいところです。
それを決めるSpriteのプロパティが"z"です。平面x,yに対して奥行きのzということですね。
この値が大きいほど手前に表示されます。

では各画像についてどういう順番で表示しましょうか?

私ならこうします。
スコア>敵の弾>自機の弾>敵>爆発>自機>背景
値はそれぞれこんなところにしておきます。
200,100,80,60,40,20,10
途中で新しいオブジェクトを追加することがあるかもしれないので、
十分に余裕を持って設定します。

これは決まり事ではありませんのでいろいろと試してみて
シックリくる順位を探してみてください。



メニューへ


14. 背景をスクロールさせる

背景の場合も基本は同じで、x座標を移動させていけばいいですね。
しかしこれは1枚絵。そのまま移動させるとあっという間に真っ黒の画面ができてしまいます。

では同じ画像が2枚あったらどうでしょう?

2枚の画像の端と端をぴったりくっつけたまま移動させて、
一番左に流れた画像をすぐさま一番右に移すのです。
これで途切れることなく背景が連続しているように見えます。

では、やってみましょう。
class Stg_background < Sprite
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(x)
    super()
    self.bitmap = RPG::Cache.picture("back") 
    self.x = x
    self.z = 10
  end
  
  #--------------------------------------------------------------------------
  # ● 背景スクロール
  #--------------------------------------------------------------------------
  def move
    self.x -= 2
    #左端に消えた画像を右端へ移動
    if self.x <= -640
      self.x += 1280
    end
  end
end

2枚の画像は次のように配置します。
    @background1 = Stg_background.new(0)
    @background2 = Stg_background.new(640)

あとはそれぞれmoveを呼ぶだけです。
  #--------------------------------------------------------------------------
  # ● 背景スクロール
  #--------------------------------------------------------------------------
  def background_move
    @background1.move
    @background2.move
  end

これで綺麗につながりましたね。

今回はずっと同じ絵のループですが、画像が完全に画面外に出たときに
画像自体を取り替えるようにすれば、どんどん新しい場所へ移動しているように
見せることもできます。


メニューへ


15. 背景を多重スクロールさせる

背景が1枚では寂しいので多重スクロールをさせてみましょう。
といっても、あんまり大きい画像ばかり使うと重くなるので
手前に表示するのはこのくらいにします。
front
front.png

このように大きさの違う画像を使うなら背景クラスに手直しが必要ですね。
class Stg_background < Sprite
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(x, y, z, sp, file)
    super()
    self.bitmap = RPG::Cache.picture(file) 
    self.x = x
    self.y = y
    self.z = z
    @sp = sp
  end
  
  #--------------------------------------------------------------------------
  # ● 背景スクロール
  #--------------------------------------------------------------------------
  def move
    self.x -= @sp
    #左端に消えた画像を右端へ移動
    if self.x <= -640
      self.x += 1280
    end
  end
end

引数が増えました。おなじみのx,y,zにspは移動速度、fileはファイル名を指定します。
呼出し命令はこんな感じになります。
    @background1 = Stg_background.new(0, 0, 10, 2, "back")
    @background2 = Stg_background.new(640, 0, 10, 2, "back")
    @background3 = Stg_background.new(640, 320, 15, 4, "front")

これだけでスピード感が出たような感じがしますね。
同じようにz=150くらいで"近景"を作ったりもできます。
まあやりすぎると重くなってしまうので程々にしましょう。



メニューへ


16. 地面に当たり判定を付ける

せっかく岩を出したので岩に当たり判定を付けてみましょうか。
当たり判定のちょっと違うやり方を紹介します。

Bitmapクラスには指定した点の色を取得するメソッドがあります。
get_pixel(x, y) です。透明な部分は当然(0,0,0,0)になります。
つまり調べた点が(0,0,0,0)でなければ色のある部分に触れたことを意味します。
これを利用してみましょう。
class Stg_background < Sprite
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(x, y, z, sp, file)
    super()
    self.bitmap = RPG::Cache.picture(file) 
    self.x = x
    self.y = y
    self.z = z
    @sp = sp
  end
  
  #--------------------------------------------------------------------------
  # ● 背景スクロール
  #--------------------------------------------------------------------------
  def move
    self.x -= @sp
    #左端に消えた画像を右端へ移動
    if self.x <= -640
      self.x += 1280
    end
  end

  #--------------------------------------------------------------------------
  # ● 背景の不透明部分との接触判定
  #--------------------------------------------------------------------------
  def crash(x, y)
    if self.bitmap.get_pixel(x, y) != Color.new(0, 0, 0, 0)
      return true 
    else
      return false
    end
  end
end

背景クラスにcrashメソッドを作りました。
画像は常に動いているのでx,yに入れる値に工夫が必要です。
シーンクラスに自機との接触判定を作ってみましょう。
      if @background3.crash(@player.x - @background3.x, @player.y - @background3.y)
        @player.damage
      end

そう、調べる座標から画像の座標を減算すればいいんです。

というわけで、こういう感じの当たり判定ならどんなに複雑な形をした地形にも使えますね。



メニューへ

次のページへ
前のページへ
一覧へ戻る
トップページへ戻る



更新日時:2006/12/18 18:00
管理人:すっぴぃ ◆ADGYPSYxII