キーコンフィグのシステムを作ろうとしたら・・・

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
branch
記事: 6
登録日時: 13年前

キーコンフィグのシステムを作ろうとしたら・・・

#1

投稿記事 by branch » 10年前

STGのような感じのゲームにキーコンフィグ機能をつけてみたいと思いキーコンフィグだけコードを作ってみたのですが、
キーコンフィグ画面に移った瞬間操作を受け付けなくなりました。
原因を探ろうと数値を可視化したところ、control.cppのwaittime変数が毎回0を代入されていたことが分かり、新しくプログラムを書き直して何とか完成しました。
しかし、上記の原因が分からずもやもやしてるため質問させて頂きました。
STG.cpp

コード:

#include "DxLib.h"
#include "STGbody.h"
#include "Control.h"
#define FRAME 60
int count = 0;


void wait_fanc(){
	int term;
	static int t = 0;
	static int fr = 0;
	if (fr%FRAME == 0){
		term = 1000 / (FRAME)+t - GetNowCount();
		if (term>0)
			Sleep(term);
	}
	else{
		term = (int)(1000 * (fr%FRAME) / FRAME + 1000 / FRAME) + t - GetNowCount();
		if (term>0)
			Sleep(term);
	}
	fr++;
	if (fr%FRAME == 0){
		t = GetNowCount();
	}
	return;
}

void fps(){
	int i;
	static int t = 0;
	static double ave = 0, f[FRAME];
	f[count%FRAME] = GetNowCount() - t;
	t = GetNowCount();
	if (count%FRAME == FRAME - 1){
		ave = 0;
		for (i = 0; i<FRAME; i++)
			ave += f[i];
		ave /= FRAME;
	}
	if (ave != 0){
		DrawFormatString(560, 460, GetColor(255, 255, 255), "%.1fFPS", 1000.0 / (double)ave);
		//DrawFormatString(560,460,GetColor(255,255,255),"%.2fms"  ,ave);
	}
	return;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if (DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0) return -1;//初期化と裏画面化

	initialize();//初期化
	Graphic_Load();
	PAD_initialize();
	int menunumber;
	menunumber = 1;
	int endhantei;
	endhantei = 0;

	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && endhantei == 0){//ループここから

		Keyboard_Update();
		Pad_Input();
		Control_Status();
		GetControl_key();
		if (menunumber == 1){
			menumode();//メニュー
			endhantei = EndProcess();
			//スタート、コンフィグ、終了
		}
		if (menunumber == 5){
			//ゲームプレイ中

			//敵登場
			//敵移動
			//敵弾発射
			bulletmove();//敵弾移動

			//自機移動
			//自機ショット発射
			//ショット移動
			//その他自機操作

			//当たり判定

			drawgame();//画像描画
		}
		drawdebug();
		fps();
		wait_fanc();
		count++;


	}//ループここまで
	DxLib_End();
	return 0;
}
STGbody.cpp

コード:

#include <math.h>
#include "DxLib.h"
#include "Control.h"
#define PI 3.1415926f
#define E_BULLET_MAX 1024
#define E_MAX 128
#define ITEM_MAX 1024

//画像用変数
static int bulletgra;
static int bulletgra2;
static int menugra1, menugra2, menugra3;

//メニュー用変数
static int modeselect;
static int menutype;
static int endflag;
static int optselect;
static int opttype;
static int kakunin;
static int waittimer;//各関数内で?
static int gamerank;

static int dbgop;


typedef struct player{
	double x, y, v;
	int arrow, control_type, shot, bomb, slow, shield, type, score, item, mg, left, formmode, no_hit;
}player;
struct player player;
//■■■■■■■■■
typedef struct shot{
	double x, y, v, angle;
	int type, pattern, frag, damage;
}shot;
struct shot shot[12][20];
//■■■■■■■■■
typedef struct item{
	double x, y, v, angle;
	int type, level, frag;
}item;
struct item item[ITEM_MAX];
//■■■■■■■■■
typedef struct bullet{
	double x, y, v, angle;
	int type, pattern, frag, time, special;
}bullet;
struct bullet bullet[E_BULLET_MAX];
//■■■■■■■■■
typedef struct enemy{
	double x, y, v, angle, aim_A, aim_B, aim_C, aim_D, aim_E;
	int type, pattern, frag, life, time;
}enemy;
struct enemy enemy[E_MAX];
//■■■■■■■■■
typedef struct{
	int left, right, up, down, buttonA, buttonB, buttonC, buttonD, start, rtn;
}ctrl;
ctrl control;

void option_mode();





//初期化する変数忘れず
void initialize(){//初期化
	modeselect = 1;
	menutype = 1;
	endflag = 0;
	optselect = 0;
	opttype = 0;
	kakunin = 0;
	waittimer = 0;
	gamerank = 0;
	player.shot = 0;
	player.bomb = 0;
	player.slow = 0;
	player.shield = 0;

	dbgop = 0;
	//ほかの変数も初期化忘れず
	for (int i = 0; i<E_BULLET_MAX; i++){
		bullet[i].x = -999;
		bullet[i].y = -999;
		bullet[i].v = 0;
		bullet[i].angle = 0;
		bullet[i].frag = 0;
		bullet[i].pattern = 0;
		bullet[i].type = 0;
	}

void Graphic_Load(){//描画する画像の読み込み
	bulletgra = LoadGraph("graphic/bulletA.png");
	bulletgra2 = LoadGraph("graphic/bulletB.png");
	menugra1 = LoadGraph("graphic/START.png");
	menugra2 = LoadGraph("graphic/OPTION.png");
	menugra3 = LoadGraph("graphic/EXIT.png");
}

void GetControl_key(){
	control.down = GetControlInput(0);
	control.left = GetControlInput(1);
	control.right = GetControlInput(2);
	control.up = GetControlInput(3);
	control.buttonA = GetControlInput(4);
	control.buttonB = GetControlInput(5);
	control.buttonC = GetControlInput(6);
	control.buttonD = GetControlInput(7);
	control.start = GetControlInput(8);
	control.rtn = GetControlInput(9);
}

void menumode(){
	waittimer++;
	//メニュー項目描画
	if (menutype == 1 && waittimer >= 2){
		DrawGraph(400, 200, menugra1, TRUE);
		DrawFormatString(400, 230, GetColor(255, 255, 255), "OPTION");
		DrawFormatString(400, 260, GetColor(255, 255, 255), "EXIT");
		//モード選択=1
		//modeselect=1←あらかじめ宣言
		DrawFormatString(380, 200 + 30 * (modeselect - 1), GetColor(255, 255, 255), "→");
		//入力に応じて数値変化
		if (control.up == 1){ modeselect--; }
		if (control.down == 1){ modeselect++; }
		if (modeselect <= 0){ modeselect = 1; }
		if (modeselect >= 4){ modeselect = 3; }
		if (control.buttonA == 1 || control.rtn == 1){
			if (modeselect == 1){
				waittimer = 0;
				menutype = 2;
			}
			if (modeselect == 2){
				waittimer = 0;
				optselect = 1;
				opttype = 0;
				menutype = 3;
			}
			if (modeselect == 3){
				waittimer = 0;
				endflag = 1;
			}
		}
		//GAME START
		//SCORE ATTACK
		//PRACTICE(DETAIL SELECT)
		//(EXTRE MODE)
		//RECORD
		//(REPLAY)
		//OPTION
	}
	if (menutype == 3){
		option_mode();
		dbgop++;
		DrawFormatString(100, 420, GetColor(255, 255, 255), "dbg %d", dbgop);
		//EXIT
	}
}
void option_mode(){
	DrawFormatString(100, 0, GetColor(255, 255, 255), "オプション"); 
	DrawFormatString(100, 20, GetColor(255, 255, 255), "%d",waittimer);
	DrawFormatString(100, 40, GetColor(255, 255, 255), "%d",opttype);
	//デバッグ
	if (opttype == 0 && waittimer >= 2){
		DrawFormatString(400, 200, GetColor(255, 255, 255), "CONFIG");
		DrawFormatString(400, 200 + 30 * 1, GetColor(255, 255, 255), "EXIT");
		DrawFormatString(380, 200 + 30 * (optselect - 1), GetColor(255, 255, 255), "→");
		if (control.up == 1){ optselect--; }
		if (control.down == 1){ optselect++; }
		if (modeselect <= 0){ optselect = 1; }
		if (modeselect >= 3){ optselect = 2; }
		if (control.buttonA == 1 || control.rtn == 1){
			if (optselect == 1){
				waittimer = 0;
				opttype = 3;
			}
			if (optselect == 2){
				waittimer = 0;
				optselect = 0;
				opttype = 0;
				menutype = 1;
			}
		}
	}
	//残機
	//エクステ設定
	//処理落ち設定
	//ステータス表示
	//BGM・SE音量
	//キーコン
	if (opttype == 3 && waittimer >= 2){
		kakunin = 0;
		Pad_Config();
		kakunin = configend();
		if (kakunin == -1){
			opttype = 0;
		}
	}
	//ボタン配置タイプ
	//デバッグ数値表示?
	//データリセット
	//戻る
}
control.cpp

コード:

#include "DxLib.h"
#define PADBN 28


static int m_Key[256];  // キーの入力状態格納用変数
static int pad_key[16];
static int config_select;
static int configtype;
static int waittime;
static int endflag;

typedef struct{
	int up, down, right, left, A, B, C, D, START;
}padInput;
typedef struct{
	int up, down, right, left, A, B, C, D, START, rtn;
}padStatus;
padInput pad_I;
padStatus pad_Sta;

// キーの入力状態更新
void Keyboard_Update(){
	DrawFormatString(500, 300, GetColor(255, 0, 255), "%d", waittime);
	char tmpKey[256];             // 現在のキーの入力状態を格納する
	GetHitKeyStateAll(tmpKey);  // 全てのキーの入力状態を得る
	for (int Key_i = 0; Key_i<256; Key_i++){
		if (tmpKey[Key_i] != 0){ // i番のキーコードに対応するキーが押されていたら
			m_Key[Key_i]++;   // 加算
		}
		else {              // 押されていなければ
			m_Key[Key_i] = 0; // 0にする
		}
	}
}

// KeyCodeのキーの入力状態を取得する
int Keyboard_Get(int KeyCode){
	return m_Key[KeyCode]; // KeyCodeの入力状態を返す
}

void PAD_initialize(){
	pad_I.down = 0;
	pad_I.left = 1;
	pad_I.right = 2;
	pad_I.up = 3;
	pad_I.A = 4;
	pad_I.B = 5;
	pad_I.C = 6;
	pad_I.D = 7;
	pad_I.START = 11;

	config_select = 0;
	configtype = 0;
	waittime = 50;
	endflag = 0;

}

void Pad_Input(){
	int i, PadInput, mul = 1;
	PadInput = GetJoypadInputState(DX_INPUT_PAD1);//パッドの入力状態を取得
	for (i = 0; i<PADBN; i++){
		if (PadInput & mul){
			pad_key[i]++;
		}
		else                {
			pad_key[i] = 0;
		}
		mul *= 2;
	}
}
void Control_Status(){
	if (Keyboard_Get(KEY_INPUT_DOWN) >= 1 || pad_key[pad_I.down] >= 1){
		pad_Sta.down++;
	}
	else{
		pad_Sta.down = 0;
	}

	if (Keyboard_Get(KEY_INPUT_LEFT) >= 1 || pad_key[pad_I.left] >= 1){
		pad_Sta.left++;
	}
	else{
		pad_Sta.left = 0;
	}

	if (Keyboard_Get(KEY_INPUT_RIGHT) >= 1 || pad_key[pad_I.right] >= 1){
		pad_Sta.right++;
	}
	else{
		pad_Sta.right = 0;
	}

	if (Keyboard_Get(KEY_INPUT_UP) >= 1 || pad_key[pad_I.up] >= 1){
		pad_Sta.up++;
	}
	else{
		pad_Sta.up = 0;
	}

	if (Keyboard_Get(KEY_INPUT_Z) >= 1 || pad_key[pad_I.A] >= 1){
		pad_Sta.A++;
	}
	else{
		pad_Sta.A = 0;
	}

	if (Keyboard_Get(KEY_INPUT_X) >= 1 || pad_key[pad_I.B] >= 1){
		pad_Sta.B++;
	}
	else{
		pad_Sta.B = 0;
	}

	if (Keyboard_Get(KEY_INPUT_LSHIFT) >= 1 || pad_key[pad_I.C] >= 1){
		pad_Sta.C++;
	}
	else{
		pad_Sta.C = 0;
	}

	if (Keyboard_Get(KEY_INPUT_C) >= 1 || pad_key[pad_I.D] >= 1){
		pad_Sta.D++;
	}
	else{
		pad_Sta.D = 0;
	}

	if (Keyboard_Get(KEY_INPUT_ESCAPE) >= 1 || pad_key[pad_I.START] >= 1){
		pad_Sta.START++;
	}
	else{
		pad_Sta.START = 0;
	}

	if (Keyboard_Get(KEY_INPUT_RETURN) >= 1){
		pad_Sta.rtn++;
	}
	else{
		pad_Sta.rtn = 0;
	}

}

int GetControlInput(int button){
	if (button == 0){
		return pad_Sta.down;
	}
	if (button == 1){
		return pad_Sta.left;
	}
	if (button == 2){
		return pad_Sta.right;
	}
	if (button == 3){
		return pad_Sta.up;
	}
	if (button == 4){
		return pad_Sta.A;
	}
	if (button == 5){
		return pad_Sta.B;
	}
	if (button == 6){
		return pad_Sta.C;
	}
	if (button == 7){
		return pad_Sta.D;
	}
	if (button == 8){
		return pad_Sta.START;
	}
	if (button == 9){
		return pad_Sta.rtn;
	}
	else{
		return -1;
	}
}
void Pad_Config(){
	waittime++;
	endflag = 0;
	DrawFormatString(200, 20, GetColor(255, 255, 255), "wait %d", waittime);
	DrawFormatString(200, 0, GetColor(255, 255, 255), "コンフィグ中 %d", configtype);
	//デバッグ
	//A,B,C,D,STARTでコンフィグ
	if (configtype == 0 && waittime >= 2){
		DrawFormatString(400, 200, GetColor(255, 255, 255), "A  %d", pad_I.A - 3);
		DrawFormatString(400, 230, GetColor(255, 255, 255), "B  %d", pad_I.B - 3);
		DrawFormatString(400, 260, GetColor(255, 255, 255), "C  %d", pad_I.C - 3);
		DrawFormatString(400, 290, GetColor(255, 255, 255), "D  %d", pad_I.D - 3);
		DrawFormatString(400, 320, GetColor(255, 255, 255), "START  %d", pad_I.START - 3);
		DrawFormatString(400, 350, GetColor(255, 255, 255), "EXIT");
		DrawFormatString(380, 200 + 30 * (config_select - 1), GetColor(255, 255, 255), "→");
		if (pad_Sta.up == 1){ config_select--; }
		if (pad_Sta.down == 1){ config_select++; }
		if (config_select <= 0){ config_select = 1; }
		if (config_select >= 7){ config_select = 6; }
		if (pad_Sta.A == 1 || pad_Sta.rtn == 1){
			if (config_select == 1){
				waittime = 0;
				configtype = 1;
			}
			if (config_select == 2){
				waittime = 0;
				configtype = 2;
			}
			if (config_select == 3){
				waittime = 0;
				configtype = 3;
			}
			if (config_select == 4){
				waittime = 0;
				configtype = 4;
			}
			if (config_select == 5){
				waittime = 0;
				configtype = 5;
			}
			if (config_select == 6){
				config_select = 1;
				waittime = 0;
				configtype = 0;
				endflag = -1;
			}
		}
	}
	if (configtype == 1 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Aボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.A = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 2 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Bボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.B = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 3 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Cボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.C = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 4 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Dボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.D = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 5 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "STARTボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.START = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
}
int configend(){
	return endflag;
}

branch
記事: 6
登録日時: 13年前

Re: キーコンフィグのシステムを作ろうとしたら・・・

#2

投稿記事 by branch » 10年前

すみません、こちらのコードでお願いします。ヘッダーファイルも追加します。
STG.cpp

コード:

#include "DxLib.h"
#include "STGbody.h"
#include "Control.h"
#define FRAME 60
int count = 0;


void wait_fanc(){
	int term;
	static int t = 0;
	static int fr = 0;
	if (fr%FRAME == 0){
		term = 1000 / (FRAME)+t - GetNowCount();
		if (term>0)
			Sleep(term);
	}
	else{
		term = (int)(1000 * (fr%FRAME) / FRAME + 1000 / FRAME) + t - GetNowCount();
		if (term>0)
			Sleep(term);
	}
	fr++;
	if (fr%FRAME == 0){
		t = GetNowCount();
	}
	return;
}

void fps(){
	int i;
	static int t = 0;
	static double ave = 0, f[FRAME];
	f[count%FRAME] = GetNowCount() - t;
	t = GetNowCount();
	if (count%FRAME == FRAME - 1){
		ave = 0;
		for (i = 0; i<FRAME; i++)
			ave += f[i];
		ave /= FRAME;
	}
	if (ave != 0){
		DrawFormatString(560, 460, GetColor(255, 255, 255), "%.1fFPS", 1000.0 / (double)ave);
		//DrawFormatString(560,460,GetColor(255,255,255),"%.2fms"  ,ave);
	}
	return;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if (DxLib_Init() == -1 || SetDrawScreen(DX_SCREEN_BACK) != 0) return -1;//初期化と裏画面化

	initialize();//初期化
	PAD_initialize();
	int menunumber;
	menunumber = 1;
	int endhantei;
	endhantei = 0;

	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && endhantei == 0){//ループここから

		Keyboard_Update();
		Pad_Input();
		Control_Status();
		GetControl_key();
		if (menunumber == 1){
			menumode();//メニュー
			endhantei = EndProcess();
			//スタート、コンフィグ、終了
		}
		drawdebug();
		fps();
		wait_fanc();
		count++;


	}//ループここまで
	DxLib_End();
	return 0;
}
STGbody.cpp

コード:

#include <math.h>
#include "DxLib.h"
#include "Control.h"
#define PI 3.1415926f
#define E_BULLET_MAX 1024
#define E_MAX 128
#define ITEM_MAX 1024

//メニュー用変数
static int modeselect;
static int menutype;
static int endflag;
static int optselect;
static int opttype;
static int kakunin;
static int waittimer;//各関数内で?
static int gamerank;

static int dbgop;
typedef struct{
	int left, right, up, down, buttonA, buttonB, buttonC, buttonD, start, rtn;
}ctrl;
ctrl control;

void option_mode();





//初期化する変数忘れず
void initialize(){//初期化
	modeselect = 1;
	menutype = 1;
	endflag = 0;
	optselect = 0;
	opttype = 0;
	kakunin = 0;
	waittimer = 0;
	gamerank = 0;

	dbgop = 0;
}

void GetControl_key(){
	control.down = GetControlInput(0);
	control.left = GetControlInput(1);
	control.right = GetControlInput(2);
	control.up = GetControlInput(3);
	control.buttonA = GetControlInput(4);
	control.buttonB = GetControlInput(5);
	control.buttonC = GetControlInput(6);
	control.buttonD = GetControlInput(7);
	control.start = GetControlInput(8);
	control.rtn = GetControlInput(9);
}

void menumode(){
	waittimer++;
	//メニュー項目描画
	if (menutype == 1 && waittimer >= 2){
		DrawFormatString(400, 200, GetColor(255, 255, 255), "START");
		DrawFormatString(400, 230, GetColor(255, 255, 255), "OPTION");
		DrawFormatString(400, 260, GetColor(255, 255, 255), "EXIT");
		//モード選択=1
		//modeselect=1←あらかじめ宣言
		DrawFormatString(380, 200 + 30 * (modeselect - 1), GetColor(255, 255, 255), "→");
		//入力に応じて数値変化
		if (control.up == 1){ modeselect--; }
		if (control.down == 1){ modeselect++; }
		if (modeselect <= 0){ modeselect = 1; }
		if (modeselect >= 4){ modeselect = 3; }
		if (control.buttonA == 1 || control.rtn == 1){
			if (modeselect == 1){
			}
			if (modeselect == 2){
				waittimer = 0;
				optselect = 1;
				opttype = 0;
				menutype = 3;
			}
			if (modeselect == 3){
				waittimer = 0;
				endflag = 1;
			}
		}
		//GAME START
		//SCORE ATTACK
		//PRACTICE(DETAIL SELECT)
		//(EXTRE MODE)
		//RECORD
		//(REPLAY)
		//OPTION
	}
	if (menutype == 3){
		option_mode();
		dbgop++;
		DrawFormatString(100, 420, GetColor(255, 255, 255), "dbg %d", dbgop);
		//EXIT
	}
}
void option_mode(){
	DrawFormatString(100, 0, GetColor(255, 255, 255), "オプション");
	DrawFormatString(100, 20, GetColor(255, 255, 255), "%d", waittimer);
	DrawFormatString(100, 40, GetColor(255, 255, 255), "%d", opttype);
	//デバッグ
	if (opttype == 0 && waittimer >= 2){
		DrawFormatString(400, 200, GetColor(255, 255, 255), "CONFIG");
		DrawFormatString(400, 200 + 30 * 1, GetColor(255, 255, 255), "EXIT");
		DrawFormatString(380, 200 + 30 * (optselect - 1), GetColor(255, 255, 255), "→");
		if (control.up == 1){ optselect--; }
		if (control.down == 1){ optselect++; }
		if (modeselect <= 0){ optselect = 1; }
		if (modeselect >= 3){ optselect = 2; }
		if (control.buttonA == 1 || control.rtn == 1){
			if (optselect == 1){
				waittimer = 0;
				opttype = 3;
			}
			if (optselect == 2){
				waittimer = 0;
				optselect = 0;
				opttype = 0;
				menutype = 1;
			}
		}
	}
	//残機
	//エクステ設定
	//処理落ち設定
	//ステータス表示
	//BGM・SE音量
	//キーコン
	if (opttype == 3 && waittimer >= 2){
		kakunin = 0;
		Pad_Config();
		kakunin = configend();
		if (kakunin == -1){
			opttype = 0;
		}
	}
	//ボタン配置タイプ
	//デバッグ数値表示?
	//データリセット
	//戻る
}


void drawdebug(){
	DrawFormatString(0, 40, GetColor(255, 255, 255), "%d", control.down);
	DrawFormatString(0, 60, GetColor(255, 255, 255), "%d", control.left);
	DrawFormatString(0, 80, GetColor(255, 255, 255), "%d", control.right);
	DrawFormatString(0, 100, GetColor(255, 255, 255), "%d", control.up);
	DrawFormatString(0, 120, GetColor(255, 255, 255), "%d", control.buttonA);
	DrawFormatString(0, 140, GetColor(255, 255, 255), "%d", control.buttonB);
	DrawFormatString(0, 160, GetColor(255, 255, 255), "%d", control.buttonC);
	DrawFormatString(0, 180, GetColor(255, 255, 255), "%d", control.buttonD);
	DrawFormatString(0, 200, GetColor(255, 255, 255), "%d", control.start);
	DrawFormatString(0, 220, GetColor(255, 255, 255), "%d", control.rtn);
}
int EndProcess(){

	return endflag;


}
control.cpp

コード:

#include "DxLib.h"
#define PADBN 28


static int m_Key[256];  // キーの入力状態格納用変数
static int pad_key[16];
static int config_select;
static int configtype;
static int waittime;
static int endflag;

typedef struct{
	int up, down, right, left, A, B, C, D, START;
}padInput;
typedef struct{
	int up, down, right, left, A, B, C, D, START, rtn;
}padStatus;
padInput pad_I;
padStatus pad_Sta;

// キーの入力状態更新
void Keyboard_Update(){
	char tmpKey[256];             // 現在のキーの入力状態を格納する
	GetHitKeyStateAll(tmpKey);  // 全てのキーの入力状態を得る
	for (int Key_i = 0; Key_i<256; Key_i++){
		if (tmpKey[Key_i] != 0){ // i番のキーコードに対応するキーが押されていたら
			m_Key[Key_i]++;   // 加算
		}
		else {              // 押されていなければ
			m_Key[Key_i] = 0; // 0にする
		}
	}
}

// KeyCodeのキーの入力状態を取得する
int Keyboard_Get(int KeyCode){
	return m_Key[KeyCode]; // KeyCodeの入力状態を返す
}

void PAD_initialize(){
	pad_I.down = 0;
	pad_I.left = 1;
	pad_I.right = 2;
	pad_I.up = 3;
	pad_I.A = 4;
	pad_I.B = 5;
	pad_I.C = 6;
	pad_I.D = 7;
	pad_I.START = 11;

	config_select = 0;
	configtype = 0;
	waittime = 50;
	endflag = 0;

}

void Pad_Input(){
	int i, PadInput, mul = 1;
	PadInput = GetJoypadInputState(DX_INPUT_PAD1);//パッドの入力状態を取得
	for (i = 0; i<PADBN; i++){
		if (PadInput & mul){
			pad_key[i]++;
		}
		else                {
			pad_key[i] = 0;
		}
		mul *= 2;
	}
}
void Control_Status(){
	if (Keyboard_Get(KEY_INPUT_DOWN) >= 1 || pad_key[pad_I.down] >= 1){
		pad_Sta.down++;
	}
	else{
		pad_Sta.down = 0;
	}

	if (Keyboard_Get(KEY_INPUT_LEFT) >= 1 || pad_key[pad_I.left] >= 1){
		pad_Sta.left++;
	}
	else{
		pad_Sta.left = 0;
	}

	if (Keyboard_Get(KEY_INPUT_RIGHT) >= 1 || pad_key[pad_I.right] >= 1){
		pad_Sta.right++;
	}
	else{
		pad_Sta.right = 0;
	}

	if (Keyboard_Get(KEY_INPUT_UP) >= 1 || pad_key[pad_I.up] >= 1){
		pad_Sta.up++;
	}
	else{
		pad_Sta.up = 0;
	}

	if (Keyboard_Get(KEY_INPUT_Z) >= 1 || pad_key[pad_I.A] >= 1){
		pad_Sta.A++;
	}
	else{
		pad_Sta.A = 0;
	}

	if (Keyboard_Get(KEY_INPUT_X) >= 1 || pad_key[pad_I.B] >= 1){
		pad_Sta.B++;
	}
	else{
		pad_Sta.B = 0;
	}

	if (Keyboard_Get(KEY_INPUT_LSHIFT) >= 1 || pad_key[pad_I.C] >= 1){
		pad_Sta.C++;
	}
	else{
		pad_Sta.C = 0;
	}

	if (Keyboard_Get(KEY_INPUT_C) >= 1 || pad_key[pad_I.D] >= 1){
		pad_Sta.D++;
	}
	else{
		pad_Sta.D = 0;
	}

	if (Keyboard_Get(KEY_INPUT_ESCAPE) >= 1 || pad_key[pad_I.START] >= 1){
		pad_Sta.START++;
	}
	else{
		pad_Sta.START = 0;
	}

	if (Keyboard_Get(KEY_INPUT_RETURN) >= 1){
		pad_Sta.rtn++;
	}
	else{
		pad_Sta.rtn = 0;
	}

}

int GetControlInput(int button){
	if (button == 0){
		return pad_Sta.down;
	}
	if (button == 1){
		return pad_Sta.left;
	}
	if (button == 2){
		return pad_Sta.right;
	}
	if (button == 3){
		return pad_Sta.up;
	}
	if (button == 4){
		return pad_Sta.A;
	}
	if (button == 5){
		return pad_Sta.B;
	}
	if (button == 6){
		return pad_Sta.C;
	}
	if (button == 7){
		return pad_Sta.D;
	}
	if (button == 8){
		return pad_Sta.START;
	}
	if (button == 9){
		return pad_Sta.rtn;
	}
	else{
		return -1;
	}
}
void Pad_Config(){
	waittime++;
	endflag = 0;
	DrawFormatString(200, 20, GetColor(255, 255, 255), "wait %d", waittime);
	DrawFormatString(200, 0, GetColor(255, 255, 255), "コンフィグ中 %d", configtype);
	//デバッグ
	//A,B,C,D,STARTでコンフィグ
	if (configtype == 0 && waittime >= 2){
		DrawFormatString(400, 200, GetColor(255, 255, 255), "A  %d", pad_I.A - 3);
		DrawFormatString(400, 230, GetColor(255, 255, 255), "B  %d", pad_I.B - 3);
		DrawFormatString(400, 260, GetColor(255, 255, 255), "C  %d", pad_I.C - 3);
		DrawFormatString(400, 290, GetColor(255, 255, 255), "D  %d", pad_I.D - 3);
		DrawFormatString(400, 320, GetColor(255, 255, 255), "START  %d", pad_I.START - 3);
		DrawFormatString(400, 350, GetColor(255, 255, 255), "EXIT");
		DrawFormatString(380, 200 + 30 * (config_select - 1), GetColor(255, 255, 255), "→");
		if (pad_Sta.up == 1){ config_select--; }
		if (pad_Sta.down == 1){ config_select++; }
		if (config_select <= 0){ config_select = 1; }
		if (config_select >= 7){ config_select = 6; }
		if (pad_Sta.A == 1 || pad_Sta.rtn == 1){
			if (config_select == 1){
				waittime = 0;
				configtype = 1;
			}
			if (config_select == 2){
				waittime = 0;
				configtype = 2;
			}
			if (config_select == 3){
				waittime = 0;
				configtype = 3;
			}
			if (config_select == 4){
				waittime = 0;
				configtype = 4;
			}
			if (config_select == 5){
				waittime = 0;
				configtype = 5;
			}
			if (config_select == 6){
				config_select = 1;
				waittime = 0;
				configtype = 0;
				endflag = -1;
			}
		}
	}
	if (configtype == 1 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Aボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.A = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 2 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Bボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.B = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 3 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Cボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.C = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 4 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Dボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.D = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 5 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "STARTボタンの設定");
		int p;
		for (p = 4; p<PADBN; p++)
		if (pad_key[p] == 1){
			pad_I.START = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
}
int configend(){
	return endflag;
}
STGbody.h

コード:

#ifndef DE#ifndef DEF_STGbody_H //二重include防止

#define DEF_STGbody_H

void initialize();
void GetControl_key();
void menumode();
void option_mode();
void drawgame();
void drawdebug();
int EndProcess();



#endif 
control.h

コード:

#ifndef DEF_Control_H //二重include防止

#define DEF_Control_H

// キーの入力状態を更新する
void Keyboard_Update();

// 引数のキーコードのキーの入力状態を返す
int Keyboard_Get(int KeyCode);

void PAD_initialize();
void Pad_Input();
void Control_Status();
int GetControlInput(int button);
void Pad_Config();
int configend();




#endif 

だんごさん
記事: 273
登録日時: 13年前

Re: キーコンフィグのシステムを作ろうとしたら・・・

#3

投稿記事 by だんごさん » 10年前

STGbody.cppの113と114行目のifの変数が違います。
それからコンフィグ設定関数内のAボタンの設定などの部分にある
for (p = 4; p<PADBN; p++)
はアクセス違反を起こします。初期値が4なのに対してカウント数はPADBN分ありますのでその分アクセス違反です。
Pad_Input関数の if (PadInput & mul)のmulは2倍ずつ増えていくようになっていますが、これはあっていますか?パッドのプログラムは作ったことないのですが気になります…。

それから条件が多い場合はswitch文を使うようにしましょう。見にくいだけでなくバグの見落としの原因です。
また終了フラグなどは変数ではなくreturnで検知するようにしたほうがいいと思います。変数が多すぎてややこしくなります。

パッと見こんな感じですが、実際に動かしてないので直接操作を受け付けなくなる原因はハッキリわかりません…すみません。
 Dango San

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: キーコンフィグのシステムを作ろうとしたら・・・

#4

投稿記事 by みけCAT » 10年前

だんごさん さんが書きました:それからコンフィグ設定関数内のAボタンの設定などの部分にある
for (p = 4; p<PADBN; p++)
はアクセス違反を起こします。初期値が4なのに対してカウント数はPADBN分ありますのでその分アクセス違反です。
4はアクセス違反に直接関係ないと思います。
pad_keyは16要素しか確保されていないのに、PADBN-1 (=27)までループしているので、確保された範囲外へのアクセスになります。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

だんごさん
記事: 273
登録日時: 13年前

Re: キーコンフィグのシステムを作ろうとしたら・・・

#5

投稿記事 by だんごさん » 10年前

みけCAT さんが書きました:
だんごさん さんが書きました:それからコンフィグ設定関数内のAボタンの設定などの部分にある
for (p = 4; p<PADBN; p++)
はアクセス違反を起こします。初期値が4なのに対してカウント数はPADBN分ありますのでその分アクセス違反です。
4はアクセス違反に直接関係ないと思います。
pad_keyは16要素しか確保されていないのに、PADBN-1 (=27)までループしているので、確保された範囲外へのアクセスになります。
あぁ、ホントその通りでした…
PADBNが28だったので配列数もかと勘違いしてました…すみません
 Dango San

branch
記事: 6
登録日時: 13年前

Re: キーコンフィグのシステムを作ろうとしたら・・・

#6

投稿記事 by branch » 10年前

返答ありがとうございます。
動作しない状況についてなのですが、別のパソコンで作っていたプログラムでは動いたのですが、今のパソコンに移した際に動かなくなったというのを書くのを忘れていました。
前のパソコンでは Visual C++ 2010 Express、現在はVisual studio Express 2013 for WD を使ってます。

branch
記事: 6
登録日時: 13年前

Re: キーコンフィグのシステムを作ろうとしたら・・・

#7

投稿記事 by branch » 10年前

あと、control.cppの53行目
void PAD_initialize()内の
waittime = 50;
は本当は0にするつもりだったんですが、デバッグのために数値を変えてます。

ほげほげ

Re: キーコンフィグのシステムを作ろうとしたら・・・

#8

投稿記事 by ほげほげ » 10年前

こんにちは。
ここには初めて書き込むのでうまくいってますかどうか。

こういうのはブレークポイントのせっていで waittime==0のとき停止
とかやると変わった瞬間に止まるので調べるのが楽ですよ。

今回のケースは、control.cppのPad_Input()内で
pad_keyが16個の配列なのにPADBIN、つまり24個書き換えることでおきてます。
バッファオーバーフローですね、そのオーバーしたとこがwaittimeの場所だったんですね。

branch
記事: 6
登録日時: 13年前

Re: キーコンフィグのシステムを作ろうとしたら・・・

#9

投稿記事 by branch » 10年前

>>ほげほげさん
ありがとうございます!ブレークポイントは変数の値に対しても設定出来るんですか!
以下のように修正してみました。

コード:

static int pad_key[PADBN];

void Pad_Config(){
	waittime++;
	endflag = 0;
	DrawFormatString(200, 20, GetColor(255, 255, 255), "wait %d", waittime);
	DrawFormatString(200, 0, GetColor(255, 255, 255), "コンフィグ中 %d", configtype);
	//デバッグ
	//A,B,C,D,STARTでコンフィグ
	if (configtype == 0 && waittime >= 2){
		DrawFormatString(400, 200, GetColor(255, 255, 255), "A  %d", pad_I.A - 3);
		DrawFormatString(400, 230, GetColor(255, 255, 255), "B  %d", pad_I.B - 3);
		DrawFormatString(400, 260, GetColor(255, 255, 255), "C  %d", pad_I.C - 3);
		DrawFormatString(400, 290, GetColor(255, 255, 255), "D  %d", pad_I.D - 3);
		DrawFormatString(400, 320, GetColor(255, 255, 255), "START  %d", pad_I.START - 3);
		DrawFormatString(400, 350, GetColor(255, 255, 255), "EXIT");
		DrawFormatString(380, 200 + 30 * (config_select - 1), GetColor(255, 255, 255), "→");
		if (pad_Sta.up == 1){ config_select--; }
		if (pad_Sta.down == 1){ config_select++; }
		if (config_select <= 0){ config_select = 1; }
		if (config_select >= 7){ config_select = 6; }
		if (pad_Sta.A == 1 || pad_Sta.rtn == 1){
			if (config_select == 1){
				waittime = 0;
				configtype = 1;
			}
			if (config_select == 2){
				waittime = 0;
				configtype = 2;
			}
			if (config_select == 3){
				waittime = 0;
				configtype = 3;
			}
			if (config_select == 4){
				waittime = 0;
				configtype = 4;
			}
			if (config_select == 5){
				waittime = 0;
				configtype = 5;
			}
			if (config_select == 6){
				config_select = 1;
				waittime = 0;
				configtype = 0;
				endflag = -1;
			}
		}
	}
	if (configtype == 1 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Aボタンの設定");
		int p;
		for (p = 4; p<PADBN-4; p++)
		if (pad_key[p] == 1){
			pad_I.A = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 2 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Bボタンの設定");
		int p;
		for (p = 4; p<PADBN-4; p++)
		if (pad_key[p] == 1){
			pad_I.B = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 3 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Cボタンの設定");
		int p;
		for (p = 4; p<PADBN-4; p++)
		if (pad_key[p] == 1){
			pad_I.C = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 4 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "Dボタンの設定");
		int p;
		for (p = 4; p<PADBN-4; p++)
		if (pad_key[p] == 1){
			pad_I.D = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
	if (configtype == 5 && waittime >= 2){
		DrawFormatString(200, 60, GetColor(255, 255, 255), "STARTボタンの設定");
		int p;
		for (p = 4; p<PADBN-4; p++)
		if (pad_key[p] == 1){
			pad_I.START = p;
			waittime = 0;
			configtype = 0;
			break;
		}
	}
}
あと、キーコンフィグのボタン設定以外の部分をSTGbody.cppに記述するように書き換えたコードも載せておきます。
STGbody.cpp

コード:

void menumode(){
	DrawFormatString(600, 0, GetColor(255, 255, 255), "%d", waittimer);
	waittimer++;
	//メニュー項目描画
	if (menutype == 1 && waittimer >= 2){
		DrawGraph(400, 200, menugra1, TRUE);
		DrawFormatString(400, 230, GetColor(255, 255, 255), "OPTION");
		DrawFormatString(400, 260, GetColor(255, 255, 255), "EXIT");
		//モード選択=1
		//modeselect=1←あらかじめ宣言
		DrawFormatString(380, 200 + 30 * (modeselect - 1), GetColor(255, 255, 255), "→");
		//入力に応じて数値変化
		if (control.up == 1){ modeselect--; }
		if (control.down == 1){ modeselect++; }
		if (modeselect <= 0){ modeselect = 1; }
		if (modeselect >= 4){ modeselect = 3; }
		if (control.buttonA == 1 || control.rtn == 1){
			if (modeselect == 1){
				waittimer = 0;
				menutype = 2;
			}
			if (modeselect == 2){
				waittimer = 0;
				optselect = 1;
				opttype = 0;
				menutype = 3;
			}
			if (modeselect == 3){
				waittimer = 0;
				endflag = 1;
			}
		}
		//GAME START
		//SCORE ATTACK
		//PRACTICE(DETAIL SELECT)
		//(EXTRE MODE)
		//RECORD
		//(REPLAY)
		//OPTION
		//EXIT
	}
	//if (menutype == 2){
	//	level_select();
	//}
	if (menutype == 3){
		option_mode();
	}
}
void option_mode(){
	if (opttype == 0 && waittimer >= 2){
		DrawFormatString(400, 200, GetColor(255, 255, 255), "CONFIG");
		DrawFormatString(400, 230, GetColor(255, 255, 255), "EXIT");
		DrawFormatString(380, 200 + 30 * (optselect - 1), GetColor(255, 255, 255), "→");
		if (control.up == 1){ optselect--; }
		if (control.down == 1){ optselect++; }
		if (optselect <= 0){ optselect = 1; }
		if (optselect >= 3){ optselect = 2; }
		if (control.buttonA == 1 || control.rtn == 1){
			if (optselect == 1){
				waittimer = 0;
				opttype = 3;
			}
			if (optselect == 2){
				waittimer = 0;
				optselect = 0;
				opttype = 0;
				menutype = 1;
			}
		}
	}
	if (opttype == 3){
		Pad_Config();
	}
	//残機
	//エクステ設定
	//処理落ち設定
	//ステータス表示
	//BGM・SE音量
	//キーコン
	//ボタン配置タイプ
	//デバッグ数値表示?
	//データリセット
	//戻る
}
void Pad_Config(){
	//A,B,C,D,STARTでコンフィグ
	DrawFormatString(400, 200, GetColor(255, 255, 255), "A  %d", PadbuttonNo(4) - 3);
	DrawFormatString(400, 230, GetColor(255, 255, 255), "B  %d", PadbuttonNo(5) - 3);
	DrawFormatString(400, 260, GetColor(255, 255, 255), "C  %d", PadbuttonNo(6) - 3);
	DrawFormatString(400, 290, GetColor(255, 255, 255), "D  %d", PadbuttonNo(7) - 3);
	DrawFormatString(400, 320, GetColor(255, 255, 255), "START  %d", PadbuttonNo(8) - 3);
	DrawFormatString(400, 350, GetColor(255, 255, 255), "EXIT");
	DrawFormatString(380, 200 + 30 * (config_select - 1), GetColor(255, 255, 255), "→");
	if (configtype == 0){
		if (control.up == 1){ config_select--; }
		if (control.down == 1){ config_select++; }
		if (config_select <= 0){ config_select = 1; }
		if (config_select >= 7){ config_select = 6; }
		if (padNo == 0){
			DrawFormatString(360, 380, GetColor(255, 255, 255), "ゲームパッドが接続されていません。");
			config_select = 6;
		}
		if ((control.buttonA == 1 || control.rtn == 1) && waittimer >= 2){
			if (config_select == 1){
				waittimer = 0;
				configtype = 1;
			}
			if (config_select == 2){
				waittimer = 0;
				configtype = 2;
			}
			if (config_select == 3){
				waittimer = 0;
				configtype = 3;
			}
			if (config_select == 4){
				waittimer = 0;
				configtype = 4;
			}
			if (config_select == 5){
				waittimer = 0;
				configtype = 5;
			}
			if (config_select == 6){
				config_select = 1;
				waittimer = 0;
				configtype = 0;
				opttype = 0;
			}
		}
	}
	if (configtype != 0 && waittimer >= 2){
		Pad_Config2(configtype);
		if (Configcomp() == 1){ waittimer = 0;
			configtype = 0; }
	}
	
}
control.cpp

コード:

void Pad_Config2(int configtype){
	configcomp = 0;

	DrawFormatString(300, 460, GetColor(255, 255, 255), "コンフィグ中だよ");
	
	if (configtype == 1){
		DrawFormatString(500, 200, GetColor(255, 255, 255), "Aボタン設定中");
		int p;
		for (p = 4; p<PADBN - 4; p++)
		if (pad_key[p] == 1){
			pad_I.A = p;
			configcomp = 1;
			break;
		}
	}
	if (configtype == 2){
		DrawFormatString(500, 230, GetColor(255, 255, 255), "Bボタン設定中");
		int p;
		for (p = 4; p<PADBN - 4; p++)
		if (pad_key[p] == 1){
			pad_I.B = p;
			configcomp = 1;
			break;
		}
	}
	if (configtype == 3){
		DrawFormatString(500, 260, GetColor(255, 255, 255), "Cボタン設定中");
		int p;
		for (p = 4; p<PADBN - 4; p++)
		if (pad_key[p] == 1){
			pad_I.C = p;
			configcomp = 1;
			break;
		}
	}
	if (configtype == 4){
		DrawFormatString(500, 290, GetColor(255, 255, 255), "Dボタン設定中");
		int p;
		for (p = 4; p<PADBN - 4; p++)
		if (pad_key[p] == 1){
			pad_I.D = p;
			configcomp = 1;
			break;
		}
	}
	if (configtype == 5){
		DrawFormatString(500, 320, GetColor(255, 255, 255), "STARTボタン設定中");
		int p;
		for (p = 4; p<PADBN - 4; p++)
		if (pad_key[p] == 1){
			pad_I.START = p;
			configcomp = 1;
			break;
		}
	}
}
int PadbuttonNo(int button){
	switch (button){
	case 4:
		return pad_I.A;
		break;
	case 5:
		return pad_I.B;
		break;
	case 6:
		return pad_I.C;
		break;
	case 7:
		return pad_I.D;
		break;
	case 8:
		return pad_I.START;
		break;
	}
}
int Configcomp(){
	return configcomp;
}

branch
記事: 6
登録日時: 13年前

Re: キーコンフィグのシステムを作ろうとしたら・・・

#10

投稿記事 by branch » 10年前

解決済み押し忘れてました…

閉鎖

“C言語何でも質問掲示板” へ戻る