Example #1
0
/*****************************************************************************
    name:    shapeDraw
    action:    draws shape WhichShape in display buffer at
        position (XPos, YPos)
*****************************************************************************/
void shapeDraw(unsigned XPos, unsigned YPos, unsigned WhichShape)
{
    unsigned Index;

    for(Index=0; Index < 4; Index++)
    {    blockDraw(XPos, YPos, Shapes[WhichShape].Color);
        XPos += Shapes[WhichShape].Dir[Index].DeltaX;
        YPos += Shapes[WhichShape].Dir[Index].DeltaY;
    }
    blockDraw(XPos, YPos, Shapes[WhichShape].Color);
}
Example #2
0
/*****************************************************************************
    name:    shapeErase
    action:    erases shape WhichShape in display buffer at
        position (XPos, YPos) by setting its color to zero
*****************************************************************************/
void shapeErase(unsigned XPos, unsigned YPos, unsigned WhichShape)
{
    unsigned Index;

    for(Index=0; Index < 4; Index++)
    {
        blockDraw(XPos, YPos, COLOR_BLACK);
        XPos += Shapes[WhichShape].Dir[Index].DeltaX;
        YPos += Shapes[WhichShape].Dir[Index].DeltaY;
    }
    blockDraw(XPos, YPos, COLOR_BLACK);
}
Example #3
0
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;
}