0% found this document useful (0 votes)
20 views7 pages

Prova 3 ic

The document is a C program that uses the SDL library to create a game titled 'Rabbit to the Hole'. The game features a character that navigates through lanes while avoiding enemies, with mechanics for spawning enemies, handling collisions, and updating the score. It includes functions for initializing the game, rendering graphics, and processing user input.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views7 pages

Prova 3 ic

The document is a C program that uses the SDL library to create a game titled 'Rabbit to the Hole'. The game features a character that navigates through lanes while avoiding enemies, with mechanics for spawning enemies, handling collisions, and updating the score. It includes functions for initializing the game, rendering graphics, and processing user input.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

#include <SDL.

h>
#include <SDL_image.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL_ttf.h>

#define SCREEN_WIDTH 800


#define SCREEN_HEIGHT 600
#define NUM_LANES 9
#define MAX_ENEMIES_PER_LANE 2
#define ENEMY_WIDTH SCREEN_WIDTH / 15
#define ENEMY_HEIGHT SCREEN_HEIGHT / NUM_LANES

SDL_Window* gWindow = NULL;


SDL_Renderer* gRenderer = NULL;
SDL_Texture* gCharacterTexture = NULL;

int currentLane = 8;
int targetLane = 0;

SDL_Texture* gTextTexture = NULL;


TTF_Font* gFont = NULL;
int clickCounter = 0;
int clickEvents = 0;
float result = 0;

struct Character {
int x, y;
int speed;
};

struct Lane {
int x1, y1, x2, y2;
Uint8 colorR, colorG, colorB, colorA;
int numEnemies;
};

struct Enemy {
int x, y;
int speed;
Uint8 colorR, colorG, colorB, colorA;
int direction;
};

struct Character character;


struct Lane lanes[NUM_LANES];
struct Enemy enemies[NUM_LANES][MAX_ENEMIES_PER_LANE];

int initialize() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) { return 0; }

gWindow = SDL_CreateWindow("Rabbit to the Hole", SDL_WINDOWPOS_UNDEFINED,


SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL) { return 0; }

gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);


if (gRenderer == NULL) { return 0; }
SDL_SetRenderDrawColor(gRenderer, 255, 255, 255, 255);

int imgFlags = IMG_INIT_PNG;


if (!(IMG_Init(imgFlags) & imgFlags)) { return 0; }
if (TTF_Init() == -1) { return 0; }

gFont = TTF_OpenFont("font.otf", 28);


if (gFont == NULL) { return 0; }

return 1;
}

float calculateResult(int n) {
float function = 1000.0f * (5.0f / n);
return function;
}

void renderText(const char* text, int x, int y, int fontSize) {


SDL_Color textColor = { 255, 255, 255 };

TTF_Font* font = TTF_OpenFont("font.otf", fontSize);


if (font == NULL) { return; }

SDL_Surface* textSurface = TTF_RenderText_Solid(font, text, textColor);


TTF_CloseFont(font);

if (textSurface == NULL) { return; }

gTextTexture = SDL_CreateTextureFromSurface(gRenderer, textSurface);


SDL_FreeSurface(textSurface);

if (gTextTexture == NULL) { return; }

int textWidth, textHeight;


SDL_QueryTexture(gTextTexture, NULL, NULL, &textWidth, &textHeight);

SDL_Rect destRect = { x, y, textWidth, textHeight };


SDL_RenderCopy(gRenderer, gTextTexture, NULL, &destRect);
}

int loadMedia() {
SDL_Surface* surface = IMG_Load("cuelho.png");
if (surface == NULL) { return 0;}

gCharacterTexture = SDL_CreateTextureFromSurface(gRenderer, surface);


SDL_FreeSurface(surface);

if (gCharacterTexture == NULL) { return 0; }

return 1;
}

void initializeLanes() {
int laneHeight = SCREEN_HEIGHT / NUM_LANES;

for (int i = 0; i < NUM_LANES; ++i) {


lanes[i].x1 = 0;
lanes[i].y1 = i * laneHeight;
lanes[i].x2 = SCREEN_WIDTH;
lanes[i].y2 = lanes[i].y1;

lanes[i].colorR = 255;
lanes[i].colorG = 0;
lanes[i].colorB = 0;

lanes[i].colorA = 255;
lanes[i].numEnemies = 0;
}
}

void spawnEnemy(int laneIndex) {


int laneHeight = SCREEN_HEIGHT / NUM_LANES;

if (lanes[laneIndex].numEnemies < MAX_ENEMIES_PER_LANE) {


int enemyIndex = lanes[laneIndex].numEnemies;

enemies[laneIndex][enemyIndex].y = rand() % laneHeight +


lanes[laneIndex].y1;

if (rand() % 2 == 0) {
enemies[laneIndex][enemyIndex].x = SCREEN_WIDTH;
}
else {
enemies[laneIndex][enemyIndex].x = -ENEMY_WIDTH;
}

enemies[laneIndex][enemyIndex].speed = rand() % 10 * 1;

if (enemies[laneIndex][enemyIndex].x < 0) {
enemies[laneIndex][enemyIndex].direction = 1;
}
else {
enemies[laneIndex][enemyIndex].direction = -1;
}

enemies[laneIndex][lanes[laneIndex].numEnemies].colorR = 255;
enemies[laneIndex][lanes[laneIndex].numEnemies].colorG = 0;
enemies[laneIndex][lanes[laneIndex].numEnemies].colorB = 0;
enemies[laneIndex][lanes[laneIndex].numEnemies].colorA = 255;

if (enemies[laneIndex][lanes[laneIndex].numEnemies].direction == 1) {
enemies[laneIndex][lanes[laneIndex].numEnemies].x = -ENEMY_WIDTH;
}
else {
enemies[laneIndex][lanes[laneIndex].numEnemies].x = SCREEN_WIDTH;
}
enemies[laneIndex][lanes[laneIndex].numEnemies].y = lanes[laneIndex].y1;

lanes[laneIndex].numEnemies++;
}
}

void initializeEnemies() {
srand((unsigned int)time(NULL));

for (int i = 0; i < NUM_LANES; ++i) {


spawnEnemy(i);
}
}

int checkCollision(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
{
return (x1 < x2 + w2 && x1 + w1 > x2 && y1 < y2 + h2 && y1 + h1 > y2);
}

void handleEvents(SDL_Event* e) {
if (e->type == SDL_QUIT) {
SDL_DestroyTexture(gCharacterTexture);
SDL_DestroyRenderer(gRenderer);
SDL_DestroyWindow(gWindow);
IMG_Quit();
SDL_Quit();
exit(0);
}
else if (e->type == SDL_KEYDOWN) {
if (e->key.keysym.sym == SDLK_LEFT || e->key.keysym.sym == SDLK_a) {
character.x -= 10;
clickCounter++;
}
else if (e->key.keysym.sym == SDLK_RIGHT || e->key.keysym.sym == SDLK_d) {
character.x += 10;
clickCounter++;
}
else if (e->key.keysym.sym == SDLK_DOWN || e->key.keysym.sym == SDLK_s) {
if (currentLane < NUM_LANES - 1) {
currentLane++;
character.y = lanes[currentLane].y1;
clickCounter++;
}
}
else if (e->key.keysym.sym == SDLK_UP || e->key.keysym.sym == SDLK_w) {
if (currentLane > 0) {
currentLane--;
character.y = lanes[currentLane].y1;
clickCounter++;
}
}
}

if (character.x < 0) {
character.x = 0;
}
else if (character.x > SCREEN_WIDTH - SCREEN_WIDTH / 10) {
character.x = SCREEN_WIDTH - SCREEN_WIDTH / 10;
}
}

void moveEnemies() {
for (int i = 0; i < NUM_LANES; ++i) {
int removeIndices[MAX_ENEMIES_PER_LANE];
int numToRemove = 0;

for (int j = 0; j < lanes[i].numEnemies; ++j) {


enemies[i][j].x += enemies[i][j].speed * enemies[i][j].direction;
if ((enemies[i][j].x < -SCREEN_WIDTH / 15 && enemies[i][j].direction ==
-1) || (enemies[i][j].x > SCREEN_WIDTH && enemies[i][j].direction == 1)) {
spawnEnemy(i);
removeIndices[numToRemove] = j;
numToRemove++;
}
}

for (int k = 0; k < numToRemove; ++k) {


for (int l = removeIndices[k] + 1; l < lanes[i].numEnemies; ++l) {
enemies[i][l - 1] = enemies[i][l];
}
}

lanes[i].numEnemies -= numToRemove;
}
}

void update() {
moveEnemies();

for (int i = 0; i < lanes[currentLane].numEnemies; ++i) {


if (checkCollision(character.x, character.y, SCREEN_WIDTH / 10,
SCREEN_HEIGHT / NUM_LANES,
enemies[currentLane][i].x, enemies[currentLane][i].y, ENEMY_WIDTH,
ENEMY_HEIGHT)) {
currentLane = 8;
character.y = lanes[currentLane].y1;
break;
}
}

if (currentLane == targetLane) {
clickCounter += clickEvents;
result += calculateResult(clickCounter);
clickEvents = 0;
clickCounter = 0;
currentLane = 8;
character.y = lanes[currentLane].y1;
}
}

void render() {
SDL_SetRenderDrawColor(gRenderer, 0, 128, 0, 255);
SDL_RenderClear(gRenderer);

for (int i = 0; i < NUM_LANES; ++i) {


for (int j = 0; j < lanes[i].numEnemies; ++j) {
SDL_Rect entityRect = { enemies[i][j].x, enemies[i][j].y, ENEMY_WIDTH,
ENEMY_HEIGHT };
SDL_SetRenderDrawColor(gRenderer, enemies[i][j].colorR, enemies[i]
[j].colorG, enemies[i][j].colorB, enemies[i][j].colorA);
SDL_RenderFillRect(gRenderer, &entityRect);
}
}

SDL_Rect characterRect = { character.x, character.y, SCREEN_WIDTH / 10,


SCREEN_HEIGHT / NUM_LANES };
SDL_RenderCopy(gRenderer, gCharacterTexture, NULL, &characterRect);

char resultText[50];
snprintf(resultText, sizeof(resultText), "Score: %.2f", result);
SDL_Color textColor = { 255, 255, 255 };
renderText(resultText, 10, 10, 28, textColor);

SDL_RenderPresent(gRenderer);
}

int main(int argc, char* args[]) {


if (!initialize()) {return -1;}

if (!loadMedia()) {return -1;}

initializeLanes();
initializeEnemies();

character.x = (SCREEN_WIDTH - SCREEN_WIDTH / 10) / 2;


character.y = SCREEN_HEIGHT - SCREEN_HEIGHT / NUM_LANES;
character.speed = 10;

SDL_Event e;

const unsigned int FRAME_DELAY = 1000 / 60;

while (currentLane != targetLane) {


Uint32 startTime = SDL_GetTicks();

while (SDL_PollEvent(&e) != 0) {
handleEvents(&e);
if (e.type == SDL_MOUSEBUTTONDOWN) {
int mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);

if (mouseX >= SCREEN_WIDTH - 50 && mouseX <= SCREEN_WIDTH && mouseY


>= 0 && mouseY <= 50) {
SDL_DestroyTexture(gCharacterTexture);
SDL_DestroyRenderer(gRenderer);
SDL_DestroyWindow(gWindow);
IMG_Quit();
SDL_Quit();
exit(0);
}
}
}

update();
render();

if (lanes[currentLane].numEnemies < MAX_ENEMIES_PER_LANE) {


spawnEnemy(currentLane);
spawnEnemy(1);
spawnEnemy(2);
spawnEnemy(3);
spawnEnemy(4);
spawnEnemy(5);
spawnEnemy(6);
spawnEnemy(7);
spawnEnemy(8);
}

Uint32 elapsedTime = SDL_GetTicks() - startTime;


Uint32 remainingTime = (elapsedTime < FRAME_DELAY) ? (FRAME_DELAY -
elapsedTime) : 0;

while (remainingTime > 0) {


elapsedTime = SDL_GetTicks() - startTime;
remainingTime = (elapsedTime < FRAME_DELAY) ? (FRAME_DELAY -
elapsedTime) : 0;
}
}

SDL_DestroyTexture(gCharacterTexture);
SDL_DestroyRenderer(gRenderer);
SDL_DestroyWindow(gWindow);
IMG_Quit();
SDL_Quit();

return 0;
}

You might also like