PICO-8でスネークゲーム「ピコニョロ」をつくっていて、どうもおかしい動作をすることに悩ませていました。
ステージ上の全てのカエルと、ヘビの体の全てに当たり判定をしているコードで、初めに頭の当たり判定をして、次に体の当たり判定を順番に行う様に書いてあります。
そして、頭と体の間にカエルが来た時にどうなるかを試したところ、カエルは食べられ(頭と当たった)、カエルに咬まれてヘビにダメージがありました(体と当たった)。
つまり、両方の動作がされたことになります。
希望する動作は、先に頭との当たり判定になった時、テーブルからカエルを削除しているので、「体の当たり判定は行われない」見解でした。
ですが「無いのに有る」・・・正に駐車場に掲げられている「空あり」です。
「なぜだろう?」理由がわかりませんので、printhで各変数の中を表示したり、別のプログラムで検証したりしました。
そこで、ある事実がわかりました。
まずは、このプログラムリストと実行結果を見てください。
似た動作をさせる2つのプログラムですが、先のはdel()命令でテーブルから座標要素を削除しているのにも関わらず、その後で要素の値を変更出来ています。
後のプログラムは、del()命令でテーブルから座標要素を削除した後に、要素にアクセスしようとするとnilだとエラーが出ています。
内部構造は わかりませんが、テーブルから要素を取り出すループにて、in all()を使う場合、要素を削除してもループ内ならアクセスできてしまうのです。
そしてループから抜けた後にアクセスすると、nilだとエラーが出ます。
なので、仕様だと受け止めて、
in all()を使う場合、要素を削除した後はアクセスしないようにする
というルールでコードを書くことです。
オフィシャルのBBSに書き込んでみようかな。
コメント