ページ 1 / 1
キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月22日(金) 21:35
by namari
アクションゲームを作っています。
ほとんどのシステムはオリジナルなのですが、
キーコンフィグに関しては恥ずかしくもつい楽な方を取って完全に8章の流用なので、
理解が及んでいなく、ここからどのようにキーコンフィグを作るか全く分かりません。
コード:
//key.cpp
#include "../include/GV.h"
unsigned int stateKey[256];
int GetHitKeyStateAll_2(){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key[i]==1) stateKey[i]++;
else stateKey[i]=0;
}
return 0;
}
int CheckStateKey(unsigned char Handle){
return stateKey[Handle];
}
//パッドの入力状態を格納する変数
pad_t pad;
//引数1と引数2のうち大きい方を引数1に代入する
void input_pad_or_key(int *p, int k){
*p = *p>k ? *p : k;
}
//パッドとキーボードの両方の入力をチェックする関数
void GetHitPadStateAll(){
int i,PadInput,mul=1;
PadInput = GetJoypadInputState( DX_INPUT_PAD1 );//パッドの入力状態を取得
//PadInputには0010100100010101のような16桁のビットが入っていて、それぞれの桁がそこのボタンが押してあるかどうかを判定する。
//ここでは、PadInput & mulのような表記で、ボタンが押しているかどうかで分岐をしている。(1~2^16=0000000000000000~1111111111111111)
for(i=0;i<16;i++){
if(PadInput & mul) pad.key[i]++;
else pad.key[i]=0;
mul*=2;
}
input_pad_or_key(&pad.key[configpad.left] ,CheckStateKey(KEY_INPUT_LEFT ));
input_pad_or_key(&pad.key[configpad.up] ,CheckStateKey(KEY_INPUT_UP ));
input_pad_or_key(&pad.key[configpad.right] ,CheckStateKey(KEY_INPUT_RIGHT ));
input_pad_or_key(&pad.key[configpad.down] ,CheckStateKey(KEY_INPUT_DOWN ));
input_pad_or_key(&pad.key[configpad.esc] ,CheckStateKey(KEY_INPUT_ESCAPE ));
input_pad_or_key(&pad.key[configpad.z] ,CheckStateKey(KEY_INPUT_Z ));
input_pad_or_key(&pad.key[configpad.x] ,CheckStateKey(KEY_INPUT_X ));
input_pad_or_key(&pad.key[configpad.space] ,CheckStateKey(KEY_INPUT_SPACE ));
input_pad_or_key(&pad.key[configpad.enter] ,CheckStateKey(KEY_INPUT_RETURN ));
}
//渡されたパッドキー番号の入力状態を返す。返り値が-1なら不正
int CheckStatePad(unsigned int Handle){
if(0<=Handle && Handle<PAD_MAX){
return pad.key[Handle];
}
else{
printfDx("CheckStatePadに渡した値が不正です\n");
return -1;
}
}
//どこか一つでもキーが押されているか?押されていたら1、押されていなかったら0を返す。
int allkeycheck(){
int i,on_flag=0;
for(i=0;i<255;i++){if(stateKey[i]>0){on_flag=1;return 1;}}
return 0;}
//ini.cpp
//一番最初の初期化
void first_ini(){
ch.x=FIELD_MAX_X/4;
ch.y=FIELD_MAX_Y/4;
ch.hp=100;
configpad.down=0;
configpad.left=1;
configpad.right=2;
configpad.up=3;
configpad.esc=13;
configpad.z=5;
configpad.x=6;
configpad.space=7;
configpad.enter=8;
}
//struct.h
typedef struct{
int key[PAD_MAX];
}pad_t;
//コンフィグに関する構造体
typedef struct{
int left,up,right,down,esc,z,x,space,enter;
}configpad_t;
//GV.h
//構造体変数宣言部
GLOBAL configpad_t configpad;//コンフィグで設定したキー情報
GLOBAL ch_t ch; //キャラクタデータ宣言
おそらく、全て8章まんまだと思います。
どのキーを押されているか、プレイヤーに押させて入力させるのは分かるのですが、
それを何に覚えさせればいいのか・・・?
プレイヤーがジョイパッドの時は、おそらくfirst_iniのconfigpad.~の数を変えるようにすればいいんでしょうか?
キーボードの場合は・・・?
かなり初歩的ですみませんが、ぜひご教授いただけると嬉しいです。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 00:48
by softya(ソフト屋)
>プレイヤーがジョイパッドの時は、おそらくfirst_iniのconfigpad.~の数を変えるようにすればいいんでしょうか?
>キーボードの場合は・・・?
>かなり初歩的ですみませんが、ぜひご教授いただけると嬉しいです。
KEY_INPUT_LEFT などがint値ですので、それぞれに対応した値を覚えれば良いと思います。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 19:04
by namari
おかげで、比較的指針が立ちました。
txtファイルに情報を保存して、そこから読み出すことにします。
コンフィグモードはtxtファイルを弄るものとします。
ありがとうございました。
しかし、作成途中、パッドの初期化部分でバグが出てしまいます。
一体どこが悪いんでしょうか・・・
コード:
void load_key_or_pad(){
int i=0;
int TxtHandle[2];
TxtHandle[0]=FileRead_open( "pad_config.txt");
TxtHandle[1]=FileRead_open( "key_config.txt");
if(TxtHandle[0] == NULL || TxtHandle[1] == NULL){
printfDx("read error\n");
exit(1);
}
while(FileRead_eof(TxtHandle[0])==0){
char a[]=FileRead_gets( TxtHandle[0] );
if(i==0){configpad.down=atoi(a);}
if(i==1){configpad.left=atoi(a);}
if(i==2){configpad.right=atoi(a);}
if(i==3){configpad.up=atoi(a);}
if(i==4){configpad.esc=atoi(a);}
if(i==5){configpad.z=atoi(a);}
if(i==6){configpad.x=atoi(a);}
if(i==7){configpad.space=atoi(a);}
if(i==8){configpad.enter=atoi(a);}
FileRead_getc( TxtHandle[0] );//改行を飛ばす
i++;
}
FileRead_close(TxtHandle[0]);
FileRead_close(TxtHandle[1]);
}
"key_config.txt"はまだ手が回ってないので、
上には書いてありますが一切いじってないです。気にしないでください。
以下はpad_config.txtです。
エラーメッセージは
error C2660: 'DxLib::FileRead_gets' : 関数に 1 個の引数を指定できません。
です。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 19:21
by softya(ソフト屋)
char a[]=FileRead_gets( TxtHandle[0] );
はC/C++的には間違っています。
Javascript、PHPやPerlの様な
動的型割付言語動的型付け言語ではありませんので、こういうことは出来ません。
【訂正】この場合は、オブジェクト指向としての型じゃなcharでは出来ませんが正しいかな。
あとFileRead_getsの引数が間違っています。
「DXライブラリ置き場 リファレンスページ」
http://homepage2.nifty.com/natupaji/DxL ... html#R19N8
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 19:38
by namari
コード:
//パッドとキーボードの両方の入力をチェックする関数
void GetHitPadStateAll(){
int i,PadInput,mul=1;
PadInput = GetJoypadInputState( DX_INPUT_PAD1 );//パッドの入力状態を取得
//PadInputには0010100100010101のような16桁のビットが入っていて、それぞれの桁がそこのボタンが押してあるかどうかを判定する。
//ここでは、PadInput & mulのような表記で、ボタンが押しているかどうかで分岐をしている。(1~2^16=0000000000000000~1111111111111111)
for(i=0;i<16;i++){
if(PadInput & mul) pad.key[i]++;
else pad.key[i]=0;
mul*=2;
}
input_pad_or_key(&pad.key[configpad.left] ,CheckStateKey(KEY_INPUT_LEFT ));//LEFT
input_pad_or_key(&pad.key[configpad.up] ,CheckStateKey(KEY_INPUT_UP ));//UP
input_pad_or_key(&pad.key[configpad.right] ,CheckStateKey(KEY_INPUT_RIGHT ));//RIGHT
input_pad_or_key(&pad.key[configpad.down] ,CheckStateKey(KEY_INPUT_DOWN ));//DOWN
input_pad_or_key(&pad.key[configpad.esc] ,CheckStateKey(KEY_INPUT_ESCAPE ));//ESCAPE
input_pad_or_key(&pad.key[configpad.z] ,CheckStateKey(KEY_INPUT_Z ));//Z
input_pad_or_key(&pad.key[configpad.x] ,CheckStateKey(KEY_INPUT_X ));//X
input_pad_or_key(&pad.key[configpad.space] ,CheckStateKey(KEY_INPUT_SPACE ));//SPACE
input_pad_or_key(&pad.key[configpad.enter] ,CheckStateKey(KEY_INPUT_RETURN ));//ENTER
}
txtファイルは数字の末尾にスペースを入れて全て2桁にしました。
このように変更したら通りましたが、
パッドキーを押す時、バグが起こるならともかく、
今回いじっていないキーボード側の入力でも同様にバグが起こりました。
バグ内容は、キーが重複して、正しく割り振れていないものだと思われます。
度々質問して申し訳ないですが、これは一体どういうことなんでしょうか
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 20:45
by softya(ソフト屋)
とりあえずデバッガでconfigpadに入っている値を確認して下さい。
読み込み部分で
char a[]=FileRead_gets( TxtHandle[0] );
が直ったとしてもFileRead系関数自体の使い方に誤りがあると思います。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 22:10
by namari
すみません。コード修正した場所を間違えました。
コード:
void load_key_or_pad(){
int i=0;
int TxtHandle[2];
TxtHandle[0]=FileRead_open( "pad_config.txt");
TxtHandle[1]=FileRead_open( "key_config.txt");
if(TxtHandle[0] == NULL || TxtHandle[1] == NULL){
printfDx("read error\n");
exit(1);
}
while(i!=9){
char a[3];
FileRead_gets(a, 2 ,TxtHandle[0] );
if(i==0){configpad.down=atoi(a);}
if(i==1){configpad.left=atoi(a);}
if(i==2){configpad.right=atoi(a);}
if(i==3){configpad.up=atoi(a);}
if(i==4){configpad.esc=atoi(a);}
if(i==5){configpad.z=atoi(a);}
if(i==6){configpad.x=atoi(a);}
if(i==7){configpad.space=atoi(a);}
if(i==8){configpad.enter=atoi(a);}
i++;
}
FileRead_close(TxtHandle[0]);
FileRead_close(TxtHandle[1]);
}
こうですね。
そして、configpad~の中身を確認したところ、
コード:
configpad.down:0
configpad.left:0
configpad.right:0
configpad.up:0
configpad.esc:1
configpad.z:0
configpad.x:0
configpad.space:2
と、かなり間違った値が代入されていました。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 22:13
by softya(ソフト屋)
サイズはナル文字も含むのでFileRead_gets(a, 3 ,TxtHandle[0] );だと思いますが。ドキュメントをよく読んでみて下さい。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月23日(土) 22:32
by namari
コード:
void load_key_or_pad(){
int i=0;
int TxtHandle[2];
TxtHandle[0]=FileRead_open( "pad_config.txt");
TxtHandle[1]=FileRead_open( "key_config.txt");
if(TxtHandle[0] == NULL || TxtHandle[1] == NULL){
printfDx("read error\n");
exit(1);
}
while(i!=9){
char a[3];
FileRead_gets(a, 3 ,TxtHandle[0] );//\0
if(i==0){configpad.down=atoi(a);}
if(i==1){configpad.left=atoi(a);}
if(i==2){configpad.right=atoi(a);}
if(i==3){configpad.up=atoi(a);}
if(i==4){configpad.esc=atoi(a);}
if(i==5){configpad.z=atoi(a);}
if(i==6){configpad.x=atoi(a);}
if(i==7){configpad.space=atoi(a);}
if(i==8){configpad.enter=atoi(a);}
FileRead_gets(a, 3 ,TxtHandle[0] );//0が含まれてしまうので飛ばす
i++;
}
FileRead_close(TxtHandle[0]);
FileRead_close(TxtHandle[1]);
}
charの基礎も分かってなかったですね。
一から覚え直す必要がありそうです。
ありがとうございました。
これで、ジョイパッドの方のコンフィグはなんとかなりそうです。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月26日(火) 00:18
by namari
遂にコンフィグに移りました。
コンフィグ用のテキストファイルからキー番号を読み込むシステムなので、
キーコンフィグに当たって、テキストファイルへ書き込みたいんですが、
書き出し時に、文字化けを起こしてしまいます。
コード:
//ヘッダファイル
int key_config_flag[9];//フラグが0の時、そのフラグ番号のキー設定を行なう。
//一番最初の初期化
void first_ini(){
・
・
・
key_config_flag[0]=0;//フラグ番号0が最初なので、このキーのフラグだけ0にして、あとは全て1としておく。
for(i=1;i<=8;i++){
key_config_flag[i]=1;
}
}
//順番にキーを押させて、key_config.txtの中身を変えさせる関数。
int keyconfig(){
FILE *TxtHandle_key;
TxtHandle_key=fopen( " ../../key_config.txt","w");
if(TxtHandle_key == NULL){
printfDx("エラー:key_config.txtが無い。");
}
int j,k,keta;
char buff[9];
if(key_config_flag[0]==0){DrawFormatString( 100, 300, WHITE , "下のキーを選んでください" );}
if(key_config_flag[1]==0){DrawFormatString( 100, 300, WHITE , "左のキーを選んでください" );}
if(key_config_flag[2]==0){DrawFormatString( 100, 300, WHITE , "右のキーを選んでください" );}
if(key_config_flag[3]==0){DrawFormatString( 100, 300, WHITE , "ジャンプのキーを選んでください" );}
if(key_config_flag[4]==0){DrawFormatString( 100, 300, WHITE , "メニューのキーを選んでください" );}
if(key_config_flag[5]==0){DrawFormatString( 100, 300, WHITE , "決定キーを選んでください" );}
if(key_config_flag[6]==0){DrawFormatString( 100, 300, WHITE , "キャンセルキーを選んでください" );}
if(key_config_flag[7]==0){DrawFormatString( 100, 300, WHITE , "決めてないけどとりあえずキーを選んでください" );}
if(key_config_flag[8]==0){DrawFormatString( 100, 300, WHITE , "決めてないけどとにかくキーを選んでください" );}
for(j=0;j<=8;j++){
for(k=0;k<=255;k++){
if(CheckHitKeyAll()==0){
nagaoshi_flag=0;//長押しで押されてしまわないように。
}
if(CheckStateKey(k)>0 && key_config_flag[j]==0 && nagaoshi_flag==0){
if(j<8){key_config_flag[j+1]=0;}//一つのキーを確定したら、次のキーの選択に映る。ただし、8番目は、もうこれ以上フラグがないので行なわない
key_config_flag[j]=1;
nagaoshi_flag=1;
int pre_k=k;//kの値はあとで使うので、ここではkの値を他の変数に移し替えておく。
if(pre_k==0){keta=1;}//kが0の時、一桁
else{for(keta=0;pre_k!=0;keta++){pre_k/=10;}}//kがゼロになるまで10で割って桁数を求める。
if(keta==1){sprintf(buff,"%d \n",k);}//テキストファイル読み込みの関係上、3文字で統一したい。
else if(keta==2){sprintf(buff,"%d \n",k);}
else if(keta==3){sprintf(buff,"%d\n",k);}
fwrite(buff,sizeof(char)*10,1,TxtHandle_key);//テキストファイルに書き込み。
if(j==8){return 1;}//8ならコンフィグを終えて、設定一覧にもどる。
}
}
}
fclose(TxtHandle_key);
return 0;
}
fwriteとsprintfの使い方に怪しいところがあるような気はします。
なお、本来出力されて欲しいのは、
コード:
208
203
205
200
1
44
45
57
28
わかりにくいですが、数字の後にスペースが置いてあります。
スペースの代わりに文字の"a"などでも動作は変わりません。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月26日(火) 00:36
by softya(ソフト屋)
書き出しているのはbuffの実質有効なサイズである必要があります。それ以上書き出すとごみになるだけですので、sizeof(char)*10は間違いです。
sprintfを止めて、そんな心配しなくて良いfprintfで書きだしたほうが分かりやすいと思いますよ。
※ sprintfを止めてを追記。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月26日(火) 19:47
by namari
fprintfを使って書きなおしたところ、文字化けはなくなりました。
コード:
int keyconfig(){
FILE *TxtHandle_key;
TxtHandle_key=fopen( " ../../key_config.txt","w");
int j,k,keta;
if(key_config_flag[0]==0){DrawFormatString( 100, 300, WHITE , "下のキーを選んでください" );}
if(key_config_flag[1]==0){DrawFormatString( 100, 300, WHITE , "左のキーを選んでください" );}
if(key_config_flag[2]==0){DrawFormatString( 100, 300, WHITE , "右のキーを選んでください" );}
if(key_config_flag[3]==0){DrawFormatString( 100, 300, WHITE , "ジャンプのキーを選んでください" );}
if(key_config_flag[4]==0){DrawFormatString( 100, 300, WHITE , "メニューのキーを選んでください" );}
if(key_config_flag[5]==0){DrawFormatString( 100, 300, WHITE , "決定キーを選んでください" );}
if(key_config_flag[6]==0){DrawFormatString( 100, 300, WHITE , "キャンセルキーを選んでください" );}
if(key_config_flag[7]==0){DrawFormatString( 100, 300, WHITE , "決めてないけどとりあえずキーを選んでください" );}
if(key_config_flag[8]==0){DrawFormatString( 100, 300, WHITE , "決めてないけどとにかくキーを選んでください" );}
for(j=0;j<=8;j++){
for(k=0;k<=255;k++){
if(CheckHitKeyAll()==0){
nagaoshi_flag=0;//長押しで押されてしまわないように。
}
if(CheckStateKey(k)>0 && key_config_flag[j]==0 && nagaoshi_flag==0){
if(j<8){key_config_flag[j+1]=0;}//一つのキーを確定したら、次のキーの選択に映る。ただし、8番目は、もうこれ以上フラグがないので行なわない
key_config_flag[j]=1;
nagaoshi_flag=1;
int pre_k=k;//kの値はあとで使うので、ここではkの値を他の変数に移し替えておく。
if(pre_k==0){keta=1;}//kが0の時、一桁
else{for(keta=0;pre_k!=0;keta++){pre_k/=10;}}//kがゼロになるまで10で割って桁数を求める。
if(keta==1){fprintf(TxtHandle_key,"%daa\n",k);}//テキストファイル読み込みの関係上、3文字で統一したい。
else if(keta==2){fprintf(TxtHandle_key,"%da\n",k);}
else if(keta==3){fprintf(TxtHandle_key,"%d\n",k);}
if(j==8){return 1;}//8ならコンフィグを終えて、設定一覧にもどる。
}
}
}
fclose(TxtHandle_key);
return 0;
}
しかし、key_config.txtに表示されたのは、以下の文だけでした。
28は最後に押した「決めてないけどとにかくキーを選んでください」に対応するENTERキーの数字です。
なぜ他のキー番号は入っていないのでしょうか。
fprintfでのファイル位置指示子がいつまで保存されるかという問題でしょうか?
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年2月26日(火) 20:51
by softya(ソフト屋)
書き換えたキーしか書きだしていないからでしょう。
ファイルを書き換える時は毎回全部のキーを書きださないとダメです。
なので、書き換えるときにfopenして全部のキーを書きだしてfcloseします。書き換えるのはコンフィグを抜けるときなどが良いでしょう。
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年3月26日(火) 16:26
by namari
旅行していたため、解決済みも付けられませんでした。
キーコンフィグが完成したので貼ります。
本当にありがとうございました。
コード:
//順番にキーを押させて、key_config.txtの中身を変えさせる関数。
int keyconfig(){
int j,k,keta;
if(key_config_flag[0]==0){DrawFormatString( 100, 300, WHITE , "下のキーを選んでください" );}
if(key_config_flag[1]==0){DrawFormatString( 100, 300, WHITE , "左のキーを選んでください" );}
if(key_config_flag[2]==0){DrawFormatString( 100, 300, WHITE , "右のキーを選んでください" );}
if(key_config_flag[3]==0){DrawFormatString( 100, 300, WHITE , "ジャンプのキーを選んでください" );}
if(key_config_flag[4]==0){DrawFormatString( 100, 300, WHITE , "メニューのキーを選んでください" );}
if(key_config_flag[5]==0){DrawFormatString( 100, 300, WHITE , "決定キーを選んでください" );}
if(key_config_flag[6]==0){DrawFormatString( 100, 300, WHITE , "キャンセルキーを選んでください" );}
if(key_config_flag[7]==0){DrawFormatString( 100, 300, WHITE , "決めてないけどとりあえずキーを選んでください" );}
if(key_config_flag[8]==0){DrawFormatString( 100, 300, WHITE , "決めてないけどとにかくキーを選んでください" );}
for(j=0;j<=8;j++){
for(k=0;k<=255;k++){
if(CheckHitKeyAll()==0){
nagaoshi_flag=0;//長押しで押されてしまわないように。
}
if(CheckStateKey(k)>0 && key_config_flag[j]==0 && nagaoshi_flag==0){
if(j<8){key_config_flag[j+1]=0;}//一つのキーを確定したら、次のキーの選択に映る。ただし、8番目は、もうこれ以上フラグがないので行なわない
key_config_flag[j]=1;
nagaoshi_flag=1;
int pre_k=k;//kの値はあとで使うので、ここではkの値を他の変数に移し替えておく。
if(pre_k==0){keta=1;}//kが0の時、一桁
else{for(keta=0;pre_k!=0;keta++){pre_k/=10;}}//kがゼロになるまで10で割って桁数を求める。
if(keta==1){fprintf(TxtHandle_key,"%daa\n",k);}//テキストファイル読み込みの関係上、3文字で統一したい。
else if(keta==2){fprintf(TxtHandle_key,"%da\n",k);}
else if(keta==3){fprintf(TxtHandle_key,"%d\n",k);}
if(j==8){return 1;}//8ならコンフィグを終えて、設定一覧にもどる。
}
}
}
return 0;
}
Re: キーコンフィグモードを作る指針さえ立ちません
Posted: 2013年3月26日(火) 16:40
by ISLe
namari さんが書きました:コード:
int pre_k=k;//kの値はあとで使うので、ここではkの値を他の変数に移し替えておく。
if(pre_k==0){keta=1;}//kが0の時、一桁
else{for(keta=0;pre_k!=0;keta++){pre_k/=10;}}//kがゼロになるまで10で割って桁数を求める。
if(keta==1){fprintf(TxtHandle_key,"%daa\n",k);}//テキストファイル読み込みの関係上、3文字で統一したい。
else if(keta==2){fprintf(TxtHandle_key,"%da\n",k);}
else if(keta==3){fprintf(TxtHandle_key,"%d\n",k);}
空白で埋めても良ければ、3文字左詰めは、
fprintf(TxtHandle_key,"%-3d\n",k);
で一発です。