画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Ouxiy
記事: 173
登録日時: 4年前

画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#1

投稿記事 by Ouxiy » 4年前

画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたいのですが、
今の(自分と何人かの方の協力で出来た)コードから展開するにはどうすればいいでしょうか。
個人的には、3D っぽくなるように座標を前もって指定して、その上だけを動くように
すればいいと考えました。ですが、どのサイトを見てもそのようなやり方が出来そうな方法が書いておらず、出来るとしても行う方法がわからずに止まっています。

座標Eに関しては真ん中をEとして表せていると思います。
あとの残りは斜線っぽい感じの座標で、座標を指定して、そこにキャラが移動する形になると考えています。
画像

イメージとして以下のようにドットキャラを置きます。
画像
以下は全体のコードです。初期値として座標nx,ny=(2,2)は中心Eを表しています。

コード:

#include "DxLib.h"



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;
}

// プログラムは WinMain から始まります
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	SetGraphMode(1600, 680, 32); // ウィンドウの大きさを指定
	ChangeWindowMode(TRUE);



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



	//1. 3x3マスの2次元配列
	int idou[5][5] = {
	{1,1,1,1,1 },
	{1,0,0,0,1 },
	{1,0,0,0,1 },
	{1,0,0,0,1 },
	{1,1,1,1,1 },
	};


	//グラフィックハンドル格納用配列
	int gh[12];
	LoadDivGraph("charall.png", 12, 3, 4, 49, 66, gh);//画像読み込み

	
	int nx = 2, ny = 2; // 最初のキャラのX座をdxとY座標をdyである。配列の真ん中の0を最初の座標としたため(2,2)となる



	SetDrawScreen(DX_SCREEN_BACK);
	while (ProcessMessage() == 0 && gpUpdateKey() == 0) {
		int playerphoto = gh[5];//ループに入れてしまうと移動した際もずっとそこにあるんでダメ。(2,2)から存在して、ずっとあるようにするためループ内に書いた。
		//DrawGraph(50 * nx, 50 * ny, playerphoto, FALSE);//一瞬ではなくずっとあるようにするためにループに書いた。

		// カーソルキーの右が押されている
		if (Key[KEY_INPUT_RIGHT] == 1)
			if (idou[ny + 0][nx + 1] == 0) { //移動しようとする先が空いていれば
			//移動可能
				nx = nx + 1; //移動
				playerphoto = gh[6];
			}

		if (Key[KEY_INPUT_LEFT] == 1)
			if (idou[ny + 0][nx - 1] == 0) { //移動しようとする先が空いていれば
			//移動可能
				nx = nx - 1; //移動
				playerphoto = gh[4];
			}

		if (Key[KEY_INPUT_UP] == 1)
			if (idou[ny - 1][nx + 0] == 0) { //移動しようとする先が空いていれば
			//移動可能
				ny = ny - 1; //移動
				playerphoto = gh[2];
			}
		if (Key[KEY_INPUT_DOWN] == 1)
			if (idou[ny + 1][nx + 0] == 0) { //移動しようとする先が空いていれば
			//移動可能
				ny = ny + 1; //移動
				playerphoto = gh[8];
			}
		
		//ScreenFlip();
		// 画面をクリア
		ClearDrawScreen();

		DrawGraph(50 * nx, 50 * ny, playerphoto, FALSE);
		ScreenFlip();
	}
	


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

	return 0;                // ソフトの終了 

}

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

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#2

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

Ouxiy さんが書きました:
4年前
3D っぽくなるように座標を前もって指定して
指定した座標を配列に入れておきます。
(例として適当な値を入れてあるが、きちんと計算した方がいいかも?)

コード:

int drawCoords[5][5][2] = {
	{{0}}, // どうせここには来ない
	{{0, 0}, {60,  60}, {100,  60}, {140,  60}, {0, 0}},
	{{0, 0}, {50, 100}, {100, 100}, {150, 100}, {0, 0}},
	{{0, 0}, {40, 160}, {100, 160}, {160, 160}, {0, 0}},
	{{0}} // どうせここには来ない
};
Ouxiy さんが書きました:
4年前
その上だけを動くように
用意した配列から座標を取ってきて描画します。

コード:

DrawGraph(drawCoords[ny][nx][0], drawCoords[ny][nx][1], playerphoto, FALSE);
全体のコードです。

コード:

#include "DxLib.h"



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;
}

// プログラムは WinMain から始まります
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	SetGraphMode(1600, 680, 32); // ウィンドウの大きさを指定
	ChangeWindowMode(TRUE);



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



	//1. 3x3マスの2次元配列
	int idou[5][5] = {
	{1,1,1,1,1 },
	{1,0,0,0,1 },
	{1,0,0,0,1 },
	{1,0,0,0,1 },
	{1,1,1,1,1 },
	};

	// 描画する座標の配列
	int drawCoords[5][5][2] = {
		{{0}}, // どうせここには来ない
		{{0, 0}, {60,  60}, {100,  60}, {140,  60}, {0, 0}},
		{{0, 0}, {50, 100}, {100, 100}, {150, 100}, {0, 0}},
		{{0, 0}, {40, 160}, {100, 160}, {160, 160}, {0, 0}},
		{{0}} // どうせここには来ない
	};

	//グラフィックハンドル格納用配列
	int gh[12];
	LoadDivGraph("charall.png", 12, 3, 4, 49, 66, gh);//画像読み込み

	
	int nx = 2, ny = 2; // 最初のキャラのX座をdxとY座標をdyである。配列の真ん中の0を最初の座標としたため(2,2)となる



	SetDrawScreen(DX_SCREEN_BACK);
	while (ProcessMessage() == 0 && gpUpdateKey() == 0) {
		int playerphoto = gh[5];//ループに入れてしまうと移動した際もずっとそこにあるんでダメ。(2,2)から存在して、ずっとあるようにするためループ内に書いた。
		//DrawGraph(50 * nx, 50 * ny, playerphoto, FALSE);//一瞬ではなくずっとあるようにするためにループに書いた。

		// カーソルキーの右が押されている
		if (Key[KEY_INPUT_RIGHT] == 1)
			if (idou[ny + 0][nx + 1] == 0) { //移動しようとする先が空いていれば
			//移動可能
				nx = nx + 1; //移動
				playerphoto = gh[6];
			}

		if (Key[KEY_INPUT_LEFT] == 1)
			if (idou[ny + 0][nx - 1] == 0) { //移動しようとする先が空いていれば
			//移動可能
				nx = nx - 1; //移動
				playerphoto = gh[4];
			}

		if (Key[KEY_INPUT_UP] == 1)
			if (idou[ny - 1][nx + 0] == 0) { //移動しようとする先が空いていれば
			//移動可能
				ny = ny - 1; //移動
				playerphoto = gh[2];
			}
		if (Key[KEY_INPUT_DOWN] == 1)
			if (idou[ny + 1][nx + 0] == 0) { //移動しようとする先が空いていれば
			//移動可能
				ny = ny + 1; //移動
				playerphoto = gh[8];
			}
		
		//ScreenFlip();
		// 画面をクリア
		ClearDrawScreen();

		DrawGraph(drawCoords[ny][nx][0], drawCoords[ny][nx][1], playerphoto, FALSE);
		ScreenFlip();
	}
	


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

	return 0;                // ソフトの終了 

}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#3

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

Ouxiy さんが書きました:
4年前
座標Eに関しては真ん中をEとして表せていると思います。
あとの残りは斜線っぽい感じの座標で、座標を指定して、そこにキャラが移動する形になると考えています。
[img​]https://mail.google.com/mail/u/0?ui=2&ik=65460f62c3&attid=0.1&permmsgid=msg-f:1642577236477548528&th=16cb9b4b386317f0&view=att&disp=safe[/img]

イメージとして以下のようにドットキャラを置きます。
[img​]https://mail.google.com/mail/u/0?ui=2&ik=65460f62c3&attid=0.1&permmsgid=msg-f:1642578503443144251&th=16cb9c72356bde3b&view=att&disp=safe[/img]
画像のはずのURLが無効なようです。
Ouxiyさんはユーザー登録とログインをしているようなので添付ファイル機能が使えるだろうと思いますが、
使わない・もしくは使えない理由はありますか?
何らかの理由で添付ファイル機能が使えない場合、Imgurなどのサービスを利用するのもいいかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#4

投稿記事 by Ouxiy » 4年前

迅速な解答感謝いたします。
こちらの方で見れますでしょうか。お手数をお掛けします
https://onslaughta.imgur.com/all/?third_party=1

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#5

投稿記事 by Ouxiy » 4年前

凄いです!まさにこのようなプログラムです!
ですが、もう少し調節してみます!どうもありがとうございます!

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#6

投稿記事 by Ouxiy » 4年前

ちなみに、より厳密に用意した配列から座標を取るには、試行錯誤するしかないのでしょうか。
もちろん、決して楽をしようとは考えていません。なので試行錯誤しか方法が無いならば納得のいく座標をとるしかありません。

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

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#7

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

例えば、DXライブラリの機能で実際に3Dで描画し、そこから座標の情報を得る方法があります。
たとえばこのような実装ができます。

コード:

#include <DxLib.h>
#include <cmath>
#include <sstream>

// 自分の環境で3D描画が壊れたようなので、その対策モードの切り替え
#if 1
#define SET_NO_3D
#endif

// 各キーが何フレーム押されているかをまとめて取得する
int getKeyStatus(int keyStatus[256]) {
	char keyBuffer[256];
	if (GetHitKeyStateAll(keyBuffer) != 0) return -1;
	for (int i = 0; i < 256; i++) {
		keyStatus[i] = keyBuffer[i] ? keyStatus[i] + 1 : 0;
	}
	return 0;
}

// キーのリピートを判定する
bool judgeKeyRepeat(int key, int firstDelay, int repeatInterval) {
	// キーが押された瞬間は入力する
	if (key == 1) return true;
	// キーが押されてfirstDelayフレーム後から、repeatIntervalフレームごとに入力する
	if (key >= firstDelay && (key - firstDelay) % repeatInterval == 0) return true;
	return false;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
#ifdef SET_NO_3D
	SetUse3DFlag(FALSE);
#endif
	if (ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() != 0) return -1;
	SetDrawScreen(DX_SCREEN_BACK);

	const int GRID_SIZE_X = 100; // 1マスの横方向のサイズ
	const int GRID_SIZE_Y = 100; // 1マスの縦方向のサイズ
	const int GRID_NUM_X = 3; // 横方向のマス数
	const int GRID_NUM_Y = 3; // 縦方向のマス数

	const int CHARA_WIDTH = 49; // キャラ画像の横幅
	const int CHARA_HEIGHT = 66; // キャラ画像の縦幅

	int gridColor = GetColor(255, 255, 255);
	int textColor = GetColor(255, 255, 255);
	int charaColor = GetColor(0, 255, 127);

	int distance = 400; // 注視点からカメラの距離
	int angle = 30; // 床に対するカメラの角度

	int targetX = GRID_SIZE_X * GRID_NUM_X / 2; // 注視点のX座標
	int targetY = 20; // 注視点のY座標
	int targetZ = GRID_SIZE_Y * GRID_NUM_Y / 2; // 注視点のZ座標

	int cx = 1, cy = 1; // キャラのマス上の座標

	SetCameraNearFar(10.0f, 2000.0f);

	int keyStatus[256];
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && getKeyStatus(keyStatus) == 0) {

		// ----- 更新 -----

		// 計算結果の出力
		if (keyStatus[KEY_INPUT_O] == 1) {
			std::stringstream ss;
			ss << "\n\n";
			ss << "// カメラ注視点: (" << targetX << ", " << targetY << ", " << targetZ <<
				")  カメラ角度: " << angle << "  カメラ距離: " << distance << "\n";
			ss << "int drawCoords[" << (GRID_NUM_Y + 2) << "][" << (GRID_NUM_X + 2) << "][2] = {\n\t{";
			for (int i = 0; i < GRID_NUM_Y + 2; i++) {
				if (i > 0) ss << ",\n\t{";
				for (int j = 0; j < GRID_NUM_X + 2; j++) {
					float charaX_3D = static_cast<float>(GRID_SIZE_X * (j - 1) + GRID_SIZE_X / 2);
					float charaZ_3D = static_cast<float>(GRID_SIZE_Y * (GRID_NUM_Y - 1 - (i - 1)) + GRID_SIZE_Y / 2);
					VECTOR charaCoord2D = ConvWorldPosToScreenPos(VGet(charaX_3D, 0.0f, charaZ_3D));
					int charaX_2D = static_cast<int>(round(charaCoord2D.x)) - CHARA_WIDTH / 2;
					int charaY_2D = static_cast<int>(round(charaCoord2D.y)) - CHARA_HEIGHT;
					if (j > 0) ss << ", ";
					ss << "{" << charaX_2D << ", " << charaY_2D << "}";
				}
				ss << "}";
			}
			ss << "\n};\n\n";
			LogFileAdd(ss.str().c_str());
		}

		// 注視点の移動
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_W], 20, 1)) targetZ++;
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_A], 20, 1)) targetX--;
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_S], 20, 1)) targetZ--;
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_D], 20, 1)) targetX++;
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_E], 20, 1)) targetY++;
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_C], 20, 1) && targetY > 0) targetY--;

		// カメラの距離の変更
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_Q], 20, 1) && distance > 10) distance--;
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_Z], 20, 1)) distance++;

		// カメラの角度の変更
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_R], 20, 3) && angle < 89) angle++;
		if (judgeKeyRepeat(keyStatus[KEY_INPUT_V], 20, 3) && angle > 0) angle--;

		// キャラクターの移動
		if (keyStatus[KEY_INPUT_UP] == 1 && cy > 0) cy--;
		if (keyStatus[KEY_INPUT_LEFT] == 1 && cx > 0) cx--;
		if (keyStatus[KEY_INPUT_RIGHT] == 1 && cx + 1 < GRID_NUM_X) cx++;
		if (keyStatus[KEY_INPUT_DOWN] == 1 && cy + 1 < GRID_NUM_Y) cy++;

		// ----- 描画 -----

		// パラメータの描画
		DrawFormatString(10, 10, textColor,
			"カメラ注視点: (%d, %d, %d)  カメラ角度: %d  カメラ距離: %d",
			targetX, targetY, targetZ, angle, distance);

		// カメラの位置と角度の設定
		float cameraAngle = static_cast<float>(angle) * DX_PI_F / 180.0f;
		float cameraY = static_cast<float>(distance) * sin(cameraAngle) + static_cast<float>(targetY);
		float cameraZ = static_cast<float>(targetZ) - static_cast<float>(distance) * cos(cameraAngle);
		SetCameraPositionAndTarget_UpVecY(
			VGet(static_cast<float>(targetX), cameraY, cameraZ),
			VGet(static_cast<float>(targetX), static_cast<float>(targetY), static_cast<float>(targetZ)));

		// マスの描画
		for (int i = 0; i <= GRID_NUM_Y; i++) {
			VECTOR s = VGet(0.0f, 0.0f, static_cast<float>(GRID_SIZE_Y * i));
			VECTOR d = VGet(static_cast<float>(GRID_SIZE_X * GRID_NUM_X), 0.0f, static_cast<float>(GRID_SIZE_Y * i));
#ifdef SET_NO_3D
			VECTOR s_2D = ConvWorldPosToScreenPos(s);
			VECTOR d_2D = ConvWorldPosToScreenPos(d);
			DrawLine(
				static_cast<int>(s_2D.x), static_cast<int>(s_2D.y),
				static_cast<int>(d_2D.x), static_cast<int>(d_2D.y), gridColor);
#else
			DrawLine3D(s, d, gridColor);
#endif
		}
		for (int i = 0; i <= GRID_NUM_X; i++) {
			VECTOR s = VGet(static_cast<float>(GRID_SIZE_X * i), 0.0f, 0.0f);
			VECTOR d = VGet(static_cast<float>(GRID_SIZE_X * i), 0.0f, static_cast<float>(GRID_SIZE_Y * GRID_NUM_Y));
#ifdef SET_NO_3D
			VECTOR s_2D = ConvWorldPosToScreenPos(s);
			VECTOR d_2D = ConvWorldPosToScreenPos(d);
			DrawLine(
				static_cast<int>(s_2D.x), static_cast<int>(s_2D.y),
				static_cast<int>(d_2D.x), static_cast<int>(d_2D.y), gridColor);
#else
			DrawLine3D(s, d, gridColor);
#endif
		}

		// キャラの描画
		float charaX_3D = static_cast<float>(GRID_SIZE_X * cx + GRID_SIZE_X / 2);
		float charaZ_3D = static_cast<float>(GRID_SIZE_Y * (GRID_NUM_Y - 1 - cy) + GRID_SIZE_Y / 2);
		VECTOR charaCoord2D = ConvWorldPosToScreenPos(VGet(charaX_3D, 0.0f, charaZ_3D));
		int charaX_2D = static_cast<int>(round(charaCoord2D.x)) - CHARA_WIDTH / 2;
		int charaY_2D = static_cast<int>(round(charaCoord2D.y)) - CHARA_HEIGHT;
		DrawBox(charaX_2D, charaY_2D, charaX_2D + CHARA_WIDTH, charaY_2D + CHARA_HEIGHT, charaColor, TRUE);

	}

	DxLib_End();
	return 0;
}
操作方法

コード:

A : カメラが見る位置を左に移動
D : カメラが見る位置を右に移動
W : カメラが見る位置を奥に移動
S : カメラが見る位置を手前に移動
E : カメラが見る位置を上に移動
C : カメラが見る位置を下に移動

Q : カメラを近づける
Z : カメラを遠ざける

R : カメラの角度を高くする
V : カメラの角度を低くする

O : 現時点での設定で計算した座標をLog.txtに書き出す

← : キャラを左に移動
→ : キャラを右に移動
↑ : キャラを上に移動
↓ : キャラを下に移動
例として、この実装のデフォルトの設定で出力した座標がこれです。

コード:

// カメラ注視点: (150, 20, 150)  カメラ角度: 30  カメラ距離: 400
int drawCoords[5][5][2] = {
	{{153, 115}, {225, 115}, {296, 115}, {367, 115}, {439, 115}},
	{{129, 147}, {212, 147}, {296, 147}, {380, 147}, {463, 147}},
	{{93, 192}, {195, 192}, {296, 192}, {397, 192}, {499, 192}},
	{{39, 261}, {167, 261}, {296, 261}, {425, 261}, {553, 261}},
	{{-55, 380}, {120, 380}, {296, 380}, {472, 380}, {647, 380}}
};
出力結果をそのまま使うもよし、描画するときに拡大縮小や平行移動の補正をかけてもよしでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#8

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

Ouxiy さんが書きました:
4年前
迅速な解答感謝いたします。
こちらの方で見れますでしょうか。お手数をお掛けします
https://onslaughta.imgur.com/all/?third_party=1
見れません。imgur: the simple 404 pageが出ます。
Imgurの現行仕様では、投稿した画像の画面の投稿した画像にマウスカーソルを当てると
点が3個描かれたボタンが出て、そこを押すと表示されるGet share linksを押すと
BBCodeが表示されるので、それをコピーして使うといいでしょう。


投稿した画像の画面:https://imgur.com/a/168L9DD
画像
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#9

投稿記事 by Ouxiy » 4年前

ん!?
どうもありがとうございます。ですが、複雑すぎて解読するには時間がかかりそうです。
うまく画像が張れずにすいません。
今使っている画像はこちらを使っています。使っている画像が張っているサイトです
それにしても、こんなことができるなんて、、、。
このドット画像を使ってどう表現できるかやってみます。本当に勉強になります。
どうもありがとうございます。

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#10

投稿記事 by Ouxiy » 4年前

あの、できればなぜそのように実装できたのか、
考え方や過程の手順を詳しく教えて頂けないでしょうか。
どうかよろしくお願いいたします。

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#11

投稿記事 by Ouxiy » 4年前

ちなみに、載せたサイトの画像を貼ることは出来ると思いますが、
これはDXライブラリの描画関数で解決できるのでしょうか?
自分の方でもやってみます。

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#12

投稿記事 by Ouxiy » 4年前

二つの載せて頂いたプログラムで、
一つ目は2Dを3Dのように見せるプログラムと二つ目は一つ目のプログラムで座標を知るために付け足したプログラムという認識で良いでしょうか。
二つ目は複雑で解読が難しそうですぐには使えないのでまずは、一つ目を使おうかなと考えています。
とりあえず、ステージとなるドットを作り座標の配置を考えます。
どうもありがとうございます!

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#13

投稿記事 by Ouxiy » 4年前

https://teratail.com/questions/edit/207686
こちらでマルチポストをしていました。
皆様のいいアイディアどうもありがとうございます。

can110
記事: 27
登録日時: 9年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#14

投稿記事 by can110 » 4年前

Ouxiy さんが書きました:
4年前
https://teratail.com/questions/edit/207686
こちらでマルチポストをしていました。
皆様のいいアイディアどうもありがとうございます。
https://teratail.com/questions/edit/207686
は開けません。

Ouxiy
記事: 173
登録日時: 4年前

Re: 画像のように3D っぽい2Dの9マスA~I上をキャラにキー入力で移動させたい

#15

投稿記事 by Ouxiy » 4年前

マルチポストしたサイトです。
以下のコードを使って行いたいことを実行しました。

コード:

#include "DxLib.h"

int Key[256];

int gpUpdateKey()
{
    char tmpKey[256];
    GetHitKeyStateAll(tmpKey);
    for (int i = 0; i < 256; i++)
        (tmpKey[i] == 0) ? (Key[i] = 0) : Key[i]++;
    return 0;
}

int idou[5][5] = {
    { 1, 1, 1, 1, 1 },
    { 1, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 1 },
    { 1, 1, 1, 1, 1 },
};

int box[4][7][2], player[5][5][2];

void init_box()
{
    for (int j = 0; j < 7; j++) {
        int w = (j - 3) * 100, h = 600;
        for (int i = 4; --i >= 0; ) {
            box[i][j][0] = w + 400, box[i][j][1] = h - 200;
            w = w * 9 / 10, h = h * 9 / 10;
        }
    }
    for (int i = 1; i <= 3; i++)
        for (int j = 1; j <= 3; j++) {
            player[i][j][0] = (box[i-1][j-1][0] + box[i][j][0])/2 - 25;
            player[i][j][1] = (box[i-1][j-1][1] + box[i][j][1])/2 - 66;
        }
}

int WINAPI WinMain(HINSTANCE hi, HINSTANCE hp, LPSTR cl, int cs)
{
    SetGraphMode(1200, 680, 32);        // ウィンドウの大きさを指定
    ChangeWindowMode(TRUE);             // 全画面ではなくウインドウを使用
    if (DxLib_Init() == -1) return -1;  // DXライブラリ初期化処理
    SetDrawScreen(DX_SCREEN_BACK);      // 裏画面を使用する設定

    init_box();
    int boxColor = GetColor(160, 64, 64);

    int nx = 2, ny = 2;  // プレイヤーの初期位置
    int px = player[ny][nx][0], py = player[ny][nx][1];  // 表示位置
    int keep = 0;  // 移動不可能状態継続カウンタ

    int gh[12];  //グラフィックハンドル格納用配列
            // 5:正面、7:右向き、2:左向き、4:上向き、3:下向き、9:移動不可
    LoadDivGraph("charall.png", 12, 3, 4, 49, 66, gh);  //画像読み込み
    int playerphoto = gh[5];

    while (ProcessMessage() == 0) {
        gpUpdateKey();  // キーの入力状態を取得
        if (Key[KEY_INPUT_RIGHT] == 1) {  // 右キーが押されている
            if (idou[nx + 1][ny] == 0) {  // 移動先が空いていれば
                nx++; playerphoto = gh[7];  // 右向き
            }
            else {
                keep = 1; playerphoto = gh[9];  // 移動不可能
            }
        }
        if (Key[KEY_INPUT_LEFT] == 1) {
            if (idou[nx - 1][ny] == 0) {  // 移動先が空いていれば
                nx--; playerphoto = gh[2];  // 左向き
            }
            else {
                keep = 1; playerphoto = gh[9];  // 移動不可能
            }
        }
        if (Key[KEY_INPUT_UP] == 1) {
            if (idou[nx][ny - 1] == 0) {  // 移動先が空いていれば
                ny--; playerphoto = gh[4];  // 上向き
            }
            else {
                keep = 1; playerphoto = gh[9];  // 移動不可能
            }
        }
        if (Key[KEY_INPUT_DOWN] == 1) {
            if (idou[nx][ny + 1] == 0) {  // 移動先が空いていれば
                ny++; playerphoto = gh[3];  // 下向き
            }
            else {
                keep = 1; playerphoto = gh[9];  // 移動不可能
            }
        }

        ClearDrawScreen();  // 裏画面をクリア

        for (int i = 0; i < 4; i++)
            DrawLine(box[i][0][0], box[i][0][1],
                     box[i][6][0], box[i][6][1], boxColor);
        for (int j = 0; j < 7; j++)
            DrawLine(box[0][j][0], box[0][j][1],
                     box[3][j][0], box[3][j][1], boxColor);

        int x = player[ny][nx][0], y = player[ny][nx][1];  // 表示位置に変換
        if (x == px && y == py) {
            if (keep == 0 || ++keep == 10) {
                keep = 0; playerphoto = gh[5];
            }
        }
        else {
            if (abs(x - px) < 8) px = x;
            else if (x > px) px += 8;
            else if (x < px) px -= 8;
            if (abs(y - py) < 6) py = y;
            else if (y > py) py += 6;
            else if (y < py) py -= 6;
        }
        DrawGraph(px, py, playerphoto, FALSE);  // プレイヤーを裏画面に描画
        ScreenFlip();  // 裏画面を表画面に反映
    }

    DxLib_End();  // DXライブラリ使用の終了処理
    return 0;  // ソフトの終了 
}

返信

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