熊でもわかるRGSS講座 初級編

<<前の章へ     第2章 クラスとメソッド     次の章へ>>





 さて今日は、クラスメソッドについて勉強するかの。
 うん。
 昨日も言ったが、クラスはオブジェクトの種類じゃ。具体的にどんなオブジェクトになるかは、クラスの定義で決まる。
 定義ってなに?
 うむ。では、実際にクラスがどのように定義されておるか、見てみるかのう。スクリプトエディタを開いてみろ。
 うん、開いたで。
 今まで、セクション『Main』ばかり使ってきたが、実は『Main』以外のセクションは、すべてクラス定義なんじゃ。
 ほう・・・。
 とりあえず、上から15番目の『Game_Party』というセクションを見てみるかのう。



 8行目に『class Game_Party』と書いてあるじゃろ? これがクラス定義の始まりじゃな。『Game_Party』が、クラス名じゃ。
 そして、一番下の358行目の『end』が、クラス定義の終わりを示す。
 つまり、classとendの間に書かれた部分が、クラス定義とみなされるようになっておるわけじゃ。
 ふうん・・・。
 ということはまあ、一番単純なクラスの定義は、下記のようなものじゃの。もちろんこれでは中身が無いから、まったく意味が無いが。

1
2
3
class Game_Party
  

end

 しかし、中身が無くとも、一応これでクラスが定義できるし、オブジェクトを作ることもできる。もちろん、役に立たぬオブジェクトじゃがな。
 中身には、どんなことを書けばええの?
 クラスの中身は、主にメソッドの定義じゃのう。
 上の画像の18行目の『def initialize』とか、32行目の『def setup_starting_members』などが、メソッドの定義じゃ。
 さては、メソッドの定義は、defからendまでやな?
 そのとおりじゃ。defとendの間に書かれた部分が、メソッドの定義とみなされる。
 def の右に書いてあるのが、メソッド名じゃの。
 メソッド定義の中には何を書くの?
 そこには、普通にプログラムを書くぞい。
 なるほど。
 では、簡単なクラスを作って、実際に使ってみることにしよう。
 うん。
 では、スクリプトエディタを開いて、セクション『Main』を右クリックするんじゃ。そうすると、下図のようにメニューが出るから、挿入をクリックせい。



 お、なんか空欄が出来たで。



 うむ。新しいセクションが出来たんじゃ。名前の欄をクリックして、セクション名を書け。
 なんて名前にすんの?
 セクション名は、適当でいい。自分の名前でも書いておけ。
 名前をつけたら、クラスの定義を書くぞ。こんな感じじゃ。

1
2
3
class Test
  

end

 こんでええか?



 うむ、ええぞ。この場合、クラス名は、Test なわけじゃな。ちなみに、クラス名は、必ずアルファベットの大文字で始まるようにせねばならん。そういう決まりじゃ。
 うん。
 次は、メソッドを書いてみるかのう。こんな感じでどうかのう。

1
2
3
class Test
  
def speak
    p
"もふもふ"
  end
end

 もふもふて・・・。
 もふもふは、どうでもええわい。これで、Testというクラスに、speakというメソッドが定義されたのは、分かるな。
 うん。
 メソッドの内容は、「もふもふ」と表示するだけのものじゃ。
 うん。
 これで、Testクラスを元にオブジェクトを生成し、speakメソッドを実行して、「もふもふ」と表示させることが出来るはずじゃな。
 うん、早速やってみよ。
 では、その命令を、いつもの通りセクション『Main』に書くぞい。こうじゃ。

7
8
9
begin
  test = Test.new
  test.speak


 オブジェクトを作るときは、Test.newのように、クラス名の後に、ピリオド、そしてnewと書く。
 左のtestは?
 変数じゃ。オブジェクトを作るときは、このように作ったオブジェクトを変数に代入して使うんじゃ。
 ふうん・・・。Testいうクラスやったら、testいう変数にせなあかんの?
 いや、そんなことはないぞ。分かりやすいように、同じ名前にしとるだけじゃ。別に、変数名はなんでもよいぞ。
 なるほど・・・。
 そのあとの、test.speakで、speakというメソッドを呼び出すわけじゃな。
 よし、ならやってみよ。



 お、ちゃんと動いたで。
 うむ。これが、基本じゃからのう。よく覚えておけ。
 オブジェクトを作るときは、newを使ってオブジェクトを生成し、変数に代入して使う。
 そして、変数名の後にピリオドで区切ってメソッド名を書けば、メソッドが呼び出せるんじゃ。
 うん、そやけどな。昨日、数値と文字列でやったときは、変数に代入したり、newとかやらんかったやんか。あれは、なんでなん?
 うむ、実はな。数値や文字のように、値をそのまま書くだけでいいオブジェクトもあるんじゃ。そういうものをリテラルと言うがの。
 リテラル・・・また専門用語が・・・。
 まあ、今は覚えんでもええぞ。ともかく、数値と文字列には、newは必要ないということじゃ。
 うん。
 さて、今書いたメソッドじゃが・・・

1
2
3
class Test
  
def speak
    p
"もふもふ"
  end
end

 これでは、もふもふと表示することしかできん。
 うん。
 そこで、文字列を記録しておくための変数を設定して、表示する文字列を自由に設定できるようにしたいのう。
 変数を扱うときは、どうすんの?
 そういうときに使うのが、initializeというメソッドじゃ。
 initialize?
 うむ、initializeという名前のメソッドを定義しておくと、newで新しくオブジェクトが生成されたとき、自動的にinitializeが実行されるのじゃ。主に、オブジェクトの初期設定をするのに使うのう。
 ほう・・・。
 実際にやってみるかのう。

1
2
3
4
5
6
7
8
9
10
11

class Test

  def initialize
    @word =
"もふもふ"
  end


  
def speak
    p @word

  end

end

 initializeというメソッドを付け足した。内容は「@word = "もふもふ"」だけじゃ。
 @wordという変数に、"もふもふ"という文字列を代入しておるわけじゃな。つまりここで、このクラスで扱うデータを変数に設定しておるわけじゃ。
 このように、そのクラスで扱うデータは、initializeという
メソッドの中で、変数に代入して準備しておけば良い。
 なんや、変数の頭に@(アットマーク)がついとるけど、これはなんや?
 うむ、これはまた後で詳しくやるが、インスタンス変数という種類の変数じゃ。今は気にせんでええ。
 うん。
 speakメソッドも書き換えてあるぞ。p @word にしておる。
 でも、@wordの中身は"もふもふ"やから、結局"もふもふ"て表示されるな。
 そうじゃ。ちゃんと、オブジェクト生成時に、initializeが実行されておれば、"もふもふ"と表示されるはずじゃのう。
 ほなやってみよ。



 うん、出たで。
 うむ、これで文字列を記録し、そのデータを表示できるクラスが出来たのう。
 うん。でも、こんなクラス役に立ちそうも無いけど・・・。
 まあ、練習で作っただけじゃからのう。では、もうちょっとゲームで使えそうなものに改造してみるか。
 うん。
 以前、Spriteという機能を使って、画像を表示したのう。
 実は、Spriteというのも組み込みクラスなんじゃが、今度はこれを使って、文字列を表示してみよう。
 ちなみに、ちょっと説明しておくとじゃな、Spriteクラスは、画像を画面に表示する仕組みを持ったクラスじゃ。
 もうひとつ、Bitmapというクラスも使うが、これは画像データそのものじゃな。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Test

  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end


  
def speak
    @sprite.bitmap.draw_text(0, 0, 640, 30, @word)
  end

end

 5行目の@sprite = Sprite.newで、 Spriteクラスを元にスプライトオブジェクトを生成し、@spriteという変数に代入しておる。
 うん。
 6行目の、Bitmap.newも、Bitmapクラスを元にビットマップオブジェクトを生成し、@sprite.bitmapという変数に代入しておる。ちなみに、640と480は、画像のサイズをピクセル数で表したものじゃ。
 @sprite.bitmapって変数なん?
 うむ、@sprite.bitmapは、Spriteクラスの中の、bitmapという変数のことじゃ。
 Spriteクラスには、bitmapという変数に値を設定するためのメソッドがあるから、このように代入できる。ま、このへんのことは後で詳しくやるぞい。
 うん。
 では、次にspeakメソッドについてじゃが、10行目に、@sprite.bitmap.draw_text(0, 0, 640, 30, @word) とあるのう。
 draw_text
は、Bitmap
クラスメソッドで、画像に文字を描画するものじゃ。
 @sprite.bitmapには、ビットマップオブジェクトが入っておるから、@sprite.bitmap.draw_textと書けば、draw_text
メソッドが呼び出せるわけじゃな。
 後ろについとる数字はなんや?
 文字を描画する位置やサイズを指定する数値じゃな。
 表示位置のX座標、Y座標、横幅、高さの順に指定する。最後が描画する文字列じゃ。今回は、変数@wordに記録されておる文字列を描画する。
 なるほど。@wordには、"もふもふ"が入っとるから、結局これも、もふもふて表示されるんか。
 うむ、しかし今回は、画面の中に表示されるからのう。やってみい。
 うん。ほんなら、やってみるでえ。
 おっと、その前に、セクション『Main』の内容も変えておけ。こんな感じじゃ。

7
8
9
10
11
12
13
begin
  test = Test.new
  test.speak
  loop
do
    Graphics.update
  
end


 ええと、ループを加えたんやな。なんでなん?
 今までは、p で表示させとったから、そこで処理が止まっておったが、今度は画面に描画するからのう。そのままでは、止まらずに次の処理に進んでしまうんじゃ。
 そこで、ループを入れて、処理を止めるようにするぞい。
 なるほど、ほな修正してと。よし、実行してみよ。



 おお、表示されたで。
 うむ、これで文字列を記録し、画面に描画できるクラスが出来たのう。これをもう少し改造して、画面全体に文章を表示できるようにしてみるか。
 おお、なんやノベルゲームみたいやな。やってみよ。
 では、次は表示する文字列を変更できるメソッドを作るかのう。もふもふしか表示できんのでは、意味ないからのう。
 うん。
 メソッドを呼び出すときに任意の文字列を指定して、変数@wrodの値を、その文字列に変更する、という仕組みにするぞ。
 そのために、引数(ひきすう)という仕組みを使う。
 引数
 うむ。引数とは、メソッドにデータを引き渡す仕組みなんじゃ。まあ、実際にやってみよう。
 うん。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Test
  # 初期化
  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end

  # 文字を画面に表示
  
def speak
    @sprite.bitmap.draw_text(0, 0, 640, 30, @word)
  end
  # 表示する文字を変更
  
def change_word(new_word)
    @word = new_word

  end

end

 change_wordというメソッドを設定したぞい。13行目じゃ。
 うん。でも、なんやchange_wordの後ろに、(new_word)なんていうのが、付いとるで?
 それが、引数を受け取るための準備じゃ。
 このメソッドでは、引数として文字列を受け取って、その文字列を
@wordという変数に代入する、という作業をしておる。
 そのために、引数を受け取る変数を指定しておるのが、(new_word)というわけじゃ。
 ふん・・・。
 よう分からんか? では、とりあえず実際に動かしてみるかのう。
 うん。
 では、実行するぞ。セクション『Main』の内容をこのように変えてみろ。
 9行目に、test.change_word("こんにちは")が追加されただけじゃ

7
8
9
10
11
12
13
begin
  test = Test.new
  test.change_word("こんにちは")
  test.speak
  loop
do
    Graphics.update
  
end


 うん。できたで。
 うむ、実行してみよ。



 うん。こんにちは、て表示されたで。
 うむ、では、解説じゃ。セクション『Main』の内容から見てみるぞ。

7
8
9
10
11
12
13
begin
  test = Test.new
  test.change_word("こんにちは")
  test.speak
  loop
do
    Graphics.update
  
end


 9行目で、change_word というメソッドを呼び出しておるのう。このとき、後ろに括弧がついて、括弧の中に文字列が書いてある。
 うん。書いたるな。
 このように、メソッド名の後ろに括弧をつけて、データを書くと、そのデータがメソッドに引き渡されるのじゃ。
 そして、その引き渡されるデータのことを、引数(ひきすう)と言うわけじゃ。
 ふうん・・・。
 では、改めて引数が渡される側を見てみるかのう。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

class Test
  # 初期化
  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end

  # 文字を画面に表示
  
def speak
    @sprite.bitmap.draw_text(0, 0, 640, 30, @word)
  end
  # 表示する文字を変更
  
def change_word(new_word)
    @word = new_word

  end

end

 13行目のメソッドchange_wordじゃな。
 ここで指定しておる
new_wordが、引数を受け取る変数じゃ。
 うん。
 セクション『Main』の9行目で、引数に"こんにちは"が設定されておるから、
 new_wordという変数には、
"こんにちは"という文字列が代入されるわけじゃな。
 なるほど・・・。
 そして、@word = new_word が実行されるわけじゃから、変数@wordに記録されておる文字列も、"こんにちは"になるわけじゃ。
 これで、表示する文字列を変更できるわけじゃな。

 ふうむ、ちょっとややこしいけど、なんとなく分かったかなあ・・・。
 うむ、まあ引数はこれから頻繁に使っていくからのう。徐々に覚えていけばええ。
 ちなみに、
 @sprite.bitmap.draw_text(0, 0, 640, 30, @word)
 の括弧の中も
引数じゃ。この場合、5つ引数がある。
 引数は何個でもええの?
 良いぞ。引数が複数ある場合は、,(コンマ)で区切って書くぞい。
 もちろん
メソッド側も、受け取る変数を、,(コンマ)で区切って同じ数だけ書いておかねばならん。
 なるほどな。。
 さて、ノベルゲームのように文字を表示するには、もう少し改造せねばならんのう。
 そうなん?
 うむ、なぜそうなのか確認するために、もっと長文を表示してみろ。
 長文か? 例えばこんなん?

7
8
9
10
11
12

begin
  test = Test.new
  test.change_word("むかしむかし、あるところに、クミちゃんとグレちゃんがいました。")
  test.speak
 


 もっとじゃ。
 もっとか。なら、こんなんでどお?

7
8
9
10
11
12

begin
  test = Test.new
  test.change_word("むかしむかし、あるところに、クミちゃんとグレちゃんがいました。クミちゃんとグレちゃんは、魔王退治に行きました。魔王の名前は、ウェハースといいました。")
  test.speak
 


 なにやら、事実が歪曲されておるようだが、まあいい。表示してみろ。
 うん。



 あれ? なんかおかしなっとるで?
 うむ、どうなっておる?
 あんな、文字が全部表示されとらん。それから、字が縮んどる。
 そうじゃな。実は、draw_textというメソッドは、1行にしか文字を描画できん。複数行に分けて描画する機能は無いんじゃ。
 そのため、描画幅に入りきらん分は、はみ出て切れてしまう。
 縮んだんは?
 うむ、これはdraw_textの仕様でな、描画幅に入りきらん場合、可能な限り文字幅を縮小して表示するんじゃ。
 なるほど。
 さて問題じゃ。では、文字が画面からはみ出んように、複数行に分けて描画するには、どうしたらええかのう?
 う〜ん・・・。
 ではちょっと、Bitmapクラスの仕様を見てみるかのう。ヘルプからの抜粋じゃ。とりあえず、使えそうなメソッドだけ書いておくぞ。必要なさそうな部分は削除してある。



width
ビットマップの幅を取得します。

height
ビットマップの高さを取得します。

clear
ビットマップ全体をクリアします。

draw_text(x, y, width, height, str[, align])
このビットマップの矩形 (x, y, width, height) に文字列 str を描画します。
テキストの長さが矩形の幅を超える場合は、幅を 60% まで自動的に縮小して描画します。
水平方向はデフォルトで左揃えですが、align に 1 を指定すると中央揃え、2 を指定すると右揃えになります。垂直方向は常に中央揃えです。
この処理には時間がかかるため、1 フレームごとに文字列を再描画するような使い方は推奨されません。

text_size(str)
draw_text メソッドで文字列 str を描画したときの矩形 (Rect) を取得します(文字の幅や高さが分かる)。ただし、イタリックの場合の傾き分は含みません。

 うーん、まずdraw_textは使うわな。text_sizeも使いそうやな。文字幅が分かれば、画面からはみ出んようにできるもんな。
 うむ、そうじゃな。
 うーん、でもどうやったらええか分からんな。
 そうじゃのう。では、もうひとつ教えてやるわい。

7
8
9
10
11
12
13
14
15

begin
  text =
"こんにちは"
  loop
do
    c = text.slice!(/./m)
  
 if c == nil
      break
   
end
    p c
  
end

 なんやこれ?

 slice!というのは、Stringクラス(文字列クラス)のメソッドで、指定された文字を抜き出すものじゃ。まあ、実際に動かしてみればどうなるか分かるわい。
 うんなら、実行してみるで。



 お・・・一文字ずつ表示された・・・。
 そうじゃ。これは、文字列を、一文字ずつ分解して処理するときのやりかたじゃ。
 ほう・・・。
 slice!(/./m)と書くと、先頭の一文字を抜き出す。元の文字列の抜き出された文字は削除される。
 textという変数には、"こんにちは"という文字列が入っておるから、c = text.slice!(/./m)とすれば、"こんにちは"から"こ"が抜き出されて、cという変数に代入され、textは"んにちは"になる。
 ループで繰り返し処理されるから、順番に文字が抜き出され、最後には抜き出す文字が無くなる。
 抜き出す文字がなくなると、slice!は、nilを返すから、11行目の条件分岐の条件を満たすので、breakされるわけじゃ。

 ちなみに、nilはデータが無いことをあらわす特別なオブジェクトじゃ。
 breakってなに?
 おお、まだbreakを教えてなかったかのう。breakは、強制的にループを抜け出す命令じゃ。
 なるほど。つまり、文字列から一文字ずつ抜き出して、空っぽになるまで続けるわけやな。
 ほんで空っぽになったら、breakしてループを抜けると。
 そのとおりじゃ。これを利用して、ノベルゲーム風の表示をしてみい。
 うーんと、メソッドspeakを改造すればええな。ええと、@wordの文字を一文字ずつ抜き出して表示すればええんかな。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

class Test
  # 初期化
  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end

  # 文字を画面に表示
  
def speak
    loop do
      c = @word.slice!(/./m)
      
if c == nil
        break
      
end
      @sprite.bitmap.draw_text(0, 0, 640, 30, c)
    
end
  end
  # 表示する文字を変更
  
def change_word(new_word)
    @word = new_word

  end

end

 こんで、どおや?
 うむ、とりあえず実行してみい。
 うん、ほんなら、実行・・・と。



 な、なんやこれ? 変な四角いのが表示されたで
 それはな、表示される文字が、全部重なって表示されたものじゃ。
 なるほど・・・。
 表示位置が、全部同じじゃから、重なって表示されるんじゃ。
 うーん、そしたら、一文字表示されるごとに、表示位置を横にずらしていかなあかんのやな。でも、一文字当たりどんだけずらせばええんやろ?
 Bitmapクラスのメソッドを思い出してみい。
 そうか。text_sizeや。これで文字幅が分かるから、その分ずらせばええねんな。
 うむ、文字幅は、@sprite.bitmap.text_size(c).widthで分かるぞ。
 よし、ならこうや。描画位置を、変数xで指定するようにしたで。ほんで、描画するたんびに文字幅を、xに加算するんや。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

class Test
  # 初期化
  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end

  # 文字を画面に表示
  
def speak
    x = 0
    loop do
      c = @word.slice!(/./m)
      
if c == nil
        break
      
end
      @sprite.bitmap.draw_text( x, 0, 640, 30, c)
      x += @sprite.bitmap.text_size(c).width
    
end
  end
  # 表示する文字を変更
  
def change_word(new_word)
    @word = new_word

  end

end

 うむ、実行してみろ。
 よしゃ、これでどうや!



 おお、表示されたで。
 うむ、しかしはみ出ておるのう。
 そ、それはこれからやんか。ええと、はみ出さんためには、変数xの値が、画面の幅より大きゅうなったら、表示位置を下の行にすればええな。
 それなら、画面の幅を基準にするより、ビットマップの幅を基準にしたほうがええのう。描画するのは、ビットマップに対してじゃからのう。
 ビットマップの幅は、ええと、@sprite.bitmap.widthやな。ようし。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

class Test
  # 初期化
  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end

  # 文字を画面に表示
  
def speak
    x =
0
    y = 0
    loop do
      c = @word.slice!(/./m)
      
if c == nil
        break
      
end
      @sprite.bitmap.draw_text(
x, y, 640, 30, c)
      x += @sprite.bitmap.text_size(c).width
     
if x >= @sprite.bitmap.width
        x = 0
        y += 30
      
end
    
end
  end
  # 表示する文字を変更
  
def change_word(new_word)
    @word = new_word

  end

end

 行の高さは、とりあえず30でええな。draw_textの高さが30になってるからな
 うむ、ええじゃろう。
 ようし、こんどこそ、うまくいくはずやで。



 やったで! 成功や!
 うむ、まずまずじゃのう。
 なんやねん、まずまずて。ちょっと不満があるみたいやんか。
 うむ、今回はたまたまうまくいっておるがのう。実は、これでは駄目なんじゃ。
 何が、だめやねん・・・。
 では、6行目の@sprite.bitmap = Bitmap.new(640,480)の640を630にしてやってみい。描画するビットマップのサイズをちょっと狭めるわけじゃな。
 なんやねん、630にしたらどやっちゅうねんうん・・・。



 あれ? 右端が切れとる!
 うむ、問題は、19行目の、x >= @sprite.bitmap.widthじゃのう。
 これだと、仮にxが639で、@sprite.bitmap.widthが640の場合でも、条件に当てはまらんから、次の行へ送られずに同じ行に描画してしまう。
 残りは、たった1ピクセルしかないのにのう。
 そっか、xに次の文字の幅を足した値が、@sprite.bitmap.widthを超えんようにせなあかんのやな。
 そうじゃな。そのためには、次の文字の幅も取得せんとな。
 ええと、もう一回、c = @word.slice!(/./m)をやったらええんかな?
 いや、slice!をすると、次の文字が@wordから削除されてしまうから駄目じゃのう。そういうときは、sliceを使うといいぞ。
 ん? ! が無くなっただけか?
 そうじゃ、sliceのほうは、抜き出した文字を元の文字列から削除せんのじゃ。
 そうなんか。なら、これでええな。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Test
  # 初期化
  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end

  # 文字を画面に表示
  
def speak
    x =
0
    y = 0
    loop do
      c = @word.slice!(/./m)
      
if c == nil
        break
      
end
      @sprite.bitmap.draw_text(
x, y, 640, 30, c)
      x += @sprite.bitmap.text_size(c).width
      c = @word.slice(/./m)
      cw = @sprite.bitmap.text_size(c).width
      
if x + cw >= @sprite.bitmap.width
        x = 0
        y += 30
      
end
    
end
  end
  # 表示する文字を変更
  
def change_word(new_word)
    @word = new_word

  end

end

 ようし、やってみるで。



 あれ? エラー出た・・・。
 出るのう。
 なんでなん?
 うむ、これは順番に文字列を処理していって、最後の文字に来たときにエラーが出ておるのじゃ。
 最後の文字?
 最後の文字の次の文字は無いじゃろ?
 そこで、次の文字を取得する、c = @word.slice(/./m)を実行すれば、cには、nilが入る。
 となれば、cw = @sprite.bitmap.text_size(c).widthで文字幅を取得しようと思っても出来んわけじゃ。
 なるほど・・・。
 次の文字が無い場合、cwは0にしておけばええじゃろう。
 なら、こんでええかな?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Test
  # 初期化
  def initialize
    @word =
"もふもふ"
    @sprite = Sprite.new
    @sprite.bitmap = Bitmap.new(
640,480)
  end

  # 文字を画面に表示
  
def speak
    x =
0
    y = 0
    loop do
      c = @word.slice!(/./m)
      
if c == nil
        break
      
end
      @sprite.bitmap.draw_text(
x, y, 640, 30, c)
      x += @sprite.bitmap.text_size(c).width
      c = @word.slice(/./m)
      
if c == nil
        cw = 0
     
else
        cw = @sprite.bitmap.text_size(c).width
      
end
      
if x + cw >= @sprite.bitmap.width
        x = 0
        y += 30
      
end
    
end
  end
  # 表示する文字を変更
  
def change_word(new_word)
    @word = new_word

  end

end

 うむ、ええじゃろう。
 よし、今度こそ、動いてくれよ・・・。



 おっしゃ! こんどこそ完璧や! そうやろ、じいちゃん?
 うむ、完璧というにはまだ早いが、現時点では、こんなもんじゃろうな。
 なんやねん、ちょっとくらい、ほめてくれてもええのに・・・。
 うむ、まあよくがんばったのう。
 やっぱし? わし、がんばった?
 うむ、クラスメソッドの基本は、このくらいでええじゃろうな。
 おっしゃ! クラスメソッド終わり!
 あくまで、基本は、じゃぞ? まだ3倍くらいは勉強することが残っておるからな。
 まだ、3倍もあんの・・・。
 うむ、しかし続きは、また後じゃ。次は、変数についてやるぞ。
 え? 変数については、もうやったやろ?
 基礎はな。しかし、まだ5倍くらいやることが残っておる。
 5倍て・・・。そら、大げさに言うとんのやろ?
 ・・・・・・・・・。
 大げさやないの・・・?
 まあ、今日これだけがんばれたんじゃ。明日もがんばれるじゃろう。
 うう・・・。グレちゃんピンチ・・・。




 本日のおさらい
・クラスは、class〜endで定義
・メソッドは、def〜endで定義
・オブジェクトは、変数に代入して使う
・オブジェクトを生成するときは、クラス名.new(クラス名 ピリオド new)
・メソッドinitializeは、初期値設定に使う
・メソッドに値を引き渡したいときは、引数を使う

 次の章は
第3章 変数の真実

 リンク
>>>この講座のトップページ
>>>タンクタウンのトップページ