CoRでRPG作ろうとしたら色々ぶつかった

投稿者:Material 185033 3 mini 光楼(114) 投稿日:2020/09/15 01:01

皆さん、超お久しぶりです!!!!!
光楼です。

前作、大砲シューティング!を公開してから早1年8ヶ月以上何のゲームも作らなかったのですが、なんか最近急に制作欲が泉の如く湧き出してきたので戻ってまいりました!
いやはやアッパレ!

久々に来るとまるで嵐が去った後のように静かで、2020年新着ゲームは現時点でなんと5作品しか無いではありませんか!
ここまで来たかRmake!っていうか私も暫く居なかったのだから偉そうには言えませんね。

返らぬ日々に思いを馳せている場合ではありません!
こうなったら少しでも早くゲームを投稿するんだ!やる気があるうちに!


で、


何を作るかというと、タイトル通りなのですが……

CoRでRPGを作ります!

大事な事なので、もう一度言いますよ?

CoRでRPGを作ります!


さてと、


早速作っていきたいのですが、RPGを作るのに何が使える?何を自作する?

まずはマップ。
これはRmakeのマップが使えます。CoRのサンプルにマップを歩き回るヤツがありました。
これでマップとキャラ移動はOKですね。

でもマップって数に制限あったよね?
だから今までと同様、1つのマップに複数のフィールド(町とか)を設定するのですが、ここで問題なのがカメラ。

従来のRPGやアクションRPGでは、この座標でカメラ止めて!ってのが無理だったので、CoRではそれをやりたい。
早速試験用のマップを用意した。

緑の所がカメラに映していい場所、黄色は映しちゃダメなマップの外。だからちょうど灰色の所でカメラが止まって欲しい。

現在操作キャラに対してカメラが自動追従する設定になっている。
だから端っこまで来たら手動でカメラを制御してやればいいわけだ。

では早速……
カチカチカチ……ッターーーン!!!

出来た。
~前略~

    #========== カメラ制御 ==========#
    pos = player_sprite.position
    x_camera = ($map_Xmin..$map_Xmax) === pos[0]
    y_camera = ($map_Ymin..$map_Ymax) === pos[1]
    if x_camera && y_camera
      if !camera_follow_up
        #範囲内に入った
        player_sprite.camera_target!
        camera_follow_up = true
      end
    else
      if camera_follow_up
        #範囲外へ行った
        player_sprite.camera_target! false
        camera_follow_up = false
      end
      #手動制御
      camera_position CameraPos("x", x_camera, pos[0]), CameraPos("y", y_camera, pos[1])
    end

~中略~

  #マップ範囲
  $map_rangeX = [1, 30] #マップ範囲X
  $map_rangeY = [1, 30] #マップ範囲Y
  #カメラ制御用設定
  $map_Xmax = 32*($map_rangeX[1]+1) - $screen_sizeX/2
  $map_Xmin = 32*$map_rangeX[0] + $screen_sizeX/2
  $map_Ymax = 32*($map_rangeY[1]+1) - $screen_sizeY/2
  $map_Ymin = 32*$map_rangeY[0] + $screen_sizeY/2

~中略~

#画面外移動時カメラ座標設定関数
def CameraPos(xy, f, pos) #座標軸 範囲内外 プレーヤー座標
  ofset = xy==="x" ? $screen_sizeX/2: $screen_sizeY/2
  posmin = xy==="x" ? $map_Xmin: $map_Ymin
  posmax = xy==="x" ? $map_Xmax: $map_Ymax
  if f
    return pos - ofset
  elsif pos < posmin
    return posmin - ofset
  else
    return posmax - ofset
  end
end

~後略~


ちゃんと止まってくれる。
因みにこれをrenderに書いて、壁に向かって歩き続けたらガクガクした。updateに書いたら解決した。
p.s.上のコード、変数の初期化とか色々雑に略したからコピペしただけじゃ動かないよ。

次はイベント!

これが無いとね。まずはキャラクターに話しかけられるようにしたいね。
まずはキャラクターを配置する。これは配列で良い。
まずは設定用の配列を用意して……
  #========== イベント設定 ==========#
  #[イベント, x位置, y位置, キャラクタ, 初期向き, イベントID]
  $map_event = [[nil, 5, 12, 'mobchara_Test', 'down', 0],
                [nil, 11, 27, 'mobchara_Test', 'up', 1],
                [nil, 19, 6, 'mobchara_Test', 'right', 2]]

一気に配置!
    #========== 他キャラクタの追加 ==========#
    #===== 配置 =====#
    count = 0
    $map_event.each do |item|
      setX = 16+32* item[1]
      setY = 32+32* item[2]
      mob_sprite = put_sprite item[3] do
        position setX, setY
        frame_index 0
      end
      character_layer.add mob_sprite # レイヤーに追加
      mob_sprite.layer_index setY # 重なり順を設定
      mob_sprite.start_animation(item[4]) # downアニメーションの開始
      #===== 当たり判定 =====#
      mob_sprite.collision_size(32, 32, 0, 8) #当たり判定位置、サイズ
      mob_sprite.movable false #衝突しても動かない
      
      $map_event[count][0] = mob_sprite
      count += 1
    end

layer_indexにはY座標を入れた。マップの下の方にいるキャラほど手前に表示できる。

さて、イベント開始処理を作らなければならないが、どうするか。

従来同様Zキーでキャラに話しかけるとして、どのイベントを始めるかをどう判定する? 考えた方法は2つ。
1.操作キャラの座標・向きとイベント用キャラの座標から求める
2.操作キャラの当たり判定を向いてる方に伸ばし、接触したキャラを取得

①はなんか面倒臭そうなので②にしました。
カチカチカチ……ッターーーン!!!
緑の四角形が当たり判定。
Zキーを押すと……

伸びる!


どうやら当たり判定変えてもすぐには反映されないようで、updateを1回ループさせなきゃダメみたいですね。
~前略~
    #========== キーボード操作 ==========#
    
    if keyboard.down?('Z') && !keyput_Z
      keyput_Z = true

      #プレーヤー向きにより当たり判定を変え、イベントと接触させる
      case $charadirection[(player_sprite.frame_index/$charadirection_pattern).floor]
        when 'down'
          player_sprite.collision_size(32, 64, 0, 24)
        when 'left'
          player_sprite.collision_size(64, 32, -16, 8)
        when 'right'
          player_sprite.collision_size(64, 32, 16, 8)
        when 'up'
          player_sprite.collision_size(32, 64, 0, -8)
      end

    elsif keyput_Z
        #===== イベントと接触時処理 =====#
        debug_log "接触判定"
        collision(player_sprite, character_layer) do
          debug_log "イベント実行"
          # 取得できるスプライトの順番とcollisionメソッドに渡した引数の順番は対応付くことに注意してください
          obj1, obj2 = collision_pair
          
          #プレーヤーの方を向く
          case (player_sprite.frame_index/$charadirection_pattern).floor
            when 0 #下
              obj2.start_animation('up')
            when 1 #左
              obj2.start_animation('right')
            when 2 #右
              obj2.start_animation('left')
            when 3 #上
              obj2.start_animation('down')
          end

          #===== 実行するイベントを取得 => 実行 =====#
          $map_event.each do |item|
            if item[0] === obj2
              #イベントの実行
              case $map_num
                when 0
                  MapEvent_num0(item[5])
              else
                debug_log "イベント設定の無いマップ:#{$map_num}"
              end
              break
            end
          end
          
        end

        #Zキー離すまで待機
        while keyboard.down?('Z')
          wait_time(10)
        end
        keyput_Z = false
        player_sprite.collision_size(32, 32, 0, 8) #当たり判定戻す

    else

~中略~

#□□□□□□□□□□ 各マップイベント設定 □□□□□□□□□□#
def MapEvent_num0(id)
  case id
    when 0
      debug_log "0番イベント"
    when 1
      debug_log "1番イベント"
    when 2
      debug_log "2番イベント"
    when 3
      debug_log "3番イベント"
  else
    debug_log "マップ0-設定の無いイベントID:#{id}"
  end
end

これでちゃんとプレーヤーの方向いてくれるし、イベントも指定通り実行してくれる。


次は……!

いよいよメッセージを表示させる時が来た!
speek文は実装されてないから自作しなきゃだぞ!!

しかし残念、もうこんな時間だ!(深夜1時前)
ということでまた次回!

コメントする

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

コメント一覧

Cdv30200 aoi icon mini aoihikawa(投稿日:2020/09/15 01:13, 履歴)
これは力作!

当たり前のように見える
ベース部分を
当たり前につくり込む部分が
実は一番、難しいところですね

次回も楽しみです
Material 185033 3 mini 光楼(114)(投稿日:2020/09/15 21:21, 履歴)
コメントありがとうございます!
そうなんですよね、色々アイデアを出しては試行錯誤の連続です(^-^;

次回もお楽しみに!