クォータビューのマップ描画について

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

クォータビューのマップ描画について

#1

投稿記事 by クロウ » 16年前

半年ぶりの投稿になります。
今、ゲームプログラミングの館を参考にさせていただいて作った歩くマインスイーパを
次はクォータービューにして作ろうとしています。

クォータービューのマップの配置で高さの違いを出そうとすると、描画位置がおかしくなったりしてうまくいきません。

まず一段目を全部描画して、次にmapHigh[/url][/url]の中の値が1以上のものを2段目として描画、その上から2以上のものを3段目、3以上を4段目・・・・としてやっているつもりです。
2段目までは微調整でうまくいったのですが、3段目からは微調整でうまくいきませんでした。

微調整をしないで、mapHigh[/url][/url]の中身を変えるだけで、マップチップを求めている段数を積んでくれるようにしたいのですがどのようにすればよいか教えてください。


ソースコードはこのようになっています。
コンパイラはVC2008でOSはvistaです。
#include "DxLib.h"


#define MAPSIZEMAX_X 4
#define MAPSIZEMAX_Y 3

int map[MAPSIZEMAX_Y][MAPSIZEMAX_X] = {//マップチップの種類
	{0,1,0,1},
	{0,1,0,1},
	{0,1,0,1},

};

int mapHigh[MAPSIZEMAX_Y][MAPSIZEMAX_X] = {//高さ用の配列
	{0,0,0,2},
	{1,2,3,3},
	{0,0,2,0},
};


int mapChip[20];      //クォーターマップチップ



typedef struct{
	int field[MAPSIZEMAX_Y][MAPSIZEMAX_X];//マップのメイン
	int fieldHigh[MAPSIZEMAX_Y][MAPSIZEMAX_X];//高さ用の配列

}mapData_t;


mapData_t mapData;




void mapLoad(){//読み込んだマップを一時配列に保存


	for(int i = 0; i < MAPSIZEMAX_X ; i++){
		for(int j = 0; j < MAPSIZEMAX_Y ; j++){
			mapData.field[j] = map[j];//マップチップNo.
			mapData.fieldHigh[j] = mapHigh[j];//高さ
		}
		
	}
}

void mapDraw(){//マップの描画

	for(int i = 0; i <MAPSIZEMAX_X -1 ; i++){//マップチップNo.
		for(int j = 0; j < MAPSIZEMAX_Y +1  ; j++){

			switch(mapData.fieldHigh[j]){//高さによって同じ物を積み上げる

				case 0:
					DrawGraph(100 + (j * 2 - i)*32 -j*32 ,100 +  (i * 2 + j)* 16 -i*16 ,mapChip[mapData.field[j]],TRUE);

					break;

				case 1:
					DrawGraph(100 + (j * 2 - i)*32 -j*32 ,100 +  (i * 2 + j)* 16 -i*16 ,mapChip[mapData.field[j]],TRUE);

					DrawGraph(100 + (j * 2 - i)*32 -j*32 + mapData.fieldHigh[j]*4-4
						, 100 + (i * 2 + j)* 16 -i*16 - mapData.fieldHigh[j]*16+2
						,mapChip[mapData.field[j]],TRUE);

					break;
				case 2:
					DrawGraph(100 + (j * 2 - i)*32 -j*32 ,100 +  (i * 2 + j)* 16 -i*16 ,mapChip[mapData.field[i][j]],TRUE);

					DrawGraph(100 + (j * 2 - i)*32 -j*32 + mapData.fieldHigh[i][j]*2-4
						, 100 + (i * 2 + j)* 16 -i*16 - mapData.fieldHigh[i][j]*8+2
						,mapChip[mapData.field[i][j]],TRUE);

					DrawGraph(100 + (j * 2 - i)*32 -j*32 + mapData.fieldHigh[i][j]*2-4
						, 100 + (i * 2 + j)* 16 -i*16 - mapData.fieldHigh[i][j]*16+2
						,mapChip[mapData.field[i][j]],TRUE);

					break;
				case 3:
					DrawGraph(100 + (j * 2 - i)*32 -j*32 ,100 +  (i * 2 + j)* 16 -i*16 ,mapChip[mapData.field[i][j]],TRUE);

					DrawGraph(100 + (j * 2 - i)*32 -j*32 + mapData.fieldHigh[i][j]*4-2
						, 100 + (i * 2 + j)* 16 -i*16 - mapData.fieldHigh[i][j]*4+4
						,mapChip[mapData.field[i][j]],TRUE);

					DrawGraph(100 + (j * 2 - i)*32 -j*32 + mapData.fieldHigh[i][j]*4-2
						, 100 + (i * 2 + j)* 16 -i*16 - mapData.fieldHigh[i][j]*8+4
						,mapChip[mapData.field[i][j]],TRUE);

					DrawGraph(100 + (j * 2 - i)*32 -j*32 + mapData.fieldHigh[i][j]*4-2
						, 100 + (i * 2 + j)* 16 -i*16 - mapData.fieldHigh[i][j]*16+4
						,mapChip[mapData.field[i][j]],TRUE);


					break;

			}

		}
	}
}



void mapMain(){//マップメイン

	mapLoad();//マップデータの読み込み
	mapDraw();//描画


}

////////////////////////////////////////////////////////////////////////////////////

unsigned int stateKey[256];

int GetHitKeyStateAll_2(){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) stateKey[i]++;
        else                            stateKey[i]=0;
    }
    return 0;
}

int CheckStateKey(unsigned char Handle){
        return stateKey[Handle];
}

//メインループで行う3大処理
int ProcessLoop(){
    if(ProcessMessage()!=0)return -1;//プロセス処理がエラーなら-1を返す
    if(ClearDrawScreen()!=0)return -1;//画面クリア処理がエラーなら-1を返す
    GetHitKeyStateAll_2();//現在のキー入力処理を行う
    return 0;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){

	ChangeWindowMode( TRUE );
	
	if( DxLib_Init() == -1 ){ return -1;} 
	//初期化処理
	SetOutApplicationLogValidFlag ( FALSE );		//ログ出力を行わない

	SetDrawScreen( DX_SCREEN_BACK ) ; 
	//最初に描画先を裏画面に設定
	LoadDivGraph("mapchip.png",4,4,1,64,48,mapChip);
	
	while(ProcessLoop()==0){//メインループ
				
		mapMain();

		if(CheckStateKey(KEY_INPUT_ESCAPE) == 1){
			break;//エスケープが入力されたらブレイク
		}

		ScreenFlip();//裏画面データを表画面へ反映する
	}
	DxLib_End();//Dxlibの終了
	return 0;					// ソフトの終了
}

Justy

Re:クォータビューのマップ描画について

#2

投稿記事 by Justy » 16年前


>mapHigh[/url][/url]の中身を変えるだけで、マップチップを求めている段数を積んでくれるようにしたい

 同じような式がいっぱいあって、目がクラクラ・・・。
 まずは、同じ式をまとめて、整理すると、
[color=#d0d0ff" face="monospace]
int x = 100 + (j * 2 - i) * 32 - j * 32;
int y = 100 + (i * 2 + j) * 16 - i * 16;
int height = mapData.fieldHigh[j];
int mapImage = mapChip[mapData.field[j]];

DrawGraph(x, y, mapImage, TRUE);
switch(height)
{
case 1:
DrawGraph(x + height * 4 - 4, y - height * 16 + 2, mapImage, TRUE);
break;

case 2:
DrawGraph(x + height * 2 - 4, y - height * 8 + 2, mapImage, TRUE);
DrawGraph(x + height * 2 - 4, y - height * 16 + 2, mapImage, TRUE);
break;

case 3:
DrawGraph(x + height * 4 - 2, y - height * 4 + 4, mapImage, TRUE);
DrawGraph(x + height * 4 - 2, y - height * 8 + 4, mapImage, TRUE);
DrawGraph(x + height * 4 - 2, y - height * 16 + 4, mapImage, TRUE);
break;
}
[/color]

 こうなります。

 さて、ここでじっくり見ていくと不思議なことがいくつか見つかります。

・ なぜ高さが1や2の時は x方向は一切ずらしていない(1*4-4=0とか 2*2-4=0)のに、
3の時だけ 3*4-2=10ずらしているのか。

・ なぜ y方向のずらしが1の時は 18、2の時は 18と 34、3の時は 16, 28, 52と
まちまちなのか。

 この点を改善すれば、うまくいくのではないでしょうか。

 一応適当に直した(あんまりチェックしてない)コードを乗せておきますので、
参考にしてください。
[color=#d0d0ff" face="monospace]
void mapDraw()
{
for(int x = 0; x < MAPSIZEMAX_X - 1; x++)
{
for(int y = 0; y < MAPSIZEMAX_Y + 1; y++)
{
int pos_x = 100 + (y * 2 - x) * 32 - y * 32;
int pos_y = 100 + (x * 2 + y) * 16 - x * 16;
int height = mapData.fieldHigh[x][y];
int mapImage = mapChip[mapData.field[x][y]];

for(int n=0; n<=height; ++n)
DrawGraph(pos_x, pos_y - n * 16, mapImage, TRUE);
}
}
}
[/color]

クロウ

Re:クォータビューのマップ描画について

#3

投稿記事 by クロウ » 16年前

うまく表示されました。
Justyさんありがとうございました。


(j*2-i)*32-j*32 → (j-i)*32
(i * 2 + j) * 16 - i * 16 → (i+j)*16
・・・実は無駄な計算をしていたようです。

閉鎖

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