Tilegrid made of RectangleShape in SFML gives conversion error - c++

I am learning C++ and want to get into graphics. I am using SFML, and am trying to make a snake game. I want to use rectangle shapes and update the position of each rectangle by referring to an array and factor of 40 (my tilesize). I believe I got the for loops right, but am struggling to use sf::setPosition. It gives me a conversion error. Here is my code:
#include <SFML\Graphics.hpp>
int main()
{
int xWindow = 1280; //Divided by 40 pixels, equals to a width of 32 tiles
int yWindow = 720; //Divided by 40 pixels, equals to a height of 18 tiles
float array[32][18] = { 0 };
sf::RenderWindow window(sf::VideoMode(xWindow, yWindow), "Title"); //32 & 18
while (window.isOpen())
{
////////Grid variables/////////
int xFactor = 32;
int yFactor = 18;
int size = 40;
////////Events////////
////////draw////////
window.clear();
for (int i = 0; i <= 31;i++)
{
for (int j = 0; j <= 17; j++)
{
sf::RectangleShape block(sf::Vector2f(size, size));
block.setFillColor(sf::Color::Blue);
block.setPosition(array[i * size][j * (size)]); //ERROR OCCURS HERE: cannot convert argument 1 from 'float' to 'const sf::Vector2f &'
window.draw(block);
}
}
///////Display//////
window.display();
}
}
I am thinking that setPosition only takes float or vector as input, but if I'm not mistaken you can't move through an array with anything other than integers?
How would set up a simple grid like this in SFML C++?
Thanks for any answers!

A position is 2 numbers, an x and y cordinate. array[i * size][j * (size)] is just one number in your 2d float array.
I would go for something like this instead
block.setPosition(i*size, j*size);

Related

shrink image c++ - 'System.AccessViolationException'

I have a project where we have to develop some image processing functions. One of the functions is shrinking an image.
this is the description of the function
void averageRegions(int blockWidth, int blockHeight)
INPUTS: Integers indicating the width and height of the blocks?to be averaged
OUTPUTS: NONE
When this function is called, you should create a new image that will consist of 1 pixel for every block of size
blockWidth by blockHeight pixels in the original image, with each pixel being the average color of the pixels in that
region in the original image.
Please note that it may be easier if you split this into 2 functions and call your helper function from within this one.
The second function could then just calculate the average value of a block of pixels given to it, and return that
to the original function to be used. However, this implementation is up to you! Complete it as you see fit.
I have completed the code of it however after closing the app I get this error
An unhandled exception of type 'System.AccessViolationException' occurred in MCS2514Pgm2.exe
Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
or this one
Heap Corruption Detected: after Normal block (#126) at 0x004cF6c0 CRT detected that the application wrote to memory after end of heap bugger.
This is the function code
void averageRegions(int blockWidth, int blockHeight)
{
//please add the code
int height = inImage.getHeight();
int width = inImage.getWidth();
pixel** myPixels = inImage.getPixels();
pixel* pixelptr;
int Rsum = 0, Gsum = 0, Bsum = 0;
int Ravg, Gavg, Bavg, pcount = 0, m, n;
outImage.createNewImage(width/blockWidth, height/blockHeight);
pixel** outPixels = outImage.getPixels();
//pixelptr = &myPixels[0][4];
for(int x = 0; x < height; x +=blockHeight)
{
for(int y = 0; y < width; y += blockWidth)
{
for(int i = x; i < blockHeight+x; i++)
{
for(int j = y; j < blockWidth+y; j++)
{
Rsum += myPixels[i][j].red;
Gsum += myPixels[i][j].green;
Bsum += myPixels[i][j].blue;
pcount++;
}
}
Ravg = Rsum/pcount;
Gavg = Gsum/pcount;
Bavg = Bsum/pcount;
for(int i = x; i < blockHeight+x; i++)
{
for(int j = y; j < blockWidth+y; j++)
{
myPixels[i][j].red = Ravg;
myPixels[i][j].green = Gavg;
myPixels[i][j].blue = Bavg;
m = x/blockHeight;
n = y/blockWidth;
outPixels[m][n].red = myPixels[i][j].red;
outPixels[m][n].green = myPixels[i][j].green;
outPixels[m][n].blue = myPixels[i][j].blue;
}
}
pcount=0;
Rsum = 0;
Gsum = 0;
Bsum = 0;
}
}
inImage = outImage;
}
this is the image.h
#ifndef IMAGE
#define IMAGE
#include <atlimage.h>
#include <string>
#include <cstdlib>
#include "globals.h"
#include "pixel.h"
using namespace std;
class image {
public:
image(); //the image constructor (initializes everything)
image(string filename); //a image constructor that directly loads an image from disk
~image(); //the image destructor (deletes the dynamically created pixel array)
void createNewImage(int width, int height); //this function deletes any current image data and creates a new blank image
//with the specified width/height and allocates the needed number of pixels
//dynamically.
bool loadImage(string filename); //load an image from the specified file path. Return true if it works, false if it is not a valid image.
//Note that we only accept images of the RGB 8bit colorspace!
void saveImage(string filename); //Save an image to the specified path
pixel** getPixels(); //return the 2-dimensional pixels array
int getWidth(); //return the width of the image
int getHeight(); //return the height of the image
void viewImage(CImage* myImage); //This function is called by the windows GUI. It returns the image in format the GUI understands.
private:
void pixelsToCImage(CImage* myImage); //this function is called internally by the image class.
//it converts our pixel struct array to a standard BGR uchar array with word spacing.
//(Don't worry about what this does)
pixel** pixels; // pixel data array for image
int width, height; // stores the image dimensions
};
#endif
And this is Pixel.h
#ifndef PIXEL_H
#define PIXEL_H
class pixel
{
public:
unsigned char red; //the red component
unsigned char green; //the green component
unsigned char blue; //the blue component
};
#endif
Can any one tell me why I am getting this error
In addition:
the error is taking me to this line in dbgdel.cpp
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
This error occurs because you are accessing outside of memory allocated for an array. There are several places in your code where this can happen.
If height is not a multiple of blockHeight, or width is not a multiple of blockWidth, your i/j loops will access elements outside of the memory allocated for myPixels.
Another possibility is when writing to outPixels if blockHeight and blockWidth are not equal. Your computation of m and n may have the blockHeight and blockWidth swapped (you're dividing x by blockHeight).
In
for (int x = 0; x < height; x += blockHeight)
say height is 100 and blockHeight is 33
x == 0. 0 < 100, so the body is entered and iterates 0 -> 32
x == 33. 33 < 100, so the body is entered and iterates 33 -> 65
x == 66. 66 < 100, so the body is entered and iterates 66 -> 98
x == 99. 99 < 100, so the body is entered and iterates 99 -> 131
Sadly there is no 100 -> 131.

C++ rendering shapes

I'm trying to generate shapes within a specific area. the game i am making has a resolution of 1024x768 but the game board occupies only 768x768 in the centre of the screen.
Currently, i can get the shapes to randomly generate and not exceed the MAXIMUM_WIDTH and MAXIMUM_HEIGHT constraints. However, the shapes can still render too far left which is off the game board. I tried adding MINIMUM_WIDTH and MINUMUM_HEIGHT but i'm not sure where to apply this in the x= and y= stage
I've included the relevant code below.
What can i add/modify to this code to make the shapes be limited to the game board?
Thanks.
const size_t MaxShapes {5};
const unsigned int MaxScale {5};
const unsigned int MINIMUM_WIDTH = 128;
const unsigned int MAXIMUM_WIDTH = 896;
const unsigned int MINUMUM_HEIGHT = 0;
const unsigned int MAXIMUM_HEIGHT = 768;
bool PlayState::onCreate()
{
snakes_.push_back(new AISnake);
snakes_.back()->setPosition(Position(40,40));
snakes_.push_back(new PlayerSnake);
snakes_.back()->setPosition(Position(20,20));
double x, y;
for(unsigned shape = 0;shape < MaxShapes;shape++)
{
x = (double)(rand() % MAXIMUM_WIDTH);
y = (double)(rand() % MAXIMUM_HEIGHT);
shapes_.push_back(Triangle({x, y}));
}
return true;
}
You could try
x = (double)((rand() % (MAXIMUM_WIDTH - MINIMUM_WIDTH)) + MINIMUM_WIDTH);
y = (double)((rand() % (MAXIMUM_HEIGHT - MINIMUM_HEIGHT)) + MINIMUM_HEIGHT);
Say you want to find a random number between 5 and 15. The difference between 5 and 15 is 10. So you first find a random number between 0 and 10 and then add that to 5 to bring it back into the proper range (between 5 and 15).

Tileset crop calculation C++

So I have this problem with my tileset rendering. It's a little tricky to explain but i'll do my best.
Basicly what i do is i load these "tile numbers" from TMX files and they only represent the tileset number in the tileset. So if i use a tile that is on a row below the first one i only get the number. But i want both X and Y position to calculate where i would crop the image when i display it in my game.
So my array would look something like this,
1,1,1,2,1,1,1,1,9,1,6,1,1
1,1,1,2,2,2,1,1,1,1,1,1,1
1,1,1,1,1,2,1,1,1,1,1,1,1
1,1,1,1,1,2,1,1,1,3,1,1,1
1,6,1,1,1,2,1,1,1,1,1,1,1
1,1,5,5,1,2,2,2,1,1,1,1,1
1,1,1,1,1,1,1,2,1,1,1,1,1
Tileset:
http://puu.sh/9Tv2X/7938b6abf4.png
so when i render all the tiles in the first row in this tileset, numbers 1-4 (since the tileset is 4 tiles long) it works fine but anything past that would get cropped outside the image.
So for that i need the Y position to increase and to reset the X position everytime it goes outside the tileset width which is (32 * (tileNumber - 1)) but my brain cant figure out how to do this.
tile width and height is 32.
my code for drawing the tilset:
void TileMap::Draw()
{
for (unsigned int i = 0; i < mapVector.size(); i++)
{
for (unsigned int j = 0; j < mapVector[i].size(); j++)
{
int tileY = 0;
int tileX = mapVector[i][j] - 1;
if (tileWidth * mapVector[i][j] > tilesetWidth)
{
//now what
}
if (mapVector[i][j] > 0)
{
tileSprite->SetPosition(j * tileWidth, i * tileHeight);
tileSprite->SetTextureRect(tileX * tileWidth, tileY * tileHeight, 32, 32);
tileSprite->Draw();
}
}
}
}

Tile mapping error

I am still learning SFML and C++ so please understand that I'm still at the basic level.
This is my first time using this site so IDK if I'm doing this right.
I want to make a function, set, that will allow me to pass a 2d array as an argument and place a tile down whenever there is a 1 in the array. So I can draw maps and things using a matrix. ww is the window width and wh is the window height. In main I made a for loop that would go through tiles and draw them to the window. But when I run this it gives me the error: Segmentation Fault (core dumped) "Error: 139". Is there a better way of doing this and what am I doing wrong?
Thank you.
struct field
{
int rectsizex;
int rectsizey;
RectangleShape * tiles;
field (int s)
{
rectsizex = ww / s;
rectsizey = wh / s;
tiles = new RectangleShape[rectsizex * rectsizey];
}
~field()
{
delete tiles;
}
RectangleShape * set(int ** matr)
{
Vector2f size((ww / rectsizex), (wh / rectsizey));
int posx = ww / rectsizex;
int posy = wh / rectsizey;
for(int x = 0; x<rectsizex; x++)
{
for(int y = 0; y<rectsizey; y++)
{
int i = ((x*rectsizey)+1)+y;
tiles[i].setSize(size);
if(matr[x][y] == 1)
{
tiles[i].setFillColor(Color::Black);
}
else
{
tiles[i].setFillColor(Color::White);
}
tiles[i].setPosition(x * posx, y * posy);
}
}
return tiles;
}
};
Find out what values you are getting for i:
int i = ((x*rectsizey)+1)+y;
This value is definitely outside of your array bounds, hence the error. Use a debugger, or put some print statements after you get the i value.

Giant Char or multiple Chars for console game map?

I'm a pretty novice c++ coder and I am starting to make a console adventure game.
My adventure game currently consists of a player character that walks around inside a console application window with an 80 character width x 40 lines.
I am not sure how to approach storing the maps for my game. Each map will consist of 80 x 40 ASCII characters with colour attributes.
Should I store each 80 x 40 map in its own char? so a single map would look something like...
int cHeight = 5; // Reduced size for this example
int cHeight = 10; // Reduced size for this example
// Set up the characters:
char map[cHeight][cWidth+1] = {
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
};
CHAR_INFO mapA[cWidth * cHeight];
for (int y = 0; y < cHeight; ++y) {
for (int x = 0; x < cWidth; ++x) {
mapA[x + cWidth * y].Char.AsciiChar = map[y][x];
mapA[x + cWidth * y].Attributes = FOREGROUND_BLUE | Black; //I have an enum setup with background colours.
}
}
// Set up the positions:
COORD charBufSize = {cWidth,cHeight};
COORD characterPos = {0,0};
SMALL_RECT writeArea = {0,0,cWidth-1,cHeight-1};
// Write the characters:
WriteConsoleOutputA(wHnd, mapA, charBufSize, characterPos, &writeArea);
Im not sure if this is entirely the correct way to display the characters but I didn't think it was a good idea to just cout every character in the for loop.
So.. lets say my console window (in the above code) is 10 characters wide and 5 lines high.
In the above code I have a single map in the Char, so when loading each map I would put each one in their own array.
I was thinking of putting the entire map into a single Char, but then only displaying what I needed by offsetting the x and y in the for loop.
mapA[x + cWidth * y].Char.AsciiChar = map[y+offset][x+offset];
So the map would look more like this;
char map[cHeight][cWidth+1] = {
"1234567890ABCDEFGHIJ",
"1234567890ABCDEFGHIJ",
"1234567890ABCDEFGHIJ",
"1234567890ABCDEFGHIJ",
"1234567890ABCDEFGHIJ",
};
with the offset I could display '1234567890' on 5 rows separately from 'ABCDEFGHIJ' on 5 rows.
So in short I would like to know the most effective way to do this, should I have multiple Chars? Should I create a class? then I could store the characters an colours? (class' are still new to me in c++).
Should I draw the terrain only in the map and then add objects (houses, trees)?
Or just draw it all in the map manually?
I think I've just thought about this too long and need a bit of direction
Thanks!
The way I would do it would be to create a map of
Node* map[height][width]
This means you would create the map which are pointers to Node* elements and you could define the Node* element to be...
class Node{
char displayCharacter;
int posx,poxy
unsigned int r; //red
unsigned int g; //green
unsigned int b; //blue
unsigned int a; //alpha
display(); // This function will know how to display a node using the colour etc
};
Then you could for example if you wanted to create a house you would give it the center point of the model etc... to draw to a function
void createHouse(Node* center)
{
if((center->posh > 0)&&(center->posh< maxheight))
{
if(map[center->posy-1][center->posx]!=NULL)
{
map[center->posy-1][center->posx]->displayCharacter = '_';
map[center->posy-1][center->posx]->r = 255;
}
}
}
Then in main you would have something like...
while(true)
{
for(int i=0; i<maxheight; i++)
{
for(int j=0; j< maxwidth; j++)
{
map[i][j]->Display();
}
}
}
I hope all this sample code is of help to you and answered your question. I have not debugged or looked for any syntax errors. If there any errors in the code, you will have to fix them!
Good luck to you!