diff options
Diffstat (limited to 'backup2.c')
-rw-r--r-- | backup2.c | 361 |
1 files changed, 361 insertions, 0 deletions
diff --git a/backup2.c b/backup2.c new file mode 100644 index 0000000..bfdc37f --- /dev/null +++ b/backup2.c @@ -0,0 +1,361 @@ +#include <SDL2/SDL.h> +#include <SDL2/SDL_image.h> +#include <SDL2/SDL_timer.h> + +#include <stdio.h> +#include <math.h> +#include <errno.h> + +#define SPEED 7 +#define RADSPD 0.2 +#define DELAY 40 +#define MAPX 8 +#define MAPY 8 +#define PI 3.1415926535 +#define DEG 0.01745329 +#define HEIGHT 512 +#define WIDTH 1232 +#define TILESIZE 64 +#define SQRTTILE 6 + +struct player +{ + float x; + float y; + float dx; + float dy; + float th; +}; + +float dist(float x1, float y1, float x2, float y2) +{ + return ( sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)) ); +} + +int processEvents(SDL_Window *window, struct player *P, int map[]) +{ + int done = 0; + SDL_Event event; + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_WINDOWEVENT_CLOSE: + { + if(window) + { + SDL_DestroyWindow(window); + window = NULL; + done = 1; + } + } + break; + + case SDL_KEYDOWN: + { + switch(event.key.keysym.sym) + { + case SDLK_ESCAPE: + done = 1; + break; + } + } + break; + + case SDL_QUIT: + done = 1; + break; + } + } + + const Uint8 *state = SDL_GetKeyboardState(NULL); + if(state[SDL_SCANCODE_A]) + P->th -= RADSPD; + + int xoff = 0; + if((P->dx)>0) {xoff = 20;} else {xoff = -20;} + + int yoff = 0; + if((P->dy)>0) {yoff = 20;} else {yoff = -20;} + + int px64 = (int)(P->x) >> SQRTTILE; + int py64 = (int)(P->y) >> SQRTTILE; + + int pxadd = (int)(P->x + xoff) >> SQRTTILE, pyadd = (int)(P->y + yoff) >> SQRTTILE; + int pxsub = (int)(P->x - xoff) >> SQRTTILE, pysub = (int)(P->y - yoff) >> SQRTTILE; + + if(state[SDL_SCANCODE_W]) { + if(map[py64*MAPX + pxadd]==0) {P->x += P->dx;} + if(map[pyadd*MAPX + px64]==0) {P->y += P->dy;} + } + if(state[SDL_SCANCODE_S]) { + if(map[py64*MAPX + pxsub]==0) {P->x -= P->dx;} + if(map[pysub*MAPX + px64]==0) {P->y -= P->dy;} + } + if(state[SDL_SCANCODE_D]) + P->th += RADSPD; + + if(P->th < 0) + P->th = 2*PI - 0.00001; + if(P->th > 2*PI) + P->th = 0.0; + + P->dx = cos(P->th)*SPEED; + P->dy = sin(P->th)*SPEED; + + return done; +} + +void drawLevel(SDL_Renderer *renderer, int map[], struct player P) +{ + for(int y = 0; y<MAPY; y++) + for(int x = 0; x<MAPX; x++) + { + if(map[y*MAPX + x]) + { + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + } else { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); + } + + SDL_Rect wall = {x*TILESIZE, y*TILESIZE, TILESIZE-2, TILESIZE-2}; + SDL_RenderFillRect(renderer, &wall); + } +} + +void drawPlayer(SDL_Renderer *renderer, struct player P) +{ + SDL_SetRenderDrawColor(renderer, 255, 220, 0, 255); + SDL_Rect rect = {P.x-5, P.y-5, 10, 10}; + SDL_RenderFillRect(renderer, &rect); + + SDL_Vertex arrow[3]; + arrow[0].position.x = P.x+5*cos(P.th-PI/2); + arrow[0].position.y = P.y+5*sin(P.th-PI/2); + arrow[0].color.r = 255; + arrow[0].color.g = 220; + arrow[0].color.b = 0; + arrow[0].color.a = 255; + + arrow[1].position.x = P.x+5*cos(P.th+PI/2); + arrow[1].position.y = P.y+5*sin(P.th+PI/2); + arrow[1].color.r = 255; + arrow[1].color.g = 220; + arrow[1].color.b = 0; + arrow[1].color.a = 255; + + arrow[2].position.x = P.x+20*cos(P.th); + arrow[2].position.y = P.y+20*sin(P.th); + arrow[2].color.r = 255; + arrow[2].color.g = 220; + arrow[2].color.b = 0; + arrow[2].color.a = 255; + + SDL_RenderGeometry(renderer, NULL, arrow, 3, NULL, 0); +} + +void drawRays(SDL_Renderer *renderer, struct player P, int map[]) +{ + int mx, my, mp, dof; + float rx, ry, ra, xo, yo, px, py, hlen, vlen, sinra, hx, hy, vx, vy, rdist; + ra=P.th-45*DEG; + if(ra<0) + ra += 2*PI; + if(ra>2*PI) + ra -= 2*PI; + + px = P.x; + py = P.y; + float antan; + for(int r = 0; r<90; r++) + { + // ----- по горизонтальным ----- + hlen = 100000; + dof = 0; + sinra = sin(ra); + if(sinra<-0.001) // "вверх" + { + antan=-1.0/tan(ra); + ry = (((int)py>>SQRTTILE)<<SQRTTILE)-0.0001; + rx = (py-ry)*antan+px; + yo = -TILESIZE; + xo = -yo*antan; + } else { + if(sinra>0.001) + { + antan=-1.0/tan(ra); + ry = (((int)py>>SQRTTILE)<<SQRTTILE)+TILESIZE; + rx = (py-ry)*antan+px; + yo = TILESIZE; + xo = -yo*antan; + } + else + { + rx = px; + ry = py; + dof = 8; + }} + + while(dof<8) + { + mx = (int)(rx)>>SQRTTILE; + my = (int)(ry)>>SQRTTILE; + mp = my*MAPX+mx; + + if(mp > 0 && mp < MAPX*MAPY && map[mp]==1){ + hx = rx; + hy = ry; + hlen = dist(px, py, hx, hy); + dof = 8; + } else { + rx += xo; + ry += yo; + dof++; + } + } + //SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255); + //SDL_RenderDrawLineF(renderer, P.x, P.y, rx, ry); + // ---------- + + // ----- по вертикальным ----- + dof = 0; + vlen = 100000; + float cosra = cos(ra); + if(cosra<-0.001) // "влево" + { + antan=-tan(ra); + rx = (((int)px>>SQRTTILE)<<SQRTTILE)-0.0001; + ry = (px-rx)*antan+py; + xo = -TILESIZE; + yo = -xo*antan; + } else { + if(cosra>0.001) + { + antan=-tan(ra); + rx = (((int)px>>SQRTTILE)<<SQRTTILE)+TILESIZE; + ry = (px-rx)*antan+py; + xo = TILESIZE; + yo = -xo*antan; + } + else + { + rx = px; + ry = py; + dof = 8; + }} + + while(dof<8) + { + mx = (int)(rx)>>SQRTTILE; + my = (int)(ry)>>SQRTTILE; + mp = my*MAPX+mx; + + if(mp > 0 && mp < MAPX*MAPY && map[mp]==1){ + vx = rx; + vy = ry; + vlen = dist(px, py, vx, vy); + dof = 8; + } else { + rx += xo; + ry += yo; + dof++; + } + } + + if(vlen < hlen) + { + rx = vx; ry = vy; rdist = vlen; + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + } + else { rx = hx; ry = hy; rdist = hlen; + SDL_SetRenderDrawColor(renderer, 200, 0, 0, 255); + } + + SDL_RenderDrawLineF(renderer, P.x, P.y, rx, ry); + + // ----- Рисуем стены ----- + float corran = P.th - ra; + if(corran<0) + corran += 2*PI; + if(corran>2*PI) + corran -= 2*PI; + rdist *= cos(corran); // рыбий глаз + //rdist += 20; + + float lineh = (TILESIZE*HEIGHT)/rdist; + if(lineh>HEIGHT) + lineh=HEIGHT; + float lineo = HEIGHT/2 - lineh/2; + + SDL_Rect line = {TILESIZE*MAPX+r*8, lineo, 8, lineh}; + SDL_RenderFillRect(renderer, &line); + + ra += DEG; + if(ra<0) + ra += 2*PI; + if(ra>2*PI) + ra -= 2*PI; + } +} + +void Render(SDL_Renderer *renderer, int map[], struct player P) +{ + SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255); // фон + SDL_RenderClear(renderer); + SDL_SetRenderDrawColor(renderer, 90, 90, 100, 255); // пол + SDL_Rect floor = {0, HEIGHT/2, WIDTH, HEIGHT/2}; + SDL_RenderFillRect(renderer, &floor); + drawLevel(renderer, map, P); + drawRays(renderer, P, map); + drawPlayer(renderer, P); + SDL_RenderPresent(renderer); + SDL_Delay(DELAY); +} + +int main(void) +{ + SDL_Window *window; + SDL_Renderer *renderer; + + SDL_Init(SDL_INIT_VIDEO); + + window = SDL_CreateWindow("Raycast", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + WIDTH, + HEIGHT, + 0); + + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + struct player P = {100, 100, 0, 0, PI/2}; + // int mapT = 64; + int layout[MAPX*MAPY] = + { + 1,1,1,1,1,1,1,1, + 1,0,1,0,0,0,0,1, + 1,0,1,0,0,0,0,1, + 1,0,1,0,0,0,0,1, + 1,0,0,0,0,0,0,1, + 1,0,0,0,0,1,0,1, + 1,0,0,0,0,0,0,1, + 1,1,1,1,1,1,1,1 + }; + + int done = 0; // bool завершения программы + + while(!done) + { + // проверка событий + if(processEvents(window, &P, layout) == 1) + done = 1; + //rendering + Render(renderer, layout, P); + } + + SDL_DestroyWindow(window); + SDL_DestroyRenderer(renderer); + + SDL_Quit(); + printf("!%d!", errno); + return 0; +}
\ No newline at end of file |