summaryrefslogtreecommitdiff
path: root/backup2.c
diff options
context:
space:
mode:
authorЕгор Львов <workregor@mail.ru>2023-03-27 11:25:27 +0300
committerЕгор Львов <workregor@mail.ru>2023-03-27 11:25:27 +0300
commit3c0a3b8413ee58a3e5678075c862e95f7c8395c6 (patch)
tree8ca9eba9378f921636788fee7664c2bd63bc40ff /backup2.c
Начальный коммит
Diffstat (limited to 'backup2.c')
-rw-r--r--backup2.c361
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