【講座?】CoRを触ってみる20~三目並べを作る7~【自分用メモ?】

投稿者:    mini 光楼(114) 投稿日:2017/06/11 10:11

【講座?】CoRを触ってみる19~複数のソースファイル間の移動~【自分用メモ?】←前回

#このブログの情報は2017年6月11日現在のものです。今後変更になる可能性があります。

ゲーム終了してから一番最初のシーンに戻れない問題が解決しました。

前回書いたような形で三目並べのソースコードを書き換えます。
まずはstart.rb
##### ↓追加分↓  #####
#ソースファイルの読込み用シーン
scene 'load' do
  update do
    require_code 'game.rb'

    #シーン「menu」の開始
    change_scene 'menu'
  end
end
##### ↑追加分↑  #####

#=====メニュー=====#
scene 'menu' do
  #変数定義
  bg_sprite = nil #背景
  title_textsprite = nil #タイトル
  description_textsprite = nil #説明文

  preload do 
    #背景素材読込み
    image 'メニュー背景画像', id: 318428, frame_size: [225, 400], frame_pattern: 11
  end

  create do
    #背景画像配置
    bg_sprite = put_sprite 'メニュー背景' do
      position 0, 450
      scale 2.0, 2.0
      angle -90
      frame_index 0
    end

    #タイトル配置
    title_textsprite = put_text 'タイトル' do
      position 800/2, 450/4
      text '三目並べ'
    end

    #説明文配置
    description_textsprite = put_text '説明文' do
      position 800/2, 450/4*3
      text '- 画面をクリックでスタート -'
    end

    #背景アニメ開始
    bg_sprite.start_animation('通常アニメ')
  end

  update do
    #クリック&タップ判定
    if pointer.down?

      ##### ↓変更分↓  #####
      #シーン「game」の開始
      change_scene 'game'
      ##### ↑変更分↑  #####

    end
  end

  render do
  end
end

##### ↓変更分↓  #####
#シーンスタート
start_scene 'load'
##### ↑変更分↑  #####


#=====定義=====#
#スプライト
sprite 'メニュー背景' do
  image 'メニュー背景画像'
  origin :left_top

  animation '通常アニメ', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 20, true
end

#テキストスプライト
text 'タイトル' do
  origin :center
  font_size 100
  color '#ffff00'
end

text '説明文' do
  origin :center
  font_size 30
  color '#ffffff'
end

続いてgame.rb
#=====対戦=====#
scene 'game' do
  #変数定義
  bg_sprite = nil #背景
  mesh_sprite = nil #マス
  mark_sprite = nil #〇
  board_data = [0,0,0,0,0,0,0,0,0] #盤面情報 0:空白 1:〇 -1:×
  comparison_board_data = board_data.dup #盤面変化判定用配列
  turn = 0 #ターン
  decision = 0 #勝敗判定実行判定用
  disposition_text_sprite = nil
  debug_log "#{board_data}"

  #定数定義
  screen_width = 800 #ゲーム画面幅
  screen_high = 450 #ゲーム画面高
  board_size = 125 #盤面1マス当たりのサイズ

  #定数計算
  board_left_position = (screen_width / 2 - (board_size / 2 + board_size)).floor #盤面一番左の位置
  board_up_position = (screen_high / 2 - (board_size / 2 + board_size)).floor #盤面一番上の位置

  #デバッグ
  debug_log "ソースファイル読込み完了!"

  preload do 
    #背景素材読込み
    image 'メニュー背景画像', id: 318428, frame_size: [225, 400], frame_pattern: 11
    image 'マス画像', id: 319591
    image '〇画像', id: 202007
    image '×画像', id: 202014
  end

  create do
    #背景画像配置
    bg_sprite = put_sprite 'メニュー背景' do
      position 0, 450
      scale 2.0, 2.0
      angle -90
      frame_index 0
    end

    #マス画像配置
    mesh_sprite = put_sprite 'マス' do
      position 800 / 2, 450 / 2
      frame_index 0
    end

    #背景アニメ開始
    bg_sprite.start_animation('通常アニメ')
  end

  update do
    comparison_board_data = board_data.dup #配列コピー

    if decision % 2 == 0 #勝敗判定実行判断
      ####プレーヤーor敵ターン####

      if turn % 2 == 0
        ####プレーヤーのターン####
  
        #クリックまたはタップしたか
        if pointer.down?
          column = ((pointer.x - board_left_position) / board_size).floor #列を求める
          paragraph = ((pointer.y - board_up_position) / board_size).floor #段を求める
    
          #列が0~2、段も0~2の範囲か
          if (0..2) === column && (0..2) === paragraph
            block = column + paragraph * 3 #列・段からマス番号を求める
            if board_data[block] == 0 #選択したマスが空白か
              board_data[block] = 1
  
              turn += 1 #行動したらターン交代
              decision += 1
            end
          end
        end
  
      else
        ####敵のターン####
        wait_time(500) #0.5秒待機
  
        #×配置場所選択
        while(board_data[result = rand(9)] != 0) do
          wait_time(100) #無限ループ対策
        end
  
        board_data[result] = -1 #盤面情報書き換え
        turn += 1 #ターン交代
        decision += 1
      end

    else
      ####勝敗判定####
      disposition = win_or_loss(board_data)

      if disposition != 0
        #終了処理
        wait_time(100)
        disposition_text_sprite = put_text '決着' do
          position screen_width / 2, screen_high / 2
        end
        disposition_text_sprite.bold true

        case disposition
        when 1
          disposition_text_sprite.color '#FF0000'
          disposition_text_sprite.text '勝利!'
        when 2
          disposition_text_sprite.color '#0000FF'
          disposition_text_sprite.text '敗北'
        when 3
          disposition_text_sprite.color '#00FF00'
          disposition_text_sprite.text '引き分け'
        end
        wait_time(2000)

        ##### ↓変更分↓  #####
        #シーン「menu」の開始
        change_scene 'menu'
        ##### ↑変更分↑  #####

      end

      decision += 1
    end
  end

  render do
    if board_data != comparison_board_data #ターン開始前と現在の盤面が違っていたら
      #違うところを探す
      9.times do |i| #9回ループ
        if board_data[i] != comparison_board_data[i]
          mark = board_data[i] == 1 ? '〇' : '×'

          #〇×配置
          mark_sprite = put_sprite mark do
            position board_left_position + i % 3 * board_size, board_up_position + (i / 3).floor * board_size
            scale board_size / 150, board_size / 150
            frame_index 0
          end
        end
      end
    end
  end
end

##### ↓削除分↓  #####
#シーンスタート
#start_scene 'game'
##### ↑削除分↑  #####


#=====定義=====#
#スプライト
sprite 'メニュー背景' do
  image 'メニュー背景画像'
  origin :left_top

  animation '通常アニメ', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1], 20, true
end

sprite 'マス' do
  image 'マス画像'
end

sprite '〇' do
  image '〇画像'
  origin :left_top
end

sprite '×' do
  image '×画像'
  origin :left_top
end

#テキストスプライト
text '決着' do
  origin :center
  font_size 100
end

#メソッド
def win_or_loss(board) #勝敗判定メソッド
  #戻り値 0:試合継続 1:プレーヤー勝利 2:プレーヤー敗北 3:引き分け

  #横3列判定
  3.times do |i|
    case board[i*3] + board[i*3 + 1] + board[i*3 + 2]
    when 3 #〇が揃っている
      return 1
    when -3 #×が揃っている
      return 2
    end
  end

  #縦3列判定
  3.times do |i|
    case board[i] + board[i+3] + board[i+6]
    when 3 #〇が揃っている
      return 1
    when -3 #×が揃っている
      return 2
    end
  end

  #斜め\
  case board[0] + board[4] + board[8]
  when 3 #〇が揃っている
    return 1
  when -3 #×が揃っている
    return 2
  end

  #斜め/
  case board[2] + board[4] + board[6]
  when 3 #〇が揃っている
    return 1
  when -3 #×が揃っている
    return 2
  end

  #引き分けチェック
  if board.include?(0) #空のマスがあるか
    return 0 #ある→試合継続
  else
    return 3 #ない→引き分け
  end
end

これでOK!

さ~てやっと前々回の続きです。
勝利した時のみゲームクリアさせます。
game.rbを開いてください。
#前略
  update do
    comparison_board_data = board_data.dup #配列コピー

    if decision % 2 == 0 #勝敗判定実行判断
      ####プレーヤーor敵ターン####

      if turn % 2 == 0
        ####プレーヤーのターン####
  
        #クリックまたはタップしたか
        if pointer.down?
          column = ((pointer.x - board_left_position) / board_size).floor #列を求める
          paragraph = ((pointer.y - board_up_position) / board_size).floor #段を求める
    
          #列が0~2、段も0~2の範囲か
          if (0..2) === column && (0..2) === paragraph
            block = column + paragraph * 3 #列・段からマス番号を求める
            if board_data[block] == 0 #選択したマスが空白か
              board_data[block] = 1
  
              turn += 1 #行動したらターン交代
              decision += 1
            end
          end
        end
  
      else
        ####敵のターン####
        wait_time(500) #0.5秒待機
  
        #×配置場所選択
        while(board_data[result = rand(9)] != 0) do
          wait_time(100) #無限ループ対策
        end
  
        board_data[result] = -1 #盤面情報書き換え
        turn += 1 #ターン交代
        decision += 1
      end

    else
      ####勝敗判定####
      disposition = win_or_loss(board_data)

      if disposition != 0
        #終了処理
        wait_time(100)
        disposition_text_sprite = put_text '決着' do
          position screen_width / 2, screen_high / 2
        end
        disposition_text_sprite.bold true

        case disposition
        when 1
          disposition_text_sprite.color '#FF0000'
          disposition_text_sprite.text '勝利!'

          ##### ↓追加分↓  #####
          wait_time(2000)
          game_clear
          ##### ↑追加分↑  #####

        when 2
          disposition_text_sprite.color '#0000FF'
          disposition_text_sprite.text '敗北'
        when 3
          disposition_text_sprite.color '#00FF00'
          disposition_text_sprite.text '引き分け'
        end
        wait_time(2000)
        #シーン「menu」の開始
        change_scene 'menu'

      end

      decision += 1
    end
  end
#後略

ここで私は気づいてしまった!
2度目以降、変数の定義が実行されない事を……!(シーンの最初のところ)

というわけで、あの位置では定義だけをして、実際の値を入れるのは初期化処理を記述するブロックであるcreatedoで行うことにします。

あ、定数は中身変わらないのでそのままにします。
#=====対戦=====#
scene 'game' do
  ##### ↓変更分↓  #####
  #変数定義
  bg_sprite = nil #背景
  mesh_sprite = nil #マス
  mark_sprite = nil #〇
  disposition_text_sprite = nil
  board_data = nil #盤面情報
  comparison_board_data = nil #盤面変化判定用配列
  turn = nil #ターン
  decision = nil #勝敗判定実行判定用
  ##### ↑変更分↑  #####

  #定数定義
  screen_width = 800 #ゲーム画面幅
  screen_high = 450 #ゲーム画面高
  board_size = 125 #盤面1マス当たりのサイズ

  #定数計算
  board_left_position = (screen_width / 2 - (board_size / 2 + board_size)).floor #盤面一番左の位置
  board_up_position = (screen_high / 2 - (board_size / 2 + board_size)).floor #盤面一番上の位置

  #デバッグ
  debug_log "ソースファイル読込み完了!"

  preload do 
    #背景素材読込み
    image 'メニュー背景画像', id: 318428, frame_size: [225, 400], frame_pattern: 11
    image 'マス画像', id: 319591
    image '〇画像', id: 202007
    image '×画像', id: 202014
  end

  create do
    ##### ↓追加分↓  #####
    #変数設定
    board_data = [0,0,0,0,0,0,0,0,0] #盤面情報 0:空白 1:〇 -1:×
    comparison_board_data = board_data.dup #盤面変化判定用配列
    turn = 0 #ターン
    decision = 0 #勝敗判定実行判定用
    ##### ↑追加分↑  #####

    #背景画像配置
    bg_sprite = put_sprite 'メニュー背景' do
      position 0, 450
      scale 2.0, 2.0
      angle -90
      frame_index 0
    end

    #マス画像配置
    mesh_sprite = put_sprite 'マス' do
      position 800 / 2, 450 / 2
      frame_index 0
    end

    #背景アニメ開始
    bg_sprite.start_animation('通常アニメ')
  end
#後略

これでOKです!

次回は音楽関係か敵AIのどちらかをやろうかな。
それではまた次回!

次回→【講座?】CoRを触ってみる21~三目並べを作る8~【自分用メモ?】

コメントする

コメントするには、ログインする必要があります。

コメント一覧

コメントはありません。