マップスクロールの考え方

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

マップスクロールの考え方

#1

投稿記事 by atci98 » 9年前

以前同じ事で質問し、申し訳ありませんが理解出来なかったので、もう一度質問させていただきます。
マップスクロールの考え方は、起動したときに出るウィンドウの表示域をカメラとして、そのカメラが動くのでしょうか?
それともカメラは動かずにマップのほうが動くのでしょうか?
最後に、マップチップを使わずに一枚絵を使ってマップを表現したいと思っているのですが、その場合の
マップの当たり判定はDrawboxで透明な四角を作って判定しなければいけないのでしょうか?

わかりにくい文章ですいません。

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

Re: マップスクロールの考え方

#2

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

atci98 さんが書きました:マップスクロールの考え方は、起動したときに出るウィンドウの表示域をカメラとして、そのカメラが動くのでしょうか?
それともカメラは動かずにマップのほうが動くのでしょうか?
作りやすい考え方で作ればいいと思いますが、自分はマップ(およびその上のオブジェクト)の座標軸は固定し、表示のオフセット(=カメラ)を動かすほうがいいと思います。
atci98 さんが書きました:最後に、マップチップを使わずに一枚絵を使ってマップを表現したいと思っているのですが、その場合の
マップの当たり判定はDrawboxで透明な四角を作って判定しなければいけないのでしょうか?
いいえ。
当たり判定にわざわざ描画関数を使い、しかも色で当たり判定をするならともかく透明な四角を作る意味は私にはわかりません。
ライブラリの標準関数、例えばDXライブラリのDrawBox (Bが大文字)とは関係ない当たり判定の関数を自作するとしても、その名前をDrawboxにする必要は全くないでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

atci98
記事: 17
登録日時: 10年前

Re: マップスクロールの考え方

#3

投稿記事 by atci98 » 9年前

自分の作りやすい考え方は、返信を下さった答えと同じで、カメラを動かすほうなのですが・・・
では、そのカメラを動かすのはどうやって実現できるのでしょうか?

二つ目の回答に対してですが・・、
DrawBoxを使わないとしたら
int Mapdata[ Height ] [ Width ] = {
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 }, }
みたいな1を行けない所、0を行ける所とした感じのマップデータを作らないといけませんか?

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

Re: マップスクロールの考え方

#4

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

atci98 さんが書きました:自分の作りやすい考え方は、返信を下さった答えと同じで、カメラを動かすほうなのですが・・・
では、そのカメラを動かすのはどうやって実現できるのでしょうか?
例えばスクロールが無い場合の描画をdrawHoge(x, y)、カメラの座標(画面の左上として表示する位置)を(cx, cy)とすると、
描画をdrawHoge(x - cx, y - cy)みたいにすればできるはずです。
明らかに画面外にしかないものは描画しない、みたいな処理を入れるとさらに良くなるでしょう。
atci98 さんが書きました:DrawBoxを使わないとしたら
int Mapdata[ Height ] [ Width ] = {
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 },
{ 1, 0, 0, 0 }, }
みたいな1を行けない所、0を行ける所とした感じのマップデータを作らないといけませんか?
好きな形式でマップデータを用意すればいいです。
1を行けない所、0を行ける所とする必要はありません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

atci98
記事: 17
登録日時: 10年前

Re: マップスクロールの考え方

#5

投稿記事 by atci98 » 9年前

・カメラとは「あああ」(プログラム名は適当).EXEを起動したとき出る黒い(画像等は何もしてない状態)画面の描画範囲のことですよね?

・スクロールがない場合の描画をたとえば(10, 10)として、カメラの座標を(100,100)とすると(-90,-90)となるのですが、これはまったく違うところを写そうとなりませんか?
自分が何か思い違いをしてそうですが・・・。

・DxLibにあるDrawGraph関数なら、画像を動かすことが出来るのですが、カメラはそれらの関数を使わずに動かすことが出来るのですか?
自分がプログラムするとき、画像を動かすときdrawGraph関数等しか知らないもので・・・。
もしくはdrawHoge関数というものがあるのでしょうか?
お手数ですが例のようなものを書いていただけると助かります。(_ _)

質問が多くなってしまい本当にすいません・・・。

moba
記事: 82
登録日時: 9年前

Re: マップスクロールの考え方

#6

投稿記事 by moba » 9年前

横から失礼します。
キャラはマス単位(グリッド制)で移動するけれど、画像だけピクセル単位で移動する感じでしょうか。
その場合でしたら、次のような変数名を付けると分かりやすいと思います。

・gridX,Y : グリッド座標位置を表わす(マス単位の座標の意味)
・worldX,Y : 画像の、マップの左上を基準としたピクセル座標を表わす
・screenX,Y : 画像をウィンドウ画面に描画するときの、ウィンドウ(カメラ)を基準としたピクセル座標を表わす

> カメラとは

そうです、ウィンドウに描画される範囲だと思っていいと思います。
ゲームによっては、ウィンドウの一部分をカメラに使い、一部分に他の情報を表示しているかもしれません。
例えば:画面右側に、常にステータスを表示しているかも。

> カメラ

y軸が下、x軸は右が正(+)です。
□をカメラ範囲内、■をカメラ範囲外のマスとします。
(scrollX,Y) = (0, 0)のときは、以下のようになります。

□□□■■■
□□□■■■
■■■■■■

(scrollX, Y ) = (10, 10)のときは、以下のようになります。
※カメラ"が"右下に動きます。動かすのはマップではありません。

■■■■■■
■□□□■■
■□□□■■

この時、左上のマスは、カメラの左上から見たら、(-10, -10)の位置にあります。
違うところというか、画面外ですよね。

> 当たり判定

普通は配列に相当するものを用意するのではないかと思います。
例えば、TiledMapEditorでjsonファイルを作って、picojsonで読み込むことになるのではないかと…

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

Re: マップスクロールの考え方

#7

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

atci98 さんが書きました:・カメラとは「あああ」(プログラム名は適当).EXEを起動したとき出る黒い(画像等は何もしてない状態)画面の描画範囲のことですよね?
いいえ。
何もしてない画面の描画範囲は空集合と考えられるので、そんなものはカメラとはいえないでしょう。
atci98 さんが書きました:・スクロールがない場合の描画をたとえば(10, 10)として、カメラの座標を(100,100)とすると(-90,-90)となるのですが、これはまったく違うところを写そうとなりませんか?
自分が何か思い違いをしてそうですが・・・。
正しい挙動です。
sukurooru-20160413.png
スクロール時の描画
sukurooru-20160413.png (6.5 KiB) 閲覧数: 6423 回
atci98 さんが書きました:・DxLibにあるDrawGraph関数なら、画像を動かすことが出来るのですが、カメラはそれらの関数を使わずに動かすことが出来るのですか?
はい。
「カメラ」、特に2Dのマップに対し自前で実装するものはDxLibとは直越関係ないので、当然DxLibの関数を使わずに動かすことができます。
(ユーザーの入力に従って動かす場合、入力の取得にはライブラリの関数を使うかもしれませんが)
atci98 さんが書きました:お手数ですが例のようなものを書いていただけると助かります。(_ _)
例えばこんな感じでしょうか?

コード:

#include <DxLib.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	if (ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() != 0) return -1;

	// マップ画像 (デモとして適当な画像を作成)
	int mapWidth = 640, mapHeight = 480;
	int mapImage = MakeScreen(mapWidth, mapHeight, FALSE);
	SetDrawScreen(mapImage);
	SRand(0);
	for (int i = 0; i < 100; i++) {
		int x1 = GetRand(mapWidth - 1);
		int y1 = GetRand(mapHeight - 1);
		int x2 = GetRand(mapWidth - 1);
		int y2 = GetRand(mapHeight - 1);
		int r = GetRand(255);
		int g = GetRand(255);
		int b = GetRand(255);
		DrawLine(x1, y1, x2, y2, GetColor(r, g, b));
	}

	int cx = 0, cy = 0; // マップの座標
	int charX = 100, charY = 200; // キャラクターの座標

	SetDrawScreen(DX_SCREEN_BACK);
	char key[256];
	while (ProcessMessage() == 0 && ClearDrawScreen() == 0 && GetHitKeyStateAll(key) == 0) {
		// カメラを移動
		if (key[KEY_INPUT_UP]) cy -= 3;
		if (key[KEY_INPUT_DOWN]) cy += 3;
		if (key[KEY_INPUT_LEFT]) cx -= 3;
		if (key[KEY_INPUT_RIGHT]) cx += 3;
		// キャラクターを移動
		if (key[KEY_INPUT_W]) charY -= 3;
		if (key[KEY_INPUT_S]) charY += 3;
		if (key[KEY_INPUT_A]) charX -= 3;
		if (key[KEY_INPUT_D]) charX += 3;
		// 写る一番左上の背景の左上の位置を求める
		int mx = (cx >= 0 ? mapWidth * (cx / mapWidth) : -mapWidth * ((-cx - 1) / mapWidth + 1));
		int my = (cy >= 0 ? mapHeight * (cy / mapHeight) : -mapHeight * ((-cy - 1) / mapHeight + 1));
		// 背景を描画
		for (int y = my; y  - cy < 480; y += mapHeight) {
			for (int x = mx; x - cx < 640; x += mapWidth) {
				DrawGraph(x - cx, y - cy, mapImage, FALSE);
			}
		}
		// キャラクター (緑の丸)を描画
		DrawCircle(charX - cx, charY - cy, 10, GetColor(0, 255, 0), TRUE);
		ScreenFlip();
	}

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

atci98
記事: 17
登録日時: 10年前

Re: マップスクロールの考え方

#8

投稿記事 by atci98 » 9年前

一回解決済みにしたのですが、改めて?なところが出てきたため、回答が来るか分かりませんが一応投稿しなおしてみました。
このプログラムでは延々とどこにでも移動できる無限ループになるのですが、これはどこがどうなってこうなるのか、どなたか分かりますでしょうか?
この無限ループをなくすにはいったいどうしたら・・・?

hide

Re: マップスクロールの考え方

#9

投稿記事 by hide » 9年前

よくわからないですわからないです助けて
みたいなのは質問になってないので、もっとちゃんとした説明を書きましょう

閉鎖

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