キーボードの入力のプログラムについて

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

キーボードの入力のプログラムについて

#1

投稿記事 by north » 10年前

お世話になっております。
前回は初歩的な質問にも関わらず回答してくださりありがとうございました。
今回も初歩的な質問・・・・もしかしたら私が簡単なミスを見落としているだけなのかもしれないのですが
カメラの移動のプログラムを組んでいるのですが該当するキーボードを押してもカメラが移動してくれず何が原因なのかわからず困っております。
下記がそのコードとなります。

input.h

コード:

#ifndef INPUTH
#define INPUTH

class CInput
{
	//int Key1[256];
public:
	CInput();
	~CInput();
	int Key1[256];
	int gpUpdateKey();
};
#endif
input.cpp

コード:

#include "DxLib.h"
#include "Input.h"

CInput::CInput()
{
	for(int i = 0; i < 256; i++)
	{
		Key1[i] = 0;
	}
}
CInput::~CInput()
{}

//--------------------------------------------------------------------
int CInput::gpUpdateKey()
{
	char tmpKey[256]; // 現在のキーの入力状態を格納する
        GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
        for( int ii = 0; ii < 256; ii++ )
		{ 
                if( tmpKey[ii] != 0 )
				{ // i番のキーコードに対応するキーが押されていたら
                        Key1[ii]++;     // 加算
                }
				else 
				{              // 押されていなければ
                        Key1[ii] = 0;   // 0にする
                }
        }
        return 0;
}
main.cpp

コード:

#include "DxLib.h"
#include "Input.h"
#include "Stage.h"
#include "Camera.h"
#include "PlayerModel.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

#define ISLAND (0)
#define MIKU (0)
#define BACK (1)
const int MaxStage = 2;
typedef struct CAMERA_DATA;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
		ChangeWindowMode(TRUE);
		SetGraphMode( 720 , 540 , 16 );	// 画面モードの設定
        DxLib_Init();					// DXライブラリ初期化処理
		CInput* input = new CInput();
		CStage* stage = new CStage();
		CCamera* camera = new CCamera();
		CPlayerModel* playermodel = new CPlayerModel();
		CCamera::CAMERA_DATA CameraInfo;
		CameraInfo = camera->GetCameraParam();
		
		
		SetDrawScreen( DX_SCREEN_BACK );												// 描画先を裏画面にする
		while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0  && input->gpUpdateKey() == 0)
		{
			camera->CameraSet(0.0f, 0.0f,-250.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);	//カメラの初期設定
			stage->LoadFiles(ISLAND,"Stage/batokin_island5.x");							//ステージのモデルの読み込み
			playermodel->LoadFile(MIKU, "PlayerModel/Miku/Miku.mv1");					//キャラクターのモデルの読み込み
			stage->SetStagePos(ISLAND, 0.0f, 0.0f, 0.0f);
			playermodel->SetPlayerPos(0.0f, 0.0f, 0.0f);
			stage->DrawStage(ISLAND);													//ステージの描画
			playermodel->DrawModel(MIKU);												//キャラの描画
			// 裏画面の内容を表画面に反映
			ScreenFlip() ;
			//カメラの移動
			if(input->Key1[KEY_INPUT_RIGHT] == 1)
			{
				CameraInfo.Position.x += 50;
			}
		}
		stage->Unload(ISLAND);
		playermodel->Unload(MIKU);
		delete stage;
		delete playermodel;
        WaitKey();      // キー入力待ち
        DxLib_End();    // DXライブラリ終了処理
        return 0;
}
DXライブラリを使用しており、VisualStudio2008を使用しております。
また、キーボードの入力については下記のサイトを参考にさせていただきました。
http://dixq.net/g/02_09.html
そしてもう1つ質問があるのですが、現在はあくまでもテストということでキーの状態を格納する変数をpublicに置いているのですが、
将来的にはprivateに置いて下手にアクセスされないようにしたいと思っております。
そのような場合はどのように修正したらよろしいでしょうか?
最初はprivateにおいてやっていたのですがmainからInputクラスにキーの状態をうまく受け渡す方法が思いつかずとりあえず現在のような形にしております。
上記2点をご教授して頂けたらと思います。
どうかよろしくお願い致します。

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

Re: キーボードの入力のプログラムについて

#2

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

north さんが書きました:カメラの移動のプログラムを組んでいるのですが該当するキーボードを押してもカメラが移動してくれず何が原因なのかわからず困っております。
CCameraが構造体の受け渡しについてに書かれているコードだと仮定した場合、
45行目で座標を変化させても38行目で上書きされるので、意味ないと思います。
north さんが書きました:そしてもう1つ質問があるのですが、現在はあくまでもテストということでキーの状態を格納する変数をpublicに置いているのですが、
将来的にはprivateに置いて下手にアクセスされないようにしたいと思っております。
そのような場合はどのように修正したらよろしいでしょうか?
変数はprivateにして、指定したキーの入力の状態を返すpublicなメンバ関数を作るのがいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

kry

Re: キーボードの入力のプログラムについて

#3

投稿記事 by kry » 10年前

このプログラムを見る限りinput->Key1の中の値は押している間中は++ですから加算され1,2,3と増えていきますよね。
1と等しいときのみ+50していますから、ほんの一瞬50だけは動いているのではないでしょうか?

変数を隠蔽するのであればprivateにしてpublicな関数を追加すれば問題ないかと思います。

コード:

int GetKey(int num){[tab=30]return Key1[num];[tab=30]} // 

kry

Re: キーボードの入力のプログラムについて

#4

投稿記事 by kry » 10年前

文字化け投稿失礼しました。

みけCATさんのおっしゃるように意味のない行動を行ってる可能性もありますので
併せて確認していくと間違いないかと思われます。

north

Re: キーボードの入力のプログラムについて

#5

投稿記事 by north » 10年前

早速のご回答ありがとうございます。
みけCAT様、kry様のご指摘の通り毎回初期位置を設定しておりましたのでmain.cppを下記のように修正いたしました。

main.cpp

コード:

#include "DxLib.h"
#include "Input.h"
#include "Stage.h"
#include "Camera.h"
#include "PlayerModel.h"
#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;

#define ISLAND (0)
#define MIKU (0)
#define BACK (1)
const int MaxStage = 2;
typedef struct CAMERA_DATA;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
		ChangeWindowMode(TRUE);
		SetGraphMode( 720 , 540 , 16 );	// 画面モードの設定
        DxLib_Init();					// DXライブラリ初期化処理
		CInput* input = new CInput();
		CStage* stage = new CStage();
		CCamera* camera = new CCamera();
		CPlayerModel* playermodel = new CPlayerModel();
		CCamera::CAMERA_DATA CameraInfo;
		CameraInfo = camera->GetCameraParam();
		
		camera->CameraSet(0.0f, 0.0f,-250.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);	//カメラの初期設定
		stage->LoadFiles(ISLAND,"Stage/batokin_island5.x");							//ステージのモデルの読み込み
		playermodel->LoadFile(MIKU, "PlayerModel/Miku/Miku.mv1");					//キャラクターのモデルの読み込み
		stage->SetStagePos(ISLAND, 50.0f, 50.0f, 0.0f);								//ステージのモデルの初期位置
		playermodel->SetPlayerPos(50.0f, 50.0f, 0.0f);								//プレイヤーモデルの初期位置
		
		SetDrawScreen( DX_SCREEN_BACK );												// 描画先を裏画面にする
		while(ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0  && input->gpUpdateKey() == 0)
		{
			//カメラの移動
			if(input->Key1[KEY_INPUT_RIGHT] != 0)
			{
				CameraInfo.Position.x += 50;
			}
			else if(input->Key1[KEY_INPUT_SPACE] != 0)
			{
				break;
			}
			stage->DrawStage(ISLAND);													//ステージの描画
			playermodel->DrawModel(MIKU);												//キャラの描画
			// 裏画面の内容を表画面に反映
			ScreenFlip() ;
			
		}
		stage->Unload(ISLAND);
		playermodel->Unload(MIKU);
		delete stage;
		delete playermodel;
        WaitKey();      // キー入力待ち
        DxLib_End();    // DXライブラリ終了処理
        return 0;
}

コード:

else if(input->Key1[KEY_INPUT_SPACE] != 0)
{
				break;
}
の部分につきましてはちゃんとキーボードの入力が取れているのか調べるために追加いたしました。
キーボードの入力はちゃんととれていることは確認できました。
修正内容としては読み込みの処理と初期位置の設定の処理をwhile文の外にだし1回だけ行うようにし
また、==1だった部分を0以外だったらにしたのですが、それでもカメラの座標が移動してくれません。
まだ、見落としているミスがあるのでしょうか?
何度も申し訳ありません。
変数の隠ぺいにつきましてはこちらのミスが修正できしだい頂いたアドバイスを基に取り掛かろうと思います。

>kry様
関数まで書いてくださりありがとうございます。
1つご質問があるのですが、[tab=30:3iukc3gm]が何をしているのかわからず、
もしよろしければご解説をお願いしてもよろしいでしょうか?

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

Re: キーボードの入力のプログラムについて

#6

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

north さんが書きました:修正内容としては読み込みの処理と初期位置の設定の処理をwhile文の外にだし1回だけ行うようにし
また、==1だった部分を0以外だったらにしたのですが、それでもカメラの座標が移動してくれません。
まだ、見落としているミスがあるのでしょうか?
cameraが持っている座標を更新しても、
それをDXライブラリのAPI(SetCameraPositionAndTargetAndUpVecなど)を呼んでDXライブラリ側に反映させなければ、
表示に用いられるカメラの位置は動かないと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

north

Re: キーボードの入力のプログラムについて

#7

投稿記事 by north » 10年前

早速のご返信ありがとうございます。
みけCAT さんが書きました:
north さんが書きました: cameraが持っている座標を更新しても、
それをDXライブラリのAPI(SetCameraPositionAndTargetAndUpVecなど)を呼んでDXライブラリ側に反映させなければ、
表示に用いられるカメラの位置は動かないと思います。
カメラの座標を更新するのに上記の関数が必要というのは知りませんでした。私の知識不足でした。
ありがとうございます。無事に動くようになりました。
カメラの座標等を更新する度にAPI(SetCameraPositionAndTargetAndUpVec)を呼び出さないといけないようでしたら
こちらを別の関数に移してしまった方が効率的にはいいですかね?
下記が現在のカメラのコードとなります

コード:

#include "Camera.h"
#define PI 3.141592654

CCamera::CCamera()
{
	memset(&tCameraData, 0, sizeof(tCameraData));
	tCameraData.Position.z = -285.0f;
	tCameraData.Angley = 1.0f;
}
//---------------------------------------------------------
CCamera::~CCamera()
{}

//---------------------------------------------------------
void CCamera::CameraSet(float PosX, float PosY, float PosZ, float WatchX, float WatchY, float WatchZ, float AngleX, float AngleY, float AngleZ)
{
	tCameraData.Position.x = PosX;
	tCameraData.Position.y = PosY;
	tCameraData.Position.z = PosZ;
	tCameraData.WatchX = WatchX;
	tCameraData.WatchY = WatchY;
	tCameraData.WatchZ = WatchZ;
	tCameraData.Anglex = AngleX;
	tCameraData.Angley = AngleY;
	tCameraData.Anglez = AngleZ;
	SetCameraPositionAndTargetAndUpVec(VGet(tCameraData.Position.x, tCameraData.Position.y, tCameraData.Position.z), 
		VGet(tCameraData.WatchX, tCameraData.WatchY, tCameraData.WatchZ), 
		VGet(tCameraData.Anglex, tCameraData.Angley, tCameraData.Anglez));
	SetCameraNearFar(1, 1000);
	SetupCamera_Perspective(PI/4);
}

CCamera::CAMERA_DATA CCamera::GetCameraParam()
{
	return tCameraData;
}
上記の
SetCameraPositionAndTargetAndUpVec関数
SetCameraNearFar関数
SetupCamera_Perspective関数
の上記3つを別の関数に移してしまおうと思っているのですがもし他に良い方法がありましたらご教授願いますでしょうか?
DXライブラリのカメラの仕様に関してまだまだ知識不足の部分等があるため間違った解釈をしてしまっているかもしれませんが
そこもありましたらご指摘していただけると今後のためになりますのでどうかよろしくお願い致します。

閉鎖

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