Shoesの暫定的日本語チュートリアル


このサイトについて
Shoesの暫定的日本語チュートリアル(ShoesというRuby(プログラミング言語)のライブラリ(Rubyの補助)の日本語チュートリアルです)。実例を挙げつつShoesの機能をかいつまんで紹介します。
Rubyはおもしろい言語だといわれて初めてのプログラミング言語をRubyに選んだのはいいのですが、自分の想像していた綺麗なグラフィックを自由自在に動かして、ネットと組み合わせて・・・、等々のイメージと実際のプログラミングはかけ離れていました。それでも毎日文字列と向き合いつつ懸命にネットを探したところ、プログラミング言語にはライブラリとか、ツールキットとかいうものがあるということを知りました。グラフィックはそこにあるのですね。しかしここでまた障害が立ちはだかりました(なぜこんなに敷居がたかいのだろうか)。Shoesの説明書は英語です。英語が読めない人はここでコンピュータの前を去るか、もしくは英語を勉強しなければなりません。これでは、効率が悪いです。「英語くらい読めてあたりまえ」なんていわれたって、プログラミングをやりたいのに、なぜ英語を勉強しなければならないのでしょうか。プログラミングの世界はもっと寛容で、ラフで、気楽で、親切で、オープンでなければなりません。以上の理由からShoesの日本語チュートリアルを作りました。部員の方、楽しんでいってください。がんばりましょう。
 



注意1:個人的な集りのためのサイトなのでShoes公認でもなければ、たびたび間違った記述があったりします。ご了承ください。
注意2:RubyがインストールされていなければShoesは使えません。まだインストールしていない人はhttp://jp.rubyist.net/magazine/?0011-CGIProgrammingForRubyBeginners-2#l2でRubyをゲットしてください。※Rubyのページが変わってしまいました.違う方法を調査中です.
注意3:Ruby,Shoesともに,正規の使い方と大幅に違った使い方を紹介しています。
注意4:リンクフリーです。
注意5:文中のプログラムでは特別な意味を持つ部分を緑色、自分が勝手に設定できる部分を黒で書いています。
注意6:連絡先はnomobonson@gmail.com です.
 
 
1.Shoesインストール(準備ってこと)
1-1.http://shoesrb.com/にいって,「ForWindows」と書いてあるところの下にある「Shoes 0.r1134+video(recommended)」(0.r1134の部分は変わる可能性がある.)をクリック.(あ,言い忘れましたが,このウェブサイトはWindowsを使っていることを前提としています.Macとか,Linux使ってる人は・・・まぁ頑張って) 

クリックするとダウンロードが始まるので,「保存」をクリック(ここでは,わかりやすいようにデスクトップに保存しましょう).見慣れないアイコンが出てくるので,ダブルクリック.インストールが始まります.「next」と「Agree」とかをどんどんクリックしていく.

1-2.ProgramFIlesに行って,そのなかのCommonFilesにいって,そのなかのShoesにいって,バージョンファイルにいく(0.r1134とか).そこに,「Shoes.exe」というのがあるから(これがShoesの入り口),これを右クリックして,ショートカットを作成をクリック,ショートカットをデスクトップにドラッグアンドドロップする.

ちなみに,ほかにいろいろやり方ありますが,この方法が初心者にとって一番わかりやすく,確実なので載せています.


 
2.Shoesでウィンドウを開く
2-1.さっそくやってみましょう。デスクトップで右クリック。新規作成でRubyProgramをクリックして新規RubyProgramを作る。
2-2.新規RubyProgramを右クリック。編集をクリック。
2-3.
Shoes.app do
end
と入力して上書き保存。
2-4.新規RubyProgramをShoesの上にドラッグアンドドロップ(環境変数の設定ができるひととか、正常に動く運のいい人はそちらでどうぞ)。真っ白なウインドウが開かれるはず。
 
 
 
3.Shoesで丸を描く
3-1.さっきのプログラムを
Shoes.app do
  oval 100,110,200,300
end
にかえて上書き保存してさっきみたいにShoesの上にドラッグアンドドロップ。黒い楕円が書かれたウィンドウが開かれるはず。
 oval 100,110,200,300 で 横の位置100で、縦の位置110で、横の幅200で、縦の幅300の楕円をかく。
基本、
      oval                   100       ,      110       ,    200     ,    300
(図形の名前) (横の位置),(縦の位置),(横の幅),(縦の幅)
という感じで書く。だから
oval 100,400,300,100
と書くと 横の位置100、縦の位置400、横の幅300、縦の幅100 で 楕円が描かれる。
ちなみに
   rect               100       ,      400       ,      300    ,    100
(四角形) (横の位置),(縦の位置),(横の幅),(縦の幅)
 
  arc            100        ,     400        ,    2.34  ,    3.14    
(円弧) (横の位置),(縦の位置),(角度1),(角度2)
※この角度1と角度2が曲者(くせもの)で、半周を3.14(π)として設定しなければなりません。
 
 arrow         100     ,     400         ,   20
(矢印) (横の位置),(縦の位置),(太さ)
 
 line                100                   ,               500                  ,                330                   ,                400
(線) (かき始めの横の位置),(かき始めの縦の位置),(かき終わりの横の位置),(かき終わりの縦の位置)
というように、
(何か)  (何かの性質1),(何かの性質2),(何かの性質3),(何かの性質4),(何かの性質5)……
という構文がShoesの基本です。
ためしに、
Shoes.app do
  oval 10,10,100,100
  rect  10,200,100,100
  arc   300,200,100,300,3.14*1.2,3.14*2.0
  arrow 200,200,20
  line 200,200,300,400
end
を実行してみてください。
 
3-2.数学をやったことのある人は丸の書かれる位置について変な感じがするかもしれません。なぜなら、「横の位置」と「縦の位置」は
 
       ↑ 数学の場合                          ↑ Shoesの場合
 
だからです。それに
 
    ↑ 普通の感覚                   ↑ Shoesの場合
 
だからです。気をつけてください。
 
 
 
4.おいしいコーヒーを入れる
4-1.インスタントコーヒーをコップに二杯入れる。
4-2.砂糖を二杯入れる。
4-3.コップの四分の一程度にお湯を注ぐ。
4-4.空いているペットボトルを探してきて、牛乳を入れてキャップを閉め、シェイク、シェイク、シェイク!する。
4-5.泡立ったら(泡立たないひと残念)コップにいれて上からシナモンをかける。
 
 
 5.図形に色をつける
5-1.色の付け方は二種類あります。
Shoes.app do
  fill blue
  oval 100,100,100,100
end
Shoes.app do
  oval 100,100,100,100,:fill=>blue
end
何がちがうのでしょうか。以下のプログラムを試してみて下さい。
Shoes.app do
  fill blue
  oval 100,100,100,100
  oval 200,100,100,100
end
Shoes.app do
  oval 100,100,100,100,:fill=>blue
  oval 100,100,100,100
end
のちがいがわかりますか?fillは「満たす」という意味です。文字どおり指定する色で図形を満たすわけですが、前者の例(fillで一行かく例)では、次にfillが書かれるまでずっとblueが有効です。だから色を指定していないはずの二番目のovalもいろがつくわけです。それに対して
      oval                  100        ,      100       ,     100    ,     100    ,  :fill=>blue   
(図形の名称) (横の位置),(縦の位置),(横の幅),(縦の幅),(色の指定)
とすると、その図形に限って色が指定されます。ということで、二番目のovalには色がつかないのです。
 
5-2.さっきのblueは「青」という色の指定を簡単にできました。でもちょっと考えてみてください。色の種類は色の名前よりたくさんあります。名前のない微妙な色はしてい出来ないのでしょうか?
以下のプログラムを試して下さい。
Shoes.app do
  fill rgb(0.4,0.2,0.4)
  oval 100,100,100,100
end
かんのいい人と真面目な人は気づきましたね。普通、コンピュータで色の指定をするときはRGBといって光の三原色(RはRED、GはGREEN、BはBLUE)を指定します。従って、Shoesでも
   rgb        (0.4    ,   0.2    ,     0.4)
(rgb宣言)  (赤  ,  緑  ,  青)  
という指定の仕方ができます。しかし面倒なのでblueと書くと青を示すRGBが自動的に入るようになっているのです。ちなみに、ShoesMannualのどこかに色の表示に便利な表があります。
 
5-3.ここでひとつ官能的なプログラムを書きましょう。
Shoes.app do
  100.times do
    oval rand(400),rand(400),rand(100),rand(100),:fill=>blue(rand(100))
  end
end
 
100.times do と rand() で、官能的なアート
おもしろいでしょう?rand(100)は0~99(注意が必要)までの値をランダムで選ぶというRubyの関数です。ここで初めてRubyの関数が出てきたので、Shoesで面白いことをやるための最低限のRubyの知識をかいておきましょう
変数 --データの名前--
nanika=399 と書くと、次に出てくる nanika はすべて 399 を意味します。だから、その次に
nanika2=nanika+100 と書くと、次に書くすべての nanika2は 499 を意味します。基本的なことなのでおしまい。
 
配列 --データを入れておく整理箱--
ohmygod=[100,100,200,300,500] と書くと、ohmygod という配列を作ることができます。しかも ohmygod には数字が入っています。
データを取り出す時は ohmygod[2] と書きます。プログラマは0から数えます(誤謬)ので、このばあいは 200 が ohmygod[2] から出力されています。
データを入れるときは ohmygod.push(600) と書きます。すると ohmygod のおしりに 600 が入ります。
 
繰り返し
ohmygod=[100,200]
10.times do |count|
  ohmygod.push(rand(100*count))
end
ちょっと混乱してきましたか?(というコメントをよく見ますが、私の場合たいていその前の段階で十分混乱しています)。まず一行目では配列がつくられています。整理箱を準備したわけです。
つぎに、10.times do |count| とありますが、これは「doとendで挟まれた部分を十回くりかえせ。それで count に今何回目かの数字をいれろ。」という命令です。count は kaisuu でも、 pikatyu でも何でも構いません。次の ohmygod.push(rand(100*count))  がすぐにわかる人は頭がいい方だとおもいます。どういうことかというと、
 
   ohmygod        .push        rand              100*count
(ohmygodに  入れろ  ランダムで  100×countの )
 
という意味です。10.times do によりこの文が繰り返されます。100にcountがかけてありますから、繰り返しの0回目(1回目ではない!!)では ohmygod のおしりに 0~0 の範囲で値がランダムに選ばれて入り(もちろん0)、1回目では ohmygod のおしりに0~100 の範囲で値がランダムに選ばれて入ります(だから、32とか4とか99とかが入る)。二回目では ohmygod のおしりに 0~200 の範囲であたいがランダムに選ばれて入ります。
 
if文
if ohmygod[0]==100
  ohmugod.push(200)
end
とかくと、もし ohmygod の整理箱の、一番目(ohmygod[0]ですから、ohmygodの一番目ですよ)が100だったら( if ohmygod[0]==100 (=ではなく==であることに注意)) ohmygod のおしりに200を入れろという命令になります。
もしあなたが、Rubyの前にShoesをやろうとしていたら、Rubyを先に勉強してください。ShoesはRubyの知識があって活用できます。おすすめの本は「はじめてのプログラミング」です。
 

 
6.マウスで操作
6-1.次のプログラム
Shoes.app do
  e=rect 100,100,100,100
end
は何をしているのでしょう?rect 100,100,100,100 も e= もわかりますが、e=rect 100,100,100,100 はわかりません。
では、
Shoes.app do
  e=rect 100,100,100,100
  e.click do
    oval rand(600),rand(600),100,100, :fill=>rgb(rand(500),rand(500),rand(100))
  end
end
は何をしているのでしょう?まず、e=rect 100,100,100,100 ではeという変数に rect 100,100,100,100 を入れています。問題は次です。
(何か).click do
   ~~~~
end
は、(何か)がクリックされたらdoとendで挟まれた文を実行しなさいという意味です。ためしに、さっきのプログラムで四角をクリックしてみてください。要領のいいひとと、かんのいい人はきづきましたね?さきの プログラムでは、 ① e=rect 100,100,100,100    でeという変数に格納し(そうそう、rect は四角で、ovalが楕円でしたね) ②e.click do で「eがクリック」されたら ③oval rand(600),rand(600),100,100,:fill=>rgb(rand(600),rand(600),rand(600)) という感じで丸を描けという命令をしています。
 
 e=rect 100,100,100,100 と e.click do で 四角をクリックして丸をかける。
6-2.次のプログラムについて考えてみて下さい。
Shoes.app do
  e=oval 100,100,100,100,:fill=>blue
  motion do
    if mouse[0]==1
      e.left=mouse[1]
      e.top=mouse[2]
    end
  end
end
お手上げでしょうか?ここまで来て諦めたくなった人のために、物理の先生に教えてもらった「未知との遭遇」という話をしましょう。
「未知との遭遇」
現代の日本の社会では、社会の活動の一環として教育があります。教育されている間は、自分で勉強する前に先生が教えてくれます。テキストも渡されますし、わからなかったら先生に聞くこともできます。大学の授業も同じようなものです。独学でなければ、それは教育なのですから。
(中略)
でも、本当に必要なことや、本当に面白い事をやろうとするとき、 概して「未知との遭遇」という事態が発生します。みなさんはロゼッタストーンをご存知でしょうか?ナポレオンが見つけた石の板です。その石には複数の言語で同じ文章が書かれていました。しかし、それが書かれたのは太古の昔で、何が書いてあるのか誰にも読めませんでした。でも、時間と努力を惜しまずに解読した人がいます。君達が頑張っている英語の文章の翻訳は「教育」ですが、ロゼッタストーンはまさに「未知との遭遇」」です。「どうやら文章みたいだ」ということしかわかりません。辞書もありません。「未知との遭遇」とは、こういったことです。
(中略)
君達が一番困るのは、人生で一度も「未知との遭遇」を経験していないのに、君達が求めるものは概して「未知との遭遇」だから、いままで通り努力すれば理解できるだろうと思って挫折するということです。
とのことです。医学部の教授をなさっていたのに物理学を教えているという方で、いま思い返してみると偉大な先生でした。
では、上のプログラムについて説明します。e=oval 100,100,100,100,:fill=>blue はもう大丈夫でしょう。その次ですが、
motion do
  ~~
end
という構文で、「マウスが動いたら~~をしろ」という命令が書けます。ためしに、
Shoes.app do
  motion do
    oval rand(800),rand(800),10,10
  end
end
というプログラムを実行してみて下さい。ほらね、マウスが動くと反応します。次の、
if mouse[0]==1
 ~~
end
について説明する必要があります。これは、「もしマウスのボタンが押されていたら~~をしなさい」という命令です。ちょっと待ってください。なぜ「 mouse[0]==1 」なのですか?
でも (なにか)[2] とかっていう表現は出てきました。配列です。という事は mouse は配列ですか?そうです。でも、どこにも mouse=[34,12,34] とかっていう文が見当たりません。
実は mouse はShoesが用意してくる配列で、その中身は自動的に mouse=[(マウスのボタンが押されているか(押されている場合は1、押されていない場合は0が入る),(マウスポインタの横の位置),(マウスポインタの縦の位置)] と決まっています。ということで、 if mouse[0]==1 とは「もしマウスのボタンが押されていたら」という意味になります。
まだわからないところがありますが、今日は疲れたので、あなたが考えてください。
 

7.アニメーション
 
7-1.ここまで静的な操作しか行ってきませんでした。しかし、面白いのはここからです。
Shoes.app do
  e=rect 100,100,100,100
  animate do
    e.left+=1
  end
end
 動いた!!そうです animate  do は end までの処理を繰り返し実行します。だから
Shoes.app do
  e=rect 100,100,100,100
  animate 20 do
    e.width+=1
  end
end
(widthとは横幅のこと)なんていう風に形を変形することもできます。ここで一番目のプログラムと二番目のプログラムをよく見比べて下さい。animate とdoの間に20が入ってます。これはアニメーションの速さを表しています。だからanimate 100 do とするとanimate do とするときより繰り返しが速くなります。ちなみにデフォルト(初期設定)は10なので、なにも書かないanimate do はanimate 10 doと同じ意味です。
Shoes.app do
  animate 20 do |i|
    para i
  end
end
para は(パラグラフのパラだと思います)文字を表示することができます。(このあたりから説明の文脈がすごく適当になっていきます。ごめんなさい。)
 
7-2.ここでひとつRubyの技術も使った面白いプログラムを書いてみましょう。少し難しいです。とりあえず何も言わずに次のプログラムを実行してみてください。
 
Shoes.app do
  class Ball
    def initialize position,move
      @position=position
      @move=move
    end
    attr_accessor :position,:move
  end
  
  balls=[]
  10.times do
    balls.push(Ball.new([rand(100),rand(100)],[rand(10),rand(10)]))
  end
 
  animate 100 do
    clear
    balls.each do |ball|
      ball.move[0]*=-1 if ball.position[0]<0 or ball.position[0]>500
      ball.move[1]*=-1 if ball.position[1]<0 or ball.position[1]>500
      ball.position[0]+=ball.move[0]
      ball.position[1]+=ball.move[1]
      oval ball.position[0],ball.position[1],10,10,:fill=>blue(0.3)
    end
  end
end
どうでしょう?すごいでしょう?アニメーションは面白いですか?
さて、このプログラムを理解するには
①Rubyの知識
②Shoesの知識
③アイデア
の三つが必要です。実際、この三つがあれば自分の思った事が即座にプログラミングできるようになります。
では、順を追って説明していきますので、ついてきてください。
 
7-3.先のプログラムではボールが壁に跳ね返ります。どうやってやるのでしょう?この効果を実現するためにはちょっとしたアイデアが必要ですが、これは頭のいい小学生なら(むしろ小学生なら)、もしかしたら思いつくようなトリックです。では、次のプログラムを実行して下さい。
Shoes.app do
  e=oval 100,100,100,100
  m=1
  animate do
    e.left+=m
  end
end
では次はどうでしょう?辛抱強くまってやってくださいね。
Shoes.app do
  e=oval 100,100,100,100
  m=1
  animate do
    if e.left>200
      m=-1
    end
    e.left+=m
  end
end
跳ね返りました。e.left にmをたす動作を繰り返し行いますが、if文で「eの横の位置が200を超えたらmを-1にしろ」という命令をしています。よく考えてください。最初はmが正の値ですからeは右横に動きます。ここでmを-1にしてやれば、e.left+=(-1) になりますから、左に動くわけです。どうですか?
では次です
Shoes.app do
  e=oval 100,100,100,100
  m=1
  animate do
    if e.left<0 or e.left>200
      m*=-1
    end
    e.left+=m
  end
end
このプログラムではさらに、左に行くと左でも跳ね返ります。さっきのプログラムを途中でやめてしまった大半の人はさっきのプログラムの行く末を見てください。左に向きを変えたあと、ウィンドウから見えなくなってしまいます。簡単なことではないので、じっくり考えてみてください。
Shoes.app do
  e=oval 100,100,100,100
  m=1
  animate do
    if e.left<0
      m=1
    end
    if e.left>200
      m=-1
    end
    e.left+=m
  end
end
と書いても同じですが、「うまくありません」。この、「うまくない」という表現は数学の先生が使いたがる表現で、「かっこよくない」とか、「頭がわるそうな」という表現です。そうです、このプログラムは全くうまくありません。ここで ③のアイデアが必要になってくるわけです。もう一度上の二つのプログラムを見比べてください。どうでしょう?
少し立ち止まって考えてみてください。「壁にぶつかる」という効果をどうとらえるかという問題です。たとえば、「壁にぶつかる」という効果を「左の壁にぶつかったら、右方向に行くようにして、右の壁にぶつかったら左方向に行くようにする」と捉えたとすると、この場合は左の壁にぶつかったときと右の壁にぶつかった時で処理を分ける必要があります。しかし、「壁にぶつかる」という効果を「壁にぶつかると向きが反転する」というとらえ方をするとただ単に -1 をかけて向きを変えるというプログラムで済むのです。プログラムを組んでいるとき、しばしばこういった問題と、問題に対するアイデアに遭遇します。私にとってはこれがプログラミングの醍醐味の一つです。
 
7-4.さっきまでは e.left という表現で丸を動かしてましたが、7-2の冒頭で紹介したおもしろいプログラムではそういった表現はまったく見当たりません。また ③アイデア が必要です。
子供の気持ちに戻って考えてみてください。コンピュータで丸を動かすのにはどうしたらよいでしょう。普通に考えてもわからない人はコンピュータに不慣れな方でしょう。問題ありません。みんな最初は不慣れですから。コンピュータで丸を動かすには、アニメの手法をもちいればいいのです。つまり、丸をいどうするのではなく、ちょびっとづつ位置を変えた丸を描いていけばいいのです。
Shoes.app do
  x=100
  y=100
  animate do
    clear
    x+=1
    y+=1
    oval x,y,100,100
  end
end
つまりこんな感じです。ここでは今まで使ってきた方法に加え、新たに clear が入っています。これは「今まで書いた絵をけせ」という命令です。この文がぬけるとどうなるか実験してみてください。
上のプログラムで見てもらうとわかる通り(わかりますか?わからない人残念)こんな発想でも動きます。要するに動けばいいわけです。外見が全てです。いろんなアイデアが浮かんできますか?
ではさっきのプログラムといまのプログラムを組み合わせてみましょう。
Shoes.app do
  x=100
  y=100
  xmove=1
  ymove=3
  animate do
    clear
    if x<0 or x>200
      xmove*=-1
    end
    if y<0 or y>200
      ymove*=-1
    end
    x+=xmove
    y+=ymove
    oval x,y,100,100
  end
end
(なぜymove=1 ではなく ymove=3 なのか分かった人は相当頭がいいです。実は跳ね返る時に横としたの壁に同時にぶつかると動作が面白くないので、こうしているだけです。)
 
7-5.すこしでもRubyを触った人は配列がわかるでしょう。配列はデータを入れる整理箱です。つまり、部屋に散らばったプリントや本を段ボールに全て投げ込むような感じでデータを配列に投げ込んでしまいます。すると、段ボールを動かすと全てのプリントと本が同時に移動できるのと同様に、配列一つを指定しただけで多くのデータを一度に扱えるのです。すごいアイデアです。
ということで、たくさんのデータを扱ってみましょう。たくさんの丸を。
Shoes.app do
  balls=[]
  10.times do
    ball=[rand(100),rand(100),rand(10),rand(10)]
    balls.push(ball)
   end
  animate do
    clear
    balls.each do |ball|
      ball[0]+=ball[2]
      ball[1]+=ball[3]
      oval ball[0],ball[1],10,10
    end
  end
end
ん?ball=[rand(100),rand(100),rand(10),rand(10)] とはなんの事でしょう?これをballsに入れているわけですから、ballsの中身はballs=[ball,ball,ball,ball,ball,ball,ball,ball,ball,ball]という感じになって、各々のballは[30,43,3,5]とか、[23,95,2,4]とかいう値が入っています。つまり、ballsはballs=[[60, 82, 6, 6], [9, 35, 3, 1], [89, 73, 4, 5], [78, 3, 0, 0], [19, 82, 4, 4], [51, 81, 5, 1], [65, 98, 5, 9], [61, 72, 9, 7], [55, 88, 1, 0], [10, 55, 9, 6]]とかっていう感じになっているのです。
ここで、ball[0]+=ball[2] と ball[1]+=ball[3] と oval ball[0], ball[1], 10, 10 を見ればわかるように、ball=[rand(100),rand(100),rand(10),rand(10)]は実はball=[(横の位置),(縦の位置),横の速さ),(縦の速さ)]となっているのです。こういった方法に嫌悪感を示す人もいるかもしれません。なぜなら、e=rect 100,100,20,10 e.left+=1 とした場合は、100という数字が「横の位置」という明確な意味を持っていますが、今回のプログラムでは数字をいじって画像に起こしただけで、ball=[32,34,1,4] を見た人は 32 が ball の「横の位置」だということをわからないからです。しかし、しばしばこういった手法はプログラムの高速化や処理の柔軟性に貢献します。
なるほど。ということは上のプログラムを少しだけ変えて、
Shoes.app do
  balls=[]
  10.times do
    balls.push([rand(100),rand(100),rand(10),rand(10)])
   end
  animate do
    clear
    balls.each do |ball|
      ball[0]+=ball[2]
      ball[1]+=ball[3]
      oval ball[0],ball[1],10,10
    end
  end
end
これでもOKです。
 
7-6.もうすこしいい方法を紹介します。そして、この方法がまさにプログラミングを楽しいものにしてくれるのです。
(※数学を全くやったことのない人へ……下のプログラムでいう x と y は、 x が「横の位置」 yが「縦の位置」という意味です。)
Shoes.app do
  class Ball
    def initialize x,y
      @x=x
      @y=y
    end
    attr_accessor :x,:y
  end
  ball=Ball.new(100,200)
  oval ball.x, ball.y, 100, 100
end
いったい何をやっているのでしょう。わからないことがたくさんあります。例えば、class, def, initialize, @x, @y, attr_accessor, Ball.new(100,200), ball.x, ball.y などです。
しかしこれらすべてがShoesではなくRubyの知識です。そして今気づいたのですが、非常に説明しにくい。ということで、自分で学んでください(なぜってこれは「暫定的」なチュートリアルですから…)。
 
 
ただし、一つだけ簡単に説明できて、かつ重要なことがあります。
 ball    =        Ball.       new          (100   ,    200)
(ball  は   Ballの  新規作成  100  200)
と書くと ball.x で100、 ball.y で200 を意味することができるのです。つまり、x=100、y=200の位置にボールを作ったのです。どういう仕組みかというと、「生む」の隣に書いたかっこの中が上の方の def initialize x,y の x,y に対応していて、そのx,y はまた、ball.x ball.y に対応しているのです。うえのプログラムであなたが自由に名前を変えられる所は下に示したブルーのぶぶんです。
Shoes.app do
  class Ball
    def initialize x,y
      @x=x
      @y=y
    end
    attr_accessor :x,:y
  end
  ball=Ball.new(100,200)
  oval ball.x, ball.y, 100, 100
end
ここで問題です。「説明していないのに問題はないでしょう」とおこらないでください。やまかんで答えてみてください。
ボールがもうひとつ、x=100、y=300の位置に欲しい時どうしたらいいでしょう?
どうするかというと、ball2=Ball.new(100,300)とすればいいのです。x=300、y=200の位置に欲しい時は ball2=Ball.new(300,200)と書けばいいのです。
では ball の x を知りたい時はどうするでしょう?
その通り、ball.x とするのです。ball2 の y を知りたい時は ball2.y とかきます。
…まぁとにかく、いじってみましょう。わからない時はいじくりまわすとなんとなくわかるようになります。(それから解説書に戻ってもいいのです。)
変更した部分をレッドにします。
Shoes.app do
  class Ball
    def initialize position
      @position=position
    end
    attr_accessor :position
  end
  ball=Ball.new([100,200])
  oval ball.position[0],ball.position[1],100,100
end
x と y を position という配列にしてしまったのです。さっき、 ball.x で 100を意味することができるといいました。いま、 ball.position で [100,200] を意味しているのです。配列です。配列とはなんだったかというと、array=[10,40,20] と書いてから array[0] とすれば 10  が出てきて、 array[1] とすれば 40 が出てくる整理箱でした。では [10,40,20][0] は何になるでしょう。答えは 10 です。どういう仕組みかというと、array=[10,30,40] とすると、この文以降の 「array」 はすべて [10,30,40] という意味になります。だから、array[0] と [10,30,40][0] は同じ意味なのです。
ということで、先ほどの ball.position に戻っていみましょう。さきのプログラムでは ball.position[0] とか ball.position[1] とかいう表現を使っています。さっきも言ったように、 ball.x で100を意味したように ball.position で[100,200]を意味します。ということは ball.position[0] は [100,200][0] を意味するということです。
 
7-7.これで、ballを自由に扱えます。手始めに配列にでもいれてみましょう。
Shoes.app do
  class Ball
    def initialize position
      @position=position
    end
    attr_accessor :position
  end
 
  balls=[]
  10.times do
    balls.push(Ball.new([rand(300),rand(300)]))
  end
 
  balls.each do |ball|
    oval ball.position[0], ball.position[1], 10, 10, :fill=>rgb(rand(500),rand(500),rand(500))
  end
end
おっと、配列をあつかうものすごくパワフルな方法を説明するのを忘れていました。eachです。eachとは英語で「それぞれ」という意味です。
Shoes.app do
  [100,200,300].each do |m|
    oval m,m,10,10
  end
end
 
mには順番に100,200,300の値が入ります。だから、
Shoes.app do
  oval 100,100,10,10
  oval 200,200,10,10
  oval 300,300,10,10
end
と書いたのと同じ効果が手軽にかけるのです。……脇道にそれました。では、上の(最初の)プログラムについて考えてみましょう。ふんふん、ballsという整理箱を用意して、そこにBall.new([rand(300),rand(300)])を入れるのを 10.times do で十回繰り返しているのですね。ええっと、じゃあ、ここの部分は
~
10.times do
  ball=Ball.new([rand(300),rand(300)])
  balls.push(ball)
end
~
と書いてもおなじかな?同じです。つまり、さっきみたいに balls=[ball,ball,ball,ball,ball,ball,ball,ball,ball,ball] というかんじになっていて、
~
balls.each do |ball|
  oval ball.position[0],ball.position[1],10,10
end
~
の部分は、
~
oval balls[0].position[0], balls[0].position[1], 10, 10
oval balls[1].position[0], balls[1].position[1], 10, 10
oval balls[2].position[0], balls[2].position[1], 10, 10
oval balls[3].position[0], balls[3].position[1], 10, 10
oval balls[4].position[0], balls[4].position[1], 10, 10
oval balls[5].position[0], balls[5].position[1], 10, 10
oval balls[6].position[0], balls[6].position[1], 10, 10
oval balls[7].position[0], balls[7].position[1], 10, 10
oval balls[8].position[0], balls[8].position[1], 10, 10
oval balls[9].position[0], balls[9].position[1], 10, 10
~
という感じです。(ここで、ちょっと自慢を。「これ書くの大変だっただろうな」と思った人、なんのその、10.times do |i| ですぐに書けるのです。)
OK、これで最初のプログラム(7-2のプログラム)を理解できますね。
 
8.キーボードをつかう
8-1.簡単なキーボード操作をしてみましょう。
プログラムを実行して、a や b を押してみてください。
Shoes.app do
  keypress do
|key|
    case key
      when "a"
      para "animal\n"
      when "b"
      para "boys\n"
    end
  end
end
さっきも e.click do で「クリックされたら」とか、 motion do で「マウスが動いたら」、とかであったように、ここでも keypress do で「キーが押されたら」という意味です。|key| というのが do のあとにありますが、これは押されたキーが入る変数で、名前は何でも構いません(よって、|key| を |button|としてもOKです。)そして、つぎのcase key ですが、これはRubyの機能です。case の次の key の値(文字)によって処理を変えたい場合に使います。すぐ下にあるwhenというのは「このときは」という意味で、次に続く値(今の場合は"a")の時はpara "animal\n" をやれという意味です。前にも言いましたが、para は次に続く文字を表示するShoesの機能です。…animalの隣に変な文字が入っています。これは、改行(行を一段移すこと)の意味です。ためしに \n を抜いてみてください。すぐに効果がわかるでしょう。
 
8-2.ではどんな風に使いましょうか。たとえばこんなのはどうですか?
プログラムを実行したら "o" や "r" を押してみて下さい。
Shoes.app do
  mode="oval"
  keypress do |key|
    case key
      when "o"
      mode="oval"
      when "r"
      mode="rect"
    end
  end
  animate do
    clear
    if mode=="oval"
      oval 100,100,100,100,:fill=>rgb(rand(500),rand(500),rand(500),rand(500))
    end
    if mode=="rect"
      rect 100,100,100,100,:fill=>rgb(rand(500),rand(500),rand(500),rand(500))
    end
  end
end
 
modeを変換するモード変換です。もう気づいた人もいるかも知れませんが、case は if で代用できます。しかし、case が「仕分け」に特化された方法である一方、if は「条件の判定」に特化されています。case の文を if に置き換えてみるとわかるように、 if  だけだとプログラムが長くなってしまうので、場合によってcase と if を使い分けます。
 
8-3.もっと実用的なプログラムを紹介します。
Shoes.app do
  word="  "
  keypress do |key|
    case key
     
when :backspace
        word.slice!(-1)
      when :tab
        word+="  "
     
else
        word+=key
   
end
    clear
    para
word
 
end
end
 
簡単なメモ帳
 
わからないところがあるでしょう。たとえば :backspace。 これはバックスペースを意味したときに使う表現です。どういうことかというと、例えばさっきまでは n が押された場合を case key ~~~ when 'n'   とかって書いてましたが、バックスペースにあたる文字はないので、同じ表現の仕方は不可能です。ということでこの表現なのです。タブ(スペースの親戚と思ってください。)も同じです。
つぎにわからないのは else です。これは、「key がどの場合にも当てはまらなかった時」という意味です。つまり、ここでは :backspace と :tab 以外のすべての入力は else と判定されて、 word+=key という処理に入ります。
…word+=key とはどういうことでしょう。上の方を見ると word="  " となっています。これで word には "  " がはいっているのです。いままで文字を扱ってこなかったので、この感覚は分かりづらいと思いますが、どうってことないです。number=344 とすれば number に 344 が入るのとおなじように、word="why do you think so?" と書けば word に "why do you think so?" が入るのです。では、word+=key とはどういうことでしょう。key には「押されたキー」が入っていますので、例えばあなたが n を押したら key には "n" がはいります。ということで、 word+=key はこの場合、 word+="n" となるのです。前にやったように、m+=n は m=m+n と同じ意味なので、word+="n" は word=word+"n" となるのです。
でも、文字列に足し算ができるのでしょうか?できます。"my name is "+" Taro" は "my name is  Taro!" と同じ意味になります。
 
8-4.ということで、さっきまで 7 でやっていた内容と組み合わせてみましょう。
Shoes.app do
  class
Word
    def initialize string,position,move

      @string=string
      @position=position
      @move=move
   
end
    attr_accessor
:string,:position,:move
 
end
  newword="  "
  words=[]
  keypress do |key|
    case key
      when :backspace
       newword.slice!(-1)
      when :tab
       newword+="  "
      when "\n"
       words.push(Word.new(newword,[300,300],[rand(10)-rand(10),rand(10)-rand(10)]))
       newword="  "
      else
       newword+=key
    end
  end
  animate do
    clear
    para
newword
    words.each do |word|
      word.move[0]*=-1 if word.position[0]<0 or word.position[0]>500
      word.move[1]*=-1 if word.position[1]<0 or word.position[1]>500
      word.position[0]+=word.move[0]
      word.position[1]+=word.move[1]
      para word.string,:left=>word.position[0],:top=>word.position[1]
    end
  end
end

 


 
9.謝辞とお詫び
ここまででこのチュートリアルを暫定的に終わりにします.ここまで参考にしてくださったユーザの方々に深く感謝申し上げます.
もし要望があれば,さらなる改善と追記をさせていただきたいと思います.
恐れながら申し上げますと,私はRubyに詳しいわけでも,Shoesを「ちゃんと」使えるわけでもありませんので,私より優秀な人がこのチュートリアルを改善すべきだと思います.
ということで,「このチュートリアルを書いている人はきっと優秀なプログラマなんだろうな」と少しでも思った方にお詫びいたします.ごめんね.
連絡先:nomobonson@gmail.com (コピペ用:nomobonson@gmail.com )
 
 
 
 
 
 
 10.おまけ
 
10-1.ウェブへGO
Shoes.app do
  rect(100,100,100,100).click do
    visit "http://google.com"
  end
end
 さぁこれでウェブを使えます.「visit("アドレス")」 でウェブ接続です.
 
 
 
 
 
 
 
 

Comments