質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

1561閲覧

情報の初期化?

yusuke.

総合スコア66

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2016/08/22 01:49

お世話になります。
rubyでゲームを作っているのですが、ゲームを始めて、終わった後、タイトルに戻って、もう一度ゲームを始めるということをしたいのですが、タイトルに戻るまではできたのですが、ゲームを始めるを押すと、ゲームが前やった時の途中からスタートしてしまいます。
たぶん、ゲームが終わった時に進行状況やタイムを初期化するなどをすることで、直すことができると思うのですが、どのようにすればいいのかわかりません。 sdlを初期化すればいいのではないかと思いsdl.initなども使ってみましたが、駄目でした。

ruby

1 #タイトル画面(main.rb) 2require "./zairyo.rb" 3 4class Main 5 6def itiban 7while true do 8 while event = SDL::Event2.poll do 9 case event 10 when SDL::Event2::Quit 11 exit 12 when SDL::Event2::MouseButtonDown 13 x = event.x 14 y = event.y 15 if @window.zairyoclicked?(x,y) 16 SDL::INIT_EVERYTHING 17 zairyo = Zairyo.new 18 zairyo.niban 19 end 20 end 21 end 22end 23end 24 25end 26main = Main.new 27main.itiban

ruby

1 # zairyo.rb 2#!ruby -Ks 3require "./window3" 4require "./syujinko" 5require "./item" 6require "sdl" 7 8class Zairyo 9 10 def nibanb (ゲームの説明画面) 11 window3 = Window3.new 12 window3.drawBack 13 window3.start 14 while true do 15 while event = SDL::Event2.poll do 16 case event 17 when SDL::Event2::Quit 18 exit 19 when SDL::Event2::KeyDown 20 if event.sym == SDL::Key::SPACE then 21 window3.drawBack 22 kaisi 23 end 24 end 25 end 26 end 27 end 28 29def gameOver(window3,syujinko) #ゲーム終了画面です 30 window3.drawEndBack #二回目から始めるとこの説明画面の次にこの画面からスタートしてしまいます 31 syujinko.draw 32 window3.refresh 33 sleep 5 34 $a = 1 35 require "./main.rb" 36 main = Main 37 main.itiban #タイトルに戻します。 38end 39 40 41def kaisi #ゲーム画面省略させてもらっています。 42 43 SDL::Key.scan 44 if SDL::Key.press?(SDL::Key::A) 45 syujinko.moveLeft 46 end 47 if SDL::Key.press?(SDL::Key::F) 48 syujinko.moveRight 49 end 50 51 window3.drawBack 52 if time < 0 #タイムが0になるとゲーム終了になります。 53 gameOver(window3,syujinko) 54 end 55 56 time2 = time.to_s.tr(' 0-9a-zA-Z',' 0-9a-zA-Z') 57 @score2 = @score.to_s.tr(' 0-9a-zA-Z',' 0-9a-zA-Z') 58 clickCount2 = clickCount.to_s.tr(' 0-9a-zA-Z',' 0-9a-zA-Z') 59 hyouji = "あなたの得点 #{@score2}点 残りは#{time2}秒 (クリック#{clickCount2} 回)" 60 window3.writeChar(hyouji) 61 window3.refresh 62 $score = @score 63end 64end 65 66end 67 68

お忙しいとは思いますが、回答お願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

Rubyist Magazineのサイトでゲームの初期化を含む
下記のようなサンプルプログラムをみつけました。

1| require "guiutil.rb"
2| require "scenario.rb"
3|
4| #--------------------------------------
5| # 初期化処理
6| #--------------------------------------
7| def init
8| # ウィンドウの作成
9| create_screen "Visual Novel", 480, 360
10| # GUI システム開始
11| start_gui
12|
13| # グローバル変数の初期化
14| $font_size = 12 # フォントの表示サイズ
15| $scene = 'opening' # 場面 ID
16| $fonts = [] # フォントオブジェクト格納用の配列
17| $bg_image = nil # 背景オブジェクトを代入する変数
18| $quit_button = nil # 終了ボタンオブジェクトを代入する変数
19| end
20|
21| #--------------------------------------
22| # メインループ
23| #--------------------------------------
24| def mainloop(tbl)
25| while true
26| # シーンデータ取り出し
27| scene_data = tbl[$scene]
28|
29| # 背景画像が指定されていれば表示する
30| bg_fname = scene_data[0][0]
31| if bg_fname
32| $bg_image = create_img 0, 0, bg_fname
33| end
34|
35| # 終了ボタンの表示
36| $quit_button = create_img_button 0, 438, 180, "quiticon0.gif", "quiticon1.gif"
37|
38| # メッセージの表示
39| message = scene_data[0][1]
40| font = create_font message, 24,218, $font_size
41| $fonts.push font
42|
43| # 選択肢メッセージの表示
44| (scene_data.size-1).times do |i|
45| sleep 0.2
46| idx = i+1
47| ch_msg = "#{idx}. #{scene_data[idx][1]}"
48| font = create_font_button idx, ch_msg, 24, 270+i*24, $font_size
49| $fonts.push font
50| end
51|
52| # ボタンの入力待ち
53| input_value = get_button_id
54| # ボタン ID が 0 なら終了
55| if input_value == 0
56| finish
57| end
58| # 選択されたフォントを水色にする
59| $fonts[input_value].color "#88FFFF"
60|
61| # 次のシーン ID を取り出す
62| $scene = scene_data[input_value][0]
63| # nil なら終了
64| if $scene == nil
65| finish
66| end
67|
68| # 画面を黒い四角で塗りつぶす
69| block_mask
70|
71| # 表示物を削除
72| delete_items
73| end
74| end
75|
76| #--------------------------------------
77| # 表示物の削除
78| #--------------------------------------
79| def delete_items2()
80| # 表示中の終了ボタンを削除
81| if $quit_button
82| $quit_button.delete
83| $quit_button = nil
84| end
85| end
86|
87| #--------------------------------------
88| # 表示物の削除
89| #--------------------------------------
90| def delete_items
91| # 表示中のフォントを削除
92| $fonts.size.times do |idx|
93| $fonts[idx].delete
94| end
95| $fonts = []
96|
97| # 表示中の背景画像を削除
98| if $bg_image
99| $bg_image.delete
100| $bg_image = nil
101| end
102| end
103|
104| #--------------------------------------
105| # 終了処理
106| #--------------------------------------
107| def finish
108| # 表示物があれば削除
109| delete_items
110| # GUI システム終了
111| stop_gui
112| # プログラムの終了
113| exit
114| end
115|
116| #======================================
117| # 実際の処理はここからスタート
118| #======================================
119| init # 初期化処理
120| mainloop ScenarioTbl # メインループ

http://magazine.rubyist.net/?0005-FirstProgramming
(ご参考)

この例のように最初に初期化ルーチンを持ってくるべき
だと思います。

投稿2016/08/29 12:07

Yatsurugi

総合スコア1628

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kei344

2016/08/29 12:12

コードはコードブロックで囲んでいただけませんか? ```(バッククオート3つ)で囲み、前後に改行をいれるか、コードを選択して「<code>」ボタンを押すとコードブロックになります。
yusuke.

2016/08/29 13:17

解答ありがとうございます。 自分の理解力がないだけなのですが、結局どのように直せばいいのかが分からないのです。あと、もしこのようにシーンごとに分けてやるのであれば、時間が足りないので無理だと思います。もしよければどのようになおしたらいいのか詳しく説明していただけませんか。
guest

0

ベストアンサー

ご無沙汰しております。
前もお伝えしましたが、rubyわからないので参考になるかは不明ですが、少しでも参考になれば幸いです。

拝見したところ、

ruby

1if time < 0 #タイムが0になるとゲーム終了になります。 2 gameOver(window3,syujinko) 3end

ここでゲームオーバー画面を呼び出していますので、呼び出すためのifの条件であるtimeが0より小さいままだから2回目以降はゲームオーバーから(続きから)になってしまっているのではないかと推測します。

よって、省略されておりますが、def kaisiでゲームが始まった直後にあると思われるwhileの前でtimeを初期化してやればいいのではないでしょうか。
また、あわせて得点やクリック回数も初期化が望ましいですね。

※ちょっと調べてみたところ、rubyはinitializeによる初期化ができるようなので、それを利用するのがいいのかもしれませんね。

お試し頂ければと思います。

追記

返信読みまして、こちらに回答させて頂きます。

たぶん、whileの中にないと、時間は1秒ごとに変化していかないと思うので、whileの中にあるのだと思います。

これはまさにその通りだと思います。
なので(書き方わかりにくかったかもですね)自分の上記回答の、

def kaisiでゲームが始まった直後にあると思われるwhileの前でtimeを初期化してやればいいのではないでしょうか。

ここが該当すると思いました。
私もrubyのinitializeの書き方がわからないので、ものすごく簡単に修正するなら、

ruby

1 //kaisi呼ばれた後 2 3 time = 0             // ←ここで初期化 4 while true do         // ゲーム開始のwhile 5 6  time = window3.getTime  // ここを通るたびに1秒追加 7  while event = SDL::Event2.poll do 8   case event 9   when SDL::Event2::Quit 10     exit 11   when SDL::Event2::MouseButtonDown 12    x = event.x 13    y = event.y

のように、whileの前(上)で初期化してやればいいかと思います。得点なんかも合わせてやるといいだろうと思いますし、initializeもやるならゲーム開始前ですね。ゲームオーバー後にタイトルに行った直後とかでもいいかもしれません。

また、

getTimeに書いてあるものをinitalizeに書くことにより、タイムを初期化することができるのだと思ったのですが、どうでしょう

getTimeは1秒を計算して返す処理(でいいのかな?)となっているため、初期化はgetTimeで取得した時間が蓄積されているtimeでなければいけないのではないかなと思います(同様に得点やクリック回数の初期化も格納されている変数を初期化する必要があります。本来ならそれをinitalizeするのがスマートなやり方かと思います)

参考になれば幸いです。

投稿2016/08/22 11:00

編集2016/08/23 03:36
SASAHARA

総合スコア247

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yusuke.

2016/08/22 23:37

回答ありがとうございます。 タイムは while true do time = window3.getTime while event = SDL::Event2.poll do case event when SDL::Event2::Quit exit when SDL::Event2::MouseButtonDown x = event.x y = event.y whileの後にこのような感じでwindow3.getTimeというのは def getTime return 20 - SDL.get_ticks/1000 end これなのですが、初期化するにはどのようにした方がよいのでしょう。 たぶん、whileの中にないと、時間は1秒ごとに変化していかないと思うので、whileの中にあるのだと思います。 ちょっと自分でも調べてみますね。参考になります。
yusuke.

2016/08/22 23:43

getTimeに書いてあるものをinitalizeに書くことにより、タイムを初期化することができるのだと思ったのですが、どうでしょう
yusuke.

2016/08/29 07:13

返信遅れて申し訳ございません。 丁寧に回答くださりありがとうございます。 SASAHARAさんが書いてくれていたように直したのですが、前と全く変わりませんどうしたらよいのでしょうか
SASAHARA

2016/08/30 03:18

すみませんよく読み返してみると、timeが0になるとゲームオーバーなんですね。失礼しました(自分の最初のレスで自分で書いているのに・・・本当すみません) ゲームが一度ゲームオーバーになったということは、timeが0以下であると思われるのでtimeを初期状態(たとえば60秒からスタートするならtime=60とか)でお試しいただけますでしょうか。
yusuke.

2016/08/30 06:31 編集

試してみました。 20秒からsdl.getTimeで引いていくので20秒を変数としてinitializeの中にtt = 20 とし、 time = tt - sdl.get_ticks/1000 としましたがだめでした。 やはり、sdlgetTimeを0にできるものをさがさなければならないのでしょうかね
SASAHARA

2016/08/30 08:10

まだ不十分ではありますが、少し調べてみました。 SDLは、SDL::INIT_EVERYTHINGで初期化なりませんか? SDL.get_ticksが初期化されればうまくいきそうな気がします。
yusuke.

2016/08/30 13:22

もうよく分からなかったので全く思考を変えて、現在の時間を取ってそれに二十秒足した物を用意して時間がその物になったときに終了させると言うことで解決しました。  せっかく悩んでくださったのに申し訳ありません。ありがとうございます。
SASAHARA

2016/08/31 02:23

いえ、解決できたならそれが何よりです。むしろ別な方法でできるならそれにこしたことはないです。全然お力になれませんでしたが、いいものを作れるようがんばってくださいね!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問