ページ 11

キーボード入力について

Posted: 2011年6月18日(土) 01:07
by much
タイピングゲームをつくろうと思っています

そこで出てくるのが
”If(CheckHitKey(KEY_INPUT_A) != 0)”
ですが
”KEY_INPUT_A” ~ ”KEY_INPUT_Z” を全てを入力せず
ループ もしくは それに変わる方法 で出す方法はありませんか?

少し意味が分からない文になっていますが、
誰かよろしくお願いします。

Re: キーボード入力について

Posted: 2011年6月18日(土) 01:26
by a5ua
タイピングゲームならば、GetInputCharのほうが適役かと思います。

DXライブラリのリファレンスはこちら
http://homepage2.nifty.com/natupaji/DxL ... html#R5N25

Re: キーボード入力について

Posted: 2011年6月18日(土) 01:36
by much
即答ありがとうございます。

そのような便利な関数があったんですね。
とても、助かりました。

次に、ある文字列(入力する文字)の先頭と、この返り値が一致したときに
先頭の文字を消すということはわかるのですが、

「先頭の文字を消して詰める」という仕組みを作れません・・・

どなたかご存知でないでしょうか?

Re: キーボード入力について

Posted: 2011年6月18日(土) 01:49
by a5ua
方法はいくつかあると思いますが、2つほど提案します。

方法1:実際に文字を削除する

コード:

char typing[100];	// 表示文字列

// 先頭の文字を削除する処理
typing[0] = typing[1];
typing[1] = typing[2];
     ・
     ・
     ・
typing[98] = typing[99];
のように1文字先を代入していくことで、先頭の文字を消すことが出来ます。
(実際に作るときは、for文を使って実現しましょう)


方法2:削除されているように見えるようにする

コード:

#include <stdio.h>

int main(void)
{
	char typing[] = "typing";
	
	puts(typing);		// 0文字目から表示
	puts(typing + 1);	// 1文字目から表示
	
	return 0;
}
配列とポインタの関係について理解する必要があります。
typing + Nとすることで、N文字目以降の文字列を表現できます。

Re: キーボード入力について

Posted: 2011年6月18日(土) 01:55
by Dixq (管理人)
文字列の先頭を一つずつずらすか、ずらしたものをコピーすれば良いのではないでしょうか?

コード:

char str[]="abcde";
printf("%s\n",&str[0]);
printf("%s\n",&str[1]);
printf("%s\n",&str[2]);
printf("%s\n",&str[3]);
このような感じで、終端の手前まで先頭を変えていけば良いかと。
配列要素番号にあたる数値はタイプが成功した回数で良いかと思います。
ただ、ゲームとしては入力し終えた文字はグレーアウトして、現在入力すべき文字を赤くするなどの仕様の方がよいような気はします。

Re: キーボード入力について

Posted: 2011年6月18日(土) 23:08
by much
次の疑問点です。
a5auさんのおかげでとりあえず、型は完成しました
とりあえず今までのコードを貼っつけておきます。
[cord]
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
char String[ 2 ] ;
char InputChar ;
char typing[] = "target";
// 画面モードの設定
SetGraphMode( 640 , 480 , 16 ) ;

// DXライブラリ初期化処理
if( DxLib_Init() == -1 )
{
// エラーが起きたら直ちに終了
return -1;
}

// 入力される文字を随時画面中央に描画します
{
String[ 1 ] = 0 ;


// ESCキーが押されるか、何らかの内部エラーが発生するまでループする
while( !ProcessMessage() && ( CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) )
{

// 文字入力バッファから文字を取得する
InputChar = GetInputChar( TRUE ) ;

// 操作コード以外の文字入力があった場合のみ表示処理を行う
if( InputChar != 0 && InputChar >= CTRL_CODE_CMP )
{
// 画面の消去
ClearDrawScreen() ;

// 文字の保存
String[ 0 ] = InputChar ;

// 描画
DrawString( 312 , 232 , String , GetColor( 255 , 255 , 255 ) ) ;
if (String[0]==typing[0])
{
int i =0;
while(typing>0) {
typing = typing[i+1];
i++;
}
if (typing[0]==0)
{
char typing[] = "target";     //←の部分がわからない
}
}
DrawString( 312 , 332 , typing , GetColor( 255 , 255 , 255 ) ) ;
}
}
}

// DXライブラリ使用の終了処理
DxLib_End() ;

// ソフトの終了
return 0 ;
}
[/cord]

時間もなく、コピペで結構雑な作りですが、
「←の部分がわからない」部のところは
全文字を打ち終えたとき文字を復活させたいのですが、
charの代入などが、よく分かっていないので誰か教えてください。

Re: キーボード入力について

Posted: 2011年6月18日(土) 23:34
by a5ua
文字列は=では代入できません。strcpy関数を使いましょう
使い方については、ご自分で調べてみてください。

Re: キーボード入力について

Posted: 2011年6月19日(日) 00:23
by much
codeの文字をミスっていました、
問題の部分だけ修正

コード:

// ESCキーが押されるか、何らかの内部エラーが発生するまでループする
while( !ProcessMessage() && ( CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) )
	{
	// 文字入力バッファから文字を取得する
	InputChar = GetInputChar( TRUE ) ;

		// 操作コード以外の文字入力があった場合のみ表示処理を行う
		if( InputChar != 0 && InputChar >= CTRL_CODE_CMP )
			{
				// 画面の消去
				ClearDrawScreen() ;

				// 文字の保存
				String[ 0 ] = InputChar ;

				// 描画
				DrawString( 312 , 232 , String , GetColor( 255 , 255 , 255 )  ) ;
				if (String[0]==typing[0])
				{
					int i =0;
						while(typing[i]>0) {
						typing[i] = typing[i+1];
						 i++;
						}
					if (typing[0]==0)
					{
					strcat(typing,target);			//←この部分
					}
				} 
			DrawString( 312 , 332 , typing , GetColor( 255 , 255 , 255 )  ) ;
			}
		}
	}

	// DXライブラリ使用の終了処理
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}
typing[]・・・実際に打っている文字列
target[]・・・打ち終わった後、追加する文字列

strcat(←この部分)を通過後、終了時に
「Run-Time Check Failure #2 - Stack around the variable 'typing' was corrupted.」
という警告エラーがでます
(最後の行「}」がエラー対象)

なにか良くない表現がありますか?
おそらく「strcat(typing,target);」だと思われます

Re: キーボード入力について

Posted: 2011年6月19日(日) 00:30
by h2so5
target という変数はどこで宣言していますか?

Re: キーボード入力について

Posted: 2011年6月19日(日) 00:36
by much

コード:

#include "DxLib.h"
#include <string.h>

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
	char String[ 2 ] ;
	char InputChar ;
	char typing[] = "target";
	char target[] = "target2";
	// 画面モードの設定
	SetGraphMode( 640 , 480 , 16 ) ;

	// DXライブラリ初期化処理
	if( DxLib_Init() == -1 )
	{
		// エラーが起きたら直ちに終了
		return -1;
	}
	
	// 入力される文字を随時画面中央に描画します
	{
		String[ 1 ] = 0 ;

		// ESCキーが押されるか、何らかの内部エラーが発生するまでループする		//ここから↑の文につながる
上部を省略しただけで、しっかり宣言されてます。
"target2"にしている理由は、target[] とtyping[]比較しやすいような形にしているからです。

Re: キーボード入力について

Posted: 2011年6月19日(日) 01:01
by h2so5
typingには6文字分の領域しかないのに、7文字分の文字列を入れることはできません。
char typing[100] などとして余分に領域を作っておく必要があります。


あと少し余計な話かもしれませんが、文字を多く使うゲームなら部分的に C++のstd::string を使ったほうが楽かもしれません。
std::string なら代入も = でできますし、連結も + でできて分かりやすいです。