提供: Japanese Scratch-Wiki
この記事では、主に100%penのゲームの作成について記述する。
前提条件
100%penを名乗る際の決まりとして、画面内に表示されているコスチュームや背景などが含まれてはいけない[1]などがある。
詳細は100%penを参照。
ペンの線を動かす
ペンはスプライトが動いた跡に線を引く機能であり、その線を任意の場所へ動かす方法は存在しない。
しかし、動いているように見せる方法は存在する。例として、スプライトを新しく作成し次のプログラムを作る。
@greenFlag が押されたとき::events hat x座標を (-200) 、y座標を (0) にする ペンの太さを (50) にする ペンを下ろす (40) 回繰り返す x座標を (10) ずつ変える end ペンを上げる
実行すると、太い線が左から右へ引かれるはずだ。
続いて、これを少し改変し、以下のようにする。
@greenFlag が押されたとき::events hat x座標を (-200) 、y座標を (0) にする ペンの太さを (50) にする (40) 回繰り返す 全部消す::pen ペンを下ろす ペンを上げる x座標を (10) ずつ変える end
実行すると、左から右へ丸が動く。
これは、実際にはペンの線は動いておらず、消しては描く、消しては描くの繰り返しで動いているように見せている。
座標の記録
複数の種類の物を描写する作品の場合、スプライトそのものが一つの物の座標を維持しなくなるので、変数で物体の座標を記録しておく必要がある。
(自機x)
(自機y)
といったように、その変数がどの物の座標を保持するのか、分かりやすいように名前を付けておくのが良い。
なお、マウスのx座標
といったブロックに座標を依存させる場合、変数への記録が不要な場合がある。
リストで複数の物の座標を管理する
シューティングゲームなどを作る場合、敵は普通、複数で出現するものである。
しかし、一つの変数では複数の物体の座標を一度に記録できない。
そういった時は、リストを使用することで記録を一度に行う。
リストが保持している全ての座標に丸(敵)を描写するプログラムは以下の通りだ。
@greenFlag が押されたとき::events hat [敵x v] のすべてを削除する::list // 初期化 [敵y v] のすべてを削除する::list ずっと // 描写を繰り返す 描写::custom end 定義 描写 ペンの太さを (50) にする 全部消す::pen // 引いている線を全て消す [i v] を (0) にする // 描写前の初期化 ([敵x v] の長さ :: list) 回繰り返す // 存在する敵の数分繰り返す [i v] を (1) ずつ変える x座標を ( [敵x v] の(i)番目 :: list) 、y座標を ( [敵y v]の(i)番目 :: list) にする // それぞれのリストのi番目の座標に移動する ペンを下ろす // 丸の描写 ペンを上げる end
なお、定義ブロックは「画面を再描写せずに実行する」にチェックを入れて作る必要がある。
物体を移動させる
物体を移動させるには、リストに保存されている座標を改変すれば良い。
次のプログラムを先ほどのプログラムの繰り返し部分の一番最後に入れると、物体を左に移動させることができる。
[敵x v] の(i) 番目を ( ([敵x v] の (i) 番目) - (5) ) で置き換える::list
リストカテゴリには[変数 v] を () ずつ変える
のようなブロックが存在しないので、リスト内の要素を、同じ場所にある要素に任意の数を引いた数で置き換えることで代用している。
物体を削除する
特定の条件で物体を削除したい場合、リストから要素を削除すれば描写されなくなる。
一番左まで物体が移動したときにその物体を消したいときは、以下を先ほどの場所に入れる。
もし <((i) 番目( [敵x v] ) :: list) < [-240]> なら [敵x v] の (i) 番目を削除する [敵y v] の (i) 番目を削除する [i v] を (-1) ずつ変える end
なお、iを-1する処理を描かないと不具合が発生するので必ず入れること。
当たり判定
コスチューム同士の接触判定ができないため、当たり判定は物体と物体の間の距離で行う必要がある(物体が円形の場合)。
しかしスプライトを一つしか使わない場合、二つ以上のスプライトが必要になる([スプライト v] までの距離)
は使えない。
代わりに三平方の定理[1]を使う。これについての詳しい解説は省略するので、左のリンク先を参照されたい。
例として、マウスポインターが大きさ(ペンの太さ)50の物体に触れたか判定するプログラムを挙げる。
定義 当たり判定 [i v] を [0] にする//処理前の初期化 [当たった? v] を [No] にする ([敵x v] の長さ :: list) 回繰り返す//敵の数分当たり判定をする もし <[25] > ((((((i v) 番目( [敵x v] ):: list) - (マウスのx座標)) * (((i v) 番目( [敵x v] ):: list) - (マウスのx座標))) + ((((i v) 番目( [敵y v] ):: list) - (マウスのy座標)) * (((i v) 番目( [敵y v] ):: list) - (マウスのy座標))))の[平方根 v]::operators)> なら // 三平方の定理を使ってマウスポインターと敵の二点の距離を求める [当たった? v] を [Yes] にする end end
実行すると、円の中にマウスポインターがあるときに変数「当たった?」が「Yes」に、ないときは「No」になる。
また、マウスポインターが触れたときに物体を消したいときは、「物体を削除する」の項で触れた方法を使えば良い。
脚注
- ↑ ただし、白の背景などは例外になる場合がある。