2015-08-05 3 views
1

Я попытался сделать ascii raycaster в C, который запускается в терминале. Я не думаю, что что-то подобное было сделано раньше. Кажется, он неправильно печатает фреймы. Надеюсь, кто-то может сказать мне, в чем проблема. Вот мой код: https://ghostbin.com/paste/9vxmz Я ожидал, что программа отобразит лабиринт (сохраненный в массиве карт) у первого лица. Я еще не реализовал элементы управления. В принципе, существует двумерный массив символов, который является размером экрана терминала. Этот массив должен печатать каждую секунду. Массив экрана получает свои значения от raycaster. Я не знаю точно, где проблема, но она не такая большая. Plz помочь мне совершенно новый для C.C: Raycaster не работает

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/ioctl.h> 
#include <math.h> 
#include <unistd.h> 
int getrows(); 
int getcols(); 
double diagnalMovementX(double x, double angle); 
double diagnalMovementY(double y, double angle); 
#define ROWS getrows()    // the amount of horisontal rows in the terminal 
#define COLS getcols()    // the amount of verticle columns in the terminal 
#define PI 3.14159265358979   // defines pi 
#define TAU 2*PI    // makes things easier because TAU is 360 degrees in radians 
#define DTOR PI/180    // multiply by this to convert degrees to radians 
#define RTOD 180/PI    // multiply by this to convert radians to degrees 
int currentframe=0;    // the current frame 
const int map[13][12]={    // the actual map 
    {1,1,0,1,1,1,1,1,1,1,1,1}, 
    {1,0,0,0,1,0,0,1,0,0,0,1}, 
    {1,1,1,0,1,1,0,1,0,1,0,1}, 
    {1,0,1,0,0,0,0,1,0,1,0,1}, 
    {1,0,1,1,1,1,0,1,1,1,0,1}, 
    {1,0,0,0,0,0,0,1,0,0,0,1}, 
    {1,0,1,0,1,1,1,1,0,1,1,1}, 
    {1,0,1,0,0,0,0,0,0,0,0,1}, 
    {1,0,1,1,1,1,1,1,1,1,0,1}, 
    {1,0,1,0,0,0,0,0,0,0,0,1}, 
    {1,0,1,1,1,1,1,0,1,1,1,1}, 
    {1,0,0,0,1,0,0,0,0,0,0,1}, 
    {1,1,1,1,1,0,1,1,1,1,1,1} 
}; 
int main() { 
    char screen[COLS][ROWS];  // this array is modified and printed every frame 
    double posX=2, posY=0;   // position for the player 
    double direction=0*DTOR;  // direction of the player 
    double fov=0*DTOR;   // the feild of vision 
    double angleBetweenEachRay=fov/COLS; // the angle between each ray 
    double rayX, rayY;   // the position of the end of the ray 
    double rayAngle;   // the angle that the ray travels 
    double distanceToWall;   // the distance the player is away from a wall 
    int lineHeight;    // how many columns the wall should use on the screen 
    int sizeOfBlankSpaces;   // the size that the ceiling and floor should appear on the screen 
    int thisIntPreventsCrashes=0;  // prevents a ray from traveling endlessly 

    // gameloop starts here 
    while (1) { 
     // this allows movement 
     /* NOT IMPLEMENTED YET */ 
     // this loop generates the columns of the frame 
     for (int i=0; i<COLS; i++) { 
      // calculate the ray angle 
      rayAngle=direction-fov/2-angleBetweenEachRay+angleBetweenEachRay*(i+1); 
      // fix the ray angle if it is not a proper value 
      if (rayAngle>TAU) { 
       rayAngle-=TAU; 
      } 
      else if (rayAngle<0) { 
       rayAngle+=TAU; 
      } 
      // makes the ray start from the player 
      rayX=posX; 
      rayY=posY; 
      // increases the ray size 
      rayX=diagnalMovementX(rayX, rayAngle); 
      rayY=diagnalMovementY(rayY, rayAngle); 
      // this code prevents the ray from traveling endlessly and the game from freezing if there is no wall for the ray to hit 
      thisIntPreventsCrashes++; 
      if (thisIntPreventsCrashes>10) { 
       lineHeight=0; 
      } 
      // checks if the ray hit a wall 
      if (map[(int) rayY][(int) rayX]==1) { 
       // calculates the distance to the wall using the distance formula 
       distanceToWall=sqrt(pow((rayX-posX), 2)+pow((rayY-posY), 2)); 
       // calculates the size the wall should appear onscreen 
       lineHeight=ROWS/(10*distanceToWall); 
      } 
      // shows X when there is no wall 
      if (lineHeight==0) { 
       for (int ii=0; ii<ROWS; ii++) { 
        screen[i][ii]='X'; 
       } 
      } 
      else { 
       // calculates the ceiling and floor size 
       sizeOfBlankSpaces=(ROWS-lineHeight)/2; 
       // ceiling 
       for(int ii=0; ii<sizeOfBlankSpaces; ii++) { 
        screen[i][ii]=' '; 
       } 
       // walls 
       for(int ii=sizeOfBlankSpaces; ii<sizeOfBlankSpaces+lineHeight; ii++) { 
        screen[i][ii]=''; 
       } 
       // floor 
       for(int ii=sizeOfBlankSpaces+lineHeight; ii<ROWS; ii++) { 
        screen[i][ii]=' '; 
       } 
      } 
     } 
     // this sets the framerate 
     sleep(1); 
     // this clears the current frame 
     fflush(stdout); 
     //this code prints a new frame 
     for (int iy=0; iy<ROWS; iy++) { 
      for (int ix=0; ix<COLS; ix++) { 
       printf("%c", screen[iy][ix]); 
      } 
      printf("\n"); 
     } 
     currentframe++; 
    } 
    return 0; 
} 
int getrows() { 
    struct winsize w; 
    ioctl(0, TIOCGWINSZ, &w); 
    return w.ws_row; 
} 
int getcols() { 
    struct winsize w; 
    ioctl(0, TIOCGWINSZ, &w); 
    return w.ws_col; 
} 
double diagnalMovementX(double x, double angle) { 
    if (angle<TAU && angle>0.5*TAU) { 
     x-=0.5*cos(angle); 
    } 
    else if (angle>0 && angle<0.5*TAU) { 
     x+=0.5*cos(angle); 
    } 
    return x; 
} 
double diagnalMovementY(double y, double angle) { 
    if (angle<TAU && angle>0.5*TAU) { 
     if (angle<0.75*TAU) { 
      y-=0.5*sin(angle); 
     } 
     else if (angle>0.75*TAU) { 
      y+=0.5*sin(angle); 
     } 
    } 
    else if (angle>0 && angle<0.5*TAU) { 
     if (angle<0.25*TAU) { 
      y+=0.5*sin(angle); 
     } 
     else if (angle>0.25*TAU) { 
      y-=0.5*sin(angle); 
     } 
    } 
    else if (angle==0 || angle==TAU) { 
     y+=0.5; 
    } 
    else if (angle==0.5*TAU) { 
     y-=0.5; 
    } 
    return y; 
} 
+0

Вы можете добавить код на вопрос? Я даже не могу просмотреть ссылку. –

+0

Я добавил код к вопросу. – Benjily3

ответ

0

fflush(stdout); после печати кадра вложенных for s

+0

Не работает. Та же проблема. :( – Benjily3

+0

Это просто показывает на первый взгляд случайные персонажи. – Benjily3

+0

Попробуйте один кадр. Можете ли вы получить это для рендеринга? –

Смежные вопросы