【DXRuby】入れ替えパズルをつくってみる。(5)-メインルーチン(4)-交換牌選択可能状態

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

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

手牌の中から、交換する牌を選択する。

選択された手牌14枚の中から、交換したい牌1枚を選択し、状態を”牌交換待機状態”にします。

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

base_x =-1  #選択された横方向の位置

次に、交換牌選択可能状態を、以下のように記述します。

case state  #case文で条件分岐
when "steel"	#選択待機状態

  ##省略

when "base_click"	#交換牌選択可能状態
  #交換牌選択可能状態の処理を書く
  base_x =-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
  		#クリックされた箇所が左から何番目かを取得
      x = Input.mouse_x/tile_w
      #クリックされた手牌が、選択待機状態時に選択された手牌と同じであれば、
      #選択された横方向の位置を取得し、牌交換待機状態に進む
      if base_y==y then
        base_x=x
        state="change_steel"
      end
    end
  end
when "change_steel" #牌交換待機状態

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

次に、選択された牌と選択可能な牌がわかるように、Window.loopメソッドの上に、以下のコードを記述して、枠線を作成します。

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

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

#選択した牌の縦軸を枠線で囲む(縦)
Window.draw(tile_w*base_x,0,x_guide)

ここまでの内容をまとめたコードは以下の通りです。

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_x =-1  #選択された横方向の位置
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)

#ガイド枠線(縦)
x_guide=Image.new(tile_w   ,tile_h*10).box(0,0,tile_w  ,tile_h*10  ,C_CYAN)
                                      .box(1,1,tile_w-1,tile_h*10-1,C_CYAN)
                                      .box(2,2,tile_w-2,tile_h*10-2,C_CYAN)
                                      .box(3,3,tile_w-3,tile_h*10-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"	#交換牌選択可能状態
    #交換牌選択可能状態の処理を書く
    base_x =-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
        #クリックされた箇所が左から何番目かを取得
        x = Input.mouse_x/tile_w
        #クリックされた手牌が、選択待機状態時に選択された手牌と同じであれば、
        #選択された横方向の位置を取得し、牌交換待機状態に進む
        if base_y==y then
          base_x=x
          state="change_steel"
        end
      end
    end

  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)
  #選択した牌の縦軸を枠線で囲む
  Window.draw(tile_w*base_x,0,x_guide)

end

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

違う手牌を選びなおしたいときの処理

今のままでは、一度手牌を選んだあとに手牌を選びなおすことができないため、ゲームとして遊びにくくなっています。

なので、手牌を選んだ後に、別の手牌を選ぶ処理を追加します。

上のコードの111~114行目を以下のように変更します。

if base_y==y then
  base_x=x
  state="change_steel"
else
  #違う手牌を再選択
  base_y = y
  sorted =tiles[base_y].sort  #理牌用
  state="base_click"
end

選択待機状態で選んだ手牌以外の手牌を選んだ時の処理を、上のelse文の中に書くことで、選びなおしが可能になります。

ここまでの内容をまとめたプログラムは以下の通りです。

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_x =-1  #選択された横方向の位置
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)

#ガイド枠線(縦)
x_guide=Image.new(tile_w   ,tile_h*10).box(0,0,tile_w  ,tile_h*10  ,C_CYAN)
                                      .box(1,1,tile_w-1,tile_h*10-1,C_CYAN)
                                      .box(2,2,tile_w-2,tile_h*10-2,C_CYAN)
                                      .box(3,3,tile_w-3,tile_h*10-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"	#交換牌選択可能状態
    #交換牌選択可能状態の処理を書く
    base_x =-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
        #クリックされた箇所が左から何番目かを取得
        x = Input.mouse_x/tile_w
        #クリックされた手牌が、選択待機状態時に選択された手牌と同じであれば、
        #選択された横方向の位置を取得し、牌交換待機状態に進む
        if base_y==y then
          base_x=x
          state="change_steel"
        else
          #違う手牌を再選択
          base_y = y
          sorted =tiles[base_y].sort  #理牌用
          state="base_click"
        end
      end
    end

  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)
  #選択した牌の縦軸を枠線で囲む
  Window.draw(tile_w*base_x,0,x_guide)

end

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

これで、交換牌選択可能状態のプログラムができました。

次回は、牌交換待機状態のプログラムを作成し、牌を交換できるようにします。

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

コメント

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