【DXRuby】入れ替えパズルをつくってみる。(4)-メインルーチン(3)-選択待機状態

前回記事はこちらです。↓

“選択待機状態”から”交換牌選択可能状態”へ移るまでの処理を作成する。

選択された縦方向の位置の取得方法

何も選択されていない状態から牌をクリックして、それが上から何段目の横軸(手牌)なのかを調べ、その位置を取得します。

DXRubyでクリックされた事を取得するには、Input.mouse_release?メソッドを使用します。

正確には”Input.mouse_release?”は、マウスボタンが押された状態から離れた瞬間を取得します。

そして、マウスポインタの場所を取得するには、Input.mouse_x、Input.mouse_yメソッドを使用します。今回は、縦方向の位置を知りたいので、Input.mouse_yメソッドを使用します。

このふたつのメソッドでクリックしたときのマウスポインタの縦方向の位置を取得して、これを牌画像の高さで割ると、何段目の手牌をクリックしたかを取得することができます。

選択待機状態の処理

まずはWindow.loopメソッドの上に、選択された縦方向の位置を保持する変数を用意します。

base_y =-1  #選択された縦方向の位置

この変数は、Windows.loopメソッド内で、常に保持しておきたい変数なので、Windows.loopメソッドが始まる前に用意する必要があります。

初期値に”-1”を入れているのは、範囲外の値を入れることによって、現在何も選択されていないことを表している(選択されたときに使用される値は、”0~9”)のと、負の値を入れることで、範囲内外の判定をしている事を、目で見てわかりやすくするためです。

次に、選択待機状態の処理を、以下のように記述します。

case state  #case文で条件分岐
when "steel"	#選択待機状態
  #選択待機状態の処理を書く
  base_y =-1  #選択された縦方向の牌の位置
  if Input.mouse_release?(0) then
	  #牌が表示されている範囲をクリックしたら以下を処理
    if (Input.mouse_x > 0) && (Input.mouse_x < tile_w * 14) && (Input.mouse_y > 0 ) && (Input.mouse_y < tile_h * 10) then
  		#クリックされた箇所が上から何段目かを取得
      y = Input.mouse_y/tile_h
      #選択された縦方向の位置を取得し、交換牌選択可能状態に進む
      if y>-1 then
        if base_y!=y then
          base_y=y
          state="base_click"
        end
      end
    end
  end
  when "base_click"	#交換牌選択可能状態

    #交換牌選択可能状態の処理を書く

  when "change_steel" #牌交換待機状態

    #牌交換待機状態の処理を書く
    
  end #ここまでがcase文

選択された手牌をわかりやすく表示

これでも動作はしているのですが、どこが選択されているのかが見た目ではわかりません。

なので、選択された手牌がわかるように、枠線で囲みたいと思います。

まず、Window.loopメソッドの上に、以下のコードを記述して、枠線を作成します。

#ガイド枠線
y_guide=Image.new(tile_w*14,tile_h   ).box(0,0,tile_w*14  ,tile_h  ,C_CYAN)
                                      .box(1,1,tile_w*14-1,tile_h-1,C_CYAN)
                                      .box(2,2,tile_w*14-2,tile_h-2,C_CYAN)
                                      .box(3,3,tile_w*14-3,tile_h-3,C_CYAN)

次に、Window.loopメソッド内に以下のコードを記述して、枠線を表示します。

#選択した手牌を枠線で囲む
Window.draw(0,tile_h*base_y,y_guide)

理牌状態を表示する。

このままでは選択した手牌がどんな手牌かがわかりにくいので、画面下に理牌した状態を表示させたいと思います。

まずは、Window.loopメソッドの上に、理牌対象である選択された手牌を保持する配列の変数を用意します。

sorted =Array.new #理牌用変数

次に、選択待機状態処理の中に次の一文を追加します。(14行目)

case state  #case文で条件分岐
when "steel"	#選択待機状態
  #選択待機状態の処理を書く
  base_y =-1  #選択された縦方向の牌の位置
  if Input.mouse_release?(0) then
	  #牌が表示されている範囲をクリックしたら以下を処理
    if (Input.mouse_x > 0) && (Input.mouse_x < tile_w * 14) && (Input.mouse_y > 0 ) && (Input.mouse_y < tile_h * 10) then
  		#クリックされた箇所が上から何段目かを取得
      y = Input.mouse_y/tile_h
      #選択された縦方向の位置を取得し、交換牌選択可能状態に進む
      if y>-1 then
        if base_y!=y then
          base_y=y
          sorted =tiles[base_y].sort  # ← ※ この一文を追加 ※
          state="base_click"
        end
      end
    end
  end
  when "base_click"	#交換牌選択可能状態

    #交換牌選択可能状態の処理を書く

  when "change_steel" #牌交換待機状態

    #牌交換待機状態の処理を書く
    
  end #ここまでがcase文

最後に、表示のためのコードをWindow.loopメソッド内に追加します。

if base_y>-1 then
  sorted.each_with_index do |v,i|
    Window.draw(tile_w*i,tile_h * 11,hai_images[v])
  end
end

完成したプログラムは、以下の通りです。

require 'dxruby'

#ウィンドウサイズ
Window.resize 672,900
#キャプション
Window.caption = "mjpzl"
#バックグラウンド色(濃い緑色)
Window.bgcolor=[63, 0, 63, 0]

#牌生成
hai_type=[
   1, 2, 3, 4, 5, 6, 7, 8, 9,	#萬子
  11,12,13,14,15,16,17,18,19,	#筒子
  21,22,23,24,25,26,27,28,29,	#索子
  31,33,35,37,                  #風牌
  41,43,45,                     #三元牌
  99                            #裏牌
]

#牌の数は各牌4枚
hais = hai_type*4

#牌をランダムにシャッフル
hais.shuffle!

#牌を14*10に並べる
tiles =Array.new
(0..9).each do |y|
  tiles[y]=Array.new
  (0..13).each do |x|
	#haisの先頭からtilesにひとつずつ代入していく。
    tiles[y][x]=hais.shift
  end
end

#牌画像
hai_images=Array.new
(1..9).each do |i|
  hai_images[     i] = Image.load("./image/p_ms#{i}_1.png")
  hai_images[ 10 +i] = Image.load("./image/p_ps#{i}_1.png")
  hai_images[ 20 +i] = Image.load("./image/p_ss#{i}_1.png")
end
hai_images[31] = Image.load("./image/p_ji_e_1.png")
hai_images[33] = Image.load("./image/p_ji_s_1.png")
hai_images[35] = Image.load("./image/p_ji_w_1.png")
hai_images[37] = Image.load("./image/p_ji_n_1.png")

hai_images[41] = Image.load("./image/p_no_1.png")
hai_images[43] = Image.load("./image/p_ji_h_1.png")
hai_images[45] = Image.load("./image/p_ji_c_1.png")

hai_images[99] = Image.load("./image/p_bk_1.png")

tile_w = 48	#牌画像の幅
tile_h = 64	#牌画像の高さ

base_y =-1  #選択された縦方向の位置

sorted =Array.new #理牌用変数

#状態変数
state = "steel" #初期値:選択待機状態

#ガイド枠線
y_guide=Image.new(tile_w*14,tile_h   ).box(0,0,tile_w*14,tile_h   ,C_CYAN)
                                      .box(1,1,tile_w*14-1,tile_h-1,C_CYAN)
                                      .box(2,2,tile_w*14-2,tile_h-2,C_CYAN)
                                      .box(3,3,tile_w*14-3,tile_h-3,C_CYAN)

Window.loop do
  # ここにゲームの処理を書く
  # update
  case state  #case文で条件分岐
  when "steel"	#選択待機状態
    #選択待機状態の処理を書く
    base_y =-1  #選択された縦方向の牌の位置
    if Input.mouse_release?(0) then
  	  #牌が表示されている範囲をクリックしたら以下を処理
      if (Input.mouse_x > 0) && (Input.mouse_x < tile_w * 14) && (Input.mouse_y > 0 ) && (Input.mouse_y < tile_h * 10) then
    		#クリックされた箇所が上から何段目かを取得
        y = Input.mouse_y/tile_h
        #選択された縦方向の位置を取得し、交換牌選択可能状態に進む
        if y>-1 then
          base_y=y
          sorted =tiles[base_y].sort  #理牌用
          state="base_click"
        end

      end
    end

  when "base_click"	#交換牌選択可能状態

    #交換牌選択可能状態の処理を書く

  when "change_steel" #牌交換待機状態

    #牌交換待機状態の処理を書く
    
  end #ここまでがcase文
  
  # draw
  tiles.each_with_index do |rows,y|
    rows.each_with_index do |v,x|
      Window.draw(tile_w * x, tile_h * y, hai_images[v])
    end
  end
  #理牌表示
  if base_y>-1 then
    sorted.each_with_index do |v,i|
      Window.draw(tile_w*i,tile_h * 11,hai_images[v])
    end
  end
  #選択した手牌を枠線で囲む
  Window.draw(0,tile_h*base_y,y_guide)
end

このプログラムを実行すると、以下のようになります。

これで、手牌が選択されるようになりました。

次回は、交換牌選択可能状態のプログラムを作成します。

次回記事は、こちらです。↓

コメント

タイトルとURLをコピーしました