HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2023
0509
大富豪loop内のスイッチON/OFF14解決


大富豪

リンク

2023/5/9(Tue) 21:27:58|NO.99413

LOOP内で特定の条件に一致した時、
数値か文字列を使い、
スイッチON/OFFを(フラグとして)制御したいです。

(例)
repeat
if マウスX>600: cn+
(マウスX座標600以上の間カウントアップ)
***範囲内に入った瞬間だけ一度サウンドを鳴らす***
loop

1. マウスが範囲外:何も起きない。
2-1. マウスが範囲内に入った瞬間:一回だけ音を鳴らす
2-2. マウスが範囲内にある間カウントUP(cn+)を続ける。
3. 1に戻る。

--------------------------------------
色々試行錯誤しましたが結構難しいですね;
一般的にどんな方法があるでしょうか。
宜しくお願いします。



この記事に返信する


沢渡

リンク

2023/5/9(Tue) 21:50:57|NO.99414

・フラグを記録する変数(たとえばflag)を用意し、
 フラグが0の時にマウスが範囲内に入ったらフラグを1にし、音を鳴らす。
・マウスが範囲外に出たらフラグを0にする。

これで良いのでは?



大富豪

リンク

2023/5/9(Tue) 22:43:30|NO.99415

>沢渡さん
ありがとうございます。
はい、何かフラグを立てて処理したいのですが、


※例えば

repeat
if マウスX>600: cn+:サウンドを鳴らす

loop

これだと鳴りっぱなしです。

範囲内にある間はずっとカウントアップしたいのですが、
同時に、入った瞬間の一度だけ音を鳴らしたいのです。

if マウスX>600// この瞬間にflag=ONでフラグを立てて、
if flag=ON:サウンドを鳴らす

鳴らしたら
前記のif マウスX>600を無効にするか、または
”既に鳴らした”事を判定して、flag=ONにしない動作が必要があります。

・・・。



沢渡

リンク

2023/5/9(Tue) 23:21:07|NO.99416

とりあえず作ってみましたが、このような形ではどうでしょうか。

#include "winmm.as" //←PlaySoundを使用するためのもの。PlaySoundを使わないなら消してください。 flag=0 cn=0 repeat if mousex>600 { if flag=0 { PlaySound "SystemAsterisk",0,1 //←システムサウンドを鳴らすAPIです。mmplayを使っているならmmplayに置き換えてください。 flag=1 } cn++ title str(cn) } else { flag=0 } await 33 loop



YUZRANIUM

リンク

2023/5/9(Tue) 23:34:35|NO.99417

こんな感じでしょうか?
(少々見づらくて申し訳ありません)

#module "my_mouse" #deffunc mouse_init dim i frame(0) = (ginfo(10) - ginfo(12)) / 2 frame(1) = (ginfo(11) - ginfo(13) - frame(0)) return ; マウスカーソルのX座標 ; #defcfunc mus_x return (ginfo(0) - ginfo(4) - frame(0)) ; マウスカーソルのY座標 ; #defcfunc mus_y return (ginfo(1) - ginfo(5) - frame(1)) ; 現在のマウスの座標位置 デバッグ表示 ; #defcfunc mus_pos_ return strf("mouse(%d, %d)", mus_x(), mus_y()) ;########################################################### ; マウス座標位置の判定 ; val = musxy(posary, mode, size) ; [array] posary : カレントX, Y座標及び横幅と高さ ; #defcfunc local musxy_ array posary, int mode, double size if (size = 0.0) {i = 1.0} else {i = size} if mode { mytmp = (posary.0 - (i * posary.2 * 0.5)), (posary.1 - (i * posary.3 * 0.5)) chk.0 = (mytmp.0 <= mus_x()) chk.1 = (mytmp.1 <= mus_y()) chk.2 = (mus_x() <= (mytmp.0 + (i * posary.2))) chk.3 = (mus_y() <= (mytmp.1 + (i * posary.3))) } else { chk.0 = (posary.0 <= mus_x()) chk.1 = (posary.1 <= mus_y()) chk.2 = (mus_x() <= (posary.0 + posary.2)) chk.3 = (mus_y() <= (posary.1 + posary.3)) } return (chk.0 & chk.1 & chk.2 & chk.3) ;########################################################### ; マウス座標位置の判定 ; val = musxy(posary, mode, size) ; [array] posary : カレントX, Y座標及び横幅と高さ ; [ int ] mode : 座標基準点中心モード (= 0, 0:左上 / 1:中心) ; [double] size : 描画サイズ連動用 ; #define global ctype musxy(%1,%2=0,%3=0.0) musxy_@my_mouse(%1,%2,%3) #global //////////////////// 以下サンプル //////////////////// screen 0, 640, 460 mouse_init ; 座標位置(200, 300)の点から幅300,高さ75の矩形範囲内 ; m_pos = 200, 300, 300, 75 ; フラグ管理用 ; (0) : マウス座標範囲内外判定 ; (1) : 処理実行判定 ; dim i, 2 *main await (1000.0 / 20.0) : title strf("i = %d, %d // %d // ", i(0), i(1), mycnt) + mus_pos_() rgbcolor 0xFFFFFF : boxf rgbcolor 0x555555 : boxf m_pos(0), m_pos(1), ( m_pos(0) + m_pos(2) ), ( m_pos(1) + m_pos(3) ) rgbcolor 0x000000 : pos mus_x(), mus_y() if musxy(m_pos) {i(0) = 1 : mycnt++ : mes "ここだよ"} else {i(0) = 0} ; マウス範囲内 かつ まだ鳴らしていない if ( i(0) & (i(1) = 0) ) {i(1) = 1 : pos 0, 0 : mes "にゃあぁ〜"} ; マウス範囲外 かつ 過去に鳴らした if ( (i(0) = 0) & i(1) ) {i(1) = 0} goto *main



YUZRANIUM

リンク

2023/5/9(Tue) 23:42:46|NO.99418

NO.99417の下から6行目当たりの

; マウス範囲内 かつ まだ鳴らしていない if ( i(0) & (i(1) = 0) ) {i(1) = 1 : pos 0, 0 : mes "にゃあぁ〜"}
このif文 i(1) = 1 の後に音を鳴らす処理を置けばよろしいかと

(ごめんなさい,音を鳴らす方法知らないです.とりあえず動作だけでも...



大富豪

リンク

2023/5/9(Tue) 23:58:10|NO.99419

>沢渡さん
ありがとうございます。
出来ました;

if mousex>600 {
if flag=0 {
***サウンド再生***
flag=1
}
cn++
title str(cn)
} else {
flag=0
}

範囲外の場合の[else]でflag=0なので、
鳴っていない判定?なのに、
elseの鳴っていないフラグを受け取って
if flag=0 {//範囲外の判定で、
**************//サウンド再生した直後に、
flag=1//再生したフラグで、
なぜ音が鳴るのか・・・。
(逆?)

ifの中にif。
初心者には思ったより難しいです・・・。


>YUZRANIUMさん
ありがとうございます。
初心者には解読不能です;;;
過去に一度再生したという変数(フラグ)?がミソなんですかね。

ずっと範囲内に入っている間でも、
”そのフラグ(再生した)を受け取ったら既に処理をしているので(再生の)処理をスキップする”
という感じだとは思いますが;


機械式のプッシュスイッチのように、
プラグラムでON/OFFするのって意外と難しい感じですね;



大富豪

リンク

2023/5/10(Wed) 00:04:45|NO.99420

>YUZRANIUM(#99418)さん
はい、希望通りの動きをしました。
ありがとうございます。

ですが難し過ぎて
自分のオリジナルソースへの組み込みが・・・。

範囲内に入った瞬間から、
 音を再生したフラグを立てて、
他の処理を継続。
 範囲外にはずれたらフラグを下げるのは簡単なのですが、
一回だけ処理をする(スイッチを1回だけONにする)処理が難しいですね;



usagi

リンク

2023/5/10(Wed) 14:35:44|NO.99422

こんにちわ
>一回だけ処理をする(スイッチを1回だけONにする)処理が難しいですね;
一例ですが、この場合のデザインパターンはステートパターンがいいかもですね。
ONOFFの”フラグ”的な発想ではなくonになった瞬間があるわけですから、”状態”としては合計4つある訳です。
それを、定義しておく感じです。いかがでしょうか。


#module ;状態(ステート)を定義 #enum global STATE_OFF = 0 #enum global STATE_ON #enum global STATE_OFF_TRG #enum global STATE_ON_TRG ;オンにする #deffunc seton var _state if _state & STATE_ON { _state = STATE_ON } else { _state = STATE_ON_TRG } return ;オフにする #deffunc setoff var _state if _state & STATE_ON { _state = STATE_OFF_TRG } else { _state = STATE_OFF } return #global repeat ; ★条件で状態をON OFF する if mousex>600 { seton state } else { setoff state } color 255,255,255:boxf:color:pos 0,0 ; ★このようにif入れ子(ネスト)無しで、状態に対する処理をシンプルに書ける。 if state = STATE_OFF : mes "OFF" if state = STATE_ON : mes "ON" if state = STATE_OFF_TRG : mes "OFFになった" if state = STATE_ON_TRG : mes "ONになった" await 330 ; 分かりやすいように長め loop



usagi

リンク

2023/5/10(Wed) 18:25:53|NO.99423

あっ、すみません。以前#とか&とか見慣れないコマンドが。。。
とあったかと思いますので書き下してみました。(おなじ大富豪さんですよね!?)

内容は同じで書き方が違うだけなので参考になれば幸いです。
(こちらの方が見やすいかな?)


;状態(ステート)を定義 STATE_OFF = 0 STATE_ON = 1 STATE_OFF_TRG = 2 STATE_ON_TRG = 3 repeat ; ★条件で状態をON OFF する if mousex>600 { gosub *SETON } else { gosub *SETOFF } color 255,255,255:boxf:color:pos 0,0 ; ★状態に対して処理をする if state = STATE_OFF : mes "OFF" ; なにもしなかったり if state = STATE_ON : mes "ON" ; カウントしたり if state = STATE_OFF_TRG : mes "OFFになった" ; なにもしなかったり if state = STATE_ON_TRG : mes "ONになった" ; 音ならしたり await 330 ; 分かりやすいように長め loop ;オンにする *SETON if state = STATE_OFF : state = STATE_ON_TRG : return if state = STATE_ON : state = STATE_ON : return if state = STATE_OFF_TRG : state = STATE_ON_TRG : return if state = STATE_ON_TRG : state = STATE_ON : return return ;オフにする *SETOFF if state = STATE_OFF : state = STATE_OFF : return if state = STATE_ON : state = STATE_OFF_TRG : return if state = STATE_OFF_TRG : state = STATE_OFF : return if state = STATE_ON_TRG : state = STATE_OFF_TRG : return return



YUZRANIUM

リンク

2023/5/10(Wed) 18:59:37|NO.99424

>過去に一度再生したという変数(フラグ)?がミソなんですかね。
>ずっと範囲内に入っている間でも、......

そうです!! それが言いたかったんです!!
ごめんなさい,よくよく考えてみるとモジュール部分必要なかったですね...
難しくしてしまったようで申し訳ないです.


私のフラグで制御する方法では

"実行するための条件" と "状態を確認するもの" が

ごちゃ混ぜになって複雑なif文を量産してしまう一方,
usagi様のデザインパターンでは気持ちいいですね(語彙力



大富豪

リンク

2023/5/11(Thu) 20:46:29|NO.99434

>usagiさん
ありがとうございます。
>(おなじ大富豪さんですよね!?) (はい^^;)

たぶんですが、

pos指定を外すと、
mes "ONになった"が繰り返されると思いますが、
それだとたぶん?NGかもです・・・;

申し訳ありません、説明不足だったかと思います。

やりたいのは、
条件に一致した瞬間だけ一度音を鳴らして、
一致している間はカウントなどの処理を継続する感じです。

repeat
if {
条件に一致したら cnt+ : ----- gosub *A(再生)
if 再生フラグがたっていればジャンプせず音も鳴らさない
if 鳴った+条件に外れた=なったフラグを降ろす
}

loop

*A
音を鳴らす
なったフラグを立てる。
return

という結構ややこしいイメージなのですが・・・。



大富豪

リンク

2023/5/11(Thu) 20:58:36|NO.99435

>YUZRANIUMさん
ありがとうございます。
モジュール(#***)はまだ勉強不足で、
まったく使いこなせません・・・;
(%dなどの使い方も;)

> ; マウス範囲内 かつ まだ鳴らしていない
> if ( i(0) & (i(1) = 0) ) ........
この部分にmmplayを入れてみると、
思った通りの動きをしました。

>; フラグ管理用
> ; (0) : マウス座標範囲内外判定
> ; (1) : 処理実行判定
> ;
> dim i, 2

>"実行するための条件" と "状態を確認するもの" が

たぶんフラグのほうが分かりやすいと思って、
変数をスイッチ切替えするイメージでやっていたのですが・・・、
じっくり勉強します;
ありがとうございます。



usagi

リンク

2023/5/11(Thu) 21:43:15|NO.99436

>pos指定を外すと、mes "ONになった"が繰り返されると思いますが
おっふ、それはダメですねぇ。そんな事ないと思うのですが。。。謎ですね。
折角なのでpos等の説明用の描画使わずに直してみました。


#include "winmm.as";仮 ;状態(ステート)を定義 STATE_OFF = 0 STATE_ON = 1 STATE_OFF_TRG = 2 STATE_ON_TRG = 3 repeat ; ★条件で状態をON OFF する if mousex>600 { gosub *SETON } else { gosub *SETOFF } ; ★状態に対して処理をする(今回はオン系だけ使う) if state = STATE_ON : cn++ if state = STATE_ON_TRG : cn++ : PlaySound "SystemAsterisk",0,1;仮音 title "カウント"+cn : await 16 loop ;オンにする *SETON if state = STATE_OFF : state = STATE_ON_TRG : return if state = STATE_ON : state = STATE_ON : return if state = STATE_OFF_TRG : state = STATE_ON_TRG : return if state = STATE_ON_TRG : state = STATE_ON : return return ;オフにする *SETOFF if state = STATE_OFF : state = STATE_OFF : return if state = STATE_ON : state = STATE_OFF_TRG : return if state = STATE_OFF_TRG : state = STATE_OFF : return if state = STATE_ON_TRG : state = STATE_OFF_TRG : return return


意にそぐわなかったようで申し訳なかったです。、
一応、意図としては、「一般的にどんな方法が」との事にたいして、、
プログラムにはよく使う"デザインパターン"と言うのが沢山ありますので、
別の概念での提案をしてみた感じでございます。(検索すると色々出てきますよ)

以下、簡単な概念。

・直接オンオフではなく... (これだとON一瞬がとれない) オン <--> オフ ・トリガ状態を経由し、一方通行で状態遷移。 ┌─オントリガ←┐ ↓  ↑│   │ オン ││  オフ │  │↓   ↑ └→オフトリガ─┘ ※オンでカウントして、オントリガで再生する ユーザー入力:オン、オフの2個 状態:4個 とユーザーの操作と処理の数を分けられるので、 このステートパターンを使うともっと複雑な物へと拡張できる利点があります。 例)ゲームコントローラーは8ボタン(入力)だけど、  キャラのアクションは32種類(状態)あるなど。


ifの中のifを許容されるのであれば、
新たにご説明いただいた内容から考えると、沢渡さんが仰られている事が
一番、大富豪さんの"手段"と"目的"にはあそうですねぇ。

デザインパターンは正しい実装って訳ではなく、
ひとつの"手段"で言語や用途によって、いろいろな書き方があります。

一例として、おそらく修正したもので動いたと思うのでこの辺りでしつれいしますね。
読んで頂きありがとうございました。



大富豪

リンク

2023/5/12(Fri) 23:36:59|NO.99437

>usagiさん
ありがとうございます。
あれ、一回しか鳴りませんね;
思うような動作になりました・・・。

(文字列のステータスと数字の定数は・・・)

サブルーチン(gosub)でステータスを切り替えるように
考えていたのでデザインパターンと併せて参考にさせて頂きます。
ifとifで二重に関係しているので難しいですね;

沢渡さんが提示して頂いたソースは、
範囲外のelse flag=0と
範囲内の if flag=0で音が鳴るというのが・・・なぜ@@
}else{の括り方がミソなんですかね;

取りあえず色々と試行錯誤してみます。
皆さんありがとうございました。



記事削除

記事NO.パスワード
(質問が解決したスレッドは他の利用者に活用してもらうため、削除しないようお願いします)

NO.99413への返信

マスコット

好きなマスコットを選んでください。

名前

e-mail
HOME
  1. 初めて利用する方は、HSP3掲示板の使い方をお読みください。
  2. 不要部分の多い長いスクリプトの投稿は ご遠慮ください。
  3. 書き込みは自動改行されません。適度に改行を入れてください。
  4. スクリプトは小文字の<pre>〜</pre>で囲むと見やすく表示できます。

削除用パスワード

解決したら質問者本人がここをチェックしてください。

エラー発生時、再送信すると二重送信になることがあります。
回答が得られたら、お礼書き込み時に[解決]チェックしてください。
SPAM防止のためURLから始まる文章は投稿できません。
SPAM防止のため英文字のみの本文を投稿することはできません。

ONION software Copyright 1997-2023(c) All rights reserved.