初版作成 2013.12.27
最終更新 2024.04.01
scratch.mit.edu
scratch でプログラミングをしていて if の動作がおかしく「なぜだ!」となることがある (ex. if 0 < 1 が偽となる) 。 その原因は全角の数字を使っていることにある。 scratch のフォントは全角と半角の区別がつきにくい 1 桁の場合 (たとえば 0) は気がつかない。 ありがちなパターンは 「日本語の変数を使うために、日本語入力モードにして 戻し忘れる」
ブラウザによっては右クリックが効かないことがある。 そのときは shift + 左クリック
x 座標が -240 〜 239 y 座標が -180 〜 179 座標値は実数で保持する
プログラムはクラウドに保存される。 プログラムは半自動でセーブされる。 明示的にセーブしたいときは「ファイル」→「直ちに保存」 別のプログラムを開きたいときは、右上の 「ユーザー名▼」→「私の作品」
scratch は「オブジェクト指向」「イベント駆動型」 の言語である。各オブジェクトはスレッドとして動作 するようだ。 オブジェクトは「背景」「スプライト○」である。 オブジェクトごとに「スクリプト」を組む
「緑色の旗」をクリックするとスタート 「赤色の八角形」をクリックすると停止 「イベント:緑旗がクリックされたとき」で ゲームスタート時の初期設定を行う。
プログラムはブロックをドラッグして接続する ことで組む。 最上行の「複製 (スタンプマーク)」をクリックし、 ブロックをクリックすると、複数のブロックをコピー することができる。 あるブロックをドラッグすると、下側が全てついてくる。 a b c を a c b にしたいときは、b をドラッグして bc を引き離し、 c をドラッグして c を引き離し、a の下につけ、 b をドラッグして b の下につける。
ブロック (ブロックエリア・スクリプトエリア どちらでも) を クリックすると、そのブロックを実行 (basic のダイレクト命令に相当)。 たとえば「隠す」をクリックするとスプライトが消える。
「見た目:次のコスチュームにする」 を使うと、歩くアニメーションが作れる。 スプライトが見えないときは 「見た目:表示する」 「動き:x 座標を 0 にする」 「動き:y 座標を 0 にする」 などをクリック 「動き:○度に向ける」において、 スプライトをそのまま表示するのは 90度 スプライトは x, y 座標に加えて向き(-180度 〜 +360度)を 持っている。「10 歩動かす」はその向きへ 10 ドット移動させる。 真上が 0 度、左が -90 度、右が 90 度、下が 180 度 デフォルトは 90 度。 スプライトの位置や向きは、「動き」の下の方にある (スクロールしないと見えないことがある)。 他のスプライトの位置は 「調べる」の「『ステージ▼』の『背景』」を 「『スプライト名▼』の『x』」で得る。
スプライトをクリックし、「コスチューム」 中央の「+」マークがスプライトの座標
最上行の中央部にアイコンがある。 消す :ハサミマークをクリックし、スプライトの上でクリック 縮小, 拡大:縮小, 拡大のアイコンをクリックして、スプライトの上でクリック 新規に選ぶ:「スプライトをライブラリーから選択」アイコンをクリック
左端の背景の領域をクリックすると、中央の領域に「背景」という タグが出現する。
「調べる」のブロックの色の選び方は以下の通り。 1. ブロックの色の上でクリック。 2. 目的の色の上でクリック。
「データ」にある。 配列は「リスト」。添字は整数で 1 からはじまる。 「すべてのスプライト用」にチェックを入れるとグローバル変数 「このスプライトのみ」にチェックを入れるとオブジェクトのローカル変数 「クローン」を作ると「このスプライトのみ」の変数は「各クローン毎」に 用意される。 変数名の横のチェックボックスに印を入れると、 変数の内容が常に表示される。 変数への代入は「データ」の 「○○ を △△ にする」というブロックを使う。 「演算」の「○ = △」ではない。 A = A + 2 は「 A を 2 ずつ変える」 A = A - 3 は「 A を -3 ずつ変える」
「調べる:○○と聞いて待つ」 で入力用テキストボックスが出現する。 入力した値は「答え」という名前の変数に入る。
「イベント:メッセージを送る」でメッセージを送り、 他のスプライトのスクリプトで「イベント:メッセージを受け取ったとき」 で受け取る。 (注意!) メッセージはすべてのオブジェクトが受け取る。 あるスプライトのクローンが 2 つ作成されていたとすると、 「本体」「クローン1」「クローン2」の 3 個が受け取り、 それぞれのオブジェクトが「メッセージを受け取ったとき」以降を 実行する。 たとえば、メッセージを受け取ったとき A = A + 1 を実行し、 クローンを含めてオブジェクトが 3 個あったとき、A は 3 増える。
キー入力の調べ方は 2 通りある。 1. 無限ループの中で「調べる:○キーが押された」 2.「イベント:○キーが押されたとき」 1. はその瞬間にキーが押されているかどうかを調べる 2. のイベントの発生のタイミングは、メモ帳や Word において、 画面に出現する文字と同じである。 たとえば、a キーを押し続けるとき、「a キーが押されたとき」 というイベントが発生するのは以下のようになる。 a aaaa ------------------> 時間 シューティングゲームなどリアルタイムのゲームでは 1. の方式を使う。 2 つのキーを同時に押したとき、両方を検知できる のは 1. である。 2. は以下のようになる。 たとえば、a と b を同時に押し、a の方が一瞬 はやかったとき、イベントの発生は ab bbbb ------------------> 時間 となり、a キーを押し続けることを検知できない。 シューティングゲームなどで、弾を連射するとき、 以下のように組む。 もし[調べる:○キーが押された]なら 弾発生の処理 制御:[ (○キーが押された) ではない]まで待つ
2 種類のキー入力を処理する必要がある。 1. 移動キー 2. 弾発射キー 弾を正しく連射するには、弾発射キーを一度離してから 再度押すことを検知する必要がある。 [ (○キーが押された) ではない]まで待つ を使う。これを実行するときに移動が止まってはいけないので、 「移動」と「弾発射」は別々の無限ループを組む。 弾発射キーを調べる無限ループは 「移動体スプライト」「弾スプライト」など どのスプライトのコード領域に置いてもよい。 弾スプライトに置くのが分かりやすい。 複数の弾を扱うときのコードの組み方は、 難解である。次の項目で説明する。
複数の弾を撃つ、複数の敵などはクローンを使う。 「制御:○のクローンを作る」 弾などは「見た目:隠す」でゲーム開始時に隠し、 弾発射を検知したらクローンを作る。 「見た目:表示する」で出現させ、 「このクローンを削除する」で消す。 シューティングゲームにおいて、 弾スプライトのコード領域に 複数の数を発生させるコードを書く場合を考える。 「自分自身のクローンを作る」は1箇所で実行する。 複数の場所で実行してはいけない。 たとえば、以下のように組んではいけない。 弾発射キーを検知 → メッセージ1を送る メッセージ1を受け取った → 自分自身のクローンを作る メッセージは全てのオブジェクトが受け取る。 「本体」「クローン1」「クローン2」があったとき、 3 個のオブジェクトがそれぞれメッセージを受け取り、 各自のクローンを作るので 「本体」「クローン1〜5」の 6 個に増殖する。 ネズミ算式に弾数が増える。 そして複数の弾が同じ位置に重なって描かれるという たちの悪いバグが発生する。 「クローンされた後」のブロックに続く部分の中で 「自分自身のクローンを作る」を実行しても 同じことが起こる。「クローンされた後」のスレッドは クローンの個数だけ実行されるので、その中で 「自分自身のクローンを作る」を実行すると、 ネズミ算が発生する。 シューティングゲームの弾発射は、 1個しか存在しないスレッド(通常は緑旗が押されたとき から続くスレッド)に以下のようにブロックを配置する。 「ずっと」 「もし「弾発射キーが押された」なら」 「自分自身のクローンを作る」 「「「弾発射キーが押された」ではない」まで待つ」
「調べる」の中に「○○に触れた」というのがある。 当たり判定はこれを利用する。 「隠す」の状態では「○○に触れた」は反応しない。 「端に触れた」は枠外に出ようとしたか否かが判定できる。 「調べる」の中の「x座標 of Sprite2」というブロックを 利用すると他のスプライトの位置が分かる(クローンの位置は わからない)。 A と B が接触し、どちらもクローンを消滅させたいとする。 A: もし B に触れたら、クローンを削除 B: もし A に触れたら、クローンを削除 ではうまくいかない。 先に if の判定をした方だけが削除される。 タイミングによって、どちらかが消滅するということになる。 クローンを削除する直前に 0.1 秒のディレイ入れるという 方法もあるが、美しくない。このようにする。 A: もし B に触れたら メッセージ1 を送って待つ このクローンを削除する B: メッセージ1 を受け取ったとき もし A に触れたら このクローンを削除する ミソは「メッセージ1 を送って待つ」である。 メッセージを受け取った側のスクリプト(全てのオブジェクトが 受け取る)が終了してから「このクローンを削除する」が 実行される。 上の場合、クローンの個数が少ない方を A に割り当てた方が 処理が速くなる。 ---------------- 「○色に触れた」の色の選び方は以下の通り。 色の場所を左クリックすると色選択モードに入る。 マウスカーソルを動かし、目的の色のドットの上に置いて左クリック
「スプライト〇に触れた」と「○色に触れた」違いは以下の通り ・スプライト○に触れた - 自分が「表示する」になっていないと yes にならない - 同じスプライト(クローン)に対しては適用できない ・○色に触れた - 自分の状態(表示する/隠す)は関係ない - 同じスプライト(クローン)に対しても yes となる。 「○色に触れた」を使う場合、色の部分でクリックすると 色選択メニューに入り、一番下のスポイトマークを押すと、 ゲーム場の中の色を拾うことができる。
「ユーザー名▼」→「プロフィール」 薮お気に入りのゲーム title: brick_road author: 103769 title: Tetris remix author: mygame11 title: 青に触れるな! author: tatsu777 他人のプログラムを見ている画面で、右上の「リミックス」 ボタンを押すと、自分のプロジェクトとして取り込むことが できる。
a >= 5 は以下のように表現する [a > 5] または [a = 5]
Game Over あるいは Clear と書いた スプライトを用意する。 ゲーム開始時に [隠す] ゲーム終了のイベントで [表示する]
演算ブロックに [○から○までの乱数] がある。[1 から 3 までの乱数]とすると 1, 2, 3 のいずれかを発生する。 [1 から 3.0 までの乱数]とすると実数の乱数を 発生する。 ゲームで敵をランダムに出現させるとき、 無限ループの組み方は 2 通りある。 もし [1 から 3 までの乱数] = 1 なら クローンを作る 0.5 秒待つ ----------------------- [0.2 から 2 までの乱数] 秒待つ クローンを作る
弾の xy 座標の初期値は敵(クローン)の xy 座標である。 敵(クローン)が弾(クローン)に位置を伝えるためには グローバル変数を使うしかない。 1 個目の敵が弾のクローンを作成し、弾がグローバル変数を読む 直前に 2 個目の敵が弾のクローンを作成すると、 2 個の弾が重なってしまう。 以下のように組むことで、可能な限り上記の現象を防ぐ。 ---------- 敵のスクリプト ------------ flag = 0 ずっと もし 乱数 = 弾発生 なら もし flag = 0 なら (1) flag = 1 (2) x を [x 座標] にする y を [y 座標] にする 弾のクローンを作る ---------- 弾のスクリプト ------------ クローンされたとき x 座標を [x] にする y 座標を [y] にする flag = 0 表示する ----------------------------------------- (1)→(2) の間にスレッドが切り替わったときは 上記の書き方でも NG である。 配列を使うと以下のように書ける。しかし、問題は 解決されない。 ---------- 敵のスクリプト ------------ ずっと もし 乱数 = 弾発生 なら x 座標を xlinst に追加 y 座標を xlinst に追加 弾のクローンを作る ---------- 弾のスクリプト ------------ クローンされたとき x 座標を 1 番目 [xlist] にする (1) 1 番目を [xlist] から削除する (2) y 座標を 1 番目 [ylist] にする (3) 1 番目を [ylist] から削除する (4) ---------------- (1)→(2) あるいは (3)→(4) の間にスレッドの 切り替えが行われると、x 座標, あるいは y 座標が 誤った位置になる。
画像は 480 x 360 下にパレットがある。 左上が前景色:ペン・長方形・塗りつぶしの色 右下が背景色:消しゴムで消すときの色 アイコン 意味 ---------------------------- ペン ペンで書く 直線 ドラッグで直線を描く 長方形 長方形を描く 丸 円を描く T 文字を書く バケツ 閉領域を塗りつぶす 消しゴム 背景色で書く 選択 領域を選択する 移動 回転 拡大縮小
関数の定義のこと 引数も取れる ブロック定義 --- ブロックを作る で関数定義開始