CoRでRPG作ろうとしたら色々ぶつかった #4
投稿者: 光楼(114) 投稿日:2020/09/26 16:05
さて前回の続き……?
メッセージのアニメーション表示が出来ました!!!
aoihikawaさんの「半角英数以外を全て3バイトとして判定する」案によって解決いたしました!有難うございます!
空白と改行の判定を書き加えて完成したコードがこちら↓
うん、ちゃんと表示されてます。良かった!!!
だがしかし!!!
改行した文字列を表示させるとこんなことに……
なんということでしょう!!!
1行目が勝手に右へ右へと移動し始めたではありませんか!
これは完全に想定外orz
まさか中央揃えになっているとは!
だが心配ご無用!
Rubyには文字の配置を指定するメソッドが存在するのだ!!!
な、なんだってー!?
では左詰めを行うljustを使ってみようではないか。フハハハハ!
ダメだった!!!!!
ljustとかrjustとかはちゃんと機能するんですが、全体的に移動するだけで各行は中央揃えのままでした!くせう!
仕方がないので、改行の所で新たにテキストスプライトを増やすことにしました。
ということで早速メッセージウィンドウの関数を書き換えます。
完成したのがこちら↓
背景表示とテキスト表示を別の関数に分けておくべきだったと後悔中。メンドクサイので必要があればやります。
さて大まかに説明すると、メッセージウィンドウに入る行数分テキストスプライトを最初に設定しておき、アニメーション表示させるときに改行を判定して、テキスト表示する箇所を変えています。
ついでに入りきらなかった行は次のウィンドウ?ページ?に表示させるようにする機能も付けました。
実行結果がこれ↓
ちゃんと左に揃えられました!やったね!
プレーヤーの向き
CoRのサンプルをやってみた方いらっしゃいます?
サンプルのキャラクターの制御は
こんな風に単純なものになっています。
しかしこれだと、斜め移動時に操作キャラのアニメーションが止まってしまうんですよね。
というか方向キー2個押ししたら止まります。
なので対処せねばなりません。
どうするかというと、「操作キャラが向いている方向を取得して実行するアニメーションを指定する」です。
先ほどのプログラムでは、押したキーによって指定しています。
なので2個キーを押すと、2つのアニメーションが連続で交互に何度も切り替えられ、アニメーションが止まっているように見えるわけです。
因みにこのstart_animationってメソッド、現在実行中のアニメを指定しても最初からやり直すわけではなく、そのまま継続してくれるようですね。
さっそく操作キャラの向きを取得しようとしたのですが、実行しているアニメーションが何かを得る方法は無さそうでした。
なのでクラスで管理することにしたぞ!
変数じゃないの?
なんか変数どんどん増えて管理が大変なことになりそうなので、プレーヤーの情報を1つのクラスで管理しようと思ったんです。
いまは向きしか管理できないけど、HPとかそういうのも管理できるようにするつもり。
向きをセットする処理はこんな感じ。
アニメーションの実行処理はrenderに書いた。
これで斜め移動時もアニメーションが止まらなくなりました!
今回はここまで。
有難うございました!
ツイート
メッセージのアニメーション表示が出来ました!!!
aoihikawaさんの「半角英数以外を全て3バイトとして判定する」案によって解決いたしました!有難うございます!
空白と改行の判定を書き加えて完成したコードがこちら↓
def StrSplit(t) #debug_log t t = t.split('') #debug_log t #set_t = "" new_t = [] counter = 0 t.each_with_index do |item, i| if counter > 0 counter = counter - 1 else #set_t << item if !(('a'..'z') === item || ('A'..'Z') === item || ('0'..'9') === item || ('!'..'~') === item || ' ' == item || "\n" == item) #debug_log set_t new_t << t[i] + t[(i + 1)] + t[(i + 2)] counter = 2 else new_t << item end end end return new_t end
うん、ちゃんと表示されてます。良かった!!!
だがしかし!!!
改行した文字列を表示させるとこんなことに……
なんということでしょう!!!
1行目が勝手に右へ右へと移動し始めたではありませんか!
これは完全に想定外orz
まさか中央揃えになっているとは!
だが心配ご無用!
Rubyには文字の配置を指定するメソッドが存在するのだ!!!
な、なんだってー!?
では左詰めを行うljustを使ってみようではないか。フハハハハ!
ダメだった!!!!!
ljustとかrjustとかはちゃんと機能するんですが、全体的に移動するだけで各行は中央揃えのままでした!くせう!
仕方がないので、改行の所で新たにテキストスプライトを増やすことにしました。
ということで早速メッセージウィンドウの関数を書き換えます。
完成したのがこちら↓
#========== メッセージウィンドウ ==========# #===== 素材定義 =====# text 'message-text' do origin :left_top end #===== 関数定義 =====# def message(m='', args = {}) # 引数はハッシュテーブル # 引数初期値 #座標, サイズ, テキストサイズ・色・太字・イタリック, 背景不透明度・色, 枠色, 文字行間 arguments = {:x => 100, :y => 300, :w => 600, :h => 125, :size => 18, :c => '#FFFFFF', :b => false, :it => false, :bg_opacity => 80, :bg_c => 0, :frame_c => 1, :h_interval => 5} # 引数書換え args.each do |key, value| arguments[key] = value end #Zキーを離していなければtrue if keyboard.down?('Z') waitloop = true else waitloop = false end #画像用設定 ofst = 10 #枠と文字位置決定用 fr_w = 2 #フレーム幅 2pxに設定 #背景の設定 msbg_sprite = filling(arguments[:x], arguments[:y], arguments[:w], arguments[:h], arguments[:bg_c], arguments[:bg_opacity]) #枠の設定 msfr = [] #上 msfr << filling(arguments[:x], arguments[:y], arguments[:w], fr_w, arguments[:frame_c], 100) #左 msfr << filling(arguments[:x], arguments[:y], fr_w, arguments[:h], arguments[:frame_c], 100) #右 msfr << filling(arguments[:x] + arguments[:w], arguments[:y], -fr_w, arguments[:h], arguments[:frame_c], 100) #下 msfr << filling(arguments[:x], arguments[:y] + arguments[:h], arguments[:w], -fr_w, arguments[:frame_c], 100) #テキストの設定 各行設定 message_sprites = [] text_y = arguments[:y] + ofst #各行のY位置 while text_y+arguments[:size] < arguments[:y]+arguments[:h] message_sprite = put_text 'message-text' do position arguments[:x] + ofst, text_y font_size arguments[:size] color arguments[:c] bold arguments[:b] italic arguments[:it] wordwrap true wordwrap_width arguments[:w] - ofst*2 camera_fixed! end message_sprites << message_sprite text_y += arguments[:size] + arguments[:h_interval] #次の行の位置を設定 end #レイヤー設定 $system_layer.add msbg_sprite #背景 msbg_sprite.layer_index 0 msfr.each do |item| #枠 $system_layer.add item item.layer_index 1 end message_sprites.each do |item| #テキスト $system_layer.add item item.layer_index 2 end #テキストのアニメーション表示 text_over = false str_arr = StrSplit(m) print_text = '' line = 0 str_arr.each_with_index do |item, i| if item === "\n" line += 1 print_text = '' if line >= message_sprites.size m = str_arr[i+1..-1].join text_over = true break end else print_text += item message_sprites[line].text print_text wait_time(10) end end #離すのを待つ while waitloop if !keyboard.down?('Z') break end wait_time(10) end #Zキー押したら終了 while !keyboard.down?('Z') wait_time(10) end #スプライトの削除 msbg_sprite.destroy msfr.each do |item| item.destroy end message_sprites.each do |item| item.destroy end if text_over message(m, arguments) end end
背景表示とテキスト表示を別の関数に分けておくべきだったと後悔中。メンドクサイので必要があればやります。
さて大まかに説明すると、メッセージウィンドウに入る行数分テキストスプライトを最初に設定しておき、アニメーション表示させるときに改行を判定して、テキスト表示する箇所を変えています。
ついでに入りきらなかった行は次のウィンドウ?ページ?に表示させるようにする機能も付けました。
実行結果がこれ↓
ちゃんと左に揃えられました!やったね!
プレーヤーの向き
CoRのサンプルをやってみた方いらっしゃいます?
サンプルのキャラクターの制御は
# キャラクターがカーソルキーの方向に向いて、向いた方向に移動する if keyboard.down?('LEFT') pos = player_sprite.position player_sprite.position pos[0] - 1, pos[1] player_sprite.start_animation('left') end if keyboard.down?('DOWN') pos = player_sprite.position player_sprite.position pos[0], pos[1] + 1 player_sprite.start_animation('down') end if keyboard.down?('RIGHT') pos = player_sprite.position player_sprite.position pos[0] + 1, pos[1] player_sprite.start_animation('right') end if keyboard.down?('UP') pos = player_sprite.position player_sprite.position pos[0], pos[1] -1 player_sprite.start_animation('up') end
こんな風に単純なものになっています。
しかしこれだと、斜め移動時に操作キャラのアニメーションが止まってしまうんですよね。
というか方向キー2個押ししたら止まります。
なので対処せねばなりません。
どうするかというと、「操作キャラが向いている方向を取得して実行するアニメーションを指定する」です。
先ほどのプログラムでは、押したキーによって指定しています。
なので2個キーを押すと、2つのアニメーションが連続で交互に何度も切り替えられ、アニメーションが止まっているように見えるわけです。
因みにこのstart_animationってメソッド、現在実行中のアニメを指定しても最初からやり直すわけではなく、そのまま継続してくれるようですね。
さっそく操作キャラの向きを取得しようとしたのですが、実行しているアニメーションが何かを得る方法は無さそうでした。
なのでクラスで管理することにしたぞ!
変数じゃないの?
なんか変数どんどん増えて管理が大変なことになりそうなので、プレーヤーの情報を1つのクラスで管理しようと思ったんです。
class Player_ctrl @@d = 'down' def self.direction(d = nil) if d != nil @@d = d end return @@d end end
いまは向きしか管理できないけど、HPとかそういうのも管理できるようにするつもり。
向きをセットする処理はこんな感じ。
if keyboard.down?('LEFT') player_sprite.velocity -speed, nil Player_ctrl.direction('left') #これ end
アニメーションの実行処理はrenderに書いた。
player_sprite.start_animation(Player_ctrl.direction())
これで斜め移動時もアニメーションが止まらなくなりました!
今回はここまで。
有難うございました!
コメントする
コメントするには、ログインする必要があります。
その後も難航があったようですが
順調に機能追加が
進行していますね
クラスは様々な要素が増えてきたときも
まとめて管理できるようになるので
良い案ですね
ありがとうございます!
なるべくスッキリとしたプログラムを書くのが目標です。