プログラミングで 図形を 動かして みよう!
目的・ ねらい
シンプルな プログラムを 理解 し、 自分で 変更 した パラメータに よって 図形の 動きが 変化 する ことを 体験する ことで、 重度 視覚 障害が あっても グラフィカルな プログラミングを 自作 する 可能性が ある ことを 感じて 欲しいと 考えて います。 DXrubyを 使い、 短い コードで 動く ものを 体験 します。
シンプルな プログラムを 理解 し、 自分で 変更 した パラメータに よって 図形の 動きが 変化 する ことを 体験する ことで、 重度 視覚 障害が あっても グラフィカルな プログラミングを 自作 する 可能性が ある ことを 感じて 欲しいと 考えて います。 DXrubyを 使い、 短い コードで 動く ものを 体験 します。
ruby および ライブラリの DXrubyを 使って、 キーボード 入力に 反応 して 図形が 動いたり 音が 再生 されたり する プログラムを 理解 し、 自分で パラメータを 変更 して 点図 ディスプレイの DV-2で 動きを 確認 します。
・ コンピュータに Rubyを インストール し、 DXrubyを 展開 して おきます。
・ .rbの ファイルの 規定の プログラムを マイエディットや メモ帳に して おきます。
・ DV-2の ドライバと GViewを インストール して おきます。 DV-2の Ver.1を Windows10で 利用 する 場合は 署名 なし ドライバの インストールを 許可 しなくては ならないので、 セキュアブートを OFFに した 後に コマンド ラインで
bcdedit /set TESTSIGNING ON
と 打ち込み、 設定の 更新と セキュリティ、 回復 メニューから PCの 起動を カスタマイズ し 署名 なし ドライバを インストール できるように する …など、 多少 面倒な 作業が 必要に なります。
・ DV-2に 表示 する プログラム GViewの 動作 確認を して おきます。 COMポートは 一回 指定 すれば 次から 正しい ものを 最初に 選んで くれます。 設定と しては フォーカスの 当たった ウィンドウだけを 表示 する モードに し、 リフレッシュ レートを 0.1秒に して おきます。
・ ユーザー ディレクトリの 下に サブディレクトリを 作り、 その 下に サンプル プログラムを すべて コピー して おきます。 もしくは USBメモリなどに 入れて おきます。
Windowsキーを 押した 後に 「cmd」と 入力 して コマンド ラインを 開きます。
「cd サブディレクトリ名」 もしくは 「ドライブレター:」などで サンプルの ある 場所に 移動 します。 サンプルは 数字で 始まる プログラム名などに して おき、 直接 入力 したり Tabキーの ファイル名 補完などを 使ったり して コマンド ラインから 開くように します。
例えば 「1.rb」と いう ファイル名を つけて いた 場合 「数字の 1を 押して Tabキーを 押してから Enterキーを 押して ください」と 伝える ことで、 メモ帳で ソース コードを 開く ことが できます。 (あらかじめ 規定の プログラムを メモ帳に して おく 必要が あります)
最初の サンプルは 以下の 四角形を 描く コードです。 開いたら 順に 説明 します。
#まず dxrubyと いう ライブラリを 使えるように する。
require 'dxruby'
#Image オブジェクトを 生成。
img1 = Image.new(640, 480, [0, 0, 0])
#白い 四角形を img1に 描く。
img1.box_fill(100, 100, 250, 200, [255, 255, 255])
#ここから 無限 ループ スタート。
Window.loop do
#img1 領域を 描く。
Window.draw(0, 0, img1)
end
・ シャープ(#) 以降は プログラムとは 関係の ない コメント すなわち 注釈に なる。
・ requireは 「要求 する」と いう 意味。 dxrubyと いう ライブラリを 使えるように 宣言 して いる。
・ ライブラリとは、 外部から 呼び出せる プログラムを ひとまとめに した もので ある。
・ まず 「新しい Image オブジェクト」を Image.newと いう 命令で 作る。 オブジェクトと いうのは プログラムの 中の 「意味の ある 塊」の こと。 とりあえず Image オブジェクトは 絵を 描く キャンバスのような ものだと 説明 して おく。
・ 最初の 数字は 横幅、 次の 数字は 高さ、 角カッコで 囲われた 数字は 背景色を 表す。 色は 順に 赤、 緑、 青の 色の 強さの 意味で あり、 255が 最大値で ある。 すべて 0だと 黒を 意味 する。
・ 生成 した Image オブジェクトに img1と いう 名前を 付けて いる。 イコールは 名前を つけると いう 意味で ある。
・ 次に img1 オブジェクトに box_fillと いう 命令で 四角形を 描く。 命令の ことを 「メソッド」と 呼ぶ。 左上の 座標と 右下の 座標、 色を 指定 する。
・ オブジェクトに 対する 命令は ドットで つなげる。
・ Window.loop doから endまでは 無限に 繰り返される。 Window オブジェクトに 対して 何も 指定 しなければ 幅 640ドット 高さ 480ドットの ウィンドウが 生成 される。
・ 無限 ループの 中で drawと いう 命令を 使って img1を 描いて いる。 左から 0ドット、 上から 0ドットの 位置を 指定 した ことに なる。 その 位置が img1の 左上の 点に なる。 位置を ずらす ことも できる。
これらの 解説を 終えたら、 実行 して みます。
ruby プログラム名
と 打ち込ませます。 適宜 ファイル名 補完を 使わせた 方が 確実です。 「rubii」などと 打って しまう 場合が あるので、 「アール、 ユー、 ビー、 ワイ、数字、 タブキー、 エンター」と 最初は 細かく 指示 する 方が 良いでしょう。 プログラムを 動かすと、 下のような ウィンドウが 現れます。 終了は Alt+F4です。
四角形を 表示 した ウィンドウ
ここで Windowsキーを 押し、 「GView」と 打ち込んで GViewを 起動 します。 移動 する 図形の 表示の ために 0.1秒の リフレッシュ レート 設定を 確認 して ください。 GViewが 問題 なく 起動 したら、 本体の 拡大・ 縮小キーと 側面に ある 上下 左右の カーソルキーの 使い方を 説明 します。 手前の ジョイスティック 部分は 古い 機種は バー状に なって いて 誤操作 して しまうかも しれないので、 周辺を 押すように 指導 します。 また、 拡大 縮小の ボタンと 間違えて 横の ステータス 表示の ボタンを 押して しまう 場合が あります。 慌てずに もう 一度 同じ ボタンを 押す ことを ここで 教えて おきます。 ステータス 表示で 誤操作を して しまうと、 DV-2の 表示 閾値を 変えて しまったり する ことも あるので 注意 します。 あらかじめ 硬い 紙などで 覆って おくのも 有効だと 思います。
線や 円など、 他の 図形を 描いて みます。 img1.box_fillの 行に 続いて 下記 コードを box_fillの 行の 下に 入力 させ、 表示 させます。 キーボードの 打ち込みに 不安が ある 場合は、 テキスト ファイルを 用意 して おいて、 全選択、 コピー、 ペーストなどを 指示 します。
説明の ポイントは 数値の 意味に なります。
#円を 描く。
img1.circle_fill(340, 200, 50, C_WHITE)
#線を 描く。
img1.line(20, 300, 500, 30, C_YELLOW)
・ circleは 円、 fillは 塗りつぶしの 意味。
・ circle_fill(x座標, y座標, 半径, 色)
・ line(端点のx座標, 端点のy座標, 異なる端点のx座標, 異なる端点のy座標, 色)
・ C_WHITEは 白、 C_YELLOWは 黄色。
これらの 意味を 理解 させた 後で、 自分で 数値を 変えて 実行 させます。
課題と しては、 見える 生徒さんに 対しては 色を 用いて 国旗などを 描かせたり、 全盲の 生徒さんに 対しては 雪だるまなど、 四角形と 円で 描ける 触察 可能な 図形を 作らせたり すると 良いと 思います。
いくつか 図形を 追加 した ウィンドウ
ここまでは Image オブジェクトを キャンバス 代わりに 使って みましたが、 実際には 画像 ファイルを 読み込んで 表示 したり する 「画像の 入れ物」と して 使います。 次の サンプルを 確認 し、 動かして みます。
require 'dxruby'
#test.pngと いう 画像 ファイルを 読み込んで img1と いう 名前を つける。
img1 = Image.load('test.png')
#ここから 無限 ループ スタート。
Window.loop do
#img1を 指定 した 座標を 左上と して 描画 する。
Window.draw(100, 100, img1)
end
新しい 部分は Image オブジェクトの load メソッドだけです。 ここを 説明 した 後で、 表示 する 座標値などを 変えさせて みて ください。 画像 ファイルには、 生徒の 年代が 皆 知って いる キャラクターの なかで DV-2に 表示 しやすい 明るい 色の ものなどを 選ぶと 良いでしょう。
キーボードの 矢印キーの 入力に ついては Input.xと Input.yで 取得 できます。 ジョイスティックが つながって いる 場合は ジョイスティックの 動きが 反映 されます。 次の サンプルを 開いて 中を 確認 します。
require 'dxruby'
#test.pngと いう 画像 ファイルを 読み込んで img1と いう 名前を つける。
img1 = Image.load('test.png')
#画像の 触察が 難しいようなら DV-2用に 以下の 行を 使う。
#img1 = Image.new(50, 50, C_WHITE)
#xと yの 値を ゼロで 初期化 する。
x=0; y=0;
#ここから 無限 ループ スタート。
Window.loop do
#xと yを 更新 して その 座標で img1を 描く。
x=x+Input.x; y=y+Input.y;
Window.draw(x, y, img1)
end
・ img1の 生成までは これまで 学んで いる。
・ xと yは 中の 数値が 変わる 入れ物で 「変数」と 呼ぶ。 最初に ゼロを 代入 して 初期化 して いる。
・ Window.loop do ~ endの 無限 ループの 中で xと yは 変化 する。
・ もとの 値に Input.xや Input.yで 得られる 値を 加えて いる。 これらは 矢印キーが 押されて いると +1や -1に なる。
説明を 終えたら 「もっと 速く 動かすには」 「遅く 動かすには」と いう 課題を 解かせます。 適宜 Input.xが 変化分で あることを ヒントに 与えたり します。
座標値を 一定 割合で 変化 させる ことで 動く ボールを 表現 して みます。 以下の サンプル コードを 流れに 沿って 確認 します。
require 'dxruby'
img1 = Image.new(30, 30, C_BLACK)
img1.circle_fill(15, 15, 15, C_WHITE)
x=0;
#ここまでは 既に 学んだ 内容。 次の dxは x方向の 変化分。
dx=1
#円を 縦方向の 真ん中に 表示 する ために 以下の 式で yを 決める。
y=(Window.height-img1.height)/2
#無限 ループ スタート
Window.loop do
#xを dxだけ 変化 させる ために x=x+dx と する。 x+=dx と いう 書き方も ある。
x+=dx
#xが ウィンドウの 横幅を はみ出そうに なったら 方向を 変える。
if(x>Window.width-30) then
#方向を 変える。 ここは dx*=-1 と 書いても 良い。
dx=dx*(-1)
end
Window.draw(x, y, img1)
end
・ dxと いう 変数が 新たに 加わった。 これは 変化分を 意味 する 変数。 初期値は +1。
・ yは 固定。 ウィンドウの 高さの 半分から img1の 半分の 高さを 引いた 座標。 これにより 図は 真ん中に 来る。
・ 無限 ループの 中で x=x+dx と する ことで 右に 移動。
・ 右端で 跳ね返る ために 「条件 分岐」を 行う。 条件 分岐とは、 「もし ~なら 〇〇 する」と いう 命令を 実現 する もので ある。
・ 条件 分岐は 「x座標が ウィンドウの右端の座標-img1の横幅 より 大きく なった 場合」に 変化分を 左方向に する こと。
・ 右方向への 変化 (dx=1)から 左方向への 変化は -1を 掛け算 すると 実現 できる。
しかし このままだと、 右で 跳ね返った 後、 左側に 消えて いって しまいます。 そこで、 「x座標が ゼロより 小さく なったら」と いう 条件を 加えさせます。
if(x>Window.width-30 || x<0) then
「この 縦棒 2つは、 「もしくは」と いう 意味で ある。 ここで dx=dx*(-1) の 意味を 再確認 する。 左方向への 移動から 右方向への 移動に 変わるのも、 実現 できて いる。」と いう ことを 理解 させます。
ここまで 来たら 生徒の 進度や 理解度を 確認 しつつ 「y方向にも 同様に 変化 する プログラムに せよ。」と いう 課題などを 出して みるのも 良いでしょう。
require 'dxruby'
img1 = Image.new(80, 80, C_BLACK)
img1.circle_fill(40, 40, 40, C_WHITE)
x=0; dx=3
y=(Window.height-img1.height)/2
dy=3
Window.loop do
x+=dx; y+=dy
if(x>Window.width-img1.width || x<0) then
dx*=-1
end
if(y>Window.height-img1.height || y<0) then
dy*=-1
end
Window.draw(x, y, img1)
end
スペースキーを 押したら 音が 再生 される サンプル コードを 開いて 中身を 確認 します。
require 'dxruby'
#Sound オブジェクトを 生成 して snd1と いう 名前を つける。
snd1 = Sound.new("C:¥¥Windows¥¥Media¥¥ding.wav")
#無限 ループ スタート。
Window.loop do
#もし SPACEキーが 押されたら snd1を 再生 する。
if Input.key_push?(K_SPACE) then
snd1.play
end
end
・ Sound.newで サウンド オブジェクトを 生成、 snd1と いう 名前に して おく。
・ Input.key_push? と いう 命令で 特定の キーが 押されたか どうか 判断が つく。
・ スペースキーが 押されたならば Sound オブジェクトの playメソッドを 呼び 音を 鳴らす
プログラムが 理解 できた 後で、 snd1=… の 行を コピー して snd2=…とし、 if文も コピー して 異なる キーを 押すと 異なる 音が 鳴る プログラムを 作成 させます。 キーコードは K_Aや K_Bなどを 使わせます。
跳ね返る ボールの プログラムを ベースに して、
・ 壁で 跳ね返る 時に 音が 鳴る
・ 上下 矢印キーで 速度が 変わる
と いう 機能を 追加 した プログラムを 作らせます。
・ 進度や 理解度の 差が 出やすいので、 進んで いる 生徒さんには 比較的 自由に やらせて 構いません。 遅い 生徒さんの フォロー時には、 あまり 講師側が キー 操作を 手伝い すぎないように しましょう。
・ サンプル プログラムの 流れを 理解 する。
・ プログラムの 中の 数値の 意味を 理解 し、 自分の 思った 通りの 動きを させられるように 編集 する ことが できる。
生徒用には、 サンプル プログラムを あらかじめ コンピュータに 入れて おきます。