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


HSPTV!掲示板


未解決 解決 停止 削除要請

2006
0822
とおりすがりキーの二度押し判定について9解決


とおりすがり

リンク

2006/8/22(Tue) 11:20:29|NO.2095

格闘ゲームみたいにキーをすばやく二度押して二度押しを判定させたいのですが
判定させたいのですがどうもうまくいきません。どなたか教えてくれませんか。
お願いします。



この記事に返信する


とおりすがり

リンク

2006/8/22(Tue) 15:20:23|NO.2099

すいません。「判定させたいのですが」が二度も出てしまいました。



cbird

リンク

2006/8/23(Wed) 11:13:13|NO.2106

私のやっている、二度押しの方法です参考になるとよいのですが。
(当方はソースを丸々乗せるのは身にならないと考えています)

----------------------------------------------------------------------------------
1、該当するキーの状態を取る変数(a)と、キーのログを取る配列を用意します。
(例:dim keylog,30,2;こんな感じ。用途は「0〜29:履歴」「0:キーの状態、1:その時間」)

2、該当するキーの状態を取ります。押されていたら1,押されてないなら0を変数(a)に入れます。

3、キーログの配列の履歴の一番新しい(0)のキーの状態と比較します。
4、同じなら、その状態が続いているのでその時間を増やします。
5、違うならキーログの履歴を奥に1つ押し出して、履歴0の部分に新しい情報をいれます。
(例:if a=keylog(0,0){keylog(0,1)++}
else{履歴の押し出し処理:keylog(0,0)=a:keylog(0,1)=1})
6、これを毎フレーム行うことで必要なキーログはとれていきます。

7、とったキーログから2度押しの判定をします
現在が1で、1つ前の変化が0で、さらに前が1なら二度押しになります。

8、それに時間の概念を追加して判定します、これは10フレ以下にしてあります。
(例:if keylog(0,0)=1 & keylog(1,0)=0 & keylog(2,0)=1 & (((keylog(0,1)+keylog(1,1)) < 10){二度押し処理})
----------------------------------------------------------------------------------
ここまでで二度押しの判定はできますが、この後はだいたい2パターンに分かれます。
2度押しを判定する場合、たいていその前に1度押した場合の処理が入っていると思います。
(2度押しでしか動かないなら楽なのですが)

・ケース1、二度押しが入った場合、1度押しの処理をキャンセルして二度押しの処理を行う。
・ケース2、時間差をつけて判定する。押したらすぐに処理を行わず、一定のフレームをおい
て2度目のボタンがこないかを見てから処理を行います。


長々と書きましたが・・・解り辛いですねぇ・・・
この方法で解らない部分があれば答えます・・・



とおりすがり

リンク

2006/8/23(Wed) 13:49:55|NO.2108

キーの履歴をとる方法は思いつきませんでした。
一度やってみます。
cbirdさんどうもヒントありがとうございます。



とおりすがり

リンク

2006/8/25(Fri) 22:40:49|NO.2148

やってみたけど無理でした。
確かにログは取れましたが、ログが狂ったり
リアルタイムで処理をしているので、
短い時間でキーを押すのは無理なので
長い時間判定しないみたいですのでかなり難しいです。
cbirdさんせっかくヒントをいただいたのに申し訳ございません。



Drip

リンク

2006/8/26(Sat) 12:32:42|NO.2157

Dripです。

 とおりすがりさん、こんにちは。
コマンド入力は感覚的に少しややこしい感じがするので初心者のうちは戸惑うことも
あると思います。cbirdさんのやりかたは配列変数を使用した、履歴を取るための
最も典型的なアルゴリズムだと思います。

 リアルタイムコンバット等のコマンド入力処理は、メモリ操作命令を使用すると、
とても簡単に作ることができ、動作も軽快です。
配列変数やループ等の使用頻度が極めて少ないので理解に苦しむこともないと思います。
コマンド入力による必殺技の発動サンプルを以下に示します。


#define maxcmd 8 //キーの最大組み合わせ数 #define keydst 20 //入力履歴が破棄される時間 //必殺技一覧と対応するコマンド cmdName(0)="新感覚癒し系": cmdCmd(0)="ASD" cmdName(1)="ベホイミ": cmdCmd(1)="ZXC" cmdName(2)="マホー": cmdCmd(2)="AZSXDC" cmdName(3)="スティンガーミサイル": cmdCmd(3)="ZAXSCDAA" cmdName(4)="ベルカ飛行隊": cmdCmd(4)="ZZSX" cmdName(5)="機体は消耗品": cmdCmd(5)="SSSSSSSS" cmdName(6)="巨像でかすぎ": cmdCmd(6)="DDDDAAAA" cmdName(7)="MGOやりませんか。": cmdCmd(7)="ASASAS" keys='Z','X','C','A','S','D' //使用するキー一覧 sdim log,maxcmd:memset log,1,maxcmd //履歴初期化 font "MS ゴシック",24,2 repeat //メインループ redraw 0 //■キーの入力関係 repeat length(keys) //キーの入力を確認 getkey tmp,keys(cnt):if tmp=1:ky(cnt)++:else:ky(cnt)=0 //キーが入力されているか? if ky(cnt)=1:{ //もしもキーが入力されていたら、履歴をとる inTime=0 //履歴を破棄する時間リセット tmp=cnt //押されたキーのIDを確保 repeat maxcmd-1 //履歴をシフトする poke log,cnt,peek(log,cnt+1) loop poke log,maxcmd-1,keys(cnt) //ログに今入力したキーを記録する } loop //■コマンドの判定関係 repeat length(cmdName) //コマンドの成立判定 if instr(log,0,cmdCmd(cnt))>-1:{ //もしも入力履歴にコマンドが発見されたら skilID=cnt //コマンドID確保 skilTime=50 //技発動時間 memset log,1,maxcmd //キー履歴クリア } loop inTime++ //履歴を破棄する時間が徐々に上昇 if inTime>keydst:memset log,1,maxcmd //履歴を破棄する時間までキーが入力されていなければ履歴破棄 //■描画関係 color 255,255,255:boxf:color:pos 0,0:mes log //背景をクリアしてキー履歴状態を表示してみる if skilTime>0 & (cnt\2=0 | skilTime<40):{ //技が発動していた場合技名描画 color pos 100,100:mes "必殺・"+cmdName(skilID)+" !!" skilTime-- } redraw 1 await 30 loop

格闘ゲームを作っていらっしゃるのでしょうか。敵のAIやエフェクトなど、
苦労する場面も多いと思いますが、がんばってください。
こうしたアルゴリズムのノウハウはプログラムの経験によって養われるものなので、
質問の回答だけを注視せず、非効率的でも自分なりのプログラムを書けるようにしていくと
技術は確実に磨かれていきますよ。



cbird

リンク

2006/8/26(Sat) 14:13:13|NO.2158

この手の判定にはどうしても正確な履歴が必要です。
なので配列の中身を画面に表示しながらボタンを押してためして、
正確な履歴がとれるようになるまで、プログラムを修正するのがよいと思いますよ。

履歴の中身が狂うのでしたら、たぶん履歴をとるルーチンにこない場合がある、
又は履歴の押し出しが間違っているのではないでしょうか。よくありがちな部分ですので。



Drip

リンク

2006/8/26(Sat) 18:41:43|NO.2160

すみません。
単に2度押しを判定させたいだけだったのですね;
キーログの話が入っていたのでてっきりコマンド入力と勘違いしていました。
2度押しならばもっと簡単にできますね;

//Zキーの素早い二度押しを判定します。 repeat getkey tmp,90:if tmp=1:ky++:else:ky=0 if ky=1:if tim>0:mes "2度押し!":tim=0:else:tim=10 tim--:await 30 loop
このように、キーの判定にタイマー変数をひとつ噛ますことで、様々な時間差処理ができます。
コマンド入力もこの応用みたいなものなので原理を理解しておくとよいですよ。



とおりすがり

リンク

2006/8/27(Sun) 17:25:57|NO.2166

cbirdさん。
そして細かいヒントを教えてくれたDripさん。
どうもありがとうございます。
>格闘ゲームを作っていらっしゃるのでしょうか。
それっぽいものですね。
最初に紹介してくれたコマンドのヒントも
参考にしてみます。
ほんとにどうもありがとうございます。



とおりすがり

リンク

2006/8/29(Tue) 20:49:09|NO.2179

見事解決しました。
ヒントをくれたcbirdさん
Dripさんに感謝です。
本当にありがとうございました。



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