キー入力に応じて処理をする関数を作りたいです

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ふらっと

キー入力に応じて処理をする関数を作りたいです

#1

投稿記事 by ふらっと » 14年前

キー入力に応じた処理の部分を関数にしたいです。

例えば、新・ゲームプログラミングの館さんで紹介されている
3.1 キーの入力に応じてキャラを移動させる
ではgpUpdateKey関数をメインのソースファイルの初めに書いて、計算部分もメインループの中に直接書いてあるのを

コード:

if( Key[ KEY_INPUT_RIGHT ] >= 1 ){ // 右キーが押されていたら
			x++;                       // 右へ移動
		}
		if( Key[ KEY_INPUT_DOWN  ] >= 1 ){ // 下キーが押されていたら
			y++;                       // 下へ移動
		}
		if( Key[ KEY_INPUT_LEFT  ] >= 1 ){ // 左キーが押されていたら
			x--;                       // 左へ移動
		}
		if( Key[ KEY_INPUT_UP    ] >= 1 ){ // 上キーが押されていたら
			y--;                       // 上へ移動
		}
ここを関数化して、別のソースファイルに書いて、メインのループではそれを関数として呼び出すだけにしたいということです。
そうすれば違う計算(例えば、キー入力に応じて違う画像を描画する)の時に応用が利くし、メインのループ内が長くならずにすむ。
と素人なりに考えています。

自分でも、配列の変数Keyのポインタをその計算関数に引数として入力状態を渡そうとしたり、いろいろしてみましたが
どうも上手くいきません。

要するに、やりたいことは、計算関数から、キー入力状態を格納してある変数Keyを参照して、それに応じて処理をしたいということです。

よろしくお願いします。

開発環境
Visual C++ 2008
Windows Vista

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#2

投稿記事 by beatle » 14年前

ふらっと さんが書きました:自分でも、配列の変数Keyのポインタをその計算関数に引数として入力状態を渡そうとしたり、いろいろしてみましたが
どうも上手くいきません。

要するに、やりたいことは、計算関数から、キー入力状態を格納してある変数Keyを参照して、それに応じて処理をしたいということです。
ふらっとさんが「いろいろしてみ」た結果のソースコードの例を載せていただくと、それに沿った回答ができるかと思います。

基本的に、配列を関数に渡すには、次のようにします。

コード:

void f(int* array_of_int, int n)
{
    for (int i = 0; i < n; ++i)
    {
        if (array_of_int[i] < -1)
        {
            ...
        }
    }
}

int main()
{
    int x[128];
    f(x, 128);
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#3

投稿記事 by softya(ソフト屋) » 14年前

前の質問を放置しないようにお願いします。
「3種類のエラーについて質問です • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=10384
ふらっと さんが書きました: 要するに、やりたいことは、計算関数から、キー入力状態を格納してある変数Keyを参照して、それに応じて処理をしたいということです。
もう少し具体的な入力と出力を考えないと関数化出来ません。
入力の一つはキー入力状態の配列として、他にはどんな入力がありますか?
それと出力はどんな形で返しますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#4

投稿記事 by ふらっと » 14年前

softya(ソフト屋)さん
回答ありがとうございます。

すみません
そもそも、具体的な入力と出力というのがよく理解できていないみたいです。
入力はキーボードとかマウスとかの事ですか?
だとしたらキーボードからの入力だけで大丈夫です。
今練習で作っているじゃんけんゲームで言うなら、左キーを押したらぐー、下キーを押したらちょき、右キーを押したらぱーといったことです。

出力がどんな形
というのはどういったことなのか教えてもらえませんか?
左キーが押されたら、ぐーの画像を描画して、プレイヤーの手はぐーだよという情報(例えばintで1)を返すの様なことですか?

初心者すぎて本当に申し訳ないです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#5

投稿記事 by softya(ソフト屋) » 14年前

ごめんなさい分かりづらかったですね。
関数の入出力です。

関数は大雑把に書くと
(1)入力
(2)処理
(3)出力
から構成されます。
(1)と(3)に於いて、どんな変数や値を入力しどんな値をどんな形で出力しますか?って事です。
ここがはっきりしないと関数の処理である(2)は決まりません。

[補足]
それと
ここを関数化して、別のソースファイルに書いて、メインのループではそれを関数として呼び出すだけにしたいということです。
そうすれば違う計算(例えば、キー入力に応じて違う画像を描画する)の時に応用が利くし、メインのループ内が長くならずにすむ。
と素人なりに考えています。
と汎用性を関数に持たせるなら汎用性のある値を便利な形で返す必要があります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#6

投稿記事 by beatle » 14年前

ふらっと さんが書きました: ここを関数化して、別のソースファイルに書いて、メインのループではそれを関数として呼び出すだけにしたいということです。
そうすれば違う計算(例えば、キー入力に応じて違う画像を描画する)の時に応用が利くし、メインのループ内が長くならずにすむ。
良い考え方だと思います。コードの再利用は重要ですね。
しかし、
ふらっと さんが書きました: 左キーが押されたら、ぐーの画像を描画して、プレイヤーの手はぐーだよという情報(例えばintで1)を返す
というように、関数の中身で画像を描画してしまうと、違う計算のときに応用が利かなくなってしまいませんか?

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#7

投稿記事 by ふらっと » 14年前

お二方回答ありがとうございます。

私自身頭がごっちゃになっていて分かりにくい質問をしてしまいました。
新・ゲームプログラミングの館さんのサンプルで言うと

コード:

int Key[256]; // キーが押されているフレーム数を格納する

// キーの入力状態を更新する
int gpUpdateKey(){
	char tmpKey[256]; // 現在のキーの入力状態を格納する
	GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
	for( int i=0; i<256; i++ ){ 
		if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
			Key[i]++;     // 加算
		} else {              // 押されていなければ
			Key[i] = 0;   // 0にする
		}
	}
	return 0;
}
これをメインのソースファイルの初めに書いておけば常にキー入力状態が取得されているということですよね?

それで
じゃんけんの関数なら
「そのキー入力状態を受けて
左キーが押されたら1を返す」
の部分を関数化したいです
だから、入力はKey[ KEY_INPUT_LEFT ]や Key[ KEY_INPUT_DOWN ](?)

それが
「Zキーが押されていたら、ある画像を描画したい」
という処理をしたければ、それをまた別の関数として作るようにする
ということです

処理をする関数に汎用性を持たせたいのではなく、gpUpdateKey関数で取得した情報を受けて
それが左キーが押された(ぐー)なら1を返すとか、Zキーが押された(描画済み)なら1を返すとか
返す値はその関数に合わせて自分で1や2や3や4をあてていけばいいのでは?と思っていますが・・・

この質問自体も分かりにくいですね;
申し訳ないです。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#8

投稿記事 by beatle » 14年前

ふらっとさんの質問が僕にはよく分からないので、叩き台として関数を定義してみます。ふらっとさんが作りたい関数はどのようなものか、以下の関数との違いを教えてください。

コード:

int f(int* keys)
{
    if (keys[KEY_INPUT_UP] > 0)
    {
        return 1;
    }
    else if (keys[KEY_INPUT_DOWN] > 0)
    {
        return 2;
    }
    else if (keys[KEY_INPUT_LEFT] > 0)
    {
        return 3;
    }
    else if (keys[KEY_INPUT_RIGHT] > 0)
    {
        return 4;
    }
    return 0;
}
使用側

コード:

int key = f(Key);
if (key == 1)
{
    // do something
}
else if (key == 2)
{
    // do something
}

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#9

投稿記事 by ふらっと » 14年前

beatle さん

ありがとうございます。
そうです。
要するに
int f(int* keys)
ここの部分について聞きたかったんです。
このようにポインタを渡して処理しようと思ったけれど、上手くいかなかった。
ということを言いたかったんです。
回りくどいというか、意味の通じないというか、変な質問をしてしまいました。

ただ、2つ分からないところがあります
使用側では
f(key)
と、アドレスを渡していませんが、これで良いのですか?
それと、keysはどこから出てきたポインタですか?

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#10

投稿記事 by beatle » 14年前

ふらっと さんが書きました:ただ、2つ分からないところがあります
使用側では
f(key)
と、アドレスを渡していませんが、これで良いのですか?
それと、keysはどこから出てきたポインタですか?
よく見てください。fに渡しているのは、先頭が大文字の「Key」であって「key」ではありません。
C言語では、配列名をそのまま書くと、配列の先頭要素へのポインタを表すということになっています。ですから、
Key

&Key[0]
は同じ意味になります。

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#11

投稿記事 by ふらっと » 14年前

あ。
見間違ってました。
ということは、使用側ではKeyの先頭のポインタを渡して
関数側ではそれをkeysという名前のポインタとして受け取る
ということですね?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#12

投稿記事 by softya(ソフト屋) » 14年前

こうするのも方法です。

コード:

//-------------------------
//	key_control.h
//-------------------------

#ifndef KEY_CONTROL_H
#define KEY_CONTROL_H

//	上下左右キーの方向取得
int GetKeyMoveDir(void);

//	上下左右キーの方向情報
enum KeyMoveDir_e {
	KEY_MOVE_DIR_NO,

	KEY_MOVE_DIR_UP,
	KEY_MOVE_DIR_DOWN,
	KEY_MOVE_DIR_LEFT,
	KEY_MOVE_DIR_RIGHT,
};

#endif

//-------------------------
//	key_control.cpp
//-------------------------

#include "DxLib.h"
#include "key_control.h"

static int gpUpdateKey();

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

//	上下左右キーの方向取得
//	ただし、左上などの同時入力は検知しない。
KeyMoveDir_e GetKeyMoveDir(void)
{
    if (Key[KEY_INPUT_UP] > 0)
    {
        return KEY_MOVE_DIR_UP;
    }
    else if (Key[KEY_INPUT_DOWN] > 0)
    {
        return KEY_MOVE_DIR_DOWN;
    }
    else if (Key[KEY_INPUT_LEFT] > 0)
    {
        return KEY_MOVE_DIR_LEFT;
    }
    else if (Key[KEY_INPUT_RIGHT] > 0)
    {
        return KEY_MOVE_DIR_RIGHT;
    }
    
    return KEY_MOVE_DIR_NO;
}

//-------------------------
//	xxx.cpp
//-------------------------

#include "DxLib.h"
#include "key_control.h"

//	呼び出し例
void xxx(void)
{
	//	上下左右キーの方向で分岐
	//	問題点:せっかく関数を分けたのにあまり変わっていない気がする。
	switch( GetKeyMoveDir() ) {
	case KEY_MOVE_DIR_UP:
		//	上の処理
		break;
	case KEY_MOVE_DIR_DOWN:
		//	下の処理
		break;
	case KEY_MOVE_DIR_LEFT:
		//	左の処理
		break;
	case KEY_MOVE_DIR_RIGHT:
		//	右の処理
		break;
	}
}
コメントにも書きましたが、せっかく関数を分けたのにあまり変わっていない気がするのが問題点でしょうか。
GetKeyMoveDirの場合の入力はKey、出力はKeyMoveDir_eです。
beatle さんの処理でもそれは同じです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#13

投稿記事 by ふらっと » 14年前

ありがとうございます。

とりあえず試してみます。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#14

投稿記事 by beatle » 14年前

ふらっと さんが書きました:あ。
見間違ってました。
ということは、使用側ではKeyの先頭のポインタを渡して
関数側ではそれをkeysという名前のポインタとして受け取る
ということですね?
はい、そういうことです。No.2に書いてあるのも同じことです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#15

投稿記事 by softya(ソフト屋) » 14年前

訂正。ごめんなさい間違いでした。

コード:

//-------------------------
//	key_control.h
//-------------------------

#ifndef KEY_CONTROL_H
#define KEY_CONTROL_H

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

//	上下左右キーの方向取得
int GetKeyMoveDir(void);

//	上下左右キーの方向情報
enum KeyMoveDir_e {
	KEY_MOVE_DIR_NO,

	KEY_MOVE_DIR_UP,
	KEY_MOVE_DIR_DOWN,
	KEY_MOVE_DIR_LEFT,
	KEY_MOVE_DIR_RIGHT,
};

#endif

//-------------------------
//	key_control.cpp
//-------------------------

#include "DxLib.h"
#include "key_control.h"


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

//	上下左右キーの方向取得
//	ただし、左上などの同時入力は検知しない。
KeyMoveDir_e GetKeyMoveDir(void)
{
    if (Key[KEY_INPUT_UP] > 0)
    {
        return KEY_MOVE_DIR_UP;
    }
    else if (Key[KEY_INPUT_DOWN] > 0)
    {
        return KEY_MOVE_DIR_DOWN;
    }
    else if (Key[KEY_INPUT_LEFT] > 0)
    {
        return KEY_MOVE_DIR_LEFT;
    }
    else if (Key[KEY_INPUT_RIGHT] > 0)
    {
        return KEY_MOVE_DIR_RIGHT;
    }
    
    return KEY_MOVE_DIR_NO;
}

//-------------------------
//	xxx.cpp
//-------------------------

//	呼び出し例
void xxx(void)
{
	//	上下左右キーの方向で分岐
	//	問題点:せっかく関数を分けたのにあまり変わっていない気がする。
	switch( GetKeyMoveDir() ) {
	case KEY_MOVE_DIR_UP:
		//	上の処理
		break;
	case KEY_MOVE_DIR_DOWN:
		//	下の処理
		break;
	case KEY_MOVE_DIR_LEFT:
		//	左の処理
		break;
	case KEY_MOVE_DIR_RIGHT:
		//	右の処理
		break;
	}
}

by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#16

投稿記事 by ふらっと » 14年前

ありがとうございました。
質問した部分に関して出来るには出来ました。

じゃんけんゲームといってもかなり難しいですね。
エラー・警告無く実行出来るんですが、また問題点がいくつか出てきました。

サンプルプログラミングの館のジャンケンのプログラムを見てみたんですが
自分の組んでみたものと全然違う上に、理解できないところがありすぎて
正直ゲームプログラミングのイメージと実際の難しさのギャップを感じています。

また、質問することになると思うのでその時はよろしくお願いします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#17

投稿記事 by softya(ソフト屋) » 14年前

解決してよかったです。
で、事情がない限りルールとして解決したコードを提示して貰うことになっています。 http://dixq.net/board/board.html

以下引用
また、解決した時は、「解決しました」とだけ言って去らず、ソースコードや解決した方法を明記して下さい。
同じ事で困っている人の為に過去ログに有用な情報を残すようお願いします
よろしくおねがいします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#18

投稿記事 by ふらっと » 14年前

しっかりルール読んでなくてすみませんでした。

全体としては上手くいってませんが、この部分の処理自体は上手くいっている・・・はずです。
この部分も、もっと効率よくするために変更になる可能性もありますが

それといらない部分は省いています。

コード:

// キー入力に応じて数値を返す
int Key_Input(int* keys){
		
	if( keys[KEY_INPUT_LEFT] == 1 ){ // 左キーが押されたら
		return 0; //0を返す(ぐー)
	}
	if( keys[KEY_INPUT_DOWN] == 1 ){ // 下キーが押されたら
		return 1; // 1を返す(ちょき)
	}

	if( keys[KEY_INPUT_RIGHT] == 1 ){ // 右キーが押されたら
		return 2; // 2を返す(ぱー)
	}
	
		return -1;
}
呼び出し側

コード:

Player_Hand = Key_Input( Key );

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#19

投稿記事 by softya(ソフト屋) » 14年前

返す値は、私が書いたように数値そのものではなくenumやconst int定義した値などを使われることをお勧めします。
理由は名前で値の意味が分かるからです。これはある程度大きなプログラムを書くためには必要なテクニックです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#20

投稿記事 by ふらっと » 14年前

確かにそうですね。
今後enumで書くことにします。
アドバイスありがとうございます。

それと、最後に聞いておきたいんですが
自分で組んだ現状のプログラムを見てもらいたい場合、ソースコードを全てコピーして貼って質問しても大丈夫でしょうか?
だいぶ長くなってしまうと思いますが。

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#21

投稿記事 by beatle » 14年前

ソース全体が大きすぎるなら、ダウンロードして実行可能なように必要なファイルをすべてフォルダにまとめ、圧縮して添付するのがいいと思います。
そのうえで、回答を得たい部分のソースを貼りつけて質問してください。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#22

投稿記事 by softya(ソフト屋) » 14年前

ふらっと さんが書きました:それと、最後に聞いておきたいんですが
自分で組んだ現状のプログラムを見てもらいたい場合、ソースコードを全てコピーして貼って質問しても大丈夫でしょうか?
だいぶ長くなってしまうと思いますが。
ここに会員登録するとファイル添付が可能になりますので、ZIP圧縮などで添付して下さい。
このページの下の方に会員登録のリンクがあると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 15年前
住所: 北海道札幌市
連絡を取る:

Re: キー入力に応じて処理をする関数を作りたいです

#23

投稿記事 by Dixq (管理人) » 14年前

よければこちらも参考にして下さい。
http://dixq.net/g/d_04.html
こうすればどこからでも気軽にキーの入力状態が取得できます。

ふらっと

Re: キー入力に応じて処理をする関数を作りたいです

#24

投稿記事 by ふらっと » 14年前

おぉ
これは良いですね!
なんでしっかり見ていなかったんだろう。

ありがとうございました。

閉鎖

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