概要
この記事は中学高校生向けプログラミング教室の教材として作ったものを一部改変したものです。
以前、
・DXRubyで 1ステップずつ作っていく「ブロック崩し」 - Qiita
という投稿をしました。
RubyやDXRubyは、衝突判定だけでなく、プログラミングに便利な数々の機能を持っています。そのため、わずか100行足らずで「ブロック崩し」ができてしまいました。
しかし、プログラミングの学習としては、便利機能に頼りすぎるのもどうなんだろうか?と思っていたところ、『プログラムはこうして作られる』という本と、その著者の平山尚さんの言葉を見つけてドキッとしました。
「なんか動くもん作れていい気になってんだろうが、ライブラリを剥ぎ取ったおまえ自身の力はその程度だ。よく鏡を見ておけ」平山 尚 @hirasho
もし、それらの便利な機能をなるべく使わず、基本的な機能だけを使って「ブロック崩し」を作ってみるとどうなるでしょうか?
プログラミングの本当の力が試されることになります。
そこで、今回はRubyとそのゲームライブラリDXRubyを使いますが、以下のような基本機能・命令だけを使うことにします。
-
Rubyは、プログラミング言語として最低限の機能
-
DXRubyは、ウィンドウの生成、座標(x,y)に点を描く、座標(x,y)の色を取得する、文字の表示、マウス/キー/カーソルキーの状態の取得のみ
今回はこの課題に挑戦してみます。
→ 『プログラムはこうして作られる プログラマの頭の中をのぞいてみよう』(平山尚 著)
前の記事
・DXRuby:「当たり判定」を自分で作ってみよう C. 色で判定する - Qiita
関連記事
・Ruby用2Dゲームライブラリ DXRuby:使い方の初歩 - Qiita
・プログラミング初心者向け:DXRubyで 1ステップずつ作っていく「ブロック崩し」 - Qiita
・DXRuby:「当たり判定」を自分で作ってみよう - Qiita
技術解説
使用する基本機能・命令
前述の著書で使われた「プログラミング言語 Sunaba」を参考にして以下の通りとしました。
→ プログラミング言語Sunaba
https://hirasho.github.io/Sunaba/
● Ruby
-
定数 変数 true false nil
-
数値 文字 文字列 ' ''
-
演算子/式
=(代入)
+ - * / % < > <= => == != ( )
&& ||
- 制御構造
while~end
if~(else)~end
return
break
- 関数
def~end
- その他
require puts p #(コメント)
※クラス、配列、ハッシュ、do~end、each などは使わない
● DXRuby
○ Image(Imageクラスはスクリーン以外は使わない)
- $screen = Image.new(640, 480) (ウィンドサイズのスクリーンの設定)
- $screen[x, y] (色の取得)
- $screen[x, y] = 色 (色の設定;これで
ドット(点)
を描く) - 色定数
○ Window
- Window.loop do~end (ウィンドウの生成、更新)
- Window.draw(x, y, $screen) (これで
ドット(点)
を描く) - Window.draw_font() (文字の表示)
○ Input
- Input.x (カーソルキー←→の押下の取得)
- Input.y (カーソルキー↑↓の押下の取得)
- Input.mouse_pos_x (マウス位置xの取得)
- Input.mouse_pos_y (マウス位置yの取得)
- Input.key_down? (キーボードの押下の取得)
○ Font
Font.new() (文字フォントの設定)
※Spriteクラス、衝突判定などは使わない
ソースコード
使用ライブラリ
Windows向けRuby用2DゲームライブラリDXRuby
を使用します。
バージョン1.4.2
以上を想定しています。
1.4.2
より前のバージョンとの主な相違点
-
Window.loop
が複数置ける -
マウス位置を取得する
Input.mouse_pos_x
、Input.mouse_pos_y
の新しい書き方として、Input.mouse_x
、Input.mouse_y
が追加
→ DXRuby 1.4.6:更新履歴
DXRubyインストールの注意点
→ DXRuby 1.4.6 をWindows10で使う時の注意点とインストール方法 - noanoa07 - Qiita
https://qiita.com/noanoa07/items/0ce14c2404df38de94b7
参考サイト
-
DXRuby のホームページ
http://dxruby.osdn.jp -
DXRuby 1.4.6 リファレンスマニュアル
http://mirichi.github.io/dxruby-doc/index.html
困ったときは、このページの「チュートリアル」と「マニュアル」にだいたい書いてあります。
- DXRuby 1.4.1 リファレンスマニュアル
http://dxruby.osdn.jp/DXRubyReference/20095313382446.htm
古いバージョンのリファレンスも役に立つときがあります。
→ 「ブロック崩し」追加課題2;なるべく基本命令だけで「ブロック崩し」を作ってみよう - noanoa 日々の日記
http://blog.livedoor.jp/noanoa07/archives/2050752.html
→ 「ブロック崩し」追加課題に向けて;コンピュータの世界の下側を見てみよう - noanoa 日々の日記
http://blog.livedoor.jp/noanoa07/archives/2048469.html
→ プログラミング言語 Sunaba で「ブロック崩し」を作ってみた - noanoa 日々の日記
http://blog.livedoor.jp/noanoa07/archives/1979433.html
このテキスト関連のブログ記事です。
ライセンス
ソースコード、本解説ともにパブリックドメイン
プログラム解説
0. 練習:ウィンドウを表示
ウィンドウを表示するために、ウィンドウサイズ 640×480(色は透明)の$screen
イメージを作成し、Window.draw
で描画します。($
でグローバル変数にしています。)
→ DXRuby 1.4.1 リファレンス:Imageクラス Image.new
http://dxruby.osdn.jp/DXRubyReference/200953184038328.htm
→ DXRubyリファレンス:チュートリアル 2. 画像の読み込みと描画
http://mirichi.github.io/dxruby-doc/tutorial/basic.html
require 'dxruby'
$screen = Image.new(640, 480)
Window.loop do
Window.draw(0, 0, $screen)
end
1. 練習:点(ドット)を表示する
座標(300, 200)に白色の点(ドット)を表示させてみます。
$screen
上の座標(x,y)に色を指定することで、点(ドット)
を表示させられます。
これには、イメージ[x, y] = 色
を使います。
色の指定は、「DXRubyリファレンス:色配列と色定数について」
http://mirichi.github.io/dxruby-doc/api/constant_color.html
を見てください。
→ DXRuby 1.4.1 リファレンス:Imageクラス Image#[x, y]=color
http://dxruby.osdn.jp/DXRubyReference/200953184038328.htm
require 'dxruby'
$screen = Image.new(640, 480)
Window.loop do
$screen[300, 200] = C_WHITE
Window.draw(0, 0, $screen)
end
2. 練習:点で線を描く
次は、長さ100の線を描いてみます。
線は点(ドット)の集まりとして描画します。
今回、繰り返しはwhile~end
のみを使います。
require 'dxruby'
$screen = Image.new(640, 480)
Window.loop do
width = 0
while width < 100
$screen[300 + width, 200] = C_WHITE
width = width + 1
end
Window.draw(0, 0, $screen)
end
3. 練習:点で四角(トウフ)を描く
線が描けたので、四角(トウフ)を描きます。
二重ループを使います。
- pri_03.rb(失敗!四角にならない)
require 'dxruby'
$screen = Image.new(640, 480)
Window.loop do
width = 0
height = 0
while width < 100
while height < 80
$screen[300 + width, 200 + height] = C_WHITE
height = height + 1
end
width = width + 1
end
Window.draw(0, 0, $screen)
end
二重ループの初期値の設定の間違いです。(ありがち?)
書き直します。
require 'dxruby'
$screen = Image.new(640, 480)
Window.loop do
width = 0
while width < 100
height = 0
while height < 80
$screen[300 + width, 200 + height] = C_WHITE
height = height + 1
end
width = width + 1
end
Window.draw(0, 0, $screen)
end
4. ブロック崩し:壁を描く
それでは、ブロック崩しの壁を描いていきます。
まず、左壁(位置(0, 0)、大きさ(横 20、縦 480) 、白色)
を作ります。
require 'dxruby'
$screen = Image.new(640, 480)
Window.loop do
x0 = 0
y0 = 0
width = 0
while width < 20
height = 0
while height < 480
$screen[x0 + width, y0 + height] = C_WHITE
height = height + 1
end
width = width + 1
end
Window.draw(0, 0, $screen)
end
5. ブロック崩し:壁を複数描く
もう一つ、上壁(位置(0, 0)、大きさ(横 640、縦 20)、白色)を追加します。
require 'dxruby'
$screen = Image.new(640, 480)
Window.loop do
x0 = 0
y0 = 0
width0 = 0
while width0 < 20
height0 = 0
while height0 < 480
$screen[x0 + width0, y0 + height0] = C_WHITE
height0 = height0 + 1
end
width0 = width0 + 1
end
x1 = 0
y1 = 0
width1 = 0
while width1 < 640
height1 = 0
while height1 < 20
$screen[x1 + width1, y1 + height1] = C_WHITE
height1 = height1 + 1
end
width1 = width1 + 1
end
Window.draw(0, 0, $screen)
end
6. ブロック崩し:「四角を描く」をまとめる(関数化)
続いて、左壁(位置(620, 0)、大きさ(横 20、縦 480) 、白色)
を作ります。
コードが複雑になってきたので、「四角を描く」という処理をrect
という名前にまとめます(関数化)。
def rect(引数)
処理内容
end
このrect
を使ってコードを書いてみます。
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
Window.loop do
rect( 0, 0, 20, 480, C_WHITE)
rect( 0, 0, 640, 20, C_WHITE)
rect(620, 0, 20, 480, C_WHITE)
Window.draw(0, 0, $screen)
end
7. 練習:トウフを動かす
トウフをカーソルキーで動かす試作をします。
→ DXRubyリファレンス:チュートリアル 5. カーソルキーの入力
http://mirichi.github.io/dxruby-doc/tutorial/basic.html
- pri_08.rb(失敗!軌跡が残る)
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
x = 300
y = 200
Window.loop do
x = x + Input.x
y = y + Input.y
rect(x, y, 100, 80, C_WHITE)
Window.draw(0, 0, $screen)
end
動いて見えるには、Window.loop
が一周する毎に前回の図形を消す処理が必要でした。
書き直します。
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
x = 300
y = 200
Window.loop do
rect(x, y, 100, 80, C_DEFAULT) # 前回の位置のトウフの軌跡を消す
x = x + Input.x
y = y + Input.y
rect(x, y, 100, 80, C_WHITE)
Window.draw(0, 0, $screen)
end
8. ブロック崩し:壁とバーを描く(pri_10.rb)
図形の動かし方がわかったので、バーを描いて、マウスと共に動くようにします。
→ DXRubyリファレンス:チュートリアル 7. マウスの入力
http://mirichi.github.io/dxruby-doc/tutorial/basic.html
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
# バーの初期位置
x = 300
Window.loop do
rect(x, 460, 100, 20, C_DEFAULT) # バーの軌跡を消す
rect( 0, 0, 20, 480, C_WHITE) # 左壁
rect( 0, 0, 640, 20, C_WHITE) # 上壁
rect(620, 0, 20, 480, C_WHITE) # 右壁
x = Input.mouse_pos_x
rect(x, 460, 100, 20, C_WHITE) # バー
Window.draw(0, 0, $screen)
end
9. ブロック崩し:ボールを描く(動かす)
ボールを描き、動かします。移動量は、x方向 4、y方向 -4 に設定しました。
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
# バーの初期位置
x = 300
# ボールの初期値
ball_x = 300
ball_y = 400
dx = 4
dy = -4
Window.loop do
rect(x, 460, 100, 20, C_DEFAULT) # バーの軌跡を消す
rect(ball_x, ball_y, 20, 20, C_DEFAULT) # ボールの軌跡を消す
rect( 0, 0, 20, 480, C_WHITE) # 左壁
rect( 0, 0, 640, 20, C_WHITE) # 上壁
rect(620, 0, 20, 480, C_WHITE) # 右壁
x = Input.mouse_pos_x
rect(x, 460, 100, 20, C_WHITE) # バー
ball_x = ball_x + dx
ball_y = ball_y + dy
rect(ball_x, ball_y, 20, 20, C_RED) # ボール
Window.draw(0, 0, $screen)
end
10. 練習:衝突判定の試作
衝突判定を作ります。判定方法は、色で判定する方法にします。
・DXRuby:「当たり判定」を自分で作ってみよう C. 色で判定する - Qiita
で使った方法です。
→ 「ブロック崩し」追加課題 1c);衝突判定の自作(色) - noanoa 日々の日記
http://blog.livedoor.jp/noanoa07/archives/2052899.html
10-1. 大きさ1ドット(点)での衝突判定
衝突判定atari?(x, y)
を作ります。座標(x, y) の色が透明(C_DEFAULT)以外なら衝突と判定します。
マウスの座標(x, y)と、壁との衝突
/非衝突
をターミナル(コマンドプロンプト)にtrue
/false
で出力します。
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
def atari?(x, y) # 衝突判定(1ドット)
if $screen[x,y] == C_DEFAULT
return false
end
true
end
Window.loop do
rect( 0, 0, 20, 480, C_WHITE) # 左壁
rect( 0, 0, 640, 20, C_WHITE) # 上壁
rect(620, 0, 20, 480, C_WHITE) # 右壁
x = Input.mouse_pos_x
y = Input.mouse_pos_y
p result = atari?(x, y) # マウスの位置と壁の衝突判定
Window.draw(0, 0, $screen)
end
10-2. 四角形での衝突判定
四角形が、壁と衝突しているかをatari_4?
で判定します。
衝突
/非衝突
の結果をターミナル(コマンドプロンプト)にtrue
/false
で出力しつつ、四角形の色も赤
/白
にします。
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
def atari?(x, y) # 衝突判定(1ドット)
if $screen[x,y] == C_DEFAULT
return false
end
true
end
def atari_4?(x, y, width, height) # 衝突判定(四角)
atari?(x, y) || atari?(x + width, y) ||
atari?(x, y + width) || atari?(x + width, y + width)
end
# 四角の初期値
x = 200
y = 300
width = 40
height = 30
Window.loop do
rect(x, y, width, height, C_DEFAULT) # 四角の軌跡を消す
rect( 0, 0, 20, 480, C_WHITE) # 左壁
rect( 0, 0, 640, 20, C_WHITE) # 上壁
rect(620, 0, 20, 480, C_WHITE) # 右壁
x = Input.mouse_pos_x
y = Input.mouse_pos_y
p result = atari_4?(x, y, width, height)
if result
rect(x, y, width, height, C_RED)
else
rect(x, y, width, height, C_WHITE)
end
Window.draw(0, 0, $screen)
end
11. ブロック崩し:壁とバーで跳ね返る
衝突判定を使って、ボールが壁とバーで跳ね返るようにします。
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
def atari?(x, y) # 衝突判定(1ドット)
if $screen[x,y] == C_DEFAULT
return false
end
true
end
def atari_4?(x, y, width, height) # 衝突判定(四角)
atari?(x, y) || atari?(x + width, y) ||
atari?(x, y + width) || atari?(x + width, y + width)
end
# バーの初期位置
x = 300
# ボールの初期値
ball_x = 300
ball_y = 400
dx = 4
dy = -4
Window.loop do
rect(x, 460, 100, 20, C_DEFAULT) # バーの軌跡を消す
rect(ball_x, ball_y, 20, 20, C_DEFAULT) # ボールの軌跡を消す
rect( 0, 0, 20, 480, C_WHITE) # 左壁
rect( 0, 0, 640, 20, C_WHITE) # 上壁
rect(620, 0, 20, 480, C_WHITE) # 右壁
x = Input.mouse_pos_x
rect(x, 460, 100, 20, C_WHITE) # バー
ball_x = ball_x + dx
if atari_4?(ball_x, ball_y, 20, 20)
ball_x = ball_x - dx
dx = -dx
end
ball_y = ball_y + dy
if atari_4?(ball_x, ball_y, 20, 20)
ball_y = ball_y - dy
dy = -dy
end
rect(ball_x, ball_y, 20, 20, C_RED) # ボール
Window.draw(0, 0, $screen)
end
12. ブロック崩し:ブロックを描く
ブロック群を描画します。
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
def atari?(x, y) # 衝突判定(1ドット)
if $screen[x,y] == C_DEFAULT
return false
end
true
end
def atari_4?(x, y, width, height) # 衝突判定(四角)
atari?(x, y) || atari?(x + width, y) ||
atari?(x, y + width) || atari?(x + width, y + width)
end
def block(x, y, color) # ブロック1つ
rect(x, y, 58, 18, color)
end
def blocks # ブロック群を描画する
count_x = 0
while count_x < 10
count_y = 0
while count_y < 5
x = 21 + 60 * count_x
y = 21 + 20 * count_y
block(x, y, C_WHITE)
count_y = count_y + 1
end
count_x = count_x + 1
end
end
# バーの初期位置
x = 300
# ボールの初期値
ball_x = 300
ball_y = 400
dx = 4
dy = -4
Window.loop do
rect(x, 460, 100, 20, C_DEFAULT) # バーの軌跡を消す
rect(ball_x, ball_y, 20, 20, C_DEFAULT) # ボールの軌跡を消す
rect( 0, 0, 20, 480, C_WHITE) # 左壁
rect( 0, 0, 640, 20, C_WHITE) # 上壁
rect(620, 0, 20, 480, C_WHITE) # 右壁
x = Input.mouse_pos_x
rect(x, 460, 100, 20, C_WHITE) # バー
ball_x = ball_x + dx
if atari_4?(ball_x, ball_y, 20, 20)
ball_x = ball_x - dx
dx = -dx
end
ball_y = ball_y + dy
if atari_4?(ball_x, ball_y, 20, 20)
ball_y = ball_y - dy
dy = -dy
end
rect(ball_x, ball_y, 20, 20, C_RED) # ボール
blocks # ブロック群
Window.draw(0, 0, $screen)
end
13. ブロック崩し:ブロックとの衝突判定(衝突したら消す)をする(完成)
衝突したブロックの (x, y) を計算して、ブロックを消す処理を追加します。
ブロック群の初期状態(白色)を設定する処理が必要になります。
# 基本機能だけでブロック崩し:衝突ブロックを消す(完成)
require 'dxruby'
$screen = Image.new(640, 480)
def rect(x, y, width, height, color) # 四角を描画する
w = 0
while w < width
h = 0
while h < height
$screen[x + w, y + h] = color
h = h + 1
end
w = w + 1
end
end
def atari?(x, y) # 衝突判定(1ドット)
if $screen[x,y] == C_DEFAULT
return false
end
true
end
def atari_4?(x, y, width, height) # 衝突判定(四角)
atari?(x, y) || atari?(x + width, y) ||
atari?(x, y + width) || atari?(x + width, y + width)
end
def block(x, y, color) # ブロック1つ
rect(x, y, 58, 18, color)
end
def blocks # ブロック群を描画する
count_x = 0
while count_x < 10
count_y = 0
while count_y < 5
x = 21 + 60 * count_x
y = 21 + 20 * count_y
block(x, y, $screen[x, y]) # 色は前回の色と同じにする
count_y = count_y + 1
end
count_x = count_x + 1
end
end
def vanish_block(x, y) # ブロックを消去する
if (20 < x && x < 600) && (20 < y && y < 120)
rect_x = x - (x - 21) % 60 # 衝突位置から衝突ブロックの
rect_y = y - (y - 21) % 20 # (x, y)を計算する
block(rect_x, rect_y, C_DEFAULT)
end
end
def initialize_blocks # ブロック群の初期色を白にする
count_x = 0
while count_x < 10
count_y = 0
while count_y < 5
x = 21 + 60 * count_x
y = 21 + 20 * count_y
$screen[x, y] = C_WHITE
count_y = count_y + 1
end
count_x = count_x + 1
end
end
# バーの初期位置
x = 300
# ボールの初期値
ball_x = 300
ball_y = 400
dx = 4
dy = -4
# ブロック群の初期色の設定
initialize_blocks
Window.loop do
rect(x, 460, 100, 20, C_DEFAULT) # バーの軌跡を消す
rect(ball_x, ball_y, 20, 20, C_DEFAULT) # ボールの軌跡を消す
rect( 0, 0, 20, 480, C_WHITE) # 左壁
rect( 0, 0, 640, 20, C_WHITE) # 上壁
rect(620, 0, 20, 480, C_WHITE) # 右壁
x = Input.mouse_pos_x
rect(x, 460, 100, 20, C_WHITE) # バー
ball_x = ball_x + dx
if atari_4?(ball_x, ball_y, 20, 20)
vanish_block(ball_x, ball_y) # 衝突ブロックを消す
ball_x = ball_x - dx
dx = -dx
end
ball_y = ball_y + dy
if atari_4?(ball_x, ball_y, 20, 20)
vanish_block(ball_x, ball_y) # 衝突ブロックを消す
ball_y = ball_y - dy
dy = -dy
end
rect(ball_x, ball_y, 20, 20, C_RED) # ボール
blocks # ブロック群
Window.draw(0, 0, $screen)
end
参考
プログラミング初心者向け:DXRubyで 1ステップずつ作っていく「ブロック崩し」 - Qiita
で作った「ブロック崩し」のプログラムです。
require 'dxruby'
img_bar = Image.new(100, 20, C_WHITE)
img_hwall = Image.new( 20, 480, C_BLUE)
img_vwall = Image.new(640, 20, C_BLUE)
img_ball = Image.new( 20, 20).circle_fill(10, 10, 10, C_RED)
img_block = Image.new( 58, 18, C_GREEN)
img_block_y = Image.new( 58, 18, C_YELLOW)
bar = Sprite.new( 0, 460, img_bar)
lwall = Sprite.new( 0, 0, img_hwall)
rwall = Sprite.new(620, 0, img_hwall)
twall = Sprite.new( 0, 0, img_vwall)
walls = [bar, lwall, rwall, twall]
ball = Sprite.new(300, 400, img_ball)
dx = 2
dy = -2
def move(sprite, speed_x, speed_y)
sprite.x += speed_x
sprite.y += speed_y
end
blocks = []
10.times do |x|
5.times do |y|
blocks << Sprite.new(21 + 60 * x, 21 + 20 * y, img_block)
end
end
Window.loop do
bar.x = Input.mouse_pos_x
Sprite.draw(walls)
move(ball, dx, 0)
if ball === walls
ball.x -= dx
dx = -dx
end
coll_x = ball.check(blocks)
if coll_x[0]
coll_x[0].image = img_block_y
coll_x[0].draw #一瞬色が変わって表示
coll_x[0].vanish #消える
ball.x -= dx
dx = -dx
end
move(ball, 0, dy)
if ball === walls
ball. y -= dy
dy = -dy
end
coll_y = ball.check(blocks)
if coll_y[0]
coll_y[0].image = img_block_y
coll_y[0].draw #一瞬色が変わって表示
coll_y[0].vanish #消える
ball. y -= dy
dy = -dy
end
ball.draw
Sprite.draw(blocks)
end