Re: 既に使用しているキーを同時押ししたい ( No.1 ) |
- 名前:管理人 日時:2019/10/07 23:03
同時押しを正しく認識させるプログラムを書くには、プログラム全体の入力関係全体を書き換えなければならず、
更に現在までにマーク42さんが組まれてきたプログラムよりも何レベルか難易度の高いプログラムを組む必要があります
申し訳ありませんが、同時押し処理は今のマーク42さんには荷が重いと思いますので
お答えは控えようと思います
ひとまず同時押しの仕様は抜きでゲームの作成を進められることをお勧めします
|
Re: 既に使用しているキーを同時押ししたい ( No.2 ) |
- 名前:マーク42 日時:2019/10/07 23:31
管理人様、どうもありがとうございます!
やはり作るのは結構難しいのですね。
わがままですいません。ちなみに、どのような感じでプログラム全体を書き換えるのでしょうか。
また、どんな原理で同時押しでの攻撃を可能にするのでしょうか。
|
Re: 既に使用しているキーを同時押ししたい ( No.3 ) |
- 名前:マーク42 日時:2019/10/08 04:04
とりあえず原理だけ聞きたいと思いました。
なので、今は同時押しを置いといて、他の部分を進めます。
|
Re: 既に使用しているキーを同時押ししたい ( No.4 ) |
- 名前:通りすがり 日時:2019/10/08 14:31
以前にDXライブラリにお世話になったことのある通りすがりの者です。
また少しDXライブラリを使わせていただく機会があり、しばらくこの掲示板を覗かせてもらっていました。
>マーク42さんへ
通りすがりでこのようなことを申し上げるのは失礼を承知の上なのですが、ここ数日の
マーク42さんの投稿を読ませていただくと、マーク42さんのプログラム特有の問題、
つまりDXライブラリの機能とは関係無い質問がほとんどのような印象を持ちました。
この掲示板の冒頭に
> ご返信は一週間に一度、土日のどちらかで行います。平日は時間に余裕があるときだけご返信します。
とあるように、管理人様は自分の休みの時間に、自分の時間を削って好意で質問の
内容を理解し、返信をしてくださっています。
これはDXライブラリを使って楽しいゲームを自作しようとしているプログラマの
皆さんや、ゲームではなくてもDXライブラリによってDirectXの力を簡単に利用させて
もらえる私のような者にも、感謝しかないOSSの貢献活動です。
マーク42さんはご自分のゲームのソースコードを全文貼りつけるようなことを
されていますが、管理人様がこれを全て読み、マーク42さんの意図を汲み取って
正しい回答をすることの大きな負担を少しでも考えてみてください。
また、あまりに個人的なプログラムの動作についての質問と回答は、DXライブラリに
関する知見を求めにくる掲示板閲覧者にとっては、あまりメリットがありません。
そうしたことを考えて質問投稿をすることが、ひいてはDXライブラリを利用させて
もらっている私たちユーザーの受益にもなります。
オープンソースのプロジェクトで、オープン、フリーを良いことにそのユーザーらが
勝手なクレームと要求ばかり出し、プロジェクトのオーナー様が疲れ切って
モチベーションを失い、終わってしまったものもたくさんあります。
どうか、DXライブラリに関係の無いようなプログラム固有の問題は、
ご自分で解決するよう努力してみてください。管理人様の消耗につながるような
質問はどうかお控えください。あなたが考えるべきことを、管理人様はじめ
回答する方たちが好意で時間を使い、代わって考えていることを踏まえてください。
ご納得いただけませんか?
*****
私の要求ばかり書いてもマーク42さんにとっては説得性が欠けると思いましたので、
キーの「同時押し」についてだけコメントします。
マーク42さんのアップしたゲームのソースコードは拝見し、動かしてみましたが、
コメントなどを読んでもゲームのプログラミングをしない私自身がマーク42さんの
意図をとらえ切れない為か、すみませんが最終的にやりたいことは分かりませんでした。
でもきっと、ゲームの動作中にキーAキーとキーKを同時に押したことを
どう検出したらよいのか、と言うことなのでしょう。
そうだとすると、ご自分で書いたプログラムコードなのに、なぜ gpUpdateKey関数内で
使っているDXライブラリのGetHitKeyStateAll関数に考えが至らないのか不思議に
思いました。どこからかコピーしたコードなのでしょうか。
下のものはマーク42さんのコードですが、
int gpUpdateKey()
{
char tmpKey[256];
GetHitKeyStateAll(tmpKey);
for (int i = 0; i < 256; i++)
(tmpKey[i] == 0) ? (Key[i] = 0) : Key[i]++;
return 0;
}
キーを離しているときは0で、押しているときは++ でインクリメントです。
これは、押したままであれば0からずっと、+1ずつインクリメントする動作です。
マーク42さんのやりたいことは
//同時押しでの攻撃
if (Key[KEY_INPUT_A] == 1 && Key[KEY_INPUT_K] == 1 && Wcount == 100) {//攻撃がキックだった場合
のようですが、Key[KEY_INPUT_A] == 1 とすると、キーの同時押しを検出する
タイミングはずっと押しっぱなしだと全ての描画フレームで1回しかありません。
少し押すタイミングがずれると絶対に他のキーとの同時押しを認識できないはずです。
ですので、せめて下のようになるのではないでしょうか。
if (Key[KEY_INPUT_A] != 0 && Key[KEY_INPUT_K] != 0 && Wcount == 100) {
つまり、0以外は押している状態ということなので、それをOR条件で問い合わすということです。
それでも今のプログラムコードはただインクリメントしているだけなので、
桁あふれを起こしたときに0になるタイミングがあります。そのときの動きはバグでしょう。
下のプログラムは私が確認の為に作ったものです。AキーとKキーの押している間だけ
Key[]の値が増えていくので、同時押しの様子が分かります。
#include "DxLib.h"
int Key[256];
int gpUpdateKey()
{
char tmpKey[256];
GetHitKeyStateAll(tmpKey);
for (int i = 0; i < 256; i++) {
(tmpKey[i] == 0) ? (Key[i] = 0) : Key[i]++;
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
if (DxLib_Init() == -1) {
return -1;
}
SetGraphMode(300, 100, 32);
ChangeWindowMode(TRUE);
unsigned int color = GetColor(255, 255, 255);
int no = 0;
while (ProcessMessage() == 0) {
no++;
gpUpdateKey();
ClearDrawScreen();
// キーAとキーKの押下状態を表示する。押していない場合は0
DrawFormatString(10, 10, color, "no=%d, A=%d, K=%d\n",
no, Key[KEY_INPUT_A], Key[KEY_INPUT_K]);
}
DxLib_End();
return 0;
}
なお、GetHitKeyStateAllはDXライブラリの関数リファレンスページに
ちゃんと関連する説明があるとおり、処理の重い関数です。
> ですが、実は CheckHitKey 関数はとても無駄の多い関数です。理由は聞かないで下さい。とにかく無駄が多い関数なのです。
これを使わないようにして速く動くゲームを作る方法も関数リファレンスページに
ちゃんと掲載されていますが、そのように変更するにはマーク42さんにはまだ
荷の重い作業になると思います。それ含めて管理人様は心配されて、回答を
控えられているのだと思います。
最初の話に戻りますが、ご質問をする際は果たしてそれが本当にDXライブラリに
関することなのかどうか、この掲示板の主旨に合っているかを再考した上で
投稿することを考えてください。これはお願いです。
通りすがりより
 |
Re: 既に使用しているキーを同時押ししたい ( No.5 ) |
- 名前:yumetodo 日時:2019/10/08 12:54
さらに捕捉ですが、複数キー判定はさらに面倒が重なります。
ある文脈ではすでにおされているキーは無視してあらたに押されたキーを検出したいという要求があるかもしれません。
一方で別の文脈ではすでに押されているキーも含めて考えたいこともあります。
また、Win32APIのメッセージボックスを出した直後はキー判定がしばらく残って検出されますので判定が消えるまで待つ必要もあります。
ここまでくるとイベント駆動形(JavaScriptでいうaddEventListenerみたいなのを作る)にしないとプログラムがややこしくなります。
で、そこまでを自分で書くのは非常に面倒です。
多分そういうのをすでに提供している別のライブラリを検討したほうがいいかもしれません(OpenSiv3D?openframeworks?)
|
Re: 既に使用しているキーを同時押ししたい ( No.6 ) |
- 名前:通りすがり 日時:2019/10/08 14:29
私が書いたテスト用WinMainのコードで、DxLib_Initの呼び出し位置が不適切だったので戻ってきました。修正済みです。
*補足の情報をありがとうございました。>yumetodoさん
復路の通りすがり より
|
Re: 既に使用しているキーを同時押ししたい ( No.7 ) |
- 名前:sidecar 日時:2019/10/08 21:40
dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4709
の最後で「DXライブラリに関係ない質問は、今後ここではしません」って言ったのに
あいかわらずDXライブラリに全く関係ないスレッドを立てまくっているのはなぜでしょうか...?
|
Re: 既に使用しているキーを同時押ししたい ( No.8 ) |
- 名前:NNN 日時:2019/10/08 23:26
こちらで回答にソースをもらえるからでしょうかね
他掲示板ではもうヒントしかもらえずソース提供する人が居ない状態です
ゲームを作りたい意欲は認めますが、ゲーム作りにはいくらか勉強の段階をすっ飛ばしています。。。
単にゲームを作りたいならツクール等他にも手段があります
ゲームを通じてプログラム技術を得たいならゲームを作る前に教本の1,2冊は読破しましょう
二兎追う者は一兎も得ずですよ
|
Re: 既に使用しているキーを同時押ししたい ( No.9 ) |
- 名前:管理人 日時:2019/10/09 01:16
> マーク42さん
> わがままですいません。ちなみに、どのような感じでプログラム全体を書き換えるのでしょうか。
> また、どんな原理で同時押しでの攻撃を可能にするのでしょうか。
すみません、私が難しく考えすぎていました、とりあえず
Aキーだけで判定されたい部分は Key[KEY_INPUT_A] == 1 && Key[KEY_INPUT_K] == 0
Kキーだけで判定されたい部分は Key[KEY_INPUT_A] == 0 && Key[KEY_INPUT_K] == 1
AキーとKキー同時押しで判定されたい部分は Key[KEY_INPUT_A] == 1 && Key[KEY_INPUT_K] == 1
とすれば良いと思います
> 通りすがりさん
お気遣いありがとうございます
おひとりだけならまだ大丈夫ですが、確かにそれとは別にマーク42さんのご質問がかなりの枠を占めてしまうのは少し問題かもしれませんね…
> なお、GetHitKeyStateAllはDXライブラリの関数リファレンスページに
> ちゃんと関連する説明があるとおり、処理の重い関数です。
>
> > ですが、実は CheckHitKey 関数はとても無駄の多い関数です。理由は聞かないで下さい。とにかく無駄が多い関数なのです。
すみません、GetHitKeyStateAll の説明は『CheckHitKey はとても無駄の多い関数なので GetHitKeyStateAll を使いましょう』という主旨の文となっています
ただ、それも 18年前の PC の性能でのことで、現在の PC の性能なら CheckHitKey を何回使っても問題ないくらいなので、
GetHitKeyStateAll の説明を( CheckHitKey 何回も呼ばなくても GetHitKeyStateAll で一度に全てのキーの状態を取得できるよ )くらいの表現に変更しました m(_ _;m
> sidecarさん
お気遣いありがとうございます
件のスレッドの No.3 のマーク42さんのお書き込みは
『DXライブラリとは関係の無い質問でしたら別の掲示板の方が早く回答を得られますよ( 別に「ここに投稿すべきではない」とは言っていない )』
という旨のお書き込みに対してのご返答なので「もうこちらの掲示板には投稿しない」という意図はマーク42さんには無かったと思います
 |