ページ 1 / 1
キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 11:28
by ふらっと
キー入力に応じた処理の部分を関数にしたいです。
例えば、新・ゲームプログラミングの館さんで紹介されている
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
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 11:49
by beatle
ふらっと さんが書きました:自分でも、配列の変数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);
}
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 12:57
by softya(ソフト屋)
前の質問を放置しないようにお願いします。
「3種類のエラーについて質問です • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=10384
ふらっと さんが書きました:
要するに、やりたいことは、計算関数から、キー入力状態を格納してある変数Keyを参照して、それに応じて処理をしたいということです。
もう少し具体的な入力と出力を考えないと関数化出来ません。
入力の一つはキー入力状態の配列として、他にはどんな入力がありますか?
それと出力はどんな形で返しますか?
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 13:25
by ふらっと
softya(ソフト屋)さん
回答ありがとうございます。
すみません
そもそも、具体的な入力と出力というのがよく理解できていないみたいです。
入力はキーボードとかマウスとかの事ですか?
だとしたらキーボードからの入力だけで大丈夫です。
今練習で作っているじゃんけんゲームで言うなら、左キーを押したらぐー、下キーを押したらちょき、右キーを押したらぱーといったことです。
出力がどんな形
というのはどういったことなのか教えてもらえませんか?
左キーが押されたら、ぐーの画像を描画して、プレイヤーの手はぐーだよという情報(例えばintで1)を返すの様なことですか?
初心者すぎて本当に申し訳ないです。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 13:35
by softya(ソフト屋)
ごめんなさい分かりづらかったですね。
関数の入出力です。
関数は大雑把に書くと
(1)入力
(2)処理
(3)出力
から構成されます。
(1)と(3)に於いて、どんな変数や値を入力しどんな値をどんな形で出力しますか?って事です。
ここがはっきりしないと関数の処理である(2)は決まりません。
[補足]
それと
ここを関数化して、別のソースファイルに書いて、メインのループではそれを関数として呼び出すだけにしたいということです。
そうすれば違う計算(例えば、キー入力に応じて違う画像を描画する)の時に応用が利くし、メインのループ内が長くならずにすむ。
と素人なりに考えています。
と汎用性を関数に持たせるなら汎用性のある値を便利な形で返す必要があります。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 13:40
by beatle
ふらっと さんが書きました:
ここを関数化して、別のソースファイルに書いて、メインのループではそれを関数として呼び出すだけにしたいということです。
そうすれば違う計算(例えば、キー入力に応じて違う画像を描画する)の時に応用が利くし、メインのループ内が長くならずにすむ。
良い考え方だと思います。コードの再利用は重要ですね。
しかし、
ふらっと さんが書きました:
左キーが押されたら、ぐーの画像を描画して、プレイヤーの手はぐーだよという情報(例えばintで1)を返す
というように、関数の中身で画像を描画してしまうと、違う計算のときに応用が利かなくなってしまいませんか?
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 14:13
by ふらっと
お二方回答ありがとうございます。
私自身頭がごっちゃになっていて分かりにくい質問をしてしまいました。
新・ゲームプログラミングの館さんのサンプルで言うと
コード:
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をあてていけばいいのでは?と思っていますが・・・
この質問自体も分かりにくいですね;
申し訳ないです。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 14:32
by beatle
ふらっとさんの質問が僕にはよく分からないので、叩き台として関数を定義してみます。ふらっとさんが作りたい関数はどのようなものか、以下の関数との違いを教えてください。
コード:
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: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 14:48
by ふらっと
beatle さん
ありがとうございます。
そうです。
要するに
int f(int* keys)
ここの部分について聞きたかったんです。
このようにポインタを渡して処理しようと思ったけれど、上手くいかなかった。
ということを言いたかったんです。
回りくどいというか、意味の通じないというか、変な質問をしてしまいました。
ただ、2つ分からないところがあります
使用側では
f(key)
と、アドレスを渡していませんが、これで良いのですか?
それと、keysはどこから出てきたポインタですか?
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 14:52
by beatle
ふらっと さんが書きました:ただ、2つ分からないところがあります
使用側では
f(key)
と、アドレスを渡していませんが、これで良いのですか?
それと、keysはどこから出てきたポインタですか?
よく見てください。fに渡しているのは、先頭が大文字の「Key」であって「key」ではありません。
C言語では、配列名をそのまま書くと、配列の先頭要素へのポインタを表すということになっています。ですから、
Key
と
&Key[0]
は同じ意味になります。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 15:03
by ふらっと
あ。
見間違ってました。
ということは、使用側ではKeyの先頭のポインタを渡して
関数側ではそれをkeysという名前のポインタとして受け取る
ということですね?
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 15:07
by softya(ソフト屋)
こうするのも方法です。
コード:
//-------------------------
// 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 さんの処理でもそれは同じです。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 15:21
by ふらっと
ありがとうございます。
とりあえず試してみます。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 15:24
by beatle
ふらっと さんが書きました:あ。
見間違ってました。
ということは、使用側ではKeyの先頭のポインタを渡して
関数側ではそれをkeysという名前のポインタとして受け取る
ということですね?
はい、そういうことです。No.2に書いてあるのも同じことです。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 15:25
by softya(ソフト屋)
訂正。ごめんなさい間違いでした。
コード:
//-------------------------
// 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;
}
}
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 17:19
by ふらっと
ありがとうございました。
質問した部分に関して出来るには出来ました。
じゃんけんゲームといってもかなり難しいですね。
エラー・警告無く実行出来るんですが、また問題点がいくつか出てきました。
サンプルプログラミングの館のジャンケンのプログラムを見てみたんですが
自分の組んでみたものと全然違う上に、理解できないところがありすぎて
正直ゲームプログラミングのイメージと実際の難しさのギャップを感じています。
また、質問することになると思うのでその時はよろしくお願いします。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 17:25
by softya(ソフト屋)
解決してよかったです。
で、事情がない限りルールとして解決したコードを提示して貰うことになっています。
http://dixq.net/board/board.html
以下引用
また、解決した時は、「解決しました」とだけ言って去らず、ソースコードや解決した方法を明記して下さい。
同じ事で困っている人の為に過去ログに有用な情報を残すようお願いします
よろしくおねがいします。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 17:38
by ふらっと
しっかりルール読んでなくてすみませんでした。
全体としては上手くいってませんが、この部分の処理自体は上手くいっている・・・はずです。
この部分も、もっと効率よくするために変更になる可能性もありますが
それといらない部分は省いています。
コード:
// キー入力に応じて数値を返す
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 );
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 17:44
by softya(ソフト屋)
返す値は、私が書いたように数値そのものではなくenumやconst int定義した値などを使われることをお勧めします。
理由は名前で値の意味が分かるからです。これはある程度大きなプログラムを書くためには必要なテクニックです。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 17:48
by ふらっと
確かにそうですね。
今後enumで書くことにします。
アドバイスありがとうございます。
それと、最後に聞いておきたいんですが
自分で組んだ現状のプログラムを見てもらいたい場合、ソースコードを全てコピーして貼って質問しても大丈夫でしょうか?
だいぶ長くなってしまうと思いますが。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 17:52
by beatle
ソース全体が大きすぎるなら、ダウンロードして実行可能なように必要なファイルをすべてフォルダにまとめ、圧縮して添付するのがいいと思います。
そのうえで、回答を得たい部分のソースを貼りつけて質問してください。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 17:53
by softya(ソフト屋)
ふらっと さんが書きました:それと、最後に聞いておきたいんですが
自分で組んだ現状のプログラムを見てもらいたい場合、ソースコードを全てコピーして貼って質問しても大丈夫でしょうか?
だいぶ長くなってしまうと思いますが。
ここに会員登録するとファイル添付が可能になりますので、ZIP圧縮などで添付して下さい。
このページの下の方に会員登録のリンクがあると思います。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月23日(金) 23:47
by Dixq (管理人)
よければこちらも参考にして下さい。
http://dixq.net/g/d_04.html
こうすればどこからでも気軽にキーの入力状態が取得できます。
Re: キー入力に応じて処理をする関数を作りたいです
Posted: 2012年3月24日(土) 22:10
by ふらっと
おぉ
これは良いですね!
なんでしっかり見ていなかったんだろう。
ありがとうございました。