Laggy Output to Console - c++

I have been trying to make asteroids in the console, I know that the console isn't an ideal way to do this, but I wanted to challenge myself.
The problem I am having is with printing to the screen. At first, my screen was flickering because I wasn't updating certain screen parts and instead redrawing every frame by appending the whole array to a string and outputting that string.
So I changed my code to do that, but my current problem now is that the fps of my game is really low because I can't batch call it to one cout function.
To print my code to the screen I have a 2d array of characters with width and height as its size. Then I copy the array, change the output, and compare it to the previous output to see if the pixel needs to be changed, then change it.
Here is my draw function
void draw() {
char prevOutput[ArrayBorder][ArrayBorder];
copyOutput(outputBuffer, prevOutput);
innitOutput();
plotPolygons();
for (int y = 0; y < GameBorder; y++) {
for (int x = 0; x < GameBorder; x++) {
if (outputBuffer[x][y] == prevOutput[x][y]) {continue;}
setCursorPosition(x, y);
cout << outputBuffer[x][y];
}
}
cout.flush();
}
Here is my previous draw function
void draw() {
innitOutput();
plotPolygons();
system("CLS");
string output = "";
for (int y = 0; y < GameBorder; y++) {
for (int x = 0; x < GameBorder; x++) {
output += outputBuffer[x][y];
}
output += "\n";
}
cout << output;
}

Related

Applying texture to array of sprites(C++, SFML, tmxlite)

I'm having some difficulty applying a texture to a sprite array. I'm trying to apply the same texture to all, so that I can later setTextRect to decide which part of the texture is used as a tile in my game.
The declaration of the sprite array is in a different class and declared as follows:
sf::Sprite tileSprites[30][40]
Going line by line and debugging the stumbling block is the for loop. The response from the window is just to close and crash out with no errors.
The game crashes once the line where I try to apply the texture.
tileSprites[idx][idy].setTexture(tileMap);
std::cout << "Creating Map... \n";
// load the image to be used as map/the spritesheet.
if (!tileMap.loadFromFile("Data/Maps/tilemap.png"))
{
std::cout << "Tilemap PNG did not load";
}
//load the generated tilemap
if(!map.load("Data/Maps/test_map.tmx"))
{
std::cout << "TMX map file failed to load";
}
// access the layers in the map
const auto& layers = map.getLayers();
const auto layer = layers[0]->getLayerAs<tmx::TileLayer>();
const auto tiles = layer.getTiles();
int idx = 0;
int idy = 0;
for (int j = 0; j < tiles.size(); ++j)
{
idx = j / 30;
idy = j % 30;
tileSprites[idx][idy].setTexture(tileMap); // <-
}
std::cout << tiles.size();
}
Any advice would be really appreciated.

Conway's game of life algoritm is not working

I'm trying to simulate conway's game of life. The algorithm I made is not working, but I can't figure out how.
If I have a situation like this:
|.........|
|....x....|
|....x....|
|....x....|
|.........|
a . is a dead cell, an x is an alive cell
It is expected that the vertical bar flips into a horizontal bar, but this doesn't happen.
Instead it only removes the bottom one, running it again again only removes the bottom so theres 1 left.
Clearly theres something wrong with the algorithm, but I can't figure out what.
I've been looking online but all problems other people have had, the solutions didn't work for me.
So what is the error in this algorithm?
This is my code:
void new_generation() {
// Create one new generation
// double for loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
// find the amount of living neighbours, stored in count
// dubbele for loop -> iterates every neighbour of the current cell
count = 0;
for (int y=0; y<2; y++) {
for (int x=0; x<2; x++){
if (i != 0 and j!= 0) { // the cell itself doesnt count
if (world[i+y][j+x]) count++;
}
}
}
if (world[i][j]) { // current cell is alive
if (count<2 or count>3) new_world[i][j] = false;
else new_world[i][j] = true;
}
else { // current cell is dead
if (count==3) new_world[i][j] = true;
else new_world[i][j] = false;
}
}
}
// copy every value from the newly generated world to the current
// double foor loop -> iterates every cell
for (int i=0; i<worldHeight; i++){
for (int j=0; j<WorldWidth; j++) {
world[i][j] = new_world[i][j];
}
}
worldHeight and worldWidth are ints denoting how big the world is.
world and new_world are 2-dimensional arrays containing booleans where true is a living cell and false is a dead cell
You count the neighbor cells wrong
Both x and y are runing from 0 to 2 not from -1 to 2. in
for (int y=0; y<2; y++) {//should be int y=-1; y<2; y++
for (int x=0; x<2; x++){//should be int x=-1; x<2; x++
if (i != 0 and j!= 0) { // shold be x!=0 or y!=0
if (world[i+y][j+x]) count++;
}
}
}
Also you have to check if world[i+y][j+x] is valid (coordinates are in teh 0,size range)
And the third problem is that when you want not to count in word[i][j] you check if (i!=0 and j!=0) not x!=0 or y!=0 i and j are the coordinates of the examined cell, x and y are the difference of the coordinates.

Extra sprite spawning when the enemies are redrawn SFML

I am making a game in sfml and at the moment when all of the enemies die. They are set to respawn however when this is happening they are respawning with one extra sprite than before.
The code for loading in the sprites is
unsigned int orcNumber = 5;
for (int i = 0; i < orcNumber; i++)
{
SpriteVector.push_back(ogreSprite);
SpriteVector[i].setPosition(spawnPointX[i], spawnPointY[i]);
}
The code for removing the enemies if they are offscreen or shot is similar to below using erase.
for (unsigned j = 0; j < SpriteVector.size(); j++)
{
if (this->SpriteVector[j].getPosition().x < 0 - 80 )
{
//this succesfully removes the object from the vector
SpriteVector.erase(SpriteVector.begin() + j);
std::cout << "Container size..." << SpriteVector.size() << "\n";
}
}
The statement for redrawing them is:
unsigned int orcNumberRespawn = 5;
if (SpriteVector.size() <= 1)
{
for (int i = 0; i < orcNumberRespawn; i++)
{
SpriteVector.push_back(ogreSprite);
SpriteVector[i].setPosition(spawnPointX[i], spawnPointY[i]);
}
}
window.draw(SpriteVector[i]);
Can anyone identify why when the sprites need to be redrawn it draws with + 1 sprite everytime?
The issue was with a loop outside of these vector loops.

C++ 2d array doesn't display

I have a 2d array filled with global variables.
#define GRID_WIDTH 19
#define GRID_HEIGHT 10
char grid[GRID_WIDTH][GRID_HEIGHT];
Later in the code i use this 2d array
void Grid::ResetGrid()
{
// Empty the console screen
system("cls");
// Fills the grid with '#' walls
for (int i=0; i<GRID_WIDTH; i++)
{
for(int j = 0; j <GRID_HEIGHT; j++)
grid[i][j] = '#';
}
ir = 2;
}
While I'm running the program, i use watches and breakpoints. In the beginning the watch on grid said:
Name: grid
Value: [0] "###################"
[0] '#'
[1] '#'
[2] '#'
//and so on, i could expand it and look at every part of the array
type: char
but now it's broken and it only shows this:
Name: grid
Value: {...}
type: Grid
The strange thing is I didn't change the array code, only wrote code lines of compare to what's inside the array.
The code of printing it to the console:
void Grid::PrintGrid(int currentX, int currentY )
{
// Empty the console screen
system("cls");
// Displays the finished maze to the screen.
for (int y=0; y < GRID_HEIGHT; y++)
{
for (int x=0; x < GRID_WIDTH; x++)
{
cout << grid[x][y];
}
cout << endl;
}
// Just for testing, which direction and on what position the solver is
cout << ir << " " << currentX << "," << currentY;
}
The question is:
Why I can't see the information in the 2d array anymore in the watch or when I hoofer over?
I hope you can help me.
I don't think the problem happens to your codes posted out, because I just tested them in my visual stuido 2008, they runs well by your printGrid function, except varable ir I defined it gloably, and your printGrid function double defined x, and y, you defined it in function head, but in the loop, using for (int x...), which means no sense..
the result just come from the printGird is like this:
###################
###################
###################
###################
###################
###################
###################
###################
###################
###################
2 3,4请按任意键继续. . .
3, 4 is the value of x, y which passed in printGrid when using it.
It looks like your print code is going out of the bounds of the array. Much like when you're filling the array, you should use
for (int y=0; y < GRID_HEIGHT; ++y)
{
for (int x=0; x < GRID_WIDTH; ++x)
{
That may be the cause of your faulty print.
The question was why I couldn't see my 2d array anymore in the watch.
It's working again. Don't know what was wrong. But the image below shows the correct use of the watch. I use this to check the information inside the 2d array. But it didn't show information for a while just grid {...} instead of grid 0x00 char (* grid)[25] and then the information about the rows and columns.

For loop for reading strings from a file into a 3D array

I'm having a problem with one of my functions, I'm working on a simple tile map editor, and I'm trying to implement a 3D array to keep track of tiles (x,y, layer). Before this I had a 1D array where all the tiles were just listed sequencially:
bool Map::OnLoad(char* File) {
TileList.clear();
FILE* FileHandle = fopen(File, "r");
if(FileHandle == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList.push_back(tempTile);
}
fscanf(FileHandle, "\n");
}
fclose(FileHandle);
return true;
}
This basically read strings from the file which looked like:
2:1 1:0 3:2...
Where the first number states the tileID and the second one states the Tile passability. The above function works. My 3D arrays are also correctly constructed, I tested them with simple assignments and calling values out of it. The function that gives me problems is the following (please note that the number 2 i.e. OnLoad2() was added so I can keep the old variables and the function untouched until the prototype is working):
bool Map::OnLoad2(char* File) {
TileList2.clear();
FILE* FileHandle2 = fopen(File, "r");
if(FileHandle2 == NULL) {
return false;
}
for(int Y = 0;Y < MAP_HEIGHT;Y++) {
for(int X = 0;X < MAP_WIDTH;X++) {
Tile tempTile;
fscanf(FileHandle2, "%d:%d ", &tempTile.TileID, &tempTile.TilePassage);
TileList2[X][Y][0] = tempTile;
}
fscanf(FileHandle2, "\n");
}
fclose(FileHandle2);
return true;
}
While this function doesn't trigger the compiler to report any errors, as soon as the application starts, it freezes up and crashes. For additional information MAP_WIDTH and MAP_HEIGHT are set to 40 each and the 3D array was constructed like this:
TileList2.resize(MAP_HEIGHT);
for (int i = 0; i < MAP_HEIGHT; ++i) {
TileList2[i].resize(MAP_WIDTH);
for (int j = 0; j < MAP_WIDTH; ++j)
TileList2[i][j].resize(3);
}
I would appreciate it if you could point me out what do I need to fix, as far as I know I must have messed up the for loop structure, as the 3D array initializes and works properly. Thank you for your help!
TileList2.clear();
This line reinitializes TileList2, so it is back to a zero-length vector. Delete that line, and you will probably be okay.