Seite 1 von 3

Isometrisch darstellen, aber wie?

Verfasst: 21.10.2005 16:09
von Artus
Hi Leute,
also ... ich will eine Isometrische-Perpektieve in mein neues Game heben. Nun habe ich aber ein Problem, also wenn ich nun ein Feld hinter einer Mauer stehe, wird meine Figur aber trotzdem vor der Mauer gemalt. Nun, also wie bringe ich ohne goßen extra Rechenaufwand alles in die richtige Reienfoge??
Ein Codebeispiel währe echt toll.

Ich danke euch jetzt schoneinmal.

PS: Ich hoffe ich habe nicht wieder mal etwas falsch gemacht beim posten dieses Beitrags ^^ :lol:

Verfasst: 21.10.2005 16:23
von Green Snake
Du köntest zb. eine maske erstellen, und wenn diese HINTER der mauer steht, dass sprite entsprächend Clippen.

in der showcase befindet sich ein beispiel zu dem.
bzw zur iso ansicht.
"Aufbau" genannt :allright:

Verfasst: 21.10.2005 16:39
von Artus
Naja, das kenn ich und es ist nicht besonders hilfreich. Es ist unübersichtlich und hat lauter Fehler. Da währs mir lieber wenn mir es jemand erklären bzw. Zeigein könnte. :|

Verfasst: 21.10.2005 17:02
von Zaphod
du mußt den zeichenvorgang in zwei durchläufe aufteilen. erst die böden, dann die wände und objekte. natürlich mußt du dir noch irgendeinen mechanismus überlegen der bestimmt wann die objekte gezeichnet werden. da du ja aber deren position kennst, sollte das kein problem sein.

Verfasst: 21.10.2005 17:27
von NicTheQuick
Du must einfach deine Liste mit alle Objekten und Spielfiguren nach der y-
Koordinate sortieren und sie dann von oben nach unten auf den
Bildschirm malen.

Verfasst: 21.10.2005 18:15
von Artus
Ahja, könnt ihr mal ein Beispiel zeigen wie man so etwas am besten programmiert? ein beispiel währe echt super.

Mfg Artus

Verfasst: 21.10.2005 18:51
von Zaphod
hab keine lust sowas jetzt in purebasic zu schreiben, vor allem weil das ein bischen mehr zeit bräuchte. ich habe aber sowas in c geschrieben, also wenn du c code lesen kannst (und ich den zwischen meinem altem kram finde) könnte ich den posten.

Verfasst: 21.10.2005 19:00
von Artus
[EDIT]

Jo, das wähhhhre super, programmiere auch C++ halt nur OpenGL anwendungen. Also kannst mal posten währe echt cool.

mfg artus

Verfasst: 21.10.2005 19:43
von NicTheQuick
PS.: "währe" schreibt man ohne "h" --> "wäre". Ich konnte es einfach nicht mehr lesen. /:->

Verfasst: 22.10.2005 02:53
von Zaphod
hier der c code. was dich interessiert wirst du in DrawScene() finden. leider hab ich nurnoch eine sehr alte version. die hier ist ein bischen unsauber und käsig, dafür aber auch gradezu winzig, weil ich da grade erst am anfang des programmes war.
sollte aber demonstrieren was zu tun ist. was hier fehlt ist code, der mit einem gewissen radius verhindert das der spieler zu nah an wände kommt, denn das führt zu fehlern in der darstellungsreihenfolge, wobei der spieler dann auch tatsächlich schon in der wand wäre. es gibt noch andere lösungen für dieses problem, aber ich denke, die ist die einfachste.

noch einfacher ist aber, dass ganze gleich in opengl zu machen und die darstellungsreihenfolge dem zbuffer zu überlassen ;)


Code: Alles auswählen

#include "allegro.h"
#include <stdlib.h>
#include <stdio.h>
#include <math.h>



int tileW=36,tileH=19;
int wallH=120;
int scrW=800,scrH=600;

int displayWidth=22,displayHeight=22;
int camX=0,camY=0;
int mouseX,mouseY;
int mapX,mapY;
int mapMouseX,mapMouseY;

int charaX,charaY;

int mouseOverTileX,mouseOverTileY;
int mouseOverTile=0;

int map[1024][1024];


BITMAP *backBuffer, *testTile, *testWall, *selector, *mouse_pointer, *chara;
PALETTE mainPalette;



void DrawScene(){
	int x,y;
	
	int drawx,drawy;
	//blit(testTile,backBuffer,0,0,0,0,tile_w,tile_h);


	//draw tiles
	for(y=0;y<displayHeight;y++){
		for(x=0;x<displayWidth;x++){
			
			//masked_blit(testTile,backBuffer,0,0, x*tile_w-18, (y/2)*(tile_h+1)-10 , tile_w, tile_h);
			//masked_blit(testTile,backBuffer,0,0, x*tile_w+18-18 , y/2*(tile_h+1)+10-10 , tile_w, tile_h);
			drawx=x*(tileW/2)-(y*(tileW/2))+(scrW/2-tileW/2);
			drawy=y*(tileH/2)+(x*(tileH/2));
			if(map[x+camX][y+camY]<100)
				masked_blit(testTile,backBuffer,0,0, drawx, drawy , tileW, tileH);
			//else
			//	masked_blit(testWall,backBuffer,0,0, drawx, drawy-(wallH-tileH) , tileW, wallH);

		}
	}
	
	int cdrawx,cdrawy,cposx,cposy;

	cposx=charaX/36;
	cposy=charaY/38;



	//draw walls
	for(y=0;y<displayHeight;y++){
		for(x=0;x<displayWidth;x++){
			
			//masked_blit(testTile,backBuffer,0,0, x*tile_w-18, (y/2)*(tile_h+1)-10 , tile_w, tile_h);
			//masked_blit(testTile,backBuffer,0,0, x*tile_w+18-18 , y/2*(tile_h+1)+10-10 , tile_w, tile_h);
			drawx=x*(tileW/2)-(y*(tileW/2))+(scrW/2-tileW/2);
			drawy=y*(tileH/2)+(x*(tileH/2));
			if(map[x+camX][y+camY]>=100)
				masked_blit(testWall,backBuffer,0,0, drawx, drawy-(wallH-tileH) , tileW, wallH);

			if(cposx-camX==x&&cposy-camY==y){
				cdrawx=0;
				cdrawy=0;
				cdrawx=(charaX/36)*(tileW/2)-((charaY/38)*(tileW/2))+(scrW/2-tileW/2);
				cdrawy=(charaY/38)*(tileH/2)+((charaX/36)*(tileH/2));
				float addx,addy;
				addx=charaX%36;
				addy=charaY%38;

				masked_blit(chara,backBuffer,0,0, drawx+(int)((addx-addy)/2), drawy-80+(int)((addy/2+addx/2)/2),41, 98);
			
			}

		}
	}





	


	if(mouseOverTile==1){
		drawx=0;
		drawy=0;
		drawx=mouseOverTileX*(tileW/2)-(mouseOverTileY*(tileW/2))+(scrW/2-tileW/2);
		drawy=mouseOverTileY*(tileH/2)+(mouseOverTileX*(tileH/2));
		masked_blit(selector,backBuffer,0,0, drawx, drawy , tileW, tileH);
	}



	//text_mode(-1);
	textprintf(backBuffer, font, 10, 10, makecol(255,255,255),"camX: %d, camY: %d ",camX,camY );
	textprintf(backBuffer, font, 10, 20, makecol(255,255,255),"mapMouseX: %d, mapMouseY: %d ",mapMouseX,mapMouseY );

	textprintf(backBuffer, font, 10, 40, makecol(255,255,255),"charaMapX: %d, charaMapY: %d ",charaX/36,charaY/38 );

	masked_blit(mouse_pointer,backBuffer,0,0,mouseX,mouseY,11,19);
}

void LoadMap(){
	FILE *fp;

	fp = fopen("test.map","r");
	if(fp!=NULL){
			fread(map,sizeof(map),1,fp);
			fclose(fp);
		}else{
			allegro_message("Could not load map!\n%s\n", allegro_error);
		}
}

void SaveMap(){
	FILE *fp;

	fp = fopen("test.map","w");
	if(fp!=NULL){
			fwrite(map,sizeof(map),1,fp);
			fclose(fp);
		}else{
			allegro_message("Could not write map!\n%s\n", allegro_error);
		}
}


void GetIO(){
	if(key[KEY_RIGHT]){
		camX++;
		if(camX>1024-displayWidth)
			camX=1024-displayWidth;
	}
	if(key[KEY_LEFT]){
		camX--;
		if(camX<0)
			camX=0;

	}
	if(key[KEY_DOWN]){
		camY++;
		if(camY>1024-displayHeight)
			camY=1024-displayHeight;
	}
	if(key[KEY_UP]){
		camY--;
		if(camY<0)
			camY=0;
	}
	//if(key[KEY_S]){
	//	SaveMap();
	//}
	if(key[KEY_L]){
		LoadMap();
	}

	if(key[KEY_PRTSCR]){
		save_bmp("screen_shot.bmp", backBuffer, mainPalette);
	}

	/////

	if(key[KEY_D]){
		charaX++;
		//if(camX>1024-displayWidth)
		//	camX=1024-displayWidth;
	}
	if(key[KEY_A]){
		charaX--;
		if(charaX<0)
			charaX=0;

	}
	if(key[KEY_S]){
		charaY++;
		/*if(camY>1024-displayHeight)
			camY=1024-displayHeight;*/
	}
	if(key[KEY_W]){
		charaY--;
		if(charaY<0)
			charaY=0;
	}

	/////


	mouseX = mouse_x;
	mouseY = mouse_y;
	
	float mouseXN = mouse_x-scrW/2-tileW/2;
	


	//mouseio

	//mapMouseX=((mouseX-scrW/2-tileW/2)/tileW)+(mouseY/tileH);
	//mapMouseY=(mouseY/tileH )-((mouseX-scrW/2-tileW/2)/tileW);
	
	float ftileW=tileW-1.0;
	float ftileH=tileH-1.0;
	float ftileWH=floor((ftileW)/2);
	float scrWH=(scrW/2);
	float fmouseX=mouseX;
	float fmouseY=mouseY;

	mapMouseX=((fmouseX-scrWH-ftileWH)/(ftileW-1))+(fmouseY/ftileH)+1;
	mapMouseY=(fmouseY/(ftileH ))-((fmouseX-scrWH-ftileWH)/ftileW);
	

	

		mouseOverTileX = mapMouseX;
		mouseOverTileY = mapMouseY;
		if(mouseOverTileX>=0&&mouseOverTileX<22&&mouseOverTileY>=0&&mouseOverTileY<22)
			mouseOverTile=1;
		else
			mouseOverTile=0;
}



int main(void){
	allegro_init();
	install_keyboard();
	install_mouse();

	set_color_depth(32);
	if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, scrW, scrH, 0, 0) != 0) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to set any graphic mode\n%s\n", allegro_error);
		return 1;
	}

	set_palette(desktop_palette);
	backBuffer = create_bitmap(scrW,scrH);
	testTile = load_bmp("tile.bmp",mainPalette);
	testWall = load_bmp("wall.bmp",mainPalette);
	selector = load_bmp("selector.bmp",mainPalette);
	mouse_pointer = load_bmp("mouse.bmp",mainPalette);
	chara = load_bmp("elsatest.bmp",mainPalette);
	
	

	while(!key[KEY_ESC]){

		

		GetIO();
		clear_to_color(backBuffer, makecol(50, 50, 255));
		
		DrawScene();

		vsync();
		acquire_screen();
		blit(backBuffer,screen,0,0,0,0,scrW,scrH);
		release_screen();
		
	}
	
	return 0;
}
END_OF_MAIN();