hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
小ワザ/stick命令の使い方 - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

小ワザ

stick

ここではstick命令の使い方について説明します。
stick命令のようにビットフラグで情報を返す命令はよくあるので、結構重要かもしれません。
逆に基本さえ押さえれば凄く簡単・便利になります。

基本的な使い方

stick命令のヘルプにあるとおり、

  • メインループ内でstick命令を実行し、変数に値を取得。
  • 取得した値を元に条件式で分岐
  • イベント実行

という流れになります。

stick a,0            ; 変数aにキー状態を読み出し
if a&16 : goto *spc  ; スペースが押されたか?
if a&32 : goto *ent  ; Enterが押されたか?

なぜa=16のようにイコールで評価しないのか。その理由はさておき、「必ず&で評価する」と覚えておきましょう。
&で評価すると、複数のキーを同時に押した場合でもちゃんと条件分岐してイベントを発生させることが出来ます。

+  stick命令の使い方サンプル

スペースキー等を押しっぱなしにしても、1回分の入力としてしか認識されませんね。(連打状態にならない。)
これはstick命令が取得するキー全てを「トリガータイプキー」として処理しているためです。
トリガー…つまり鉄砲の引き金のように、1回押したら1回だけ反応し、以降は押しっぱなしにしても反応しない状態です。
押しっぱなしでも値を取得するには後で記述する非トリガータイプキーの機能を使う必要があります。

条件式に「&」を使う理由

条件式に「&」を使う理由について、これを理解するためには、ビット演算についてif命令の条件式の評価について読んでおいてください。

上のほうでも書いたように、1,2,4,8,16,…は特別な規則に沿った数値です。まずはこれについての説明を。 1,2,4,8,16,…を2進数で表記すると次のようになります。

10進数2進数
100000000001
200000000010
400000000100
800000001000
1600000010000
3200000100000
6400001000000
12800010000000
25600100000000
51201000000000
102410000000000

このように10進数では半端な数字でも2進数ではケタが変わり、とてもきりの良い数字になります。
プログラミングではstick命令に限らず数値を2進数表記して考えることはよくあるため、より深くプログラミングを学びたければ2進数について知っておいたほうがいいでしょう。

条件式に&を使用すると、変数に指定した数値が含まれているか、を知ることが出来ます。正確には2進数表記したときに、その桁のビットフラグが立っている(1になっている)かを知ることが出来ます。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
 
 
 
 
 
 
a = 5 : mes "a = " + a
b = a&1 : if a&1 : mes "aは1を含む"
b = a&2 : if a&2 : mes "aは2を含む"
b = a&4 : if a&4 : mes "aは4を含む"
b = a&8 : if a&8 : mes "aは8を含む"
b = 1+4 : mes "1 + 4 = " + b

イコール(=)で変数の内容を調べようとしても、完全一致しか条件が成立しないため、上のような複数のビットフラグが立っている場合を検出できません。

非トリガータイプキー

キーを押しっぱなしにしている間中、値を取得し続けるには、第2引数の非トリガータイプキーを指定しなければいけません。
何も指定しなければ、stick命令はキーを押した瞬間の1回だけしか値を返しません。

非トリガータイプキーには、押しっぱなしの間でも値を取得したいキーを指定します。
指定の仕方をスペースキーとCtrlキーを非トリガータイプキーに指定する場合を例に説明します。まずスペースキーとCtrlキーが押されたときに返される値はこのようになっています。

16 : スペースキー
64 : Ctrlキー

この2つを非トリガータイプキーに指定するには次のようにします。

stick a, 16|64			; スペースとCtrlを非トリガータイプキーに指定

このように指定したいキーの値の論理和(|, or*1の数値を指定します。 もしくは、

stick a, 16+64			; スペースとCtrlを非トリガータイプキーに指定

のように、足した数値を指定してもかまいません。これは1,2,4,8,…といった数値がある規則を持った特別な数値であるため足し算でも代用することが出来ています。
とりあえずここでは、「|」でつなぐと覚えておいたほうが後々困らないでしょう。
詳しくはビット演算の解説を参照してみてください。

+  サンプル

スペースとCtrlは押しっぱなしの間も値を取得し、Enterは非トリガータイプキーに指定していないので押した瞬間の一瞬だけ押されたことを取得します。

複数の条件で処理を分ける

stick命令で取得した値変数flgの値の2つの条件が一致したときのみイベントを実行する場合を考えて見ます。
このケースは上手く動かないという人をよく見かけます。上手くいかない場合は、たいてい次のように記述しています。

stick key, 16
if (key&16) & (flg=0) : gosub *event		;これでは動かない!

皆さん1度はこう記述して上手くいかなかったことがあったのではないでしょうか?

このような間違いは、HSPでは、if命令の条件式は「真」や「偽」という値になるのではなくあくまで数値であり、0以外を真、0を偽とみなしているという点、また論理演算(and,or,xor)も条件の真偽を判断しているのではなくビット演算をしているという点、この2つを理解していないためにstick命令の取得値を正しく扱えず、起きているのだと思います。
まあとりあえず御託は置いておきます。使い方を見てみましょう。2つの条件を使う場合は次のように記述します。

stick key, 16
if ((key&16)!0) & (flg=0) : gosub *event		;これでちゃんと動く

stick命令で取得した値は、( ( key&16 ) ! 0 )と記述します。カッコは省略してはいけません。*2

+  サンプル

なぜこのように記述しなければいけないか、その理由はif命令ビット演算について知る必要があります。
しかし、書き方さえ覚えてしまえばとりあえずは大丈夫でしょう。

コメント

  • 説明が変だったりわかりにくい所は、どんどん消して書き換えてください。説明が足りなければつけたし歓迎。 -- GENKI? 2009-08-30 (日) 01:07:00
  • stick命令はきちんと全部説明しようとすると凄くおくが深くて大変ですね。 -- GENKI? 2009-08-30 (日) 01:08:14
  • 複数の条件〜をすこしだけ弄らせて戴きました。 -- SYAM? 2009-08-30 (日) 04:09:30
  • 失敗例が実際にどう計算されて失敗になっているかを説明するほうがわかりやすいのかもしれません。 -- SYAM? 2009-08-30 (日) 04:15:09

URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

*1 「|」はキーボードで「Shift + \」とすれば入力できます。
*2 カッコを省略してはいけない理由は、「プログラミングマニュアル・基本仕様ガイド」の「3.6. 式」の演算子の優先順位に関する記述を参照してください。
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2009-08-30 (日) 04:15:09 (1561d)