diff options
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | OpenSans-Bold.ttf | bin | 0 -> 224452 bytes | |||
| -rw-r--r-- | main.c | 326 |
3 files changed, 335 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c4a6865 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ +## +# Doom +# +# @main.c +# @version 0.1 + +main: main.c + cc main.c -Wall -lSDL2 -lSDL2_ttf -lm -o doom +# end diff --git a/OpenSans-Bold.ttf b/OpenSans-Bold.ttf Binary files differnew file mode 100644 index 0000000..7b52945 --- /dev/null +++ b/OpenSans-Bold.ttf @@ -0,0 +1,326 @@ +#include <SDL2/SDL.h> +#include <SDL2/SDL_ttf.h> +#include <stdbool.h> +#include <math.h> +// TODO FIRSST get rendering and movement around map working. + +// TODO Enemies, Load maps. Weapons + +struct Tile +{ + int type; + bool discovered; +}; + +struct Player +{ + float x; + float y; + float angle; + int health; +}; + +struct Ray +{ + float angle; + float xDir; + float yDir; + float distance; + int type; +}; + +float shootRay(float xDir, float yDir, float x, float y, float angle, float baseAngle, float map_depth, int map_w, int map_h, struct Tile map[map_w][map_h], int *type) + { + float stepX, stepY, vx, vy, hx, hy; + bool hit; + //Checking Vertical Intersections + if(xDir < 0.0) + { + stepX = -1; + vx = floor(x); + } + else + { + stepX = 1; + vx = ceil(x); + } + if(yDir < 0.0) + vy = y - (fabs(vx - x) * fabs(tan(angle))); + else + vy = y + (fabs(vx - x) * fabs(tan(angle))); + + //printf("xDir: %f yDir: %f\n", xDir, yDir); + //printf("--- Vertical check ---\n"); + //printf("x: %f, y: %f", vx, vy); + if(sqrt(pow(fabs(vx - x), 2) + pow(fabs(vy - y), 2)) > map_depth) + hit = true; + else if(xDir < 0.0 && map[(int)vx - 1][(int)vy].type != 0) + hit = true; + else if(map[(int)vx][(int)vy].type != 0) + hit = true; + else + hit = false; + //printf(" hit: %b\n", hit); + while(!hit) + { + vx += stepX; + if(yDir < 0.0) + vy -= fabs(tan(angle)); + else + vy += fabs(tan(angle)); + //printf("x: %f, y: %f", vx, vy); + if(sqrt(pow(fabs(vx - x), 2) + pow(fabs(vy - y), 2)) > map_depth) + hit = true; + else if(xDir < 0.0 && map[(int)vx - 1][(int)vy].type != 0) + hit = true; + else if(map[(int)vx][(int)vy].type != 0) + hit = true; + //printf(" hit: %b\n", hit); + } + //printf("distance: %f\n", sqrt(pow(fabs(vx - x), 2) + pow(fabs(vy - y), 2))); + //printf("--- Done ---\n\n"); + + //Checking Horizontal Intersections + if(yDir < 0.0) + { + stepY = -1; + hy = floor(y); + } + else + { + stepY = 1; + hy = ceil(y); + } + + if(xDir < 0.0) + hx = x - (fabs(hy - y) / fabs(tan(angle))); + else + hx = x + (fabs(hy - y) / fabs(tan(angle))); + + //printf("--- Horizontal check ---\n"); + //printf("x: %f, y: %f", hx, hy); + if(sqrt(pow(fabs(hx - x), 2) + pow(fabs(y - hy), 2)) > map_depth) + hit = true; + else if(yDir < 0.0 && map[(int)hx][(int)hy - 1].type != 0) + hit = true; + else if(map[(int)hx][(int)hy].type != 0) + hit = true; + else + hit = false; + //printf(" hit: %b\n", hit); + while(!hit) + { + hy += stepY; + if(xDir < 0.0) + hx -= 1/fabs(tan(angle)); + else + hx += 1/fabs(tan(angle)); + //printf("x: %f, y: %f", hx, hy); + if(sqrt(pow(fabs(hx - x), 2) + pow(fabs(hy - y), 2)) > map_depth) + hit = true; + else if(yDir < 0.0 && map[(int)hx][(int)hy - 1].type != 0) + hit = true; + else if(map[(int)hx][(int)hy].type != 0) + hit = true; + //printf(" hit: %b\n", hit); + } + //printf("distance: %f\n", sqrt(pow(fabs(hx - x), 2) + pow(fabs(hy - y), 2))); + //printf("--- Done ---\n\n"); + + float vdistance = sqrt(pow(fabs(vx - x), 2) + pow(fabs(vy - y), 2)), hdistance = sqrt(pow(fabs(hx - x), 2) + pow(fabs(hy - y), 2)); + if(vdistance < hdistance) + { + if((fabs(ceil(vx) - vx) < 0.05) && (fabs(ceil(vy) - vy) < 0.05)) + *type = 0; + else if(xDir < 0.0) + *type = map[(int)vx - 1][(int)vy].type; + else + *type = map[(int)vx][(int)vy].type; + return(vdistance * cos(angle - baseAngle)); + } + else + { + if((fabs(ceil(hx) -hx) < 0.05) && (fabs(ceil(hy) - hy) < 0.05)) + *type = 0; + else if(yDir < 0.0) + *type = map[(int)hx][(int)hy - 1].type; + else + *type = map[(int)hx][(int)hy].type; + return(hdistance * cos(angle - baseAngle)); + } + } + +bool gameLoop(int map_w, int map_h, SDL_Renderer *renderer, SDL_Event event, struct Tile map[map_w][map_h]) + { + int framerate = 30, ticksPerFrame = 1000/framerate, startFrame = 0, ray_n = 150; + float fov = 90 * (M_PI/180), angle_step = fov/ray_n, map_depth = sqrt(pow(map_w, 2) + pow(map_h, 2)); + bool end = false; + + SDL_Rect floor; + floor.w = 640; + floor.h = 240; + floor.x = 0; + floor.y = 240; + + // Make minimap squares 60x60 pixels. DONE + SDL_Rect minimap[map_w][map_h]; + for(int y = 0;y < map_h;y++) + { + for(int x = 0;x < map_w;x++) + { + minimap[x][y].x = x * 60 + 640; + minimap[x][y].y = y * 60; + minimap[x][y].w = 60; + minimap[x][y].h = 60; + } + } + + struct Player player; + player.x = 3.5; + player.y = 3.5; + player.angle = 0.0; + player.health = 10; + + //struct Ray ray[ray_n]; + struct Ray ray[ray_n + 1]; + SDL_Rect rayDisplay[ray_n + 1]; + + while(!end) + { + startFrame = SDL_GetTicks(); + SDL_RenderClear(renderer); + + // Make player shoot out rays from position with an FoV of 60 degrees + for(int i = 0;i <= ray_n;i++) + { + ray[i].angle = player.angle - (fov / 2) + (angle_step * i); + ray[i].xDir = cos(ray[i].angle); + ray[i].yDir = sin(ray[i].angle); + + ray[i].distance = shootRay(ray[i].xDir, ray[i].yDir, player.x, player.y, ray[i].angle, player.angle, map_depth, map_w, map_h, map, &ray[i].type); + } + + /* --- CONTROLS --- */ + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_KEYDOWN: + switch(event.key.keysym.sym) + { + case SDLK_w: + player.x += cos(player.angle); + player.y += sin(player.angle); + break; + case SDLK_s: + player.x -= cos(player.angle); + player.y -= sin(player.angle); + break; + case SDLK_a: + player.angle -= 5 * angle_step; + if(player.angle < 0) + player.angle += 2 * M_PI; + break; + case SDLK_d: + player.angle += 5 * angle_step; + if(player.angle > 2 * M_PI) + player.angle -= 2 * M_PI; + break; + } + break; + case SDL_QUIT: + return true; + break; + } + } + + /* --- RENDERING --- */ + SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255); + SDL_RenderFillRect(renderer, &floor); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + for(int y = 0;y < map_h;y++) + { + for(int x = 0;x < map_w;x++) + { + if(map[x][y].type == 0) + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + if(map[x][y].type == 1) + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + if(map[x][y].type == 2) + SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); + if(map[x][y].type == 3) + SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); + SDL_RenderFillRect(renderer, &minimap[x][y]); + SDL_SetRenderDrawColor(renderer, 100, 100, 100, 50); + SDL_RenderDrawLine(renderer, (x * 60) + 640, y * 60, (x * 60) + 700, y * 60); + SDL_RenderDrawLine(renderer, (x * 60) + 640, y * 60, (x * 60) + 640, (y * 60) + 60); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + } + } + + for(int i = 0;i <= ray_n;i++) + { + rayDisplay[i].w = 640 / ray_n; + rayDisplay[i].h = 300 / ray[i].distance; + rayDisplay[i].x = i * (640 / ray_n); + rayDisplay[i].y = 240 - (rayDisplay[i].h / 2); + if(ray[i].type == 0) + SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255); + else if(ray[i].type == 1) + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + else if(ray[i].type == 2) + SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); + else if(ray[i].type == 3) + SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255); + SDL_RenderFillRect(renderer, &rayDisplay[i]); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderDrawLine(renderer, (player.x * 60) + 640, player.y * 60, ((player.x + cos(ray[i].angle) * ray[i].distance) * 60) + 640, (player.y + sin(ray[i].angle) * ray[i].distance) * 60); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + } + + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderDrawLine(renderer, (player.x * 60) + 640, player.y * 60, ((player.x + cos(player.angle)) * 60) + 640, (player.y + sin(player.angle)) * 60); + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + SDL_RenderPresent(renderer); + int ticks = startFrame - SDL_GetTicks(); + if(ticks < ticksPerFrame) + SDL_Delay(ticksPerFrame - ticks); + } + return true; + } + +int main() + { + int map_w = 8, map_h = 8; + struct Tile map[map_w][map_h]; + bool quit = false; + for(int y = 0;y < map_h;y++) + { + for(int x = 0;x < map_w;x++) + { + if(x == 0 || x == map_w - 1 || y == 0 || y == map_h - 1) + map[x][y].type = 1; + else if(x == 3 && y == 5) + map[x][y].type = 2; + else if(x == 2 && y >= 2 && y <= 6) + map[x][y].type = 3; + else + map[x][y].type = 0; + } + } + + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Event event; + + SDL_Init(SDL_INIT_VIDEO); + TTF_Init(); + + window = SDL_CreateWindow("Doom", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640 + 480, 480, SDL_WINDOW_OPENGL); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + + while(!quit) + { + quit = gameLoop(map_w, map_h, renderer, event, map); + } + } |
