A First Person Shooter at the command line? Yup...
Please see the source file on how to configure your command line before running.
This is designed for MS Windows
A First Person Shooter at the command line? Yup...
CommandLineFPS/CommandLineFPS.cpp
Line 270 in b25beb7
@OneLoneCoder Shame on you David, you worthless loser slave.
Shame on you cheap loser slave for openly promoting the stupidest places on earth ["univeristies"] and boasting about your daftness when you included that disgusting 3-letter word in your trashy account description. Death to you and death to every loser slave who uses the disgusting 2-letter word stupid "title" when mentioning first names. Death to every cheap loser slave who refers to that infinitely stupid and dumb 2-letter word. You showned nothing other that how stupid and cheap you mainstream propaganda clowns are. Death to "univeristies". Death to every low life lower clown who uses those stupid and childish and pathetic "prefixes" when mentioning first names. Death to open source. Hope you have a tragic life and painful death.
Death to the UK. Death to the stupid and trashy "national" [garbage] "service. Don't stay at home, and don't protect the stupid moron donkey "national" clown "service".
Shame on them, cheap slaves. Shame on them cheap loser slaves for promoting dumpsters in socities called "universities" [dumpsterversities]. Shame on David for boasting about his stupidity. How extremely dumb and childish you are for promoting those ultra racist clowns. Death to "univeristies" [dumpsterversities]. Death to every low life lower clown who uses those stupid and childish and pathetic "prefixes" when mentioning first name. Death to open source. Death to OneLoneCoder David. Hope you clown devs have a tragic life and painful death.
And another thing....
Stop making lies about real Engineering. Engineering has nothing to do with sitting behind a keyboard and writing code or games. Engineering is a real subject. Engineering means designing and building real mechanical systems, like vehicular engines and turbojets. Software devs are the biggest liars. Game/software devs have absolutely nothing to do with engineering, you are just being stupid wannabe liars. You will never be engineers, not even close. In fact, you don't even know what it takes to be an engineer. None of you are engineers, and you'll never even be close. So stop being disrespectful to real engineers (mechanical engineering is real engineering, and nothing else)
Mechanical Engineering is the ONLY ENGINEERING. Period.
the function "swprintf_s" was not declared says the compiler :(
i already included the "cstdio" "wchar.h", and the "stdio" but it is not working please help...
CommandLineFPS/CommandLineFPS.cpp
Line 271 in b25beb7
This should be for (int ny = 0; ny < nMapHeight; ny++)
instead.
I am getting low FPS on my laptop and it is around 150 to 250 (Without the screen recorder in background).
Specifications of my Laptop:
Is there any possibility to tweak the code for better FPS on my laptop?
What license can this code be distributed under? I know the source code says I don't care what you use this for,
but I was hoping for something a little more material. I've duped this repo into https://github.com/WillNilges/fpscli/ for a hackathon project, and my friends and I intend to change a lot. I've kept the original text here but I was thinking an MIT or Beerware license would be in the spirit of that COPYING file of mine.
Thoughts?
first error: swprint_s was not declared
I fixed it.
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <chrono>
using namespace std;
#include <cmath>
#include <stdio.h>
#include <Windows.h>
int nScreenWidth = 120; // Console Screen Size X (columns)
int nScreenHeight = 40; // Console Screen Size Y (rows)
int nMapWidth = 16; // World Dimensions
int nMapHeight = 16;
float fPlayerX = 14.7f; // Player Start Position
float fPlayerY = 5.09f;
float fPlayerA = 0.0f; // Player Start Rotation
float fFOV = 3.14159f / 4.0f; // Field of View
float fDepth = 16.0f; // Maximum rendering distance
float fSpeed = 5.0f; // Walking Speed
int main()
{
// Create Screen Buffer
wchar_t *screen = new wchar_t[nScreenWidth*nScreenHeight];
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
SetConsoleActiveScreenBuffer(hConsole);
DWORD dwBytesWritten = 0;
// Create Map of world space # = wall block, . = space
wstring map;
map += L"#########.......";
map += L"#...............";
map += L"#.......########";
map += L"#..............#";
map += L"#......##......#";
map += L"#......##......#";
map += L"#..............#";
map += L"###............#";
map += L"##.............#";
map += L"#......####..###";
map += L"#......#.......#";
map += L"#......#.......#";
map += L"#..............#";
map += L"#......#########";
map += L"#..............#";
map += L"################";
auto tp1 = chrono::system_clock::now();
auto tp2 = chrono::system_clock::now();
while (1)
{
// We'll need time differential per frame to calculate modification
// to movement speeds, to ensure consistant movement, as ray-tracing
// is non-deterministic
tp2 = chrono::system_clock::now();
chrono::duration<float> elapsedTime = tp2 - tp1;
tp1 = tp2;
float fElapsedTime = elapsedTime.count();
// Handle CCW Rotation
if (GetAsyncKeyState((unsigned short)'A') & 0x8000)
fPlayerA -= (fSpeed * 0.75f) * fElapsedTime;
// Handle CW Rotation
if (GetAsyncKeyState((unsigned short)'D') & 0x8000)
fPlayerA += (fSpeed * 0.75f) * fElapsedTime;
// Handle Forwards movement & collision
if (GetAsyncKeyState((unsigned short)'W') & 0x8000)
{
fPlayerX += sinf(fPlayerA) * fSpeed * fElapsedTime;;
fPlayerY += cosf(fPlayerA) * fSpeed * fElapsedTime;;
if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
{
fPlayerX -= sinf(fPlayerA) * fSpeed * fElapsedTime;;
fPlayerY -= cosf(fPlayerA) * fSpeed * fElapsedTime;;
}
}
// Handle backwards movement & collision
if (GetAsyncKeyState((unsigned short)'S') & 0x8000)
{
fPlayerX -= sinf(fPlayerA) * fSpeed * fElapsedTime;;
fPlayerY -= cosf(fPlayerA) * fSpeed * fElapsedTime;;
if (map.c_str()[(int)fPlayerX * nMapWidth + (int)fPlayerY] == '#')
{
fPlayerX += sinf(fPlayerA) * fSpeed * fElapsedTime;;
fPlayerY += cosf(fPlayerA) * fSpeed * fElapsedTime;;
}
}
for (int x = 0; x < nScreenWidth; x++)
{
// For each column, calculate the projected ray angle into world space
float fRayAngle = (fPlayerA - fFOV/2.0f) + ((float)x / (float)nScreenWidth) * fFOV;
// Find distance to wall
float fStepSize = 0.1f; // Increment size for ray casting, decrease to increase
float fDistanceToWall = 0.0f; // resolution
bool bHitWall = false; // Set when ray hits wall block
bool bBoundary = false; // Set when ray hits boundary between two wall blocks
float fEyeX = sinf(fRayAngle); // Unit vector for ray in player space
float fEyeY = cosf(fRayAngle);
// Incrementally cast ray from player, along ray angle, testing for
// intersection with a block
while (!bHitWall && fDistanceToWall < fDepth)
{
fDistanceToWall += fStepSize;
int nTestX = (int)(fPlayerX + fEyeX * fDistanceToWall);
int nTestY = (int)(fPlayerY + fEyeY * fDistanceToWall);
// Test if ray is out of bounds
if (nTestX < 0 || nTestX >= nMapWidth || nTestY < 0 || nTestY >= nMapHeight)
{
bHitWall = true; // Just set distance to maximum depth
fDistanceToWall = fDepth;
}
else
{
// Ray is inbounds so test to see if the ray cell is a wall block
if (map.c_str()[nTestX * nMapWidth + nTestY] == '#')
{
// Ray has hit wall
bHitWall = true;
// To highlight tile boundaries, cast a ray from each corner
// of the tile, to the player. The more coincident this ray
// is to the rendering ray, the closer we are to a tile
// boundary, which we'll shade to add detail to the walls
vector<pair<float, float>> p;
// Test each corner of hit tile, storing the distance from
// the player, and the calculated dot product of the two rays
for (int tx = 0; tx < 2; tx++)
for (int ty = 0; ty < 2; ty++)
{
// Angle of corner to eye
float vy = (float)nTestY + ty - fPlayerY;
float vx = (float)nTestX + tx - fPlayerX;
float d = sqrt(vx*vx + vy*vy);
float dot = (fEyeX * vx / d) + (fEyeY * vy / d);
p.push_back(make_pair(d, dot));
}
// Sort Pairs from closest to farthest
sort(p.begin(), p.end(), [](const pair<float, float> &left, const pair<float, float> &right) {return left.first < right.first; });
// First two/three are closest (we will never see all four)
float fBound = 0.01;
if (acos(p.at(0).second) < fBound) bBoundary = true;
if (acos(p.at(1).second) < fBound) bBoundary = true;
if (acos(p.at(2).second) < fBound) bBoundary = true;
}
}
}
// Calculate distance to ceiling and floor
int nCeiling = (float)(nScreenHeight/2.0) - nScreenHeight / ((float)fDistanceToWall);
int nFloor = nScreenHeight - nCeiling;
// Shader walls based on distance
short nShade = ' ';
if (fDistanceToWall <= fDepth / 4.0f) nShade = 0x2588; // Very close
else if (fDistanceToWall < fDepth / 3.0f) nShade = 0x2593;
else if (fDistanceToWall < fDepth / 2.0f) nShade = 0x2592;
else if (fDistanceToWall < fDepth) nShade = 0x2591;
else nShade = ' '; // Too far away
if (bBoundary) nShade = ' '; // Black it out
for (int y = 0; y < nScreenHeight; y++)
{
// Each Row
if(y <= nCeiling)
screen[y*nScreenWidth + x] = ' ';
else if(y > nCeiling && y <= nFloor)
screen[y*nScreenWidth + x] = nShade;
else // Floor
{
// Shade floor based on distance
float b = 1.0f - (((float)y -nScreenHeight/2.0f) / ((float)nScreenHeight / 2.0f));
if (b < 0.25) nShade = '#';
else if (b < 0.5) nShade = 'x';
else if (b < 0.75) nShade = '.';
else if (b < 0.9) nShade = '-';
else nShade = ' ';
screen[y*nScreenWidth + x] = nShade;
}
}
}
// Display Stats
_snwprintf(screen, 40, L"X=%3.2f, Y=%3.2f, A=%3.2f FPS=%3.2f ", fPlayerX, fPlayerY, fPlayerA, 1.0f/fElapsedTime);
// Display Map
for (int nx = 0; nx < nMapWidth; nx++)
for (int ny = 0; ny < nMapWidth; ny++)
{
screen[(ny+1)*nScreenWidth + nx] = map[ny * nMapWidth + nx];
}
screen[((int)fPlayerX+1) * nScreenWidth + (int)fPlayerY] = 'P';
// Display Frame
screen[nScreenWidth * nScreenHeight - 1] = '\0';
WriteConsoleOutputCharacterW(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
}
return 0;
}
Hello, i,m having troubles when i start to compile the floor, the wall just stay black, what i do?
Getting this error after building:
argument of type wchar_t* incomparible with LPCSTR in function call:
Line 279 - WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
screen is of data type wchar_t*
The function expects 2nd argument of type LPCTR
When I compiled the program this happened, please tell me what to do.
$ g++ -std=gnu++17 -o game CommandLineFPS.cpp
CommandLineFPS.cpp: In function 'int main()':
CommandLineFPS.cpp:267:114: error: 'swprintf_s' was not declared in this scope
swprintf_s(screen, 40, L"X=%3.2f, Y=%3.2f, A=%3.2f FPS=%3.2f ", fPlayerX, fPlayerY, fPlayerA, 1.0f/fElapsedTime);
^
CommandLineFPS.cpp:279:103: error: cannot convert 'wchar_t*' to 'LPCSTR {aka const char*}' for argument '2' to 'BOOL WriteConsoleOutputCharacterA(HANDLE, LPCSTR, DWORD, COORD, PDWORD)'
WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
^
Hi, can you make a portable oversion of your program that can be used on systems such as linux or macOS?
I will glad to you if you do that, because that's the only project of this kind i found
My environment is Cmake + MinGW on Windows.
It reported 2 kinds of bugs:
1.Some functions like sinf(); cosf(); was not declared in this scope.
2.Can not convert 'wchar_t*' to 'LPCSTR'
Here are my solutions:
1.Add #include <math.h>
to sourse code
2.Change funtion WriteConsoleOutputCharacter()
to WriteConsoleOutputCharacterW()
at line 279
My antivirus is saying it's a virus, and when I restore it, it says it's a virus again.
I use McAfee Real Protect - 1 Device
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.