Käytän kentän ja tilejen lataukseen tällaista systeemiä, joka on vielä kesken:
main.cpp:
#include <SDL/SDL.h> #include <SDL/SDL_gfxPrimitives.h> #include <string.h> #include <stdio.h> #include <iostream> #include <stdlib.h> #include "hit.h" SDL_Surface *ruutu, *ukko, *lattia, *hiir; SDL_Event events; signed int force = -10; int ukkoy, ukkox, ukkoJumpPos, ukkoJumpStart, hiirix, hiiriy, cursorx, cursory; Uint8 *nappi; #define RES_X 640 #define RES_Y 480 #define UKKOJUMPHEIGHT 10 #define UKKOFALLSPEEDMAX 15 void blit(SDL_Surface*, SDL_Surface*, int, int); int main(int argc, char *argv[]) { SDL_Init(SDL_INIT_VIDEO); ruutu = SDL_SetVideoMode(RES_X, RES_Y, 32, SDL_HWSURFACE | SDL_DOUBLEBUF); SDL_WM_SetCaption("xd", 0); ukko = SDL_LoadBMP("tiles/ukko.bmp"); SDL_SetColorKey(ukko, SDL_SRCCOLORKEY, SDL_MapRGB(ukko->format,255,255,255)); lattia = SDL_LoadBMP("tiles/maa.bmp"); SDL_SetColorKey(lattia, SDL_SRCCOLORKEY, SDL_MapRGB(lattia->format,255,255,255)); hiir = SDL_LoadBMP("hiir.bmp"); SDL_SetColorKey(hiir, SDL_SRCCOLORKEY, SDL_MapRGB(hiir->format, 255,255,255)); if (LoadMap("maps/level0.lev") == MPL_SUCCESS) { std::cout << "onnas" << std::endl; } std::cout << "koko: " << (sizeof(tileDataTaulu) / sizeof(TileData)) << std::endl; SDL_ShowCursor(0); bool running=true; while (running) { SDL_GetMouseState(&hiirix, &hiiriy); SDL_FillRect(ruutu, NULL, SDL_MapRGB(ruutu->format, 0,100,100)) ; nappi = SDL_GetKeyState(NULL); if (nappi[SDLK_LEFT]) { ++ukkox;; } else if(nappi[SDLK_RIGHT]) { --ukkox; } else if(nappi[SDLK_UP]) { ukkoJumpStart = ukkox; } else if(nappi[SDLK_DOWN]) { ++ukkoy; } else if(nappi[SDLK_ESCAPE]) { running=false; } stringRGBA(ruutu, 10, 10, "muikka", 255, 0, 255, 255); while (SDL_PollEvent(&events)) { switch(events.type) { case SDL_QUIT: running=false; break; } } cursorx += (hiirix - cursorx) / 4; cursory += (hiiriy - cursory) / 4; if (ukkoy < (RES_Y - 64)) { ++ukkoy; } blit(ukko, ruutu, ukkox, ukkoy); blit(hiir, ruutu, cursorx-13, cursory-13); blit(tileDataTaulu[6].Data, ruutu, 20, 20); SDL_Flip(ruutu); //SDL_Delay(1); } tyhjennaMuisti(); SDL_Quit(); return 0; } void blit(SDL_Surface *kuva, SDL_Surface *naytto, int x, int y) { SDL_Rect alue; // mille alueellä näyttöä kuva piirretään alue.x = x; // koordinaatit alue.y = y; SDL_BlitSurface(kuva, NULL, naytto, &alue); // piirto }
hit.h:
#define MPL_SUCCESS 1 #define MPL_FILE_NOT_FOUND 2 #define MPL_SYNTAX_ERROR 3 #define MPL_MISSING_TILE 4 struct TilePlacement{ int X; int Y; int ID; }; struct TileData{ int solid; SDL_Surface *Data; }; TileData *tileDataTaulu = NULL; TilePlacement *tilePlacementTaulu = NULL; bool tileDataTauluUsed=false, tilePlacementTauluUsed=false; int LoadMap(char filename[255]) { FILE *tiedosto; tiedosto = fopen(filename, "r"); if (tiedosto!=NULL) { char rivi[256]; bool tiledata=false, mapdata=false, tiledim=false, mapdim=false; unsigned int tileamount, mapSizeX, mapSizeY, menossa; while(!feof(tiedosto)) { fgets(rivi, 255, tiedosto); int paikka = 0; while (paikka < 255) { if (rivi[paikka] == '\r') { rivi[paikka] = '\0'; } else if (rivi[paikka] == '\n') { rivi[paikka] = '\0'; } ++paikka; } std::cout << "Rivi luettu!" << std::endl; std::cout << "\"" << rivi << "\"" << std::endl; if (strcmp(rivi, "TILEDATA") == 0) { tiledata=true; std::cout << "Tiledata alkoi!" << std::endl; } else if (tiledata == true) { if (strcmp(rivi, "MAPDATA") == 0) { tiledata = false; mapdata = true; std::cout << "Mapdata alkoi!" << std::endl; } else if (tiledim == false) { sscanf(rivi, "%d", &tileamount); std::cout << "tilemäärä: " << tileamount << std::endl; if (tileDataTauluUsed) free(tileDataTaulu); tileDataTaulu = (TileData *) realloc(tileDataTaulu, tileamount * sizeof(TileData)); tiledim=true; std::cout << "Suurennettiin tiletaulu." << std::endl; } else if (tiledim == true) { char filu[256]; sscanf(rivi, "%s %d", &filu, &tileDataTaulu[menossa].solid); tileDataTaulu[menossa].Data = SDL_LoadBMP(filu); if (tileDataTaulu[menossa].Data == NULL) { return MPL_MISSING_TILE; } std::cout << "Menossa: " << menossa << std::endl; std::cout << "Ladattiin tile: " << filu << std::endl; ++menossa; } } rivi[0] = '\0'; } } else { return MPL_FILE_NOT_FOUND; } return MPL_SUCCESS; } void tyhjennaMuisti(void) { free(tileDataTaulu); free(tilePlacementTaulu); } /* int CheckHit(Tile lahde, Tile kohde) { int lahdeX2 = lahde.X + lahde.Width; int lahdeY2 = lahde.Y + lahde.Height; int kohdeX2 = kohde.X + kohde.Width; }*/ /* <Metabolix> Tyyppi * Taulu = (Tyyppi *) malloc(Taulun_Koko * sizeof(Tyyppi)); <Metabolix> Taulu = (Tyyppi *) realloc(Taulu, Uusi_Koko * sizeof(Tyyppi)); <Metabolix> free(Taulu); */
Karttana testatessani käytin tätä:
TILEDATA 2 tiles/grass.bmp 0 tiles/crate.bmp 1 MAPDATA 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
Jokin on systeemissä pielessä, sillä tilet löytyvät taulukossa "tileDataTaulu" vasta alkiosta 5 ja 6, vaikka kaiken järjen mukaan niiden kuuluisi olla kohdissa 0 ja 1. Myöskin nuo coutit joita käytin debuggauksessa tulostavat kuvien latauksen kohdalla, että ollaan menossa luvuissa 5 ja 6, vaikka ++menossa ei ole suoritettu vielä kertaakaan. Jos pistän muuttujan "menossa" alustuksessa sille arvoksi 0, ohjelma kaatuu segfaulttiin. Osaisiko joku neuvoa?
Tökkää menossa nollaksi ennen looppiin astumista, sillä muuttujiahan ei laiteta nolliks niitä varatessa.
sooda kirjoitti:
Tökkää menossa nollaksi ennen looppiin astumista, sillä muuttujiahan ei laiteta nolliks niitä varatessa.
Siinä juuri ongelma kun ohjelma kaatuu segfaulttiin, jos noin teen.
EDIT: Joo taas oli oma ajattelemattomuus syynä. Viaksi paljastui se, että kun korjasin tuon "Menossa" muuttujan nollaksi, oli blit hakemassa muistista tavaraa sieltä, mistä ei pitäisi (eli alkiosta numero 6, jota ei ollut). :P
if (tileDataTauluUsed) free(tileDataTaulu); tileDataTaulu = (TileData *) realloc(tileDataTaulu, tileamount * sizeof(TileData));
En nyt jaksanut kaikkea kahlata, mutta tuo näyttää virheeltä. Taulua ei kuulu tuhota ennen reallocia, jos haluaa, että data säilyy. Sitä paitsi tuo teoriassa kaatuu, jos se vapautetaan. Vapautuksen yhteydessä (eli jälkeen) pointterin arvoksi pitäisi laittaa NULL. Et näytä myöskään muuttavan tuossa tileDataTauluUsed-muuttujan arvoa, eli vapautus tapahtuu joka kierroksella.
Aihe on jo aika vanha, joten et voi enää vastata siihen.