便乗して投稿、もっきゅりと噛み砕いてみる。(・皿・)
------------------(・ω・)--------------------
分かりやすく4キーだけで考えてみましょう。
上下左右のアローキーの押下を判定できるとします。
[上を押しているか][下を押しているか][左を押しているか][右を押しているか]
という4つの情報があればいいですね。
これを数字に置き換えると、
[0か1][0か1][0か1][0か1](0は押していない、1は押している)
と考えることができます。
例えば上と下を押していれば、
[1][1][0][0]
と表現できますね。
逆に[0][0][1][1]という数からは、左右キーのみを押している状態とわかります。
さて、"[0][0][1][1]から左右キーのみを押している状態が分かる"、と簡単に言いました。
がしかし、人間は左二つが[0],右二つが[1]であるから当たり前にわかりますが、機械はそうもいきません。
ということで、何かしらの判定を与える必要があります。
------------------(・ω・)--------------------
[?1][?2][?3][?4]という中身がわからないものを渡されたとき、どのキーが押されているのかを調べる方法を考えてみましょう。
例えば下キーが押されているかは、[?2]が1であるかを調べればいいですね。
つまり、[?2]以外の[?1],[?3],[?4]には関心がありません。
関心がない場所は0とすると、[0][1][0][0]という数字を考えることができます。
これを[?1][?2][?3][?4]と"組み合わせ"れば、何かしら結果を得られるのではないでしょうか。
("組み合わせ"は結論から言えば"&演算"である)
[?1][?2][?3][?4]
[0] [1] [0] [0]
と縦に並べてみましょう。(小学校の時の筆算のように)
まず[?4]と[0]を"計算"してみましょう。
[?4]がなんであれ、その数字には別に関心がないので結果は[0]としておきます。
これは[?1]や[?3]にも言えることです。
つまり、
[?1][?2][?3][?4]
[0] [1] [0] [0]
----------------
[0] [ ] [0] [0]
ここまでは計算結果が確定します。
[?2]と[1]の計算は、[?2]が0ならキーを押してないので[0]、そうでないなら[1]としたいです。
[?1][?2][?3][?4]
[0] [1] [0] [0]
----------------
[0] [?2] [0] [0]
筆算の結果は"[0] [?2] [0] [0]"となりました。めでたしめでたし。
------------------(・ω・)--------------------
では、具体例として、?1〜?4に実際数字を入れてみましょう。
[0][1][1][1](上キー以外押している)
これに対して左キーを押しているか?と問いたい時は、
[0][1][1][1]
[0][0][1][0]
------------
[0][0][1][0]
計算結果は、[0][0][1][0]です。
[左を押しているか]の部分が[1]となったので押しているようだ、ということがわかりますね。
では、"上キーと右キーをどちらも押しているか"はどうなるでしょうか。
実際には"上キーと左キーを押している"状態であると仮定します。
上と左を押している状態は、[1][0][1][0]と表せますね。
"上右を押している"の判別に使うコードは、[1][0][0][1]となります。
[1][0][1][0]
[1][0][0][1]
------------
[1][0][0][0]
結果が出ました。[1][0][0][0]は上のみが押されている、ですね。
[1][0][0][0]は、[1][0][0][1]と"一致しない"ので上右は同時に押されていないとわかります。
------------------(・ω・)--------------------
で、実際これらをプログラム上での話に置き換えていきます。
まずは、先に書いた通り、筆算が"&演算"という話から。
[0] | [0] | [1] | [1]
[0] | [1] | [0] | [1]
--- | --- | --- | ---
[0] | [0] | [0] | [1]
結局、筆算にはこの4種類の組み合わせしかでてこないですよね。
結果はご存知の通り、[0],[0],[0],[1]です。
つまりどちらかが0なら0,両方1なら1になるのです。これが"&演算"というやつです。
プログラミング風に書くと、
0&0 → 0
0&1 → 0
1&0 → 0
1&1 → 1
とまとめることができます。
------------------(・ω・)--------------------
もう一つは[0][0][1][0]の[]区切りの数字の話。
当たり前ですが、[]には0か1かしか入りません。そう決めたのだから当たり前か(・ω・)
これはいわゆる2進数というやつですね。
[]の中に0〜9が入るのが、普段使っている10進数というやつなのです。
"一万二千五百十九"は12519です。あたりまえの話ですが。
でもこれって実際は、
1*10000+2*1000+5*100+1*10+9*1の結果なんですよねえ。
ここで、位が一つ左にずれると、掛かる数字に10を掛けることが見てわかります。(ややこしいですが)
(例えば100の位の次は1000の位、これは100*10の結果と考えられる)
さてさて、2進数の例として、下右同時押しの[0][1][1][0]を考えてみましょう。
一番右は0*1ですねえ。その左の1はどうなる?
答えは1*2です。なんたって"2"進数ですからね。
同様に考えると、
0*(2*2*2)+1*(2*2)+1*(2)+0*(1)
が、下右同時押しを表す"数"を10進数にしたものになります。
結果としてはこれは4+2=6ですね。
さて、この数字に対して右キーを押しているか?と聞きたい時はどうしましょう。
もちろん[0][0][1][0]を用意しますね、これは10進数では"4"です。
0110(2) & 0010(2) の結果が 0010(2) なら右キー押下
↓
6(10) & 4(10) の結果が 4(10) なら右キー押下
と書き換えることが出来ました。
------------------(・ω・)--------------------
さて、いよいよ
stick key,17,1
if key&8 : dialog "ok"
の話に移ります。
まず、stickの第2引数に17を設定していますが、これは
>>スペースキーと←キーのつもりだったんですけど。
という意図とは、残念ながらずれています。リファレンスを読み直しましょう。
ここに値を設定したって、keyには1〜1024の"組み合わせ"が入ります。
------------------(・ω・)--------------------
さてさて、やっとできる本題の"if key&8"の話。
上の方の例で"6(10) & 4(10) の結果が 4(10) なら右キー押下"と言いましたよね。
これを実際に記述すると、
if (key&4) == 4 に相当します。
だから今回は、
if (key&8) == 8
とでも記述するべきだったのですが、"== 8"がどっかいってしまいました。
(ちなみに(key&8)と()を付けているのは、こちらの演算が先であるとわかりやすくするため)
実は"(key&8) == 8"というのは、
(key&8)が8でないなら0、(key&8)が8なら1
をとる値となるのです。
つまりif文で実際に判定されるときには、
if 0かif 1のどちらかの形になっているのです。
ifの後のdialog "ok"が実行される条件っていうのは、
if 0ではない場合、という風に内部で決められています。
訳が分かんないよ!というのなら、
mes str(8==-1)
mes str(8==0)
mes str(8==5)
mes str(8==8)
if -1 : mes "ok:-1"
if 0 : mes "ok:0"
if 1 : mes "ok:1"
if 5 : mes "ok:5"
こんなソースを実行してみて下さい。
気持ち悪いかもしれませんが、普通に通りますし動きます( ・ω・)(・ω・ )
これを動かしてみれば、いろいろと察すると思います。
------------------(・ω・)--------------------
ここまでの話から、"==8"が省略できる理由、なんとなくわかりましたか?
key&8の結果は0か8にしかなりません。
つまり、if (key&8)は、if 0かif 8にしかなりません。
前者ならdialog "ok"は実行されないし、後者なら実行される。
そういうことです。if 1でもif 8でも動くならどっちでもいいやと、そんなノリなのです(´・ω・`)
------------------(・ω・)--------------------
ヲシマイ。長々とすいませんでした。
お偉いさんの方々からいろいろ突っ込まれそうですけど、少し目をつむってくださいな。
拙い文章ですが、少しは参考になってくれればうれしいです。