Advertisement
Willium_Bob_Cole

MigRay 1.03 - now with strafing

Mar 22nd, 2014
158
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.99 KB | None | 0 0
  1. #include <iostream>
  2. #include <Windows.h>
  3. #include <time.h>       /* clock_t, clock, CLOCKS_PER_SEC */
  4. #include <math.h>       /* sqrt */
  5.  
  6. using namespace std;
  7.  
  8. //use these chars for depth: from # to N to V to / on one set, and % to & to : to . on the other
  9.  
  10. //globals
  11. //engine--------------------------------------------------------------
  12. #define MAP_WIDTH 32
  13. #define MAP_HEIGHT 32
  14.  
  15. #define SCREEN_WIDTH 72
  16. #define SCREEN_HEIGHT 72
  17.  
  18.  
  19. int worldMap[MAP_HEIGHT][MAP_WIDTH] =
  20. {
  21.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
  22.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
  23.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
  24.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
  25.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
  26.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
  27.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1},
  28.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,1,1,1,1,1,1},
  29.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  30.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  31.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  32.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  33.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  34.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  35.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  36.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  37.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  38.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  39.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  40.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  41.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  42.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  43.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  44.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  45.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  46.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  47.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  48.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  49.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  50.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  51.     {1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  52.     {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
  53. };
  54.  
  55.  
  56. char screenMap[SCREEN_HEIGHT][SCREEN_WIDTH];
  57.  
  58.  
  59. //game--------------------------------------
  60. bool running;
  61.  
  62. clock_t oldTime = 0;
  63. clock_t frameTime = 0;
  64.  
  65.  
  66. //player------------------------------------
  67. double playerPosX = (MAP_WIDTH/2), playerPosY = (MAP_HEIGHT/2); //spawn in middle of map
  68. double playerDirX = -1, playerDirY = 0; //initial direction vector
  69. double planeX = 0, planeY = 0.66; //2d raycaster version of camera plane
  70. double moveSpeed;
  71. double rotSpeed;
  72.  
  73.  
  74. //functions---------------------------------
  75. void init();
  76. void gameLoop();
  77. void updatePos();
  78. void updateWorld();
  79. void drawScreen();
  80. void writeToBuffer();
  81. void printScreen();
  82. int getTime();
  83. float getFPS();
  84. void getInput();
  85. void movement();
  86.  
  87.  
  88. //main program-------------------------------------------------------------
  89. int main()
  90. {
  91.     init();
  92.  
  93.     gameLoop();
  94.  
  95.     cin.get();
  96.  
  97.     return 0;
  98. }
  99.  
  100.  
  101. //initialise (load map, spawn player, etc.)--------------------------------
  102. void init()
  103. {
  104.     running = true;
  105. }
  106.  
  107.  
  108. void gameLoop()
  109. {
  110.     while(running)
  111.     {
  112.         updatePos();
  113.         updateWorld();
  114.         drawScreen();
  115.         printScreen();
  116.         getInput();
  117.     }
  118. }
  119.  
  120.  
  121. void updatePos()
  122. {
  123.    
  124. }
  125.  
  126.  
  127. void updateWorld()
  128. {
  129.  
  130. }
  131.  
  132.  
  133. void drawScreen()
  134. {
  135.     for(int x = 0; x < SCREEN_WIDTH; x++)
  136.     {
  137.         //calculate ray position and direction
  138.         double cameraX = 2 * x / double(SCREEN_WIDTH) - 1; //x-coordinate in camera space
  139.         double rayPosX = playerPosX;
  140.         double rayPosY = playerPosY;
  141.         double rayDirX = playerDirX + planeX * cameraX;
  142.         double rayDirY = playerDirY + planeY * cameraX;
  143.  
  144.  
  145.         //which box of the map we're in  
  146.         int mapX = int(rayPosX);
  147.         int mapY = int(rayPosY);
  148.        
  149.         //length of ray from current position to next x or y-side
  150.         double sideDistX;
  151.         double sideDistY;
  152.        
  153.         //length of ray from one x or y-side to next x or y-side
  154.         double deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
  155.         double deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
  156.         double perpWallDist;
  157.        
  158.         //what direction to step in x or y-direction (either +1 or -1)
  159.         int stepX;
  160.         int stepY;
  161.        
  162.         int hit = 0; //was there a wall hit?
  163.         int side; //was a NS or a EW wall hit?
  164.  
  165.  
  166.         //calculate step and initial sideDist
  167.         if (rayDirX < 0)
  168.         {
  169.             stepX = -1;
  170.             sideDistX = (rayPosX - mapX) * deltaDistX;
  171.         }
  172.         else
  173.         {
  174.             stepX = 1;
  175.             sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;
  176.         }
  177.         if (rayDirY < 0)
  178.         {
  179.             stepY = -1;
  180.             sideDistY = (rayPosY - mapY) * deltaDistY;
  181.         }
  182.         else
  183.         {
  184.             stepY = 1;
  185.             sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;
  186.         }
  187.  
  188.  
  189.         //perform DDA
  190.         while (hit == 0)
  191.         {
  192.             //jump to next map square, in x-direction, OR in y-direction
  193.             if (sideDistX < sideDistY)
  194.             {
  195.                 sideDistX += deltaDistX;
  196.                 mapX += stepX;
  197.                 side = 0;
  198.             }
  199.  
  200.             else
  201.             {
  202.                 sideDistY += deltaDistY;
  203.                 mapY += stepY;
  204.                 side = 1;
  205.             }
  206.             //Check if ray has hit a wall
  207.             if (worldMap[mapX][mapY] > 0) hit = 1;
  208.         }
  209.  
  210.  
  211.         //Calculate distance projected on camera direction (oblique distance will give fisheye effect!)
  212.         if (side == 0)
  213.         perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
  214.         else
  215.         perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
  216.  
  217.  
  218.         //Calculate height of line to draw on screen
  219.         int lineHeight = abs(int(SCREEN_HEIGHT / perpWallDist));
  220.        
  221.         //calculate lowest and highest char to fill in current stripe
  222.         int drawStart = -lineHeight / 2 + SCREEN_HEIGHT / 2;
  223.         if(drawStart < 0)drawStart = 0;
  224.         int drawEnd = lineHeight / 2 + SCREEN_HEIGHT / 2;
  225.         if(drawEnd >= SCREEN_HEIGHT)drawEnd = SCREEN_HEIGHT - 1;
  226.  
  227.  
  228.         //choose wall color
  229.         //ColorRGB color;
  230.         switch(worldMap[mapX][mapY])
  231.         {
  232.             case 1:  'M';  break;
  233.             case 2:  '#';  break;
  234.             case 3:  '=';   break;
  235.             case 4:  '-';  break;
  236.             default: '0'; break;
  237.         }
  238.        
  239.         //give x and y sides different brightness
  240.         //if (side == 1) {color = color / 2;}
  241.  
  242.         //draw the pixels of the stripe as a vertical line
  243.         //verLine(x, drawStart, drawEnd, color);
  244.        
  245.         for(int y = 0; y < SCREEN_HEIGHT; y++)
  246.         {
  247.             if(y >= drawStart && y <= drawEnd)
  248.             {
  249.                 screenMap[x][y] = '#';
  250.  
  251.                 if(side == 1) screenMap[x][y] = '%';
  252.             }
  253.             else screenMap[x][y] = ' ';
  254.         }
  255.     }
  256.    
  257.     writeToBuffer();
  258. }
  259.  
  260.  
  261. void writeToBuffer()
  262. {
  263.     HANDLE hOutput = (HANDLE)GetStdHandle( STD_OUTPUT_HANDLE );
  264.  
  265.     COORD dwBufferSize = { SCREEN_WIDTH,SCREEN_HEIGHT };
  266.     COORD dwBufferCoord = { 0, 0 };
  267.     SMALL_RECT rcRegion = { 0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
  268.  
  269.     CHAR_INFO buffer[SCREEN_HEIGHT][SCREEN_WIDTH];
  270.  
  271.     ReadConsoleOutput( hOutput, (CHAR_INFO *)buffer, dwBufferSize,
  272.     dwBufferCoord, &rcRegion );
  273.  
  274.     for(int y = 0; y < SCREEN_HEIGHT; y++)
  275.     {
  276.         for(int x = 0; x < SCREEN_WIDTH; x++)
  277.         {
  278.             buffer[y][x].Char.AsciiChar = screenMap[x][y];
  279.             buffer[y][x].Attributes = 0x0E;
  280.         }
  281.     }
  282.  
  283.     /*buffer[5][11].Char.AsciiChar = 'i';
  284.     buffer[5][11].Attributes = 0x0B;
  285.     buffer[5][12].Char.AsciiChar = '!';
  286.     buffer[5][12].Attributes = 0x0A;*/
  287.  
  288.     system ("CLS");
  289.  
  290.     WriteConsoleOutput( hOutput, (CHAR_INFO *)buffer, dwBufferSize,
  291.     dwBufferCoord, &rcRegion );
  292. }
  293.  
  294.  
  295. void printScreen()
  296. {
  297.     /*
  298.     for(int y = 0; y < SCREEN_HEIGHT; y++)
  299.     {
  300.         for(int x = 0; x < SCREEN_WIDTH; x++)
  301.         {
  302.             cout << screenMap[x][y];
  303.         }
  304.  
  305.         cout << endl;
  306.     }*/
  307.  
  308.     cout << "Time Elapsed: " << getTime() << " seconds" << endl;
  309.     cout << "move speed: " << float(moveSpeed) << "\tposition: " << playerPosX << ", " << playerPosY << endl;
  310.     cout << /*"rot speed: " << float(rotSpeed) <<*/ "\trotation: " << playerDirX << ", " << playerDirY << endl;
  311.     cout << "FPS " << (1.0 / getFPS());
  312. }
  313.  
  314.  
  315. int getTime()
  316. {
  317.     oldTime = frameTime;
  318.  
  319.     frameTime = clock();
  320.  
  321.     float time = ((float)frameTime)/CLOCKS_PER_SEC;
  322.  
  323.     //speed modifiers
  324.     moveSpeed = ((frameTime - oldTime) / 1000.0) * 3; //the constant value is in squares/second
  325.     rotSpeed = ((frameTime - oldTime) / 1000.0) * 1.25; //the constant value is in radians/second
  326.  
  327.     return time;
  328. }
  329.  
  330.  
  331. float getFPS()
  332. {
  333.     return (frameTime - oldTime) * 1000;
  334. }
  335.  
  336.  
  337. void getInput()
  338. {
  339.     //move forward if no wall in front of you
  340.     if (GetAsyncKeyState(0x57))
  341.     {
  342.       if(worldMap[int(playerPosX + playerDirX * moveSpeed)][int(playerPosY)] == false) playerPosX += playerDirX * moveSpeed;
  343.       if(worldMap[int(playerPosX)][int(playerPosY + playerDirY * moveSpeed)] == false) playerPosY += playerDirY * moveSpeed;
  344.     }
  345.     //move backwards if no wall behind you
  346.     if (GetAsyncKeyState(0x53))
  347.     {
  348.       if(worldMap[int(playerPosX - playerDirX * moveSpeed)][int(playerPosY)] == false) playerPosX -= playerDirX * moveSpeed;
  349.       if(worldMap[int(playerPosX)][int(playerPosY - playerDirY * moveSpeed)] == false) playerPosY -= playerDirY * moveSpeed;
  350.     }
  351.     //strafe left if no wall left of you
  352.     if (GetAsyncKeyState(0x41))
  353.     {
  354.       if(worldMap[int(playerPosX + (-playerDirY) * moveSpeed)][int(playerPosY)] == false) playerPosX += (-playerDirY) * moveSpeed;
  355.       if(worldMap[int(playerPosX)][int(playerPosY + playerDirX * moveSpeed)] == false) playerPosY += playerDirX * moveSpeed;
  356.     }
  357.     //strafe right if no wall right of you
  358.     if (GetAsyncKeyState(0x44))
  359.     {
  360.       if(worldMap[int(playerPosX + playerDirY * moveSpeed)][int(playerPosY)] == false) playerPosX += playerDirY * moveSpeed;
  361.       if(worldMap[int(playerPosX)][int(playerPosY + (-playerDirX) * moveSpeed)] == false) playerPosY += (-playerDirX) * moveSpeed;
  362.     }
  363.     //rotate to the right
  364.     if (GetAsyncKeyState(VK_RIGHT))
  365.     {
  366.       //both camera direction and camera plane must be rotated
  367.       double oldDirX = playerDirX;
  368.       playerDirX = playerDirX * cos(-rotSpeed) - playerDirY * sin(-rotSpeed);
  369.       playerDirY = oldDirX * sin(-rotSpeed) + playerDirY * cos(-rotSpeed);
  370.       double oldPlaneX = planeX;
  371.       planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed);
  372.       planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed);
  373.     }
  374.     //rotate to the left
  375.     if (GetAsyncKeyState(VK_LEFT))
  376.     {
  377.       //both camera direction and camera plane must be rotated
  378.       double oldDirX = playerDirX;
  379.       playerDirX = playerDirX * cos(rotSpeed) - playerDirY * sin(rotSpeed);
  380.       playerDirY = oldDirX * sin(rotSpeed) + playerDirY * cos(rotSpeed);
  381.       double oldPlaneX = planeX;
  382.       planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed);
  383.       planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed);
  384.     }
  385.     movement();
  386. }
  387.  
  388.  
  389. void movement()
  390. {
  391.  
  392. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement