Help us understand the problem. What is going on with this article?

Ruby用2Dゲームライブラリ DXRuby:使い方の初歩

概要

この記事は中学高校生向けプログラミング教室の教材として作ったものを一部改変したものです。
Rubyでプログラミングの初歩を学んだ次のステップとして、ゲームライブラリDXRubyの使い方を学んでいきます。

dx22.png

続編
プログラミング初心者向け:DXRubyで 1ステップずつ作っていく「ブロック崩し」 - Qiita

技術解説

ソースコード

https://github.com/noanoa07/dxruby_blocks

使用ライブラリ

Windows向けRuby用2DゲームライブラリDXRubyを使用します。
バージョン1.4.2以上を想定しています。

1.4.2より前のバージョンとの主な相違点

  • Window.loopが複数置ける

  • マウス位置を取得するInput.mouse_pos_xInput.mouse_pos_yの新しい書き方として、Input.mouse_xInput.mouse_yが追加

→ DXRuby 1.4.6:更新履歴
http://mirichi.github.io/dxruby-doc/CHANGELOG.html

DXRubyインストールの注意点

→ DXRuby 1.4.6 をWindows10で使う時の注意点とインストール方法 - noanoa07 - Qiita
https://qiita.com/noanoa07/items/0ce14c2404df38de94b7

参考サイト

 困ったときは、このページの「チュートリアル」と「マニュアル」にだいたい書いてあります。

 古いバージョンのリファレンスも役に立つときがあります。

 このテキストのブログ記事での解説です。

 Nyle-canvas(DXRubyスタイル)で書き直した記事です。

ライセンス

本解説文および解説内のソースコードはともにパブリックドメイン
(DXRuby本体のソースコードは、zlib/libpngライセンス)

プログラム解説

1. DXRubyの練習

DXRubyの基本の使い方を練習します。

使い方を学んだ後は、「ブロック崩し」を作っていくのを目標にしています。

1-1. DXRubyのウィンドウを出す(dx01.rb)

DXRubyの基本の形です。
大きさを指定しないと、横640、縦480のウィンドウが開きます(左上の座標が(0, 0))。

Window.loop do 〜 end の間に書いたコードは、1秒間に60回繰り返し実行されます。

→ DXRubyリファレンス:チュートリアル 1. 基本の形
http://mirichi.github.io/dxruby-doc/tutorial/basic.html

dx01.rb
require 'dxruby'

Window.loop do

end

dx01.png

1-2. ウィンドウの大きさを変える(dx02.rb)

ウィンドウの大きさを変えるには、Window.width =Window.height =を使います。

プログラムの内、最初の1回だけ実行されて以後変える必要のないものは、Window.loop do 〜 end より前に書いておきます。

→ DXRubyリファレンス:API INDEX;module Window
http://mirichi.github.io/dxruby-doc/api/Window.html

dx02.rb
require 'dxruby'

Window.width  = 400
Window.height = 300

Window.loop do

end

dx02.png

1-3. ウィンドウの背景の色を変える(dx03.rb)

ウィンドウの背景の色を変えるには、Window.bgcolor =を使います。

色の指定は、「DXRubyリファレンス:色配列と色定数について」
http://mirichi.github.io/dxruby-doc/api/constant_color.html

を見てください。

→ DXRubyリファレンス:API INDEX;module Window
http://mirichi.github.io/dxruby-doc/api/Window.html

dx03.rb
require 'dxruby'

Window.bgcolor = C_CYAN

Window.loop do

end

dx03.png

1-4. タイトルを表示する;文字(dx04.rb)

ウィンドウの左上にタイトルを表示するには、Window.caption =を使います。

→ DXRubyリファレンス:API INDEX;module Window
http://mirichi.github.io/dxruby-doc/api/Window.html

dx04.rb
require 'dxruby'

Window.caption = "ブロック崩し"

Window.loop do

end

dx04.png

1-5. 画面に文字を出す(dx05.rb)

画面に文字を出すには、

font = Font.new(文字サイズ) で文字サイズ(とフォント名)を指定しておいて、

Window.draw_font(x位置, y位置, "文字列", フォント, {:color => 色})

で表示します。

→ DXRubyリファレンス:チュートリアル 9. 文字の描画
http://mirichi.github.io/dxruby-doc/tutorial/basic.html

→ DXRubyリファレンス:API INDEX;Font.new

http://mirichi.github.io/dxruby-doc/api/Font_new.html

dx05.rb
require 'dxruby'

font = Font.new(32)

Window.loop do
  Window.draw_font(200, 100, "ブロック崩し", font, {:color => C_GREEN})
end


dx05.png

1-6. キー入力をとらえる(dx06.rb)

キー入力はInput.key_down?(キーコード定数)を使います。

キーコード定数については、「DXリファレンス:キーコード定数」
http://mirichi.github.io/dxruby-doc/api/constant_keycode.html

を見てください。

→ DXRubyリファレンス:チュートリアル 8. キーボードの入力
http://mirichi.github.io/dxruby-doc/tutorial/basic.html

dx06.rb
require 'dxruby'

font = Font.new(32)

Window.loop do
  Window.draw_font(200, 100, "ESCキーで終了します", font, {:color => C_GREEN})

  if Input.key_down?(K_ESCAPE)
    exit                 # exit でプログラムを終了する
  end
end

dx06.png

1-7. ウィンドウを切り替える(dx07.rb)

DXRuby 1.4.2 から、Window.loop do 〜 end が複数置けるようになったので、breakでループを抜けると次のWindow.loop do 〜 endが始まり、別のウィンドウを表示できます。

→ Window.loopを複数置く - mirichiの日記 2014-11-24
https://mirichi.hatenadiary.org/entry/20141124/p1

dx07.rb
require 'dxruby'

font = Font.new(32)

Window.loop do
  Window.draw_font(200, 100, "Nキーで次の画面へ", font, {:color => C_WHITE})

  if Input.key_down?(K_N)
    break                # breakで loopを抜ける
  end
end


Window.loop do
  Window.draw_font(200, 100, "ブロック崩し", font, {:color => C_GREEN})

  Window.draw_font(200, 150, "(ESCキーで終了)", font, {:color => C_RED})

  if Input.key_down?(K_ESCAPE)
    exit                 # exit でプログラムを終了する
  end
end

dx07a.png

dx07b.png

1-8. 画像の読み込み(dx08.rb)

画像ファイルの読み込みは、Image.load(画像ファイル)を使います。対応するファイル形式は、jpgpngbmpです。

読み込んだ画像はイメージになります。

→ DXRubyリファレンス:チュートリアル 2. 画像の読み込みと描画
http://mirichi.github.io/dxruby-doc/tutorial/basic.html

→ DXRubyリファレンス:API INDEX;Image.load
http://mirichi.github.io/dxruby-doc/api/Image_load.html

dx08.rb
require 'dxruby'

image = Image.load('../image/apple.png')

Window.loop do
  Window.draw(100, 100, image)
end

dx08.png

1-9. 画像の背景色の透明化(dx09.rb)

イメージでset_color_key(色)を使うと、指定した色を透明にできます。

→ DXRubyリファレンス:Image;set_color_key
http://mirichi.github.io/dxruby-doc/api/Image_23set_color_key.html

dx09.rb
require 'dxruby'

image = Image.load('../image/apple.png')
image.set_color_key(C_WHITE)

Window.loop do
  Window.draw(100, 100, image)
end

dx09.png

1-10. 画像の拡大・縮小(dx10.rb)

イメージを拡大・縮小して表示したい時は、Window.draw_scale(x位置, y位置, イメージ, 横の拡大率, 縦の拡大率)を使います。

→ DXRubyリファレンス:API INDEX;Image;Window.draw_scale
http://mirichi.github.io/dxruby-doc/api/Window_draw_scale.html

dx10.rb
require 'dxruby'

image = Image.load('../image/apple.png')
image.set_color_key(C_WHITE)

Window.loop do
  Window.draw_scale(100, 100, image, 0.2, 0.2)
end

dx10.png

1-11. トウフを表示(イメージで表示)(dx11.rb)

画像は元の画像ファイルがなくても、作ることもできます。Image.new(横幅, 縦幅, 色) で、四角形のイメージを作ります。
(白い四角形の見た目で豆腐(トウフ)

表示するには、Window.draw(x位置, y位置, イメージ)を使います。位置の基準はイメージの左上になります。

→ DXRubyリファレンス:API INDEX;class Image
http://mirichi.github.io/dxruby-doc/api/Image.html

→ DXRubyリファレンス:API INDEX;Window.draw
http://mirichi.github.io/dxruby-doc/api/Window_draw.html

dx11.rb
require 'dxruby'

img_tohu = Image.new(100, 100, C_WHITE)

Window.loop do
  Window.draw(200, 200, img_tohu)
end

dx11.png

1-12. トウフを表示(スプライトで表示)(dx12.rb)

DXRubyには画像を扱うのに、もう一つスプライトというクラスがあります。スプライトは、x位置y位置のデータを自分で持ち、描画メソッドも独自に持っており、衝突判定もできるのが特徴です。そのため、「ブロック崩し」ではスプライトを主に使います。

スプライトは、Sprite.new(x位置, y位置, イメージ)
で作ります。(イメージはあらかじめ作っておきます。)

表示させるのは、drawです。

→ DXRubyリファレンス:Spriteを使うためのチュートリアル
http://mirichi.github.io/dxruby-doc/tutorial/sprite.html

→ DXRubyリファレンス:API INDEX;class Sprite
http://mirichi.github.io/dxruby-doc/api/Sprite.html

dx12.rb
require 'dxruby'

img_tohu = Image.new(100, 100, C_WHITE)

tohu = Sprite.new(200, 200, img_tohu)

Window.loop do
  tohu.draw
end

dx12.png

1-13. トウフの中に赤丸を描く(dx13.rb)

丸を描くには、イメージにcircle_fill(中心のx位置, 中心のy位置, 半径, 色)を使います。中心の位置の座標は、(ウィンドウの位置ではなく)そのイメージの左上が(0, 0)になります。

→ DXRubyリファレンス:API INDEX;Image#circle_fill
http://mirichi.github.io/dxruby-doc/api/Image_23circle_fill.html

dx13.rb
require 'dxruby'

img_tohu = Image.new(100, 100, C_WHITE).circle_fill(50, 50, 50, C_RED)

tohu = Sprite.new(200, 200, img_tohu)

Window.loop do
  tohu.draw
end

dx13.png

1-14. 赤丸だけにする(dx14.rb)

Image.new(横幅, 縦幅, 色)の指定を省略すると、透明色が指定されたことになり、見えなくなります。

→ DXRuby1.4.1 リファレンス:Imageクラス;Image.new
http://dxruby.osdn.jp/DXRubyReference/200953184038328.htm

dx14.rb
require 'dxruby'

img_ball = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)

ball = Sprite.new(200, 200, img_ball)

Window.loop do
  ball.draw
end

dx14.png

1-15. カーソルキーで移動(dx15.rb)

カーソルキーが押されると、左右方向はInput.x、上下方向はInput.y-1, 0, 1 に変化します。

これを利用することで、画面上を移動させることができます。

→ DXRuby 1.4.1 リファレンス:Inputモジュール
http://dxruby.osdn.jp/DXRubyReference/200953184011156.htm

dx15.rb
require 'dxruby'

img_ball = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)

ball = Sprite.new(0, 0, img_ball)
ball.x = 200
ball.y = 200

Window.loop do
  ball.x = ball.x + Input.x
  ball.y = ball.y + Input.y

  ball.draw
end

dx15.png

1-16. カーソルキーで移動(別の書き方)(dx16.rb)

ball.x = ball.x + Input.x を別の書き方である、

ball.x += Input.x に書き換えてみます。同じ意味ですが、こちらの方が文字数が少なくて済むので、間違いが減らせるかも。

dx16.rb
require 'dxruby'

img_ball = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)

ball = Sprite.new(0, 0, img_ball)
ball.x = 200
ball.y = 200

Window.loop do
  ball.x += Input.x
  ball.y += Input.y

  ball.draw
end

dx16.png

1-17. マウスに合わせて移動(dx17.rb)

マウスのx座標、y座標はそれぞれmouse_pos_xmouse_pos_yで取得できます。
(DXRuby 1.4.2 からは、mouse_xmouse_yという書き方もできます。)

→ DXRubyリファレンス:API INDEX;module Input
http://mirichi.github.io/dxruby-doc/api/Input.html

→ DXRubyリファレンス:API INDEX;Input.mouse_pos_x
http://mirichi.github.io/dxruby-doc/api/Input_23mouse_pos_x.html

dx17.rb
require 'dxruby'

img_ball = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)

ball = Sprite.new(0, 0, img_ball)

Window.loop do
  ball.x = Input.mouse_pos_x
  ball.y = Input.mouse_pos_y

  ball.draw
end

dx17.png

1-18. 画像を切り替える(dx18.rb)

スプライトの画像イメージは、スプライト.image = で変更できます。

ここでは、x位置が300を超えるかどうかで、画像が変わるようにしています。

→ DXRubyリファレンス:API INDEX;Sprite.image =
http://mirichi.github.io/dxruby-doc/api/Sprite_23image_3D.html

dx18.rb
require 'dxruby'

img_ball = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)
img_tohu = Image.new(100, 100, C_WHITE)

ball  = Sprite.new(0, 0, img_ball)

Window.loop do
  ball.x = Input.mouse_pos_x
  ball.y = Input.mouse_pos_y

  if ball.x > 300
    ball.image = img_ball
  else
    ball.image = img_tohu
  end

  ball.draw
end

dx18a.png

dx18b.png

1-19. 2つの画像を表示する(dx19.rb)

ひとつの画像は位置が固定で、もうひとつはマウスに追従します。

dx19.rb
require 'dxruby'

img_ball  = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)
img_tohu = Image.new(100, 100, C_WHITE)

ball  = Sprite.new(0, 0, img_ball)
tohu  = Sprite.new(100, 100, img_tohu)

Window.loop do
  ball.x = Input.mouse_pos_x
  ball.y = Input.mouse_pos_y

  ball.draw
  tohu.draw
end

dx19.png

1-20. 画像をまとめて表示する(dx20.rb)

複数のスプライトを配列にまとめると、ひとつの命令Sprite.drawで表示させることができます。

ここでは、スプライトballとスプライトtohuを配列imgsにまとめて、Sprite.draw(imgs)で一気に表示させています。

→ DXRubyリファレンス:Spriteを使うためのチュートリアル
http://mirichi.github.io/dxruby-doc/tutorial/sprite.html

→ DXRubyリファレンス:API INDEX;Sprite.draw
http://mirichi.github.io/dxruby-doc/api/Sprite_draw.html

dx20.rb
require 'dxruby'

img_ball  = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)
img_tohu = Image.new(100, 100, C_WHITE)

ball  = Sprite.new(0, 0, img_ball)
tohu  = Sprite.new(100, 100, img_tohu)

imgs = [ball, tohu]

Window.loop do
  ball.x = Input.mouse_pos_x
  ball.y = Input.mouse_pos_y

  Sprite.draw(imgs)
end

dx20.png

1-21. 衝突判定1;===(dx21.rb)

スプライトは衝突したかを判定する===があります。
衝突しているしていないtruefalseで返します。

→ DXRubyリファレンス:Spriteを使うためのチュートリアル;衝突判定
http://mirichi.github.io/dxruby-doc/tutorial/sprite.html

→ DXRubyリファレンス:API INDEX;Sprite;===
http://mirichi.github.io/dxruby-doc/api/Sprite_23_3D_3D_3D.html

dx21.rb
require 'dxruby'

img_ball  = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)
img_tohu = Image.new(100, 100, C_WHITE)

ball  = Sprite.new(0, 0, img_ball)
tohu  = Sprite.new(100, 100, img_tohu)

imgs = [ball, tohu]

font = Font.new(24)

Window.loop do
  ball.x = Input.mouse_pos_x
  ball.y = Input.mouse_pos_y

  if ball === tohu
    Window.draw_font(200, 300, "衝突!", font)
  end

  Sprite.draw(imgs)
end

dx21.png

1-22. 衝突判定2;check(dx22.rb)

スプライトの衝突判定===では、衝突の有無は分かりますが、衝突した相手は分かりません。そんな時は、checkを使います。checkは衝突している相手を配列で返します。

配列をcollとすると(collision:衝突)、0番目のcoll[0]に何か入っていれば衝突してるし、ならば衝突していないという、衝突判定にも使えます。

→ DXRubyリファレンス:Spriteを使うためのチュートリアル;衝突したオブジェクトを取得する
http://mirichi.github.io/dxruby-doc/tutorial/sprite.html

→ DXRubyリファレンス:API INDEX;Sprite;check
http://mirichi.github.io/dxruby-doc/api/Sprite_23check.html

dx22.rb
require 'dxruby'

img_ball  = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)
img_tohu   = Image.new(100, 100, C_WHITE)
img_tohu_r = Image.new(100, 100, C_RED)


ball   = Sprite.new(  0,   0, img_ball)
tohu1  = Sprite.new(150, 150, img_tohu)
tohu2  = Sprite.new(300, 150, img_tohu)
tohu3  = Sprite.new(300, 300, img_tohu)

blocks = [tohu1, tohu2, tohu3]

font = Font.new(24)

Window.loop do
  ball.x = Input.mouse_pos_x
  ball.y = Input.mouse_pos_y

  coll = ball.check(blocks)
  if coll[0]
    coll[0].image = img_tohu_r
  end

  Window.draw_font(200, 10, "#{blocks.size}個中、#{coll.size}個 衝突!", font)

  Sprite.draw(blocks)
  ball.draw
end

dx22.png

1-23. 衝突判定3;check後に、vanish, clean(dx23.rb)

vanishは、checkで衝突していると判定されたスプライトを無効化します。無効化されたスプライトは描画されません。ただし、無効化されただけで、そのスプライトは削除された訳ではありません。

衝突したスプライトを削除したい時は、Sprite.clean(配列)を使います。これは、配列内のスプライトで無効化されているものを配列から削除します。まだ衝突していないスプライトの数を知りたい時などに使えます。

→ DXRubyリファレンス:Spriteを使うためのチュートリアル;ライフサイクルを管理する
http://mirichi.github.io/dxruby-doc/tutorial/sprite.htmlSpriteの

→ DXRubyリファレンス:API INDEX;Sprite;vanish
http://mirichi.github.io/dxruby-doc/api/Sprite_23vanish.html

→ DXRubyリファレンス:API INDEX;Sprite.clean
http://mirichi.github.io/dxruby-doc/api/Sprite_clean.html

dx23.rb
require 'dxruby'

img_ball  = Image.new(100, 100).circle_fill(50, 50, 50, C_RED)
img_tohu   = Image.new(100, 100, C_WHITE)


ball   = Sprite.new(  0,   0, img_ball)
tohu1  = Sprite.new(150, 150, img_tohu)
tohu2  = Sprite.new(300, 150, img_tohu)
tohu3  = Sprite.new(300, 300, img_tohu)

blocks = [tohu1, tohu2, tohu3]

font = Font.new(24)

Window.loop do
  ball.x = Input.mouse_pos_x
  ball.y = Input.mouse_pos_y

  coll = ball.check(blocks)
  if coll[0]
    coll[0].vanish
  end

  Sprite.clean(blocks)

  Window.draw_font(200, 10, "#{blocks.size}個中、#{coll.size}個 衝突!", font)

  Sprite.draw(blocks)
  ball.draw
end

dx23a.png

dx23b.png

dx23c.png

これで、DXRubyの練習は終わりです。
次は、「ブロック崩し」を作っていきます。

→ ・プログラミング初心者向け:DXRubyで 1ステップずつ作っていく「ブロック崩し」 - Qiita

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away