<環境>
- Windows10
- visual studio 2019
- C++
- X64
<質問内容>
Bullさんから頂いたこちらのコード
#include <DxLib.h> int Pad[32]; int gpUpdatePad() { int padStat = GetJoypadInputState(DX_INPUT_KEY_PAD1); //入力状態を padStat に格納 for (int i = 0; i < 28; i++) { //ボタン28個分ループ if (padStat & (1 << i)) { //ボタンiの入力フラグが立っていたら Pad[i]++; //加算 } else { //入力がなければ Pad[i] = 0; //0 にする } } return 0; } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更,初期化,裏画面設定 int x = 320; int y = 240; const int PAD_DOWN = 0; const int PAD_LEFT = 1; const int PAD_RIGHT = 2; const int PAD_UP = 3; const int KEY_ESC = 12; // while( 裏画面を表画面に反映, メッセージ処理, 画面クリア ) while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) { gpUpdatePad(); if (Pad[PAD_LEFT]) { if (x > 4) x -= 4; } if (Pad[PAD_RIGHT]) { if (x < 622) x += 4; } if (Pad[PAD_UP]) { if (y > 4) y -= 4; } if (Pad[PAD_DOWN]) { if (y < 464) y += 4; } DrawFormatString(x, y, GetColor(255,255,0), "●"); if (Pad[KEY_ESC]) break; } DxLib_End(); return 0; }
を参考に、キーボード入力で正しく動くこちらのプログラム
//キーLを押したまま別のキーを押すと武器が切り替わる if (Key[KEY_INPUT_L] == 1) { Lcount = 1; } if (Lcount > 0) { ++Lframe; } if (Key[KEY_INPUT_L] == !1) { Lcount = 0; Lframe = 0; }//キーLを離すとLcountは0になる。 if (Lcount > 0) { if (Key[KEY_INPUT_G] == 1) { Gtime = 0; ++Gfunction_status; ++Gkey; } } if (Gkey > 2) { Gkey = 1; } if (Gfunction_status > 1) { Gfunction_status = 0; }
と
if (Gfunction_status == 0) { if (Key[KEY_INPUT_G] == 1 && Gcount >= 1 && Gtime == 0 && Gkey == 1 && Key[KEY_INPUT_L] == !1) { //キーGを押していて且つ残り弾数( Gcount )が1発以上あって銃を撃ってからの経過時間( Gtime )が0の場合のみ銃を撃てる Gtime = 1; //銃を撃ってからの経過時間を1にする Gcount = Gcount - 1; //残弾数を-1する playerImage = playerGHandle[7]; //真正面の状態にする if (playerY == enemyY && playerX + 1 == enemyX || playerY == enemyY && playerX + 2 == enemyX || playerY == enemyY && playerX + 3 == enemyX || playerY == enemyY && playerX + 4 == enemyX || playerY == enemyY && playerX + 5 == enemyX) {//これで前に敵がいるときのみに攻撃が出来る。 enemysabunHP = 100; enemyImage = enemyGHandle[5]; } } }
をコントローラで操作できるように以下のように編集しました。
if (jyoicon == 1) { //キーLを押したまま別のキーを押すと武器が切り替わる if (Pad[PAD_5] == 1) { Lframe = 1; } if (Lcount > 0) { ++Lframe; } if (Pad[PAD_5] != 1) { Lframe = 0; }//キーLを離すとLcountは0になる。 if (Lframe > 0) { if (Pad[PAD_1] == 1) { Gtime = 0; ++Gfunction_status; ++Gkey; } } if (Gkey > 2) { Gkey = 1; } if (Gfunction_status > 1) { Gfunction_status = 0; } }
と
if (jyoicon == 1) { if(Pad[PAD_1] == 1 && playerX > 0 && Gcount >= 1 && Gtime == 0 && Gkey == 1 && Pad[PAD_5] != 1) {//「右」は今押された //「右」が押されたときの処理 Gtime = 1; //銃を撃ってからの経過時間を1にする Gcount = Gcount - 1; //残弾数を-1する playerImage = playerGHandle[7]; //真正面の状態にする if (playerY == enemyY && playerX + 1 == enemyX || playerY == enemyY && playerX + 2 == enemyX || playerY == enemyY && playerX + 3 == enemyX || playerY == enemyY && playerX + 4 == enemyX || playerY == enemyY && playerX + 5 == enemyX) {//これで前に敵がいるときのみに攻撃が出来る。 enemyHP = enemyHP - 10; enemyImage = enemyGHandle[5]; } } }
と二つのキーボードのプログラムをコントローラ版に編集してみました。
そこで問題があります。**(質問1)L1ボタンを押している最中はLframeは1になるのになぜか0のままになってしまい、武器の切り替えができません。**キーボード版の方ではしっかりできました。
こちらはキーボードとコントローラの二つの操作ができる全体のプログラムです。
上にも書きました通りコントローラの方は書いた通りに機能していません。
ちなみに、こちらのプログラムを作りました。
このプログラムもキーボードとfanaさんの書いていただいた下に書いてあるプログラムを参考にコントローラで正しく操作できます。
epistemeとか言う人曰く
(質問2)fanaさんのやり方はgpUpdateKey()方式の"簡略版"だそうなのですが、簡略化にしても上に載せたキーボードを操作するためにあるgpUpdateKey()と同じように働くgpUpdatePad()はなぜ同じように働かないのでしょうか。
fanaさんから頂いたプログラムです。
//「前回」と「今回」のパッド状態調査結果(GetJoypadInputState()の戻り値)を覚えておく場所 //を(適切な場所に)用意する int PrevPadState = 0; //適切な初期値は0かなきっと int CurrPadState = 0; //適切な初期値は0かなきっと //現在のパッドの状態をGetJoypadInputState()を用いて調査し, //2つの変数{ PrevPadState ,CurrPadState }を更新する作業を担う関数. //この関数をメインループから毎回呼ぶ感じ. void UpdatePadState() { //「前回」情報を更新 PrevPadState = CurrPadState; //「今回」情報を更新 CurrPadState = GetJoypadInputState( DX_INPUT_KEY_PAD1 ); //引数はこれで良いのかな? } //実際どんなコードなのかはわからんけど,メインループで毎度↑の関数UpdatePadState()を呼ぶ int main() { ... //初期処理 while( true ) //メインループのつもり { UpdatePadState(); //パッド状態の調査 ... //その他の処理 } ... //後処理 return 0; } // //以下はどこか(PrevPadStateとCurrPadStateの値を参照できる場所)での処理 // //パッドの「右」ボタンが「今」押されたかどうか判定するとき if( ( PrevPadState & PAD_INPUT_RIGHT ) == 0 //前回は押されていなくて && //且つ ( CurrPadState & PAD_INPUT_RIGHT ) != 0 //今回は押されている ) {//「右」は今押された //「右」が押されたときの処理 }
編集
以下のようにfanaさんから頂いたプログラムで四角を押していて、かつL1ボタンを押していない時は弾がでないようにしたのですが
if (Gfunction_status == 1) {if (Glock == 0) { { if ( (PrevPadState & PAD_INPUT_1) != 0 && MGcount >= 1 && Gtime == 0 && Gkey == 2 && //且つ (CurrPadState & PAD_INPUT_1) != 0 && MGcount >= 1 && Gtime == 0 && Gkey == 2 ) { MGframe = 1; MGtime = 1; } if ( (PrevPadState & PAD_INPUT_5) == 0 && MGcount > 0 && MGframe == 1 && //且つ (CurrPadState & PAD_INPUT_5) == 0 && MGcount > 0 && MGframe == 1 ) { --MGcount;//マシンガンの弾が減っていき、かつ相手が同じ行にいるときに相手のHPが減る。そうかかないと一度マシンガンを使った後、ボタンを押していなくても敵が同じ行にいるだけで相手のHPが勝手に減る。 ++MGtime; if (playerY == enemyY && playerX + 1 == enemyX || playerY == enemyY && playerX + 2 == enemyX || playerY == enemyY && playerX + 3 == enemyX || playerY == enemyY && playerX + 4 == enemyX || playerY == enemyY && playerX + 5 == enemyX) {//if (Key[KEY_INPUT_G] == 1 && Gcount >= 1 && Gtime == 0 && Gkey == 2)の中ではKey[KEY_INPUT_] == 1の都合で押し続けても一回しか押さないようにしかカウントされないため、中には書かなかった。 enemyHP = enemyHP - 2; enemyImage = enemyGHandle[5]; } }
武器の切り替えを以下のように書いた時にL1が押されている状態なのに弾が垂れ流しになります。
fanaさんのプログラムもif ((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_X) == 0) と同様に押されている間はフレームがずっと働くと思うのですが、なぜ武器の切り替えの時にL1が押されている状態なのに弾が垂れ流しになるのかわかりません。
if ((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_5) != 0) { Lframe = 1; } if ((GetJoypadInputState(DX_INPUT_PAD1) & PAD_INPUT_5) == 0) { Lframe = 0; }//キーLを離すとLcountは0になる。 //if (Lcount > 0) { ++Lframe; } if (Lframe > 0) { if (Pad[PAD_1] == 1) { Gtime = 0; ++Gfunction_status; ++Gkey; } } if (Gkey > 2) { Gkey = 1; } if (Gfunction_status > 1) { Gfunction_status = 0; }