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


HSPTV!掲示板


未解決 解決 停止 削除要請

2021
0205
みそしるにあんこキー押しで反応を求める試行3解決


みそしるにあんこ

リンク

2021/2/5(Fri) 13:35:18|NO.92214

こんにちは、HSP(3.5.1.0)を使用している者です。

先日「キー入力でループから脱出」という題目で質問をさせていただき、
その時の回答を元に下記の流れを設計しようとしています。

[1] 
待機画面、Enterキーで進行。
[2]
スクリーン中央に画像が、下側に四角形が表示される。
四角形は1000msの時間間隔で1つずつ横並びに表示されていき、
3つ表示されると消え、また1つ目から表示が始まる。
[3]
AまたはSのキーが押されると中央に表示された画像が消える。
四角形の表示は、キーが押されたタイミングではなく
キー押しが行われた周をやりきった後でループを終える。
[4]
[2]〜[3]の流れを3回繰り返す。
各回において「画像表示からキー押しまでの時間」を記録する。

試行錯誤してみているのですが、想定通りの作動は叶わず…
現段階での問題は次の通りです。

・AやSを押しても進行せず、1つ目の画像と四角形の提示が繰り返される。
 連打や押しっぱなしだと2週目に移りますが、2&3週目はボタンを押さなくても自動で進んでしまいます。
・キーを押しても画像が消えない。
・四角形の提示が再スタートする際に画像も一度消えてしまう。
 (同じスクリーンに表示しているものの表示条件を別々に設定する手順が分かりません)

現在のスクリプトを記述しておきます。
他のフォルダ内から画像を引っ張るようにしてあるので再現性はないのですが、
下手に手を加えると問題の所在が不鮮明になるかもしれないと思い、
そのまま掲示させていただきました。


#const TRIAL_ALL 3 // 総試行数 #const SESSION_ALL 1 // セッション数 #const fontsize 60 // フォントサイズ設定 #const ITI 10 // 試行間間隔(ms) #const interval 1000 // 四角形の提示間隔 #const GAZOUTEIJI 1 // 画像提示をするか否か 提示=1 非提示=0 #const GAZOU_FORMAT 1 // 読み込む刺激画像の拡張子 gif=0 jpg=1 bmp=2 #const GAZOU_RANDOM 1 // 刺激画像の提示順序のランダマイズ あり=1 なし=0 // 時間計測準備 #uselib "winmm.dll" #cfunc timegettime "timeGetTime" #func timeBeginPeriod "timeBeginPeriod" int #func timeEndPeriod "timeEndPeriod" int timeBeginPeriod 1 //タイマー精度を1msに設定 phase=3 //フェイズ flag=0 //Aキーを押したフラグ c=s //時間がこの値以上になったらフェイズを進行 dim ans, 3 //キー入力保存用配列 notesel record //メモリーノートパッド命令で使用するバッファの割り当て savetitle = "RES" + str(gettime(0)) + str(gettime(1)) + str(gettime(3)) + str(gettime(4)) + str(gettime(5)) //ファイル名 noteadd "Date:" + str(gettime(0)) + "年" + str(gettime(1)) + "月" + str(gettime(3)) + "日" + str(gettime(4)) + "時" + str(gettime(5)) + "分" //ファイル内1行目 noteadd "\n" noteunsel dim rt, TRIAL_ALL, SESSION_ALL dim gazouid, TRIAL_ALL // 表示する画像の識別 dim pic_x, TRIAL_ALL // 読み込んだ画像の横サイズ dim pic_y, TRIAL_ALL // 読み込んだ画像の縦サイズ if(GAZOUTEIJI){ repeat TRIAL_ALL // 画像読み込み buffer cnt+11 // 画像用bufferの割り当て switch(GAZOU_FORMAT) case 1 picload "figure\\"+str(cnt)+".jpg" pic_x(cnt) = ginfo_winx // 画像の横サイズ読み込み pic_y(cnt) = ginfo_winy // 画像の縦サイズ読み込み swbreak swend gazouid(cnt) = cnt loop if GAZOU_RANDOM { randomize repeat TRIAL_ALL temp = gazouid(cnt) r = rnd(TRIAL_ALL) gazouid(cnt) = gazouid(r) gazouid(r) = temp loop } } screen 1, ginfo_dispx, ginfo_dispy // フルスクリーンウィンドウ #define shiji "Enterキーで開始します" font msGothic, fontsize // フォント設定 pos ginfo_dispx/2-(strlen(shiji)*(fontsize/2))/2, ginfo_dispy/2-fontsize/2 // 表示位置設定(中央揃え) mes shiji repeat // Enterキーを押すと進行 getkey Esc, 27 getkey Enter, 13 if Esc = 1 : goto *owari // Escキーが押されたらデータ保存後終了 if Enter = 1 : break wait 1 loop // 試行開始 // repeat TRIAL_ALL // 試行のループ trialnum = cnt repeat SESSION_ALL //セッションのループ sessionnum = cnt start = timeGetTime() repeat getkey Esc, 27 if Esc = 1 : goto *owari //Escキーが押されたらデータ保存後終了 gosub *gazouhyouji getkey A, 65 getkey S, 83 if A : flag=1 : finish = timeGetTime() if S : flag=1 : finish = timeGetTime() if timeGetTime()>=c { phase++ if phase>3 : phase=0 c+=interval if (phase=0)&flag : break switch phase case 0 cls 0 swbreak case 1 boxf ginfo_dispx/2-250, ginfo_dispy/2+300, ginfo_dispx/2-150, ginfo_dispy/2+400 swbreak case 2 boxf ginfo_dispx/2-50, ginfo_dispy/2+300, ginfo_dispx/2+50, ginfo_dispy/2+400 swbreak case 3 boxf ginfo_dispx/2+150, ginfo_dispy/2+300, ginfo_dispx/2+250, ginfo_dispy/2+400 swbreak swend } await Interval loop ans(trialnum, cnt) = A rt(trialnum, cnt) = finish - start // 反応時間を保存 wait ITI loop wait ITI loop goto *owari *gazouhyouji // 画像の表示 if(GAZOUTEIJI){ pos ginfo_dispx/2-pic_x/2, ginfo_dispy/2-pic_y/2 // 画像を中央に提示 gzoom ginfo_dispx/2, ginfo_dispy/2, gazouid(trialnum)+11, 0, 0, pic_x(gazouid(trialnum)), pic_y(gazouid(trialnum)), 0 // 画像をコピーして表示 } return *owari //ファイル出力// notesel record noteadd "試行No." + "\t" + "刺激No." + "\t" + "反応キー" + "\t" + "反応時間(ms)" repeat TRIAL_ALL trialnum = cnt repeat SESSION_ALL noteadd str(trialnum+1) + "\t" + gazouid(trialnum) + "\t" + str(ans(trialnum, cnt)) + "\t" + rt(trialnum, cnt) loop loop notesave savetitle + ".dat" noteunsel timeEndPeriod 1 // タイマー精度復帰 end
問題点が多くあり申し訳ないのですが、
部分的にもお力添えいただけましたら幸いです。



この記事に返信する


沢渡

リンク

2021/2/6(Sat) 13:18:01|NO.92221

このような形で直してみましたがどうでしょうか。
直した部分については「//※」という形でコメントしているので
そちらを参照してください。
(画像ファイルが無いので代わりに何らかの色でベタ塗りした画像を使っています)

#const TRIAL_ALL 3 // 総試行数 #const SESSION_ALL 1 // セッション数 #const fontsize 60 // フォントサイズ設定 #const ITI 10 // 試行間間隔(ms) #const interval 1000 // 四角形の提示間隔 #const GAZOUTEIJI 1 // 画像提示をするか否か 提示=1 非提示=0 #const GAZOU_FORMAT 1 // 読み込む刺激画像の拡張子 gif=0 jpg=1 bmp=2 #const GAZOU_RANDOM 1 // 刺激画像の提示順序のランダマイズ あり=1 なし=0 // 時間計測準備 #uselib "winmm.dll" #cfunc timegettime "timeGetTime" #func timeBeginPeriod "timeBeginPeriod" int #func timeEndPeriod "timeEndPeriod" int //timeBeginPeriod 1 //タイマー精度を1msに設定 //※←これ必要でしょうか? //※↓これらはプログラムの冒頭ではなく、表示する画像を切り替えるたびに行う //phase=3 //フェイズ //flag=0 //Aキーを押したフラグ //c=s //時間がこの値以上になったらフェイズを進行 dim ans, 3 //キー入力保存用配列 notesel record //メモリーノートパッド命令で使用するバッファの割り当て savetitle = "RES" + str(gettime(0)) + str(gettime(1)) + str(gettime(3)) + str(gettime(4)) + str(gettime(5)) //ファイル名 noteadd "Date:" + str(gettime(0)) + "年" + str(gettime(1)) + "月" + str(gettime(3)) + "日" + str(gettime(4)) + "時" + str(gettime(5)) + "分" //ファイル内1行目 noteadd "\n" noteunsel dim rt, TRIAL_ALL, SESSION_ALL dim ans, TRIAL_ALL, SESSION_ALL //※これを実行していないのでESCで中断した時にエラーになる dim gazouid, TRIAL_ALL // 表示する画像の識別 dim pic_x, TRIAL_ALL // 読み込んだ画像の横サイズ dim pic_y, TRIAL_ALL // 読み込んだ画像の縦サイズ randomize //仮 if(GAZOUTEIJI){ repeat TRIAL_ALL // 画像読み込み buffer cnt+11,rnd(100)+200,rnd(100)+100 // 画像用bufferの割り当て //仮 switch(GAZOU_FORMAT) case 1 color rnd(256),rnd(256),rnd(256) //仮 boxf //picload "figure\\"+str(cnt)+".jpg" pic_x(cnt) = ginfo_winx // 画像の横サイズ読み込み pic_y(cnt) = ginfo_winy // 画像の縦サイズ読み込み swbreak swend gazouid(cnt) = cnt loop if GAZOU_RANDOM { randomize repeat TRIAL_ALL temp = gazouid(cnt) r = rnd(TRIAL_ALL) gazouid(cnt) = gazouid(r) gazouid(r) = temp loop } } screen 1, ginfo_dispx, ginfo_dispy // フルスクリーンウィンドウ #define shiji "Enterキーで開始します" font msGothic, fontsize // フォント設定 pos ginfo_dispx/2-(strlen(shiji)*(fontsize/2))/2, ginfo_dispy/2-fontsize/2 // 表示位置設定(中央揃え) mes shiji repeat // Enterキーを押すと進行 getkey Esc, 27 getkey Enter, 13 if Esc = 1 : goto *owari // Escキーが押されたらデータ保存後終了 if Enter = 1 : break wait 1 loop // 試行開始 // repeat TRIAL_ALL // 試行のループ trialnum = cnt repeat SESSION_ALL //セッションのループ sessionnum = cnt start = timeGetTime() c=start //※ flag=0 //※ phase=3 //※ repeat getkey Esc, 27 if Esc = 1 : goto *owari //Escキーが押されたらデータ保存後終了 if flag=0 { //※ 同じキーを2度押した時にfinishが上書きされないようにする。 getkey A, 65 getkey S, 83 if A : flag=1 : finish = timeGetTime() if S : flag=1 : finish = timeGetTime() } if timeGetTime()>=c { phase++ if phase>3 : phase=0 c+=interval if (phase=0)&flag : break switch phase case 0 cls 0 gosub *gazouhyouji //※画像表示はこのタイミングで行う swbreak case 1 boxf ginfo_dispx/2-250, ginfo_dispy/2+300, ginfo_dispx/2-150, ginfo_dispy/2+400 swbreak case 2 boxf ginfo_dispx/2-50, ginfo_dispy/2+300, ginfo_dispx/2+50, ginfo_dispy/2+400 swbreak case 3 boxf ginfo_dispx/2+150, ginfo_dispy/2+300, ginfo_dispx/2+250, ginfo_dispy/2+400 swbreak swend } await 66 //※awaitにIntervalを使うと1秒間に一回しか判定されない。awaitの待ち時間と四角形の表示間隔時間は別物。 //await Interval loop ans(trialnum, cnt) = A rt(trialnum, cnt) = finish - start // 反応時間を保存 wait ITI loop wait ITI loop goto *owari *gazouhyouji // 画像の表示 if(GAZOUTEIJI){ pos ginfo_dispx/2-pic_x/2, ginfo_dispy/2-pic_y/2 // 画像を中央に提示 gzoom ginfo_dispx/2, ginfo_dispy/2, gazouid(trialnum)+11, 0, 0, pic_x(gazouid(trialnum)), pic_y(gazouid(trialnum)), 0 // 画像をコピーして表示 } return *owari //ファイル出力// notesel record noteadd "試行No." + "\t" + "刺激No." + "\t" + "反応キー" + "\t" + "反応時間(ms)" repeat TRIAL_ALL trialnum = cnt repeat SESSION_ALL noteadd str(trialnum+1) + "\t" + gazouid(trialnum) + "\t" + str(ans(trialnum, cnt)) + "\t" + rt(trialnum, cnt) loop loop notesave savetitle + ".dat" noteunsel //timeEndPeriod 1 // タイマー精度復帰 //※←これも必要? end



沢渡

リンク

2021/2/7(Sun) 19:25:59|NO.92226

追記です。
下の方にある

await 66 //※awaitにIntervalを使うと1秒間に一回しか判定されない。awaitの待ち時間と四角形の表示間隔時間は別物。
は、以下のように直してください。(66では15fpsになり、さすがに遅い)

await 33 //30fps相当
もしくは

await 16 //60fps相当



みそしるにあんこ

リンク

2021/2/8(Mon) 13:03:43|NO.92229

沢渡様、丁寧な回答ありがとうございます。
返信が遅くなり申し訳ございません。

回答いただいたスクリプトでほぼ期待通りの流れが確認できました。
加えて、追記によりスムーズな動作になりました。

前回の質問も含め、非常に助けになりました。
本当にありがとうございます。



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