Hatena::Groupnadesiko

雪乃☆雫のなでしこ日和

2016-03-26

ゲームパッドの入力を「キー状態」と同じ感じで使いたい!

| 09:49

 なでりすのソースを、うーむと眺めていたんだけど、よくわかんな~い(爆)

 でも、キー操作でブロックを左右に動かしたり転させたり落としたり・・・とゆう操作自体は、「キー処理」という関数にまとまっている。

 ふつーに、バーチャルキーのキー状態オンオフをとって、もしもし条件分岐してる。

 てことは、ゲームパッドの入力を、なでしこの標準命令であるキー状態」と同じ感じで取得できれば、最小限の変更でゲームパッドで遊べるように改造することができるだろうし、後何か作ろうと思った時にも便利に違いない


 ・・・とゆーわけで、知恵が足りないから、通常のボタンと十字キーは手軽に別関数にしてしまったけれど、こんな感じの関数にしてみた。

#-----------------------------------------------------------------------
# 『JOYキー状態』『JOY十字キー状態』
#・なでしこの「キー状態」と同じ感じで、ジョイパッドのボタン入力状態を調べ、オンオフを返す。
#・肝心のWindowsAPI部分は「なでしこ質問掲示板」の一般人さまの答による。
#http://nade.jp-pro.net/bbs/bbs/cbbs.cgi?mode=one&number=7435&type=7400&space=45&no=0
#-----------------------------------------------------------------------

#-----------------------------------------------------------------------
!JOYERR_NOERROR = 0 //情報取得時にエラーがないときに返される値
!JOY_RETURNALL = 255 //Joystickの情報を全て取り込む値
#-----------------------------------------------------------------------
//Joystickの情報を取り込む関数
●joyGetPosEx(uJoyID,{参照渡し}pji) =DLL("winmm.dll","UINT joyGetPosEx(UINT uJoyID,LPJOYINFOEX pji)")
//Joystickの最大サポート数(?)は未使用
●joyGetNumDevs =DLL("winmm.dll","UINT joyGetNumDevs(VOID)")

//JOYINFOEXの構造体をグループで構成
■JOYINFOEXとは
 ・dwSize
 ・dwFlags
 ・dwXpos
 ・dwYpos
 ・dwZpos
 ・dwRpos
 ・dwUpos
 ・dwVpos
 ・dwButtons
 ・dwButtonNumber
 ・dwPOV
 ・dwReserved1
 ・dwReserved2
#-----------------------------------------------------------------------
●JOYキー状態(Sで|Sの)
  AとはJOYINFOEX
  A.dwSize = 52 //Cで言うsizeof()がわからなかったためマジックナンバー
  A.dwFlags = JOY_RETURNALL
  Bとは文字列
  PACK(A,B,`DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD`)
  もし、joyGetPosEx(0, POINTER(B))=JOYERR_NOERRORならば
    UNPACK(B,A,`DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD`)
    もし、S=A.dwButtonsならばオン戻る。
    違えばオフ戻る。
  違えばキャンセル戻る。

●JOY十字キー状態(Sで|Sの)
  AとはJOYINFOEX
  A.dwSize = 52 //Cで言うsizeof()がわからなかったためマジックナンバー
  A.dwFlags = JOY_RETURNALL
  Bとは文字列
  PACK(A,B,`DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD`)
  もし、joyGetPosEx(0, POINTER(B))=JOYERR_NOERRORならば
    UNPACK(B,A,`DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD`)
    Sで条件分岐
      # $2777とか$D888とかの数値は暫定。アナログジョイスティックのための措置。
      "L"ならば、
        もし、(A.dwXpos<$2777)ならばオン戻る。  # (A.dwXpos=0)
        違えばオフ戻る。
      "U"ならば、
        もし、(A.dwYpos<$2777)ならばオン戻る。  # (A.dwYpos=0)
        違えばオフ戻る。
      "R"ならば、
        もし、(A.dwXpos>$D888)ならばオン戻る。  # (A.dwXpos=$FFFF)
        違えばオフ戻る。
      "D"ならば、
        もし、(A.dwYpos>$D888)ならばオン戻る。  # (A.dwYpos=$FFFF)
        違えばオフ戻る。
      違えばオフ戻る。
  違えばキャンセル戻る。
#-----------------------------------------------------------------------

 以下はサンプルプログラム。

 十字キーで「●」を動かし、ボタンで色を変えるプログラムが、キーボードの場合のをコピペしてキー番号と関数名の書き換えだけで、全く同様に動いたよ!

#-----------------------------------------------------------------------
#----バーチャルキー定義-------------
!VK_LEFT = 37
!VK_UP = 38
!VK_RIGHT = 39
!VK_DOWN = 40
!VK_Z = 90
!VK_X = 88
#----ジョイパッドのキー定義-------------
!JOY_Aとは整数=$01
!JOY_Bとは整数=$02
!JOY_Cとは整数=$04
!JOY_Xとは整数=$08
!JOY_Yとは整数=$10
!JOY_Zとは整数=$20
!JOY_Lとは整数=$40
!JOY_Rとは整数=$80
!JOY_STARTとは整数=$100
!JOY_SELECTとは整数=$200
!JOY_LEFTとは文字列="L"
!JOY_UPとは文字列="U"
!JOY_RIGHTとは文字列="R"
!JOY_DOWNとは文字列="D"
#-----------------------------------------------------------------------

ゲームパッド使用=オンオフにするとキーボードで動きます
CX=母艦のクライアント幅/2-24/2
CY=母艦のクライアント高さ/2-24/2
文字書体は「MS ゴシック|24|太字」
母艦CX,CYへ「●」を文字表示もし、ゲームパッド使用=オンならば
  1の
    もし(JOY_UPのJOY十字キー状態オン)ならば
      もし、(JOY_RIGHTのJOY十字キー状態オン)ならばCX=CX+3。CY=CY-3。
      違えばもし、(JOY_LEFTのJOY十字キー状態オン)ならばCX=CX-3。CY=CY-3。
      違えば、CY=CY-3。
    違えばもし(JOY_DOWNのJOY十字キー状態オン)ならば
      もし、(JOY_RIGHTのJOY十字キー状態オン)ならばCX=CX+3。CY=CY+3。
      違えばもし、(JOY_LEFTのJOY十字キー状態オン)ならばCX=CX-3。CY=CY+3。
      違えば、CY=CY+3。
    違えばもし(JOY_RIGHTのJOY十字キー状態オン)ならばCX=CX+3。
    違えばもし(JOY_LEFTのJOY十字キー状態オン)ならばCX=CX-3。

    もし、(JOY_AのJOYキー状態オンならば文字色緑色。
    違えばもし、(JOY_BのJOYキー状態オンならば文字色赤色。
    違えばもし、(JOY_CのJOYキー状態オンならば文字色青色。
    違えばもし、(JOY_XのJOYキー状態オンならば文字色紫色。
    違えば文字色黒色。
    母艦白色画面クリア
    母艦CX,CYへ「●」を文字表示。
    0.01秒待つ
違えば
  1の
    もし(VK_UPのキー状態オン)ならば
      もし、(VK_RIGHTのキー状態オン)ならばCX=CX+3。CY=CY-3。
      違えばもし、(VK_LEFTのキー状態オン)ならばCX=CX-3。CY=CY-3。
      違えば、CY=CY-3。
    違えばもし(VK_DOWNのキー状態オン)ならば
      もし、(VK_RIGHTのキー状態オン)ならばCX=CX+3。CY=CY+3。
      違えばもし、(VK_LEFTのキー状態オン)ならばCX=CX-3。CY=CY+3。
      違えば、CY=CY+3。
    違えばもし(VK_RIGHTのキー状態オン)ならばCX=CX+3。
    違えばもし(VK_LEFTのキー状態オン)ならばCX=CX-3。

    もし、(VK_Zのキー状態オンならば文字色赤色。
    違えばもし、(VK_Xのキー状態オンならば文字色青色。
    違えば文字色黒色。
    母艦白色画面クリア
    母艦CX,CYへ「●」を文字表示。
    0.01秒待つ
#-----------------------------------------------------------------------

 同様にして、なでりすの「キー処理」関数だけ書き換えたら、ちゃんと遊べました♪


 途中で、アナログジョイスティックの場合の実験に移行してしまったため、ここまでえらく時を食ったけれど、おかげでやっぱりゲームパッドによって、割り当て数値がまたちょっと違うみたいだとゆうことも分かった。

 のジョイパッドのキー定義は、サターンパッドに合わせています(サターンパッドにセレクトボタンないけど)

 でも、PS2の場合は、Aボタン(○)が$02、Bボタン(×)が$04・・・みたいなことになってるし、LRボタンも、SSのLとRがPS2ではR2とR1になっているなど、自分以外の人にも遊んでもらおうと思う場合は、キー設定のオプションが必須になるかもしないねえ。

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20160326

2016-03-25

アナログジョイスティックの場合

| 17:09

 ゲームパッドが使えるとゆうことを知り、異常にテンションを上げたワタシだけど、頭の中がゲームのわりには大したゲームがプレイ出来ないから、実は家にはPCようのゲームパッドなんてない(爆)

 唯一あったのが、ン十年前のセガサターン、初代プレステ(笑)、ドリームキャスト(!)のコントローラーをUSBでPCにつなげるようにするというアダプター。

 同様のアダプターは当然あるだろうけれど、つなげる機器が泣けるねwww

 Win7でも使えるのか・・・? と思いながら挿してみたら、サターンパッドがふつーに使えたよ!

 ・・・とゆーわけで、それで色々ためして遊んでいたんだけれど、アナログジョイスティックの場合は、ふつーのデジタルの十字キーとはまた異なるということを教えて頂いた。

 アナログは、どのくらい押されたか、スティックの傾きの値が段階的に取得出来るらしいんだけど、ここで重要なのは、斜めの場合に必ずしも限界値まで入らないよ、ということ!

 あまり詳しいことは分からないけれど、とにかくこれはよろしくありません。

 なぜなら、デジタルの場合(うちでサターンパッドでためした結果)押されていない時は「$7FFF」、上/左は「0」、下/右は「$FFFF」の値が、それぞれ「dwYpos」と「dwXpos」に帰ってくるので、オンオフで8方向を取得するとゆうサンプルをつくり、あまつさえそれを掲示板に乗っけてしまったからです。

 こんな感じね。

    UD=A.dwYpos
    LR=A.dwXpos
    もし、(UD=$FFFF)ならば
      もし、(LR=$FFFF)ならば、JOY_十字キー=「右下」
      違えばもし、(LR=0)ならば、JOY_十字キー=「左下」
      違えば、JOY_十字キー=「下」
    違えばもし、(UD=0)ならば
      もし、(LR=$FFFF)ならば、JOY_十字キー=「右上」
      違えばもし、(LR=0)ならば、JOY_十字キー=「左上」
      違えば、JOY_十字キー=「上」
    違えばもし、(LR=$FFFF)ならば、JOY_十字キー=「右」
    違えばもし、(LR=0)ならば、JOY_十字キー=「左」
    違えば、JOY_十字キー=「」
    オン戻る

 アナログコントローラーの場合、これじゃ8方向は取れないってことになるんじゃない?(汗)


 しかし、ウチにはアナログジョイスティックなんてない~~~・・・と思っていたら、PSようのところにPS2のコントローラーがふつーに挿さり、ANALOGボタンを押したら、左側のスティックがアナログモードで認識されました!すごい!!

 ためしてみたら、やはり上下左右の4方向しか認識しない

 値を取ってみると、・・・古くておまけに雑に扱われていたせいか、中央の値が一定してないよw しかも、上下は「$7EFF~$6FFF、左右は「$7FFF~$9659」と若干右上に曲がってしまってるっぽいwww

 しかしまあ、それそれとして、ぐりぐりしてみると、細かく値が返ってくるけど、一応ぐるっと360度、で動いた時のX軸Y軸で考えた場合の座標なのかなー?などと予想するも、一方の値が限界値のままというが案外多いので、こまできめ細やかでもない

 これはもちろん、のジョイスティックの性能とかにもよるんだろうね?

 本来、アナログスティックは、いっぱい押したら早く動いたり・・・みたいな、押し加減でびみょーな動きを実現出来たりするものだろうけど、んなヤツが作れるような気はしないので、擬似的にオンオフを取って8方向認識出来るようにさえなればいいんじゃないの?

 とゆーわけで、こうなった。

    UD=A.dwYpos
    LR=A.dwXpos
    もし、(UD>$D888)ならば
      もし、(LR>$D888)ならば、JOY_十字キー=「右下」
      違えばもし、(LR<$2777)ならば、JOY_十字キー=「左下」
      違えば、JOY_十字キー=「下」
    違えばもし、(UD<$2777)ならば
      もし、(LR>$D888)ならば、JOY_十字キー=「右上」
      違えばもし、(LR<$2777)ならば、JOY_十字キー=「左上」
      違えば、JOY_十字キー=「上」
    違えばもし、(LR>$D888)ならば、JOY_十字キー=「右」
    違えばもし、(LR<$2777)ならば、JOY_十字キー=「左」
    違えば、JOY_十字キー=「」
    オン戻る

 $2777とか$D888とかの数値は暫定です。

 イメージ的に、こんなもんじゃないかにゃーと入れてみたけど、妥当かどうかは不明;;;

 まっ、いちおう8方向認識出来るようにはなりました。

 でも・・・さらだけど8方向ってゆうのは、サターンパッドだったからこで、プレステの十字キーなんかじゃ2ボタンを同時押ししなきゃならないコトになって現実的じゃないし、アナログモードでは正確に斜めに入れられるかって言うとびみょーだし、あんま意味ないんじゃないの?orz

 度札幌に行ったら、イマドキのゲームパッドはどんなもんなんだか、みてこようwww

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20160325

2016-03-24

なでしこでもゲームパッドが使えた!

| 16:54

 なななんとっ!!

 DirectInput必須なものとばかり思い込んでいましたが、WindowsAPIの中にも、ジョイスティックを扱うための関数があって、これを取り込んで使えば、なでしこでもゲームパッドを使うプログラムが作れるようになるとゆうことなんです。

 先日来の質問掲示板のやりとりで、判明。

 質問したのはワタシではなく、ワタシはむしろ無責任に「ムリじゃね?」などと言い放ってしまったわけなのですが;;;

(一応、それだけじゃあれなんで、よくあるゲームパッドのボタンを任意のキーボードに割り当てるようなプログラムを、DirectXDLLあるHSPかなんかでの部分だけ、なでしこ側から起動してうまく連携出来るように作れないかなー? なんて、無理矢理系なことを検討していたw)

 いやー、それにしてもWindowsAPIなんぞの分かる人って天才だよね!

 ホント、尊敬する~~☆

 の記事が、こちら。

http://nade.jp-pro.net/bbs/bbs/cbbs.cgi?mode=one&number=7435&type=7400&space=45&no=0

 むむむ(@_@)

 知恵の足りないワタシなんぞが理解するには、百年くらいかかりそうな内容だけど、一応自力で十字キーの入力も八方向取得出来たし、これをうまく使わせてもらえば、ゲームパッドで操作のできるプログラムが、案外簡単に作れそう

 素晴らしい!!

 ・・・と言っても、まで自分が作ったものの中には、ゲームパッドどころか、もキーボードで操作する的なものがなかったw

 なにぶん、反射神経が0%なんで、作れる作れない以前に、アクション、シューティング、落ちもの的なゲームはプレイ出来ないのだ><

 でも、ちょっと面白いので、なでしこのサンプルに入っている「なでりす」をゲームパッドで遊べるように改造してみたいと思う。

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20160324

2016-03-21

続・選択肢の怪

| 13:45

 さて・・・現実逃避ばかりもしてられないので、ちょっと、選択肢に関係したところを、抜き出してみる。

#------------------------------------------------------------
#    分岐
#------------------------------------------------------------
違えばもし、コマンドが「選択肢」ならば
  改行確認=オフ
  選択肢数=シナリオ¥行番号,2
   もし、選択肢表示位置固定=オンならば
    保持用を表画面の0,0へ画像コピー。
    メッセージ行数=0
  違えば
    選択肢表示Y=(テキストウィンドウY+メッセージY)+((「あ」の文字高さ取得+メッセージ影+行)*(メッセージ行数+1))

  #選択肢ボタンの設定
  #0ボタン表示位置X、1ボタン表示位置Y、2ボタン幅、3ボタン高さ
  (選択肢数)
    選択肢ボタン回数,0は選択肢表示X
    選択肢ボタン回数,1は選択肢表示Y+(回数-1)*((「あ」の文字高さ取得+メッセージ影+選択肢隔))
    選択肢ボタン回数,2は選択肢幅
    選択肢ボタン回数,3は(「あ」の文字高さ取得+メッセージ影)

  (選択肢数)
    行番号=行番号+1
    もし、シナリオ¥行番号,0=「-」でなければ
      選択肢数=回数-1
      抜ける
    ラベル一覧¥(回数-1)=シナリオ¥行番号,2
    シナリオ¥行番号,1を(「あ」の文字高さ取得+メッセージ影+選択肢隔)*(回数-1)へ選択肢表示。
  選択肢をボタン化。
  選択待機オン

 まず、シナリオの中に「選択肢」のコマンドがあったら、選択肢の表示位置を確認してる。

 これは、選択肢表示Xと、選択肢表示Yを、あらかじめ変数で指定しているんだけど、Yに関しては、サウンドノベル風にまで表示してきた文章の下に選択肢を表示するのか、それまでの文章は消して、毎決まった位置に選択肢を表示するのか選べるようにしているから、前者の場合Yの位置が毎変わるからなんだけど、問題のXの位置は基本固定なんだし、関係ない気がする。(ほんとか?!)

 いずれにしても、選択肢の位置を固定してるか否かに関わりなく怪現象は発生している。

 それから、表示位置とコマンドで指定した選択肢数に基づいて、ボタンの設定。

 画面に実際に選択肢を表示し、それをマウスオーバーボタン化するのは、以下関数

#-----選択肢表示---------------------------------------------
*選択肢表示(Sを{数値=0}Yへ)
  表画面の(選択肢表示X),(選択肢表示Y)+Yへメッセージ色,メッセージ影色,メッセージ影,0でSをノベルテキスト描画。
  テキスト保存

*選択肢をボタン化
  選択肢用の幅は選択肢幅*2。選択肢用の高さは(「あ」の文字高さ取得+メッセージ影)*選択肢数。
  選択肢用を選択肢幅*2,(「あ」の文字高さ取得+メッセージ影)*選択肢数で画像リサイズ。
  
  (選択肢数)
    表画面の選択肢表示X,選択肢表示Y+((回数-1)*(「あ」の文字高さ取得+メッセージ影+選択肢隔)),選択肢幅,(「あ」の文字高さ取得+メッセージ影)を選択肢用の選択肢幅,(回数-1)*(「あ」の文字高さ取得+メッセージ影)へ画像部分コピー。

   選択肢用を画像ネガポジ。
  (選択肢数)
    表画面の選択肢表示X,選択肢表示Y+((回数-1)*(「あ」の文字高さ取得+メッセージ影+選択肢隔)),選択肢幅,(「あ」の文字高さ取得+メッセージ影)を選択肢用の0,(回数-1)*(「あ」の文字高さ取得+メッセージ影)へ画像部分コピー。

#------------------------------------------------------------

 表示は、選択肢表示Xと、選択肢表示Yの位置に、選択肢として設定された文字列を、ほんとにただ表示してるだけだから問題ないでしょ。

 して、表示された選択肢の部分を一行ずつ切り取って、ボタン用の画像を作っている。

 面倒なようだけど、これで半透明に合成された背景なんかもちゃんと反映されたネガポジになるわけ。

 して・・・問題の実際にマウスオーバーを反映する部分は、元のマウスオーバーボタンとほぼ一緒だからね~。

表画面のマウス移動した時は~
  もし、選択待機オンならば
    選択肢用の選択肢ボタンを表画面へ選択肢数でマウスインアウト反映。
#------------------------------------------------------------
●マウスインアウト反映({グループ=?}OBJ1のAを{数値=0}Sで{グループ=?}OBJ2へ)
  (S)
    もし、((OBJ2→マウスX)>(A¥回数,0))かつ
      ((OBJ2→マウスX)<(A¥回数,0)+(A¥回数,2))かつ
      ((OBJ2→マウスY)>(A¥回数,1))かつ
      ((OBJ2→マウスY)<(A¥回数,1)+(A¥回数,3))ならば
        選択ボタン回数。
    違えばもし、(回数=Aの要素数)かつ(選択ボタン=0)ならば
      選択ボタンは0。
    ここまで

  もし、前選択ボタン<>選択ボタンならば
    もし、前選択ボタン>0ならば
      OBJ1の(A\0,0),(A\0,1)+(前選択ボタン-1)*(A¥(前選択ボタン),3),(A¥(前選択ボタン),2),(A¥(前選択ボタン),3)をOBJ2の(A¥(前選択ボタン),0),(A¥(前選択ボタン),1)へ画像部分コピー。
    もし、選択ボタン>0ならば
      OBJ1の(A\0,0)+(A¥(選択ボタン),2),(A\0,1)+(選択ボタン-1)*(A¥(選択ボタン),3),(A¥(選択ボタン),2),(A¥(選択ボタン),3)をOBJ2の(A¥(選択ボタン),0),(A¥(選択ボタン),1)へ画像部分コピー。
  前選択ボタン=選択ボタン
  選択ボタン=0
  描画処理反映
#------------------------------------------------------------

 僅かに変わっているのは、ボタン設定の配列要素数ではなく、引数で選択肢数を与えているところ。

 これは、シナリオの方のミスで、コマンドで指定した選択肢数より、実際に記載されてる選択肢が少なかった時に、表示がへんちくりんになるのを避するためだったような?

 選択肢を表示してから設定を行えば、ふつーに避出来るような気がするけど・・・っていうそれならむしろコマンドで選択肢数を指示する必要あるのか?ってゆう話だけど、何か訳があったような気もするし・・・ちょっとよく覚えておらんね;;;

 なんにしろ、この追加された引数が問題ではないことは、マウスオーバーボタンのサンプルプログラムで、検証済みなのだ。


 やっぱ、よく分からん~~~><

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20160321

2016-03-17

動的作成したフォームを壊すと、母艦のボタンが効かなくなるって、なんで?!

| 04:56

 質問掲示板に、「フォームのフェードイン・アウト」とゆうのがあって、フォームって、透明に出来るんだぁ~、こりゃあ面白いと、遊んでいたんだけれども(選択肢のナゾが解明しないから、現実逃避中w)ここにも、ナゾ現象が!><

 フォーム関数内で動的に作って、VCL_FREEで破棄したら、母艦ボタンが効かなくなるんだよ!

関数内でフォーム作成し破棄するテスト
ボタンAとはボタン
のクリックした時は~
  「関数内でフォーム作成のテスト」と言う。
  実験

実験

*実験
  実験用をフォームとして作成
  実験用→可視はオン
  実験用→タイトルは「実験用」
  1秒待つ
  
  VCL_FREE(実験用)

 ↑で、ボタンAを押しても、無反応。

 特に違ったことはしてないつもりなんだけど・・・

 フォームじゃ無くて、イメージ部品とかなら、これで大丈夫なんだけどね。

 イメージの時は、「→壊す」がダメで、「VCL_FREE」にしたら、一発解決だったんだけど、フォームは、VCL_FREEもダメらしい・・・?

 

 ちなみに、「VCL_FREE(実験用)」をコメントアウトすれば、ちゃんとボタンAが押せて、「関数内でフォーム作成のテスト」を言ってくれますが、実験用フォームがが壊れてないから、もう一「実験」を呼んだら、「既に存在するので生成できません」かなんか言われてエラーになっちゃう~。

 ×で終わらせても、可視がオフになってるだけで、フォーム自体は残っているらしく、やっぱり既に存在するといわれてしまうよ! むむむ。

 まあ、ふつーに関数の外で定義すればいいんだけどもさあ。

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20160317

2016-03-15

2Dを振るよ!

| 08:56

 さて、行き詰まった時は・・・サイコロだよ!(なんだそれ;)

 昔、TRPGをやっていたワタシは、ダイスが大好き☆

 べっ、べつに駄洒落じゃありません、念のため;;;

 いや~、転がしてるだけで、何か癒やされる~www

 と言うわけで、ちょぼいちは1Dでしたが、ちょっと2Dを振ってみます。

#2Dを振る
#-----母艦設計-----------------------------------------------
!母艦設計=「母艦の可視はオフ母艦のタイトルは「2Dを振る」
母艦のクライアント幅は640。母艦のクライアント高さは480。
母艦を$006600で画面クリア母艦のスタイルは「枠固定」
母艦オフに最大化ボタン有効変更。
母艦中央移動。
#------------------------------------------------------------

#-----宣言---------------------------------------------------
ダイスサイズとは整数=80

裏画面とはイメージの可視はオフ。
裏画面の幅はダイスサイズ*6。裏画面の高さはダイスサイズ。

処理用とはイメージの可視はオフ。

#---サイコロ振るボタン----
ボタンAとはボタンの可視はオンの幅は100。の高さは35。
のXは母艦のクライアント幅/2-ボタンAの幅/2。のYは母艦の高さ-100。
のテキストは「2Dを振る」

ボタンAをクリックした時は~
  サイコロ振る。
#------------------------------------------------------------

#-----メインルーチン-----------------------------------------
母艦の可視はオン。

ダイスサイズでサイコロ準備。
乱数初期化。
サイコロ振る。
#------------------------------------------------------------

#-----2Dを振る---------------------------------------------
*サイコロ振る
  処理用をダイスサイズ,ダイスサイズへ画像高速リサイズ。
  2
    r=6の乱数。出目¥(回数-1)=r+1。
    x=r*ダイスサイズ。y=0。
    裏画面のx,y,ダイスサイズ,ダイスサイズを処理用の0,0へ画像部分コピー。
    処理用を母艦の((母艦のクライアント幅/4)*(回数))-(ダイスサイズ/2)+(母艦のクライアント幅/8),(母艦のクライアント高さ/2)-(ダイスサイズ/2)へ画像合成通。
#------------------------------------------------------------
*サイコロ準備(Sで)
  裏画面を$00FF00で画面クリア。    #透過色
  目サイズ=S/10。
  数を0から5まで繰り返す。
    もし、数=0ならば                #1のサイコロ
      線色黒色塗り色白色。          #地の色は白
      外枠(S)。                   #ダイスの外枠
      線色赤色塗り色赤色。          #目の色は赤
      半径=目サイズ+S/20。            #大き目
      中点(S)。
  
    もし、数=1ならば                #2のサイコロ
      線色黒色塗り色白色。
      外枠(S)。
      線色黒色塗り色黒色。
      半径=目サイズ。
      左上点(S)。右下点(S)。
  
    もし、数=2ならば                #3のサイコロ
      線色黒色塗り色白色。
      外枠(S)。
      線色黒色塗り色黒色。
      半径=目サイズ。
      中点(S)。左上点(S)。右下点(S)。
  
    もし、数=3ならば                #4のサイコロ
      線色黒色塗り色白色。
      外枠(S)。
      線色黒色塗り色黒色。
      半径=目サイズ。
      左上点(S)。左下点(S)。右上点(S)。右下点(S)。
  
    もし、数=4ならば                #5のサイコロ
      線色黒色塗り色白色。
      外枠(S)。
      線色黒色塗り色黒色。
      半径=目サイズ。
      中点(S)。左上点(S)。左下点(S)。右上点(S)。右下点(S)。
  
    もし、数=5ならば                #6のサイコロ
      線色黒色塗り色白色。
      外枠(S)。
      線色黒色塗り色黒色。
      半径=目サイズ-S/100。
      左上点(S)。左下点(S)。右上点(S)。右下点(S)。左中点(S)。右中点(S)。

*外枠(S)
  x=数*S。y=0。
  x2=x+S。y2=S。
  裏画面のx,yからx2,y2へS/3,S/3で角丸四角。

*中点(S)
  xx=(x+S/2)-半径。yy=S/2-半径
  xx2=(x+S/2)+半径。yy2=S/2+半径。
  裏画面のxx,yyからxx2,yy2へ。

*左上点(S)
  xx=(x+S/4)-半径。yy=S/4-半径
  xx2=(x+S/4)+半径。yy2=S/4+半径。
  裏画面のxx,yyからxx2,yy2へ。

*左下点(S)
  xx=(x+S/4)-半径。yy=(S/4)*3-半径
  xx2=(x+S/4)+半径。yy2=(S/4)*3+半径。
  裏画面のxx,yyからxx2,yy2へ。

*右上点(S)
  xx=(x+S/4*3)-半径。yy=S/4-半径
  xx2=(x+S/4*3)+半径。yy2=S/4+半径。
  裏画面のxx,yyからxx2,yy2へ。

*右下点(S)
  xx=(x+S/4*3)-半径。yy=(S/4)*3-半径
  xx2=(x+S/4*3)+半径。yy2=(S/4)*3+半径。
  裏画面のxx,yyからxx2,yy2へ。

*左中点(S)
  xx=(x+S/4)-半径。yy=S/2-半径
  xx2=(x+S/4)+半径。yy2=S/2+半径。
  裏画面のxx,yyからxx2,yy2へ。

*右中点(S)
  xx=(x+S/4*3)-半径。yy=S/2-半径
  xx2=(x+S/4*3)+半径。yy2=S/2+半径。
  裏画面のxx,yyからxx2,yy2へ。
#------------------------------------------------------------
●画像合成通({グループ}コピー元を{数値=$00FF00}透過色で{グループ}コピー先のX,Yへ)
  # マスクの作成(キャラの透過部分が白、表示部分が黒の画像)
  マスク画像をイメージとして作成。マスク画像の可視はオフ。
  マスク画像→画像はコピー元→名前
  マスク画像を透過色で画像マスク作成

  # キャラの透過色部分を黒に変換
  # はじめからキャラの透過色を黒にすると髪や目や文字に黒が使用出来なくなる
  キャラ画像をイメージとして作成。キャラ画像の可視はオフ
  キャラ画像→画像はコピー元→名前
  マスク画像を画像ネガポジ
  マスク画像をキャラ画像の0,0へ画像ANDコピー
  マスク画像を画像ネガポジ

  # 合成実行
  マスク画像をコピー先のX,Yへ画像ANDコピー
  キャラ画像をコピー先のX,Yへ画像ORコピー
 
  VCL_FREE(マスク画像)
  VCL_FREE(キャラ画像)
#------------------------------------------------------------

 別に何一つ、目新しいことも学んだことも無いんだけど、1Dと違って2Dはこれだけで、「6ゾロ出たっ!」とか「ぎゃー、1ゾロだ><」とか言って、盛り上がることが出来ますね(バカw)

 一応、「サイコロ準備」は、無駄っぽいコードはのままに、ちょこっとだけ変えて、サイズの違うサイコロが作り易いようにしました。

 それから画像合成ですが、なでしこの画像合成も、それがどうもイマイチでやられまくり、ちょぼいちでは使わせてもらっていた画像合成改も、左上のドットを取得して透過色とする仕様なんですけど、透過色を指定して合成するように変更して「画像合成通」(笑)とした。

 いちいちカラーを指定しなくてもいいようにとゆう配慮なんだろうけど、四角い枠の内側だけを抜きたいとか、あるでしょ?

 単に、ノベルのキャラ合成から、半透明で合成する処理の部分を抜いたものなんで、キャラ合成をのまま使っても良かったんだけど、やはりなんか無駄に長くなる気がして。

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20160315

2016-03-06

選択肢の怪

| 01:55

 選択肢表示状態の時、何故か一部分だけ、マウスを認識せず、選択肢の色が変わらず、クリックしても次へ飛ばない部分があったり、逆に勝手に選択されてしまうなどの怪現象があり、これは当初、動的に作成した部品を壊すとエラーが出まくるために、壊さないで済ましていたことが原因で、新たに覚えた「VCL_FREE」のまじない追加したら直った! と思っていたのですが、なんかやっぱりおかしな時がある・・・?

 行き詰まった時には、現場に戻……ではなくて、初心に立ち返り、問題点を明確にすることが必要です。

 と、いうわけで――

 一体どーゆう現象かというと、以下のようなサンプルシナリオを実行すると、

#,選択肢の怪を確認するサンプルシナリオ
#,--------------------------------------------------------
#, ビジュアルノベル風
#,--------------------------------------------------------
$,テキストウィンドウサイズ,640,120
$,テキストウィンドウ表示位置,0,360
$,テキストウィンドウ半透明,0,0,640,120,50
$,テキストウィンドウ色,$000077
$,メッセージ書式,MS ゴシック|20|太字,$FFFFFF,$000000,3
$,メッセージ表示位置,15,15
$,メッセージ速度,10
$,行,0
$,ブリンク表示,600,445,300
$,選択肢表示位置固定,オン
$,選択肢表示,15,375,600,0
#,--------------------------------------------------------

!,背景,北竜.jpg
!,立ち絵ロード,立ち絵.bmp
!,立ち絵オン,,70
!,テキストウィンドウオン

!,選択肢,2
 -,1234567890,A
 -,1234567890,B

 *,A
 Aへとんだよ

 *,B
 Bへとんだよ

#,注:はてなでは、「-」や「*」が特別なヘッダーみたいで表示が変になっちゃうから頭に半角スペースを入れてるけど、実際には行頭。

 こういう画面になります。

f:id:snowdrops89:20160306162422j:image

 ここまでは、正しい。

 さて、これは選択肢なんで、マウスカーソルを合わせると、上の「1~0」のように反転し、クリックするとラベルに飛ぶわけ。

 ところが、どーゆうわけか、「4、5」の辺りだけ、マウスを認識しないんだよね。

 色も変わらないし、クリックしても反応しない

 それ以外の場所では問題なく反転もするし、ジャンプもするとゆう、まさに謎の怪現象なんだよ!

 まあ、こに目をつぶれば、ふつーに動作はするのだけど、だから、どってこと無い些細な問題と言えばそうなんだけど、一度気になったからには、どうしても気になるっ。

 ナゾ解明しないことには、気持ち悪い。

 この選択肢は、初期の頃に試行錯誤しながら作った無理矢理感満載のマウスオーバーボタンのまま流用しているから、違いが無いとも言い切れないけど、他のやつでまで問題が出たことはないんだよね。

 マウスオーバーボタンは、こんな感じ。

#--------------------------------------------------------------
# マウスオーバーボタン
#--------------------------------------------------------------

#-----母艦設計--------------------------------------------------
!母艦設計=「母艦の可視はオフ母艦のタイトルは「マウスオーバーボタン母艦を$FFFFFFで画面クリア母艦のスタイルは「枠固定」
母艦オフに最大化ボタン有効変更。
母艦のクライアント幅は640。母艦のクライアント高さは480。
母艦中央移動
母艦の可視はオン。
#--------------------------------------------------------------

#-----ボタン準備------------------------------------------------
ボタン幅とは整数=600。
ボタン高さとは整数=40。
ボタン位置Xとは整数=20。
ボタン位置Yとは整数=50。
ボタン隔とは整数=20。
ボタン数とは整数=6
文字書体は「MS ゴシック|14|標準」。

裏画面とはイメージの可視はオフの幅はボタン幅*2。の高さはボタン高さ*ボタン数

#なんか画像を用意すればかっこいいんだけど、とりあえずボタンの画像を書いている。
#左側が通常時のボタンで、右側がマウスオーバー時のボタンとなる。
(ボタン数)
  塗り色は$AAAAAA
  裏画面の0,(回数-1)*ボタン高さからボタン幅,回数*ボタン高さへ四角。
  裏画面の25,(回数-1)*ボタン高さ+10へ「マウスオーバーボタン{回数}」を文字描画塗り色は$FFAAAA
  裏画面のボタン幅,(回数-1)*ボタン高さからボタン幅*2,回数*ボタン高さへ四角。
  裏画面のボタン幅+25,(回数-1)*ボタン高さ+10へ「マウスオーバーボタン{回数}」を文字描画。
#--------------------------------------------------------------

#-----ボタンを設定----------------------------------------------
選択肢とは配列。 #0ボタン表示位置X、1ボタン表示位置Y、2ボタン幅、3ボタン高さ
(ボタン数)
  選択肢¥回数,0はボタン位置X
  選択肢¥回数,1はボタン位置Y+(回数-1)*(ボタン高さ+ボタン隔)
  選択肢¥回数,2はボタン幅
  選択肢¥回数,3はボタン高さ
#--------------------------------------------------------------

#-----ボタンを描画------------------------------------------------------
裏画面の0,0を選択肢で母艦へマウスオーバーボタン表示
#-----------------------------------------------------------------------

#----マウス入力待ち----------------------------------------------
母艦マウス移動した時は~
  裏画面の選択肢を母艦へマウスインアウト反映。

母艦のマウス押した時は~
  もし、前選択ボタン=0でなければ
    「ボタン{前選択ボタン}をクリック」と言う
#--------------------------------------------------------------

#--------------------------------------------------------------
●マウスオーバーボタン表示({グループ=?}OBJ1のX,YをAで{グループ=?}OBJ2へ)
  A\0,0=X。A\0,1=Y
  (Aの要素数-1)
    OBJ1のX,Y+(回数-1)*(A¥回数,3),(A¥回数,2),(A¥回数,3)をOBJ2の(A¥回数,0),(A¥回数,1)へ画像部分コピー。

●マウスインアウト反映({グループ=?}OBJ1のAを{グループ=?}OBJ2へ)
  (Aの要素数-1)
    もし、((OBJ2→マウスX)>(A¥回数,0))かつ
      ((OBJ2→マウスX)<(A¥回数,0)+(A¥回数,2))かつ
      ((OBJ2→マウスY)>(A¥回数,1))かつ
      ((OBJ2→マウスY)<(A¥回数,1)+(A¥回数,3))ならば
        選択ボタン回数。
    違えばもし、(回数=Aの要素数)かつ(選択ボタン=0)ならば
      選択ボタンは0。
    ここまで

  もし、前選択ボタン<>選択ボタンならば
    もし、前選択ボタン>0ならば
      OBJ1の(A\0,0),(A\0,1)+(前選択ボタン-1)*(A¥(前選択ボタン),3),(A¥(前選択ボタン),2),(A¥(前選択ボタン),3)をOBJ2の(A¥(前選択ボタン),0),(A¥(前選択ボタン),1)へ画像部分コピー。
    もし、選択ボタン>0ならば
      OBJ1の(A\0,0)+(A¥(選択ボタン),2),(A\0,1)+(選択ボタン-1)*(A¥(選択ボタン),3),(A¥(選択ボタン),2),(A¥(選択ボタン),3)をOBJ2の(A¥(選択ボタン),0),(A¥(選択ボタン),1)へ画像部分コピー。
  前選択ボタン=選択ボタン
  選択ボタン=0
  描画処理反映
#--------------------------------------------------------------

 要するに、左側に通常時のボタン画像、右側にマウスオーバー時のボタン画像を並べた裏画面を用意して、配列に指定したボタン設定に基づいて画像部分コピーしてるんだよね。

 いちおう、ノベルの選択肢に合わせて、ボタンの幅を長~くしてみて色々ためしたけど、このサンプルプログラムではマウスの認識に問題のある箇所は見当たらなかった。

 というとはやっぱり、なこノベルの方に問題があるんだー><

 選択肢として表示したものをコピーして、都度ボタン化したりしていて、確かにこのサンプルとは少し変わっている部分もあるんだけど、それにしても肝心の、マウスの出入りは、「マウス移動した時~」の座標を単純に取って、「ボタン表示位置X、ボタン表示位置Y、ボタン幅、ボタン高さ」から、ボタンの中にマウスが入ったかどうかを判断しているだけで、どう考えても、ボタンの中の一部分にだけ抜けが生じるようなものには思えないんだけど・・・むむむ。

トラックバック - http://nadesiko.g.hatena.ne.jp/snowdrops89/20160306