プチコン3号で1画面プログラム「BLK2048」をリリース
飛び出すブロック崩し BLK2048 をリリースしました。
名前にもあるように 2048 面が選択できます。
投稿プログラム : BLK2048 - プチコン3号まとめWiki
公開キーは 【1D34VKKV】 です。
プレイするには、ダウンロードしたフォルダの BLK2048 を実行してください。
1画面プログラムはワンライナーのようなもので、スクロールしない1画面の範囲におさめた文字数の少ないプログラムのことです。
最初は習作として作っていたブロック崩しでしたが、飛び出すアニメーションをつけて大喜利に出そうと検討したとき、せっかくならまだやったことがない1画面プログラムにできるかどうかやってみようと思いチャレンジしました。
もう、見た感じうじゃーっとしてて保守してくださいとか言われたら、反射的にいやです(`・ω・´)とお断りするレベルのプログラムです。
でも、やってみるとこれはこれで面白いです。
1画面プログラムを作るときに意識したこと
自分の感想では50~60行くらいの普通のプログラムならなんとかぎゅぎゅっと圧縮すれば1画面にいけると思いました。
圧縮といっても、機械的に次のことをやっただけです。
- 数字のあとの命令文はくっつけて書く(ENDIF だけは区切る必要あり)
- ラベルの前の文はくっつけて書く
- 文字列の前後の文はくっつけて書く
- 配列[]のあとの文はくっつけて書く
とにかく、区切る必要のないものはくっつけて書くだけです。
IF 文は ENDIF を忘れると条件分岐の処理として後の命令が呼び出されてしまうので1行IFで省略している場合は、ENDIFを書いてから圧縮したほうがよいです。
変数名など省略できるものはなるべく少ない文字数にしました。
しかし、どの変数が何を表すのかがわかりにくくなります。
そこで、プログラムにコメントを書くかわりに、パソコンのテキストで変数名の管理をしました。
このアルファベットは使ってないよね?とびくびくしながら変数を使う問題がこれで解消できます。
50~60行というのもさらっといいましたがわりと短いです。
普通に書いてたら、変数宣言と初期化だけでそれぐらい使うかもしれません。
プログラムを書く上で気をつけたのは、同じ命令はなるべく1回書くだけにする。
たとえば、何度も BUTTON の入力を行ったり、 LOCATE で表示位置を変えないようにして、1箇所ですむように、仕様も含めて工夫しました。
「本当にやりたいことは何だ?」
これは私がお世話になった方からよくされたアドバイスですが、1画面プログラムのような限られた文字数の中で、この問いかけは何度も思い出されました。
ちょっとシチュエーションは違うのですが、要するに限られた中で取捨選択をしてよりよいものを作るというトレーニングという側面が1画面プログラムにはあるのかなーと思ったり思わなかったりしました。
作品の紹介
そんなこんなで作ったのがこんな感じです。
なんかよくわからないかもしれませんが、ブロック崩しで崩したブロックがくるくる回転しながら手前にとびだしてきているところです。
これが、意外ときれいで爽快です。自画自賛で3割り増しだとは思うのですが、そう思いました。
[プチコン3号]BLK2048[1画面プログラム][ブロック崩し][petitcom] - YouTube
私のプレイ動画ですが、ブロック崩しがこんなに難しいとは思いませんでした。
この動画は撮影のために操作しづらい姿勢でやっているというのはあるのですが、それにしても瞬殺レベルです。途中からはバーをのばした鑑賞モードにしています。
鑑賞モードを作ってよかったと本当に思いながら撮影しました。
その後、あらためて本気で挑戦しましたが、ブロック数が100個を超えるものはクリアできませんでした。(´・ω・`)
球の反射
ブロックと球との当たり判定が、ぐぐってもジャストなものがなかなかでてこなくて結局自分でいろいろと工夫してそれっぽくしてみました。
持っているゲーム開発のための物理の本などをみても、当たった方向に対して、移動の増分値の符号を反転させると書いてあるだけで、肝心な当たった方向の検知については書かれていませんでした。
まずは、壁の上下左右のどこにぶつかったのかを次の前提条件から判別します。
- ブロックの上と下、左と右が同時にぶつかるということはありません。
- 水平方向と垂直方向でそれぞれ進行方向にブロックがあります。
そこで、SPHITSP でブロックとぶつかったら、そのブロックとの水平方向と垂直方向の差分を比較します。
水平方向のほうが差分が大きいなら、水平方向で進行方向にブロックがあると判断します。
そのときは球を移動させる水平方向の増分値 V に -1 をかけて逆にします。
同様に垂直方向の差分が大きければ垂直方向の増分値 W に -1 をかけて逆にします。
もしも差分が同じならば角にあたったと判断して、V,W両方に -1 をかけて進行方向を逆にします。
周りの壁については球の座標を比較して、超えたら増分値 V, W の該当する変数に -1 をかけています。
左側にあるバーとの接触の際は、球がバーのどの位置にいようとも右側に跳ね返すようにしました。
途中までは物理の勉強などをしようとしていたのですが、途中でブロック崩しを作るのであって物理エンジンを作るのではない(そもそも難しすぎる)と思い直しました。
そうしたら、変なこだわりが消えて、ケースバイケースの処理を組み合わせて短いプログラムで、それっぽく動かせるようになりました。
それはそれとして、球の反射に関するよい説明などありましたら教えていただけるとうれしいです。