void Clouds::display(float timeSinceLastFrame, const Matrix4& inverseViewProjection, const Matrix4& view, const Vector3& cameraDirection, const Vector3& cameraPosition, const Vector3& lightDir) { glDisable(GL_DEPTH_TEST); // through all the following passes the "read" buffer will be read // in the "write" buffer comes new data, that will be sorted // i'am hoping to maximes parallism this way: first the data will be upated, but everyone uses the old // then (still rendering) the upated particles will be sorted - frame ended, buffer switch // (so new data is used with a delay!) // move clouds moveClouds(); // render fom renderFOM(inverseViewProjection, cameraDirection, cameraPosition, lightDir); // render clouds renderClouds(lightDir, view); // sort the new hopefully ready particles, while hopefully the screen itself is drawing particleSorting(); // rotate read/write buffer swap(vao_cloudParticleBuffer_Read, vao_cloudParticleBuffer_Write); swap(vbo_cloudParticleBuffer_Read[0], vbo_cloudParticleBuffer_Write[0]); swap(vbo_cloudParticleBuffer_Read[1], vbo_cloudParticleBuffer_Write[1]); swap(vbo_cloudParticleBuffer_Read[2], vbo_cloudParticleBuffer_Write[2]); }
int startGame(SDL_Surface *screen, SDL_Event event, struct resolution res, int level) { // ============================== LEVEL-DATEI ============================== char filepath[50]; sprintf(filepath, "resources/maps/level%d.map", level); FILE *worldFile = fopen(filepath, "r"); if (worldFile == NULL) return FAILURE; char *line = NULL; size_t len = 0; char *tok = NULL; // ============================== HINTERGRUND ============================== Uint32 color = SDL_MapRGB( screen->format, 208, 244, 247 ); // ============================== WELT ============================== // LEVEL-Block suchen do {getline(&line, &len, worldFile);} while(strcmp(line, "==LEVEL==\n") != 0); // erste Zeile: Größe des Levels getline(&line, &len, worldFile); tok = strtok(line, ","); sscanf(tok, "%d", &worldSizeY); tok = strtok(NULL, ","); sscanf(tok, "%d", &worldSizeX); unsigned char world[worldSizeY][worldSizeX]; int column = 0; int row = 0; // lese restliche Zeilen: das eigentliche Level while (row < worldSizeY) { getline(&line, &len, worldFile); tok = strtok(line, ","); column = 0; // lese einzelnen Elemente ein while (tok) { sscanf(tok, "%d", (int *)&world[row][column]); column++; tok = strtok(NULL, ","); } row++; } // berechne Blockgröße blockSize = res.height / worldSizeY; // Gravitation a = 0.6 * ((double) blockSize / 48); // Counter zum Zeichnen der Welt int x; int y; // Lade Grafik für die Blöcke SDL_Surface *tmp = IMG_Load("resources/images/blockset.png"); if (tmp == NULL) { printf("Surface nicht geladen!\n"); printf("%s\n", SDL_GetError()); exit(-1); } else printf("Surface wurde geladen\n"); // skaliere Grafik SDL_Surface *blockset = shrinkSurface(tmp, blockSize * BLOCK_SET_WIDTH, blockSize * BLOCK_SET_HEIGHT); SDL_FreeSurface(tmp); // ============================== OBJEKTE ============================== struct objectListElement *objectList = NULL; // Variable zum Bearbeiten der Liste struct objectListElement *liste; // ============================== SPIELER ============================== struct object player; player.type = 0; player.posX = 0; player.posY = 0; player.sizeX = ((double) 36/48) * blockSize; player.sizeY = blockSize; player.v = 0; player.moveDir = 1; player.moveSpeed = 0; player.frame = 0; // lade Grafik für den Spieler SDL_Surface *tmp1 = IMG_Load("resources/images/player_final.png"); player.sprite = shrinkSurface(tmp1, (int)((double) 36/48 * blockSize * 10), blockSize*2); SDL_FreeSurface(tmp1); // ===== Position aus Leveldatei laden ===== // PLAYER-Block suchen do {getline(&line, &len, worldFile);} while(strcmp(line, "==PLAYER==\n") != 0); // erste Zeile: Position des Spielers getline(&line, &len, worldFile); tok = strtok(line, ","); sscanf(tok, "%d", &player.posX); player.posX *= blockSize; tok = strtok(NULL, ","); sscanf(tok, "%d", &player.posY); player.posY *= blockSize; objectAppend(&objectList, &player); short playMoveLeft = 0; short playMoveRight = 0; unsigned int playerBlockX = 0; unsigned int playerBlockY = 0; unsigned int playerBlockXold = 0; unsigned int playerBlockYold = 0; unsigned char hitbox = 0; // ============================== GEGNER ============================== struct object *enemy; // Lade Grafik für die Gegner SDL_Surface *tmp2 = IMG_Load("resources/images/enemy.png"); SDL_Surface *enemySprite = shrinkSurface(tmp2, (int)((double) 36/48 * blockSize * 10), blockSize*2); SDL_FreeSurface(tmp2); // ENEMYS-Block suchen do {getline(&line, &len, worldFile);} while(strcmp(line, "==ENEMYS==\n") != 0); getline(&line, &len, worldFile); while(strcmp(line, "\n") != 0) { enemy = (struct object*) malloc(sizeof(*enemy)); enemy->type = 1; enemy->sizeX = (int) ((double) 36 / 48 * blockSize); enemy->sizeY = blockSize; enemy->v = 0; enemy->moveDir = 1; enemy->moveSpeed = 3; enemy->frame = 0; enemy->sprite = enemySprite; // Zeile: Position des Gegners tok = strtok(line, ","); sscanf(tok, "%d", &enemy->posX); enemy->posX *= blockSize; tok = strtok(NULL, ","); sscanf(tok, "%d", &enemy->posY); enemy->posY *= blockSize; objectAppend(&objectList, enemy); getline(&line, &len, worldFile); } // ============================== TRIGGER ============================== struct trigger *triggerList = NULL; // TRIGGERS-Block suchen do {getline(&line, &len, worldFile);} while(strcmp(line, "==TRIGGERS==\n") != 0); getline(&line, &len, worldFile); while(strcmp(line, "\n") != 0) { unsigned int triggerX; unsigned int triggerY; unsigned int targetX; unsigned int targetY; unsigned int targetBlock; tok = strtok(line, ","); sscanf(tok, "%u", &triggerX); tok = strtok(NULL, ","); sscanf(tok, "%u", &triggerY); tok = strtok(NULL, ","); sscanf(tok, "%u", &targetX); tok = strtok(NULL, ","); sscanf(tok, "%u", &targetY); tok = strtok(NULL, ","); sscanf(tok, "%u", &targetBlock); triggerAppend(&triggerList, triggerX, triggerY, targetX, targetY, (unsigned char) targetBlock); getline(&line, &len, worldFile); } // ============================== KAMERA ============================== // Variable ist Global camPosition.x = 0; int camPositionXold = 0; // ============================== PUNKTE ============================== score = 0; int scoreRender = 0; SDL_Color scoreColor = {100,100,100,0}; char scoreString[7]; SDL_Surface *scoreText; SDL_Rect scorePosition; scorePosition.y = blockSize/2; scorePosition.x = blockSize/2; // Main-Loop while(SDL_WaitEvent (&event)) { switch(event.type) { // Quit-Event: quit-Flag setzen case SDL_QUIT: { exitCode = EXIT_GAME; goto cleanGame; break; } // Timer-Event: Bildschirm neu zeichnen case SDL_USEREVENT: { // ============================== LOGIK ============================== // Spielersteuerung if(playMoveLeft && playMoveRight == 0) {player.moveDir = -1; player.moveSpeed = 3; } else if(playMoveRight && playMoveLeft == 0) {player.moveDir = 1; player.moveSpeed = 3;} else {player.moveSpeed = 0;} // Bewegung für alle Objekte liste=objectList; objectCollisionAndGravity( liste->object, &world[0][0]); while (liste->next != NULL) { liste=liste->next; objectCollisionAndGravity( liste->object, &world[0][0]); } // Spieler in vertikaler Richtung aus der Welt if(player.posY < 0-blockSize || player.posY > worldSizeY*blockSize) { exitCode = GAME_OVER; goto cleanGame; } // Blocklogik // Körpermitte playerBlockX = (player.posX + player.sizeX / 2) / blockSize; playerBlockY = (player.posY + player.sizeY / 2) / blockSize; // spiele Block sound ab playBlockSound(world[playerBlockY][playerBlockX]); switch(world[playerBlockY][playerBlockX]) { // Goldene Münze case 50: world[playerBlockY][playerBlockX] = 255; score += 50; break; // Silberne Münze case 51: world[playerBlockY][playerBlockX] = 255; score += 30; break; // Bronzefarbene Münze case 52: world[playerBlockY][playerBlockX] = 255; score += 15; break; // Roter Schalter case 53: if(player.v > 0) { playBlockSound(BLOCKS); world[playerBlockY][playerBlockX] = 54; triggerRun(triggerList, &world[0][0], playerBlockX, playerBlockY); score += 10; } break; // Levelausgang case 55: exitCode = score; goto cleanGame; break; // Leere Blöcke case 255: if(playerBlockX != playerBlockXold || playerBlockY != playerBlockYold) { triggerRun(triggerList, &world[0][0], playerBlockX, playerBlockY); } break; } playerBlockXold = playerBlockX; playerBlockYold = playerBlockY; // Füße playerBlockX = (player.posX + player.sizeX / 2) / blockSize; playerBlockY = (player.posY + player.sizeY - 1) / blockSize; switch(world[playerBlockY][playerBlockX]) { // Sprungfeder (Unten) case 57: playBlockSound(BLOCKS + 2); player.v = 2 * -9 * ((double) blockSize / 48); world[playerBlockY][playerBlockX] = 56; break; // Sprungfeder (Oben) case 56: if(player.v > 0) {world[playerBlockY][playerBlockX] = 57;} break; } // Kollision zwischen Spieler und Objekten liste=objectList->next; while (liste != NULL) { hitbox = objectCollisionToObject(&player, liste->object); if(hitbox) { if((hitbox == 4 || hitbox == 8 || hitbox == 12) && player.v > 0) { playBlockSound(BLOCKS + 1); player.v = -9 * ((double) blockSize / 48); struct objectListElement *tmp = liste->next; objectDelete(&objectList, liste); liste = tmp; score += 25; } else { exitCode = GAME_OVER; goto cleanGame; } } else { liste=liste->next; } } // Kamera camPositionXold = camPosition.x; camPosition.x += ((player.posX - res.width / 2 + blockSize / 2) - camPosition.x) / 10; if(camPosition.x < 0) {camPosition.x = 0;} else if(camPosition.x > worldSizeX*blockSize-res.width) {camPosition.x = worldSizeX*blockSize-res.width;} // ============================== RENDERN ============================== // Lösche den Hintergrund SDL_FillRect( screen, NULL, color ); // Wolken renderClouds(screen, camPosition.x - camPositionXold); // Zeichne alle Blöcke for(y = 0; y < res.height/blockSize; y++) { for(x = camPosition.x/blockSize; x < camPosition.x/blockSize+res.width/blockSize+2; x++) { blockDraw(screen, blockset, x, y, blockGet(&world[0][0], x, y)); } } // Zeichne alle Objekte liste=objectList; objectDraw( screen, liste->object ); while (liste->next != NULL) { liste=liste->next; objectDraw( screen, liste->object ); } // Zeichne die Punktzahl // Punktzahl einzeln Hochzählen if(scoreRender < score) {scoreRender++;} sprintf(scoreString, "%06d", scoreRender); scoreText = TTF_RenderText_Solid(font, scoreString, scoreColor); SDL_BlitSurface(scoreText, NULL, screen, &scorePosition); // Zeichne das berechnete Bild SDL_Flip( screen ); break; } // Tasten gedrückt case SDL_KEYDOWN: { switch(event.key.keysym.sym) { // Pfeil-Links case SDLK_LEFT: playMoveLeft = 1; break; // Pfeil-Rechts case SDLK_RIGHT: playMoveRight = 1; break; // Springen case SDLK_SPACE: if(player.v == 0) {player.v = -9 * ((double) blockSize / 48);} break; case SDLK_UP: if(player.v == 0) {player.v = -9 * ((double) blockSize / 48);} break; #ifdef DEBUG // Schwerkraft umkehren case SDLK_q: a *= -1; break; // W case SDLK_w: if(world[(player.posY + player.sizeY / 2) / blockSize - 1][(player.posX + player.sizeX / 2) / blockSize ] < 50) { world[(player.posY + player.sizeY / 2) / blockSize - 1][(player.posX + player.sizeX / 2) / blockSize ] = 255;} else { world[(player.posY + player.sizeY / 2) / blockSize - 1][(player.posX + player.sizeX / 2) / blockSize ] = 4;} break; // S case SDLK_s: if(world[(player.posY + player.sizeY / 2) / blockSize + 1][(player.posX + player.sizeX / 2) / blockSize ] < 50) { world[(player.posY + player.sizeY / 2) / blockSize + 1][(player.posX + player.sizeX / 2) / blockSize ] = 255;} else { world[(player.posY + player.sizeY / 2) / blockSize + 1][(player.posX + player.sizeX / 2) / blockSize ] = 4;} break; // A case SDLK_a: if(world[(player.posY + player.sizeY / 2) / blockSize ][(player.posX + player.sizeX / 2) / blockSize - 1] < 50) { world[(player.posY + player.sizeY / 2) / blockSize ][(player.posX + player.sizeX / 2) / blockSize - 1] = 255;} else { world[(player.posY + player.sizeY / 2) / blockSize ][(player.posX + player.sizeX / 2) / blockSize - 1] = 4;} break; // D case SDLK_d: if(world[(player.posY + player.sizeY / 2) / blockSize ][(player.posX + player.sizeX / 2) / blockSize + 1] < 50) { world[(player.posY + player.sizeY / 2) / blockSize ][(player.posX + player.sizeX / 2) / blockSize + 1] = 255;} else { world[(player.posY + player.sizeY / 2) / blockSize ][(player.posX + player.sizeX / 2) / blockSize + 1] = 4;} break; #endif // Escape case SDLK_ESCAPE: exitCode = EXIT_LEVEL; goto cleanGame; break; // alles andere ignorieren default: break; } break; } // Taste losgelassen case SDL_KEYUP: { switch(event.key.keysym.sym) { case SDLK_LEFT: playMoveLeft = 0; break; case SDLK_RIGHT: playMoveRight = 0; break; default: break; } break; } } } cleanGame: // ============================== AUFRÄUMEN ============================== printf("Gebe Speicher frei ..."); SDL_FreeSurface(blockset); SDL_FreeSurface(player.sprite); SDL_FreeSurface(enemySprite); printf(" done\n"); return exitCode; }