Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <Windows.h>
- #include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */
- #include <math.h> /* sqrt */
- using namespace std;
- //use these chars for depth: from # to N to V to / on one set, and % to & to : to . on the other
- //globals
- //engine--------------------------------------------------------------
- #define MAP_WIDTH 32
- #define MAP_HEIGHT 32
- #define SCREEN_WIDTH 72
- #define SCREEN_HEIGHT 72
- int worldMap[MAP_HEIGHT][MAP_WIDTH] =
- {
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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},
- {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}
- };
- char screenMap[SCREEN_HEIGHT][SCREEN_WIDTH];
- //game--------------------------------------
- bool running;
- clock_t oldTime = 0;
- clock_t frameTime = 0;
- //player------------------------------------
- double playerPosX = (MAP_WIDTH/2), playerPosY = (MAP_HEIGHT/2); //spawn in middle of map
- double playerDirX = -1, playerDirY = 0; //initial direction vector
- double planeX = 0, planeY = 0.66; //2d raycaster version of camera plane
- double moveSpeed;
- double rotSpeed;
- //functions---------------------------------
- void init();
- void gameLoop();
- void updatePos();
- void updateWorld();
- void drawScreen();
- void writeToBuffer();
- void printScreen();
- int getTime();
- float getFPS();
- void getInput();
- void movement();
- //main program-------------------------------------------------------------
- int main()
- {
- init();
- gameLoop();
- cin.get();
- return 0;
- }
- //initialise (load map, spawn player, etc.)--------------------------------
- void init()
- {
- running = true;
- }
- void gameLoop()
- {
- while(running)
- {
- updatePos();
- updateWorld();
- drawScreen();
- printScreen();
- getInput();
- }
- }
- void updatePos()
- {
- }
- void updateWorld()
- {
- }
- void drawScreen()
- {
- for(int x = 0; x < SCREEN_WIDTH; x++)
- {
- //calculate ray position and direction
- double cameraX = 2 * x / double(SCREEN_WIDTH) - 1; //x-coordinate in camera space
- double rayPosX = playerPosX;
- double rayPosY = playerPosY;
- double rayDirX = playerDirX + planeX * cameraX;
- double rayDirY = playerDirY + planeY * cameraX;
- //which box of the map we're in
- int mapX = int(rayPosX);
- int mapY = int(rayPosY);
- //length of ray from current position to next x or y-side
- double sideDistX;
- double sideDistY;
- //length of ray from one x or y-side to next x or y-side
- double deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
- double deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
- double perpWallDist;
- //what direction to step in x or y-direction (either +1 or -1)
- int stepX;
- int stepY;
- int hit = 0; //was there a wall hit?
- int side; //was a NS or a EW wall hit?
- //calculate step and initial sideDist
- if (rayDirX < 0)
- {
- stepX = -1;
- sideDistX = (rayPosX - mapX) * deltaDistX;
- }
- else
- {
- stepX = 1;
- sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;
- }
- if (rayDirY < 0)
- {
- stepY = -1;
- sideDistY = (rayPosY - mapY) * deltaDistY;
- }
- else
- {
- stepY = 1;
- sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;
- }
- //perform DDA
- while (hit == 0)
- {
- //jump to next map square, in x-direction, OR in y-direction
- if (sideDistX < sideDistY)
- {
- sideDistX += deltaDistX;
- mapX += stepX;
- side = 0;
- }
- else
- {
- sideDistY += deltaDistY;
- mapY += stepY;
- side = 1;
- }
- //Check if ray has hit a wall
- if (worldMap[mapX][mapY] > 0) hit = 1;
- }
- //Calculate distance projected on camera direction (oblique distance will give fisheye effect!)
- if (side == 0)
- perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
- else
- perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
- //Calculate height of line to draw on screen
- int lineHeight = abs(int(SCREEN_HEIGHT / perpWallDist));
- //calculate lowest and highest char to fill in current stripe
- int drawStart = -lineHeight / 2 + SCREEN_HEIGHT / 2;
- if(drawStart < 0)drawStart = 0;
- int drawEnd = lineHeight / 2 + SCREEN_HEIGHT / 2;
- if(drawEnd >= SCREEN_HEIGHT)drawEnd = SCREEN_HEIGHT - 1;
- //choose wall color
- //ColorRGB color;
- switch(worldMap[mapX][mapY])
- {
- case 1: 'M'; break;
- case 2: '#'; break;
- case 3: '='; break;
- case 4: '-'; break;
- default: '0'; break;
- }
- //give x and y sides different brightness
- //if (side == 1) {color = color / 2;}
- //draw the pixels of the stripe as a vertical line
- //verLine(x, drawStart, drawEnd, color);
- for(int y = 0; y < SCREEN_HEIGHT; y++)
- {
- if(y >= drawStart && y <= drawEnd)
- {
- screenMap[x][y] = '#';
- if(side == 1) screenMap[x][y] = '%';
- }
- else screenMap[x][y] = ' ';
- }
- }
- writeToBuffer();
- }
- void writeToBuffer()
- {
- HANDLE hOutput = (HANDLE)GetStdHandle( STD_OUTPUT_HANDLE );
- COORD dwBufferSize = { SCREEN_WIDTH,SCREEN_HEIGHT };
- COORD dwBufferCoord = { 0, 0 };
- SMALL_RECT rcRegion = { 0, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1 };
- CHAR_INFO buffer[SCREEN_HEIGHT][SCREEN_WIDTH];
- ReadConsoleOutput( hOutput, (CHAR_INFO *)buffer, dwBufferSize,
- dwBufferCoord, &rcRegion );
- for(int y = 0; y < SCREEN_HEIGHT; y++)
- {
- for(int x = 0; x < SCREEN_WIDTH; x++)
- {
- buffer[y][x].Char.AsciiChar = screenMap[x][y];
- buffer[y][x].Attributes = 0x0E;
- }
- }
- /*buffer[5][11].Char.AsciiChar = 'i';
- buffer[5][11].Attributes = 0x0B;
- buffer[5][12].Char.AsciiChar = '!';
- buffer[5][12].Attributes = 0x0A;*/
- system ("CLS");
- WriteConsoleOutput( hOutput, (CHAR_INFO *)buffer, dwBufferSize,
- dwBufferCoord, &rcRegion );
- }
- void printScreen()
- {
- /*
- for(int y = 0; y < SCREEN_HEIGHT; y++)
- {
- for(int x = 0; x < SCREEN_WIDTH; x++)
- {
- cout << screenMap[x][y];
- }
- cout << endl;
- }*/
- cout << "Time Elapsed: " << getTime() << " seconds" << endl;
- cout << "move speed: " << float(moveSpeed) << "\tposition: " << playerPosX << ", " << playerPosY << endl;
- cout << /*"rot speed: " << float(rotSpeed) <<*/ "\trotation: " << playerDirX << ", " << playerDirY << endl;
- cout << "FPS " << (1.0 / getFPS());
- }
- int getTime()
- {
- oldTime = frameTime;
- frameTime = clock();
- float time = ((float)frameTime)/CLOCKS_PER_SEC;
- //speed modifiers
- moveSpeed = ((frameTime - oldTime) / 1000.0) * 3; //the constant value is in squares/second
- rotSpeed = ((frameTime - oldTime) / 1000.0) * 1.25; //the constant value is in radians/second
- return time;
- }
- float getFPS()
- {
- return (frameTime - oldTime) * 1000;
- }
- void getInput()
- {
- //move forward if no wall in front of you
- if (GetAsyncKeyState(0x57))
- {
- if(worldMap[int(playerPosX + playerDirX * moveSpeed)][int(playerPosY)] == false) playerPosX += playerDirX * moveSpeed;
- if(worldMap[int(playerPosX)][int(playerPosY + playerDirY * moveSpeed)] == false) playerPosY += playerDirY * moveSpeed;
- }
- //move backwards if no wall behind you
- if (GetAsyncKeyState(0x53))
- {
- if(worldMap[int(playerPosX - playerDirX * moveSpeed)][int(playerPosY)] == false) playerPosX -= playerDirX * moveSpeed;
- if(worldMap[int(playerPosX)][int(playerPosY - playerDirY * moveSpeed)] == false) playerPosY -= playerDirY * moveSpeed;
- }
- //strafe left if no wall left of you
- if (GetAsyncKeyState(0x41))
- {
- if(worldMap[int(playerPosX + (-playerDirY) * moveSpeed)][int(playerPosY)] == false) playerPosX += (-playerDirY) * moveSpeed;
- if(worldMap[int(playerPosX)][int(playerPosY + playerDirX * moveSpeed)] == false) playerPosY += playerDirX * moveSpeed;
- }
- //strafe right if no wall right of you
- if (GetAsyncKeyState(0x44))
- {
- if(worldMap[int(playerPosX + playerDirY * moveSpeed)][int(playerPosY)] == false) playerPosX += playerDirY * moveSpeed;
- if(worldMap[int(playerPosX)][int(playerPosY + (-playerDirX) * moveSpeed)] == false) playerPosY += (-playerDirX) * moveSpeed;
- }
- //rotate to the right
- if (GetAsyncKeyState(VK_RIGHT))
- {
- //both camera direction and camera plane must be rotated
- double oldDirX = playerDirX;
- playerDirX = playerDirX * cos(-rotSpeed) - playerDirY * sin(-rotSpeed);
- playerDirY = oldDirX * sin(-rotSpeed) + playerDirY * cos(-rotSpeed);
- double oldPlaneX = planeX;
- planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed);
- planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed);
- }
- //rotate to the left
- if (GetAsyncKeyState(VK_LEFT))
- {
- //both camera direction and camera plane must be rotated
- double oldDirX = playerDirX;
- playerDirX = playerDirX * cos(rotSpeed) - playerDirY * sin(rotSpeed);
- playerDirY = oldDirX * sin(rotSpeed) + playerDirY * cos(rotSpeed);
- double oldPlaneX = planeX;
- planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed);
- planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed);
- }
- movement();
- }
- void movement()
- {
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement