Isometrisch darstellen, aber wie?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Artus
Beiträge: 280
Registriert: 15.01.2005 20:53

Isometrisch darstellen, aber wie?

Beitrag 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:
Benutzeravatar
Green Snake
Beiträge: 1394
Registriert: 22.02.2005 19:08

Beitrag 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:
-.-"
Benutzeravatar
Artus
Beiträge: 280
Registriert: 15.01.2005 20:53

Beitrag 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. :|
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag 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.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag 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.
Benutzeravatar
Artus
Beiträge: 280
Registriert: 15.01.2005 20:53

Beitrag 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
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag 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.
Benutzeravatar
Artus
Beiträge: 280
Registriert: 15.01.2005 20:53

Beitrag 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
Zuletzt geändert von Artus am 21.10.2005 19:50, insgesamt 1-mal geändert.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8812
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Beitrag von NicTheQuick »

PS.: "währe" schreibt man ohne "h" --> "wäre". Ich konnte es einfach nicht mehr lesen. /:->
Benutzeravatar
Zaphod
Beiträge: 2875
Registriert: 29.08.2004 00:40

Beitrag 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();
Antworten