The TMX map is loading correctly but it seems to be positioning my tiles incorrectly.
I'm using the TMX Parser from here: https://code.google.com/p/tmx-parser/
It loads the TMX fine, with no errors. But it's only positioning the tiles according to the their location in the spritesheet.
Here is the code sample:
void Game::DrawMap()
{
SDL_Rect rect_CurTile;
SDL_Rect pos;
int DrawX;
int DrawY;
for (int i = 0; i < map->GetNumLayers(); ++i)
{
// Get a layer.
currLayer = map->GetLayer(i);
for (int x = 0; x < currLayer->GetWidth(); ++x)
{
for (int y = 0; y < currLayer->GetHeight(); ++y)
{
int CurTile = currLayer->GetTileId(x, y);
int Num_Of_Cols = 8;
int tileset_col = (CurTile % Num_Of_Cols);
tileset_col++;
int tileset_row = (CurTile / Num_Of_Cols);
rect_CurTile.x = (1 + (32 + 1) * tileset_col);
rect_CurTile.y = (1 + (32 + 1) * tileset_row);
rect_CurTile.w = 32;
rect_CurTile.h = 32;
DrawX = (x * 32);
DrawY = (y * 32);
pos.x = DrawX;
pos.y = DrawY;
pos.w = 32;
pos.h = 32;
apply_surfaceClip(DrawX,DrawY, surfaceTileset, destSurface, &rect_CurTile);
sprTexture = SDL_CreateTextureFromSurface(mRenderer,destSurface);
SDL_RenderCopy(mRenderer,sprTexture,&rect_CurTile,&pos);
}
}
}
void apply_surfaceClip( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
{
//Holds offsets
SDL_Rect offset;
//Get offsets
offset.x = x;
offset.y = y;
//Blit
SDL_BlitSurface( source, clip, destination, &offset );
}
I fixed the issue the problem was when using two layers it was drawing zeros here is the finished sample
for (int i = 0; i < map->GetNumLayers(); ++i)
{
// Get a layer.
currLayer = map->GetLayer(i);
for (int x = 0; x < currLayer->GetWidth(); ++x)
{
for (int y = 0; y < currLayer->GetHeight(); ++y)
{
int CurTile = currLayer->GetTileId(x, y);
if(CurTile == 0)
{
continue;
}
int Num_Of_Cols = 8;
int tileset_col = (CurTile % Num_Of_Cols);
int tileset_row = (CurTile / Num_Of_Cols);
std::cout << CurTile << std::endl;
rect_CurTile.x = (1 + (32 + 1) * tileset_col);
rect_CurTile.y = (1 + (32 + 1) * tileset_row);
rect_CurTile.w = 32;
rect_CurTile.h = 32;
DrawX = (x * 32);
DrawY = (y * 32);
pos.x = DrawX;
pos.y = DrawY;
pos.w = 32;
pos.h = 32;
apply_surfaceClip(DrawX,DrawY, surfaceTileset, destSurface, &rect_CurTile);
sprTexture = SDL_CreateTextureFromSurface(mRenderer,destSurface);
SDL_RenderCopy(mRenderer,sprTexture,&rect_CurTile,&pos);
}
}
}
Related
I'm trying to use GPU Delegate in Tensorflow Lite on iOS. My model has inputs and outputs as OpenCV BGR image ([258, 540, 3]). How can I set inputs and outputs in C++ tensorflow lite interpreter? I tried to use this code
int input = interpreter->inputs()[0];
float* out = interpreter->typed_tensor<float>(input);
NSData* slicedData = [self inputDataFromCvMat:slicedImage];
uint8_t* in = (uint8_t*) slicedData.bytes;
ProcessInputWithFloatModel(in, out, WIDTH, HEIGHT, CHANNELS);
void ProcessInputWithFloatModel(uint8_t* input, float* buffer, int image_width, int image_height, int image_channels) {
for (int y = 0; y < wanted_input_height; ++y) {
float* out_row = buffer + (y * wanted_input_width * wanted_input_channels);
for (int x = 0; x < wanted_input_width; ++x) {
const int in_x = (y * image_width) / wanted_input_width;
const int in_y = (x * image_height) / wanted_input_height;
uint8_t* input_pixel =
input + (in_y * image_width * image_channels) + (in_x * image_channels);
float* out_pixel = out_row + (x * wanted_input_channels);
for (int c = 0; c < wanted_input_channels; ++c) {
out_pixel[c] = (input_pixel[c] - input_mean) / input_std;
}
}
}
}
- (NSData *)inputDataFromCvMat:(Mat)image {
NSMutableData *inputData = [[NSMutableData alloc] initWithCapacity:0];
for (int row = 0; row < HEIGHT + 10; row++) {
for (int col = 0; col < WIDTH + 10; col++) {
Vec3b intensity = image.at<Vec3b>(row, col);
int blue = intensity.val[0];
int green = intensity.val[1];
int red = intensity.val[2];
// we need to put pixel values in BGR (model was trained with opencv)
[inputData appendBytes:&blue length:sizeof(blue)];
[inputData appendBytes:&green length:sizeof(green)];
[inputData appendBytes:&red length:sizeof(red)];
}
}
return inputData;
}
but I don't know what is wrong
After some research, I managed to get it working
const int wanted_input_width = 258;
const int wanted_input_height = 540;
const int wanted_input_channels = 3;
Mat image = ...
// write to input
int input = interpreter->inputs()[0];
float* out = interpreter->typed_tensor<float>(input);
uint8_t* in = image.ptr<uint8_t>(0);
ProcessInputWithFloatModel(in, out);
// run interpreter
if (interpreter->Invoke() != kTfLiteOk) {
LOG(FATAL) << "Failed to invoke!";
}
// get output
int output_idx = interpreter->outputs()[0];
float* output = interpreter->typed_output_tensor<float>(output_idx);
Mat outputMat = ProcessOutputWithFloatModel(output);
/// Preprocess the input image and feed the TFLite interpreter buffer for a float model.
void ProcessInputWithFloatModel(uint8_t* input, float* buffer) {
for (int y = 0; y < wanted_input_height; ++y) {
float* out_row = buffer + (y * wanted_input_width * wanted_input_channels);
for (int x = 0; x < wanted_input_width; ++x) {
uint8_t* input_pixel = input + (y * wanted_input_width * wanted_input_channels) + (x * wanted_input_channels);
float* out_pixel = out_row + (x * wanted_input_channels);
for (int c = 0; c < wanted_input_channels; ++c) {
out_pixel[c] = input_pixel[c] / 255.0f;
}
}
}
}
Mat ProcessOutputWithFloatModel(float* input) {
cv::Mat image = cv::Mat::zeros(wanted_input_height, wanted_input_width, CV_8UC3);
for (int y = 0; y < wanted_input_height; ++y) {
for (int x = 0; x < wanted_input_width; ++x) {
float* input_pixel = input + (y * wanted_input_width * wanted_input_channels) + (x * wanted_input_channels);
cv::Vec3b & color = image.at<cv::Vec3b>(cv::Point(x, y));
color[0] = (uchar) floor(input_pixel[0] * 255.0f);
color[1] = (uchar) floor(input_pixel[1] * 255.0f);
color[2] = (uchar) floor(input_pixel[2] * 255.0f);
}
}
return image;
}
I'm trying to update a 128x128 D3DLOCKED_RECT with sub images using the following code, but it seems to squish them down along the top, the X offset is ignored and the y offset is 60 percent off.
I've also tried to make the texture the correct size and copy it into a 128x128 texture at the correct location using RECT, however this is very slow and didn't seem to work correctly when I attempted it. There must be way to do it using the raw pixel data?
Any help would be much appreciated :)
EDIT: I got it semi working using the below code, the locations are now correct and the sizes. But it's only using the blue channel and everything is grey scale (blue scale?)
srcdata = (byte *) pixels;
dstdata = (unsigned int *)lockrect.pBits;
for (y = yoffset; y < (yoffset + height); y++)
{
for (x = xoffset; x < (xoffset + width); x++)
{
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 0] = (unsigned int)srcdata[0];
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 1] = (unsigned int)srcdata[1];
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 2] = (unsigned int)srcdata[0];
dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 3] = (unsigned int)srcdata[3];
srcdata += srcbytes;
}
}'
END Edit
Test call after creating the 128x128 texture:
int x, y;
byte temp[132*132*4];
// Test texture (pink and black checker)
for( y = 0; y < 16; y++ )
{
for( x = 0; x < 16; x++ )
{
if(( y < 8 ) ^ ( x < 8 ))
((uint *)&temp)[y*16+x] = 0xFFFF00FF;
else ((uint *)&temp)[y*16+x] = 0xFF000000;
}
}
UpdateSubImage (0, 0, 16, 16, temp )
The update Fuction:
void UpdateSubImage (int xoffset, int yoffset, int width, int height, const
GLvoid *pixels)
{
int x, y;
int srcbytes = 4; //Hard coded for now, as all tests are RGBA
int dstbytes = 4; // ^
byte *srcdata;
byte *dstdata;
D3DLOCKED_RECT lockrect;
pTexture->LockRect( 0, &lockrect, NULL, 0);
srcdata = (byte *) pixels;
dstdata = (byte *) lockrect.pBits;
dstdata += (yoffset * width + xoffset) * dstbytes;
for (y = yoffset; y < (yoffset + height); y++)
{
for (x = xoffset; x < (xoffset + width); x++)
{
if (srcbytes == 1)
{
if (dstbytes == 1)
dstdata[0] = srcdata[0];
else if (dstbytes == 4)
{
dstdata[0] = srcdata[0];
dstdata[1] = srcdata[0];
dstdata[2] = srcdata[0];
dstdata[3] = srcdata[0];
}
}
else if (srcbytes == 3)
{
if (dstbytes == 1)
dstdata[0] = ((int) srcdata[0] + (int) srcdata[1] + (int) srcdata[2]) / 3;
else if (dstbytes == 4)
{
dstdata[0] = srcdata[2];
dstdata[1] = srcdata[1];
dstdata[2] = srcdata[0];
dstdata[3] = 255;
}
}
else if (srcbytes == 4)
{
if (dstbytes == 1)
dstdata[0] = ((int) srcdata[0] + (int) srcdata[1] + (int) srcdata[2]) / 3;
else if (dstbytes == 4)
{
dstdata[0] = srcdata[2];
dstdata[1] = srcdata[1];
dstdata[2] = srcdata[0];
dstdata[3] = srcdata[3];
}
}
// advance
srcdata += srcbytes;
dstdata += dstbytes;
}
}
pTexture->UnlockRect(0);
}
What the output looks like:
What the output should look like:
You're assuming that the data accessable through lockrect.pBits is linear in memory. This is in general not the case. Instead you have a constant offset between your rows which is defined by the lockrect.Pitch value.
To get the address of a pixel in the destination use:
byte * destAddr = (lockrect.pBits + y * lockrect.Pitch + 4 * x);
// for 32 bit images. For other formats adjust the hard-coded 4.
Thanks for the help :), in the end the following code worked:
Can it be made faster?
for (y = yoffset; y < (yoffset + height); y++)
{
for (x = xoffset; x < (xoffset + width); x++)
{
ARGB pixel;
pixel.r = srcdata[0];
pixel.g = srcdata[1];
pixel.b = srcdata[2];
pixel.a = srcdata[3];
memcpy( &dstdata[lockrect.Pitch * y + dstbytes * x], &pixel, dstbytes );
srcdata += srcbytes;
}
}
For an embedded design I am attempting to implement sobel's edge detection on a board without the use of a buffer. i.e. I am reading and writing directly from the screen. I can however, store about one or two imge width full of data to be referenced later. This is due to limitations set forth by the board. However I have fallen into some issue. All that I recieve is noise regardless if I attempt to do sobel or another edge detection algorithm. The code is below, does anyone have any suggestions
Version 1
void sobelEdgeDetection2() {
int GX[3][3];
int GY[3][3];
int sumX[3];
int sumY[3];
int SUM[3];
int piX = 0;
int piY = 0;
//uint8_t R, G, B = 0;
int I, J = 0;
//UnpackedColour pixVal;
uint16_t *buffer;
// allocate space for even scan lines and odd scan lines
buffer = new uint16_t[_gl->getWidth()];
//buffer for previous line
uint16_t *bufT;
// allocate space for even scan lines and odd scan lines
bufT = new uint16_t[_gl->getWidth()];
// Masks //////////////////////////////////////
//X//
GX[0][0] = -1;
GX[0][1] = 0;
GX[0][2] = 1;
GX[1][0] = -2;
GX[1][1] = 0;
GX[1][2] = 2;
GX[2][0] = -1;
GX[2][1] = 0;
GX[2][2] = 1;
//Y//
GY[0][0] = 1;
GY[0][1] = 2;
GY[0][2] = 1;
GY[1][0] = 0;
GY[1][1] = 0;
GY[1][2] = 0;
GY[2][0] = -1;
GY[2][1] = -2;
GY[2][2] = -1;
for (int Y = 0; Y < _gl->getHeight(); Y++) {
for (int X = 0; X < _gl->getWidth(); X++) {
sumX[0] = sumX[1] = sumX[2] = 0;
sumY[0] = sumY[1] = sumY[2] = 0;
if (Y == 0 || Y == _gl->getHeight() - 1) {
SUM[0] = SUM[1] = SUM[2] = 0;
} else if (X == 0 || X == _gl->getWidth() - 1) {
SUM[0] = SUM[1] = SUM[2] = 0;
} else {
for (I = -1; I <= 1; I++) {
for (J = -1; J <= 1; J++) {
piX = J + X;
piY = I + Y;
pixel16 pix = getPixel(piX, piY);
uint8_t Red = pix.Red;
uint8_t Green = pix.Green;
uint8_t Blue = pix.Blue;
sumX[0] += (Red) * GX[J + 1][I + 1];
sumX[1] += (Green) * GX[J + 1][I + 1];
sumX[2] += (Blue) * GX[J + 1][I + 1];
sumY[0] += (Red) * GY[J + 1][I + 1];
sumY[1] += (Green) * GY[J + 1][I + 1];
sumY[2] += (Blue) * GY[J + 1][I + 1];
}
}
SUM[0] = abs(sumX[0]) + abs(sumY[0]);
SUM[1] = abs(sumX[1]) + abs(sumY[1]);
SUM[2] = abs(sumX[2]) + abs(sumY[2]);
}
if (SUM[0] > 255)
SUM[0] = 255;
if (SUM[0] < 0)
SUM[0] = 0;
if (SUM[1] > 255)
SUM[1] = 255;
if (SUM[1] < 0)
SUM[1] = 0;
if (SUM[2] > 255)
SUM[2] = 255;
if (SUM[2] < 0)
SUM[2] = 0;
int newPixel[3];
newPixel[0] = (255 - ((unsigned char) (SUM[0])));
newPixel[1] = (255 - ((unsigned char) (SUM[1])));
newPixel[2] = (255 - ((unsigned char) (SUM[2])));
pixel16 pix(newPixel[0], newPixel[1], newPixel[2]);
buffer[X] = packColour(pix).packed565;
}
//Need to move cursor back
// draw it
this->paintRow(Point(0, Y), buffer, _gl->getWidth());
}
delete[] buffer;
}
Version2
/**
* https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/image-processing/edge_detection.html
* 1 Iterate over every pixel in the image
* 2 Apply the x gradient kernel
* 3 Apply the y gradient kernel
* 4 Find the length of the gradient using pythagoras' theorem
* 5 Normalise the gradient length to the range 0-255
* 6 Set the pixels to the new values
*/
void sobelEdgeDetection4() {
UnpackedColour colour;
for (int x = 1; x < _gl->getWidth() - 1; x++) {
for (int y = 1; y < _gl->getHeight() - 1; y++) {
// initialise Gx and Gy to 0
int Gx = 0;
int Gy = 0;
unsigned int intensity = 0;
// Left column
pixel16 pixel = this->getPixel(x - 1, y - 1);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gx += -intensity;
Gy += -intensity;
pixel = this->getPixel(x - 1, y);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gx += -2 * intensity;
pixel = this->getPixel(x - 1, y + 1);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gx += -intensity;
Gy += +intensity;
// middle column
pixel = this->getPixel(x, y - 1);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gy += -2 * intensity;
pixel = this->getPixel(x, y + 1);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gy += +2 * intensity;
// right column
pixel = this->getPixel(x + 1, y - 1);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gx += +intensity;
Gy += -intensity;
pixel = this->getPixel(x + 1, y);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gx += +2 * intensity;
pixel = this->getPixel(x + 1, y + 1);
intensity = pixel.Red + pixel.Green + pixel.Blue;
Gx += +intensity;
Gy += +intensity;
// calculate the gradient length
unsigned int length = (unsigned int) sqrt(
(float) (Gx * Gx) + (float) (Gy * Gy));
// normalise the length to 0 to 255
length = length / 17;
// draw the pixel on the edge image
pixel16 pixel2(length,length,length);
this->setPixel(x, y, pixel2);
}
}
}
Version 3
// sobel map for the x axis
const double _SOBEL_Gx[3][3] = { { -1.0, +0.0, +1.0 }, { -2.0, +0.0, +2.0 },
{ -1.0, +0.0, +1.0 } };
// sobel map for the y axis
const double _SOBEL_Gy[3][3] = { { +1.0, +2.0, +1.0 }, { +0.0, +0.0, +0.0 },
{ -1.0, -2.0, -1.0 } };
double get_sobel_gradient(int width, int height, int x, int y) {
double sobel_gradient_x = 0, sobel_gradient_y = 0;
int mx = 0, my = 0, sx = 0, sy = 0;
for (mx = x; mx < x + 3; mx++) {
sy = 0;
for (my = y; my < y + 3; my++) {
if (mx < width && my < height) {
//int r, g, b, idx;
int idx = (mx + width * my) * 3;
pixel16 pixVal = this->getPixel(idx);
//r = pixVal.Red;
//g = pixVal.Green;
//b = pixVal.Blue;
UnpackedColour col = this->packColour(pixVal);
sobel_gradient_x += col.packed565 * _SOBEL_Gx[sx][sy];
sobel_gradient_y += col.packed565 * _SOBEL_Gy[sx][sy];
}
sy++;
}
sx++;
}
return abs(sobel_gradient_x) + abs(sobel_gradient_y);
}
void sobelEdgeDetection3() {
double threshold = 50000.0;
UnpackedColour colour;
for (int y = 0; y < _gl->getHeight(); y++) {
for (int x = 0; x < _gl->getWidth(); x++) {
if (get_sobel_gradient(_gl->getWidth(), _gl->getHeight(), x, y)
>= threshold) {
colour.packed565 = 0x0000; //set white
} else {
colour.packed565 = 0xFFFF; //set black
}
this->setPixel(x, y, colour);
}
}
}
For Version 1, after you allocate 2 buffers (just use buffer and bufT), create 2 pointers to point to the current and previous rows, like this:
uint16_t *currentRow = buffer;
uint16_t *prevRow = bufT;
Inside the row loop, write to currentRow instead of buffer:
pixel16 pix(newPixel[0], newPixel[1], newPixel[2]);
currentRow[X] = packColour(pix).packed565;
Because the Sobel filter reads from the previous row, you can't overwrite a row until after you have finished calculating the filtered values for the row after it. So at the end of the loop, where you are currently calling paintRow(), draw the previous row (if one exists), and then swap the buffers so that the current becomes the previous, and the previous becomes the new current row (to be overwritten on the next pass through the loop). On the last row the current row is also drawn, because otherwise it won't be since the outer loop is about to terminate.
if(Y > 0) // draw the previous row if this is not the first row:
this->paintRow(Point(0, Y-1), prevRow, _gl->getWidth());
if(Y == _gl->getHeight()-1) // draw the current row if it is the last:
this->paintRow(Point(0, Y), currentRow, _gl->getWidth());
// swap row pointers:
uint16_t *temp = prevRow;
prevRow = currentRow;
currentRow = temp;
The same strategy should work for the other versions.
I am running for displaying RGB image from raw in C++ without any library. When I input the square image (e.g: 512x512), my program can display the image perfectly, but it does not in not_square size image (e.g: 350x225). I understand that I need padding for this case, then I tried to find the same case but it didn't make sense for me how people can pad their image.
If anyone can show me how to pad, I would be thanks for this. And below is what I have done for RGB from Raw.
void CImage_MyClass::Class_MakeRGB(void)
{
m_BMPheader.biHeight = m_uiHeight;
m_BMPheader.biWidth = m_uiWidth;
m_pcBMP = new UCHAR[m_uiHeight * m_uiWidth * 3];
//RGB Image
{
int ind = 0;
for (UINT y = 0; y < m_uiHeight; y++)
{
for (UINT x = 0; x < m_uiHeight*3; x+=3)
{
m_pcBMP[ind++] = m_pcIBuff[m_uiHeight - y -1][x+2];
m_pcBMP[ind++] = m_pcIBuff[m_uiHeight - y -1][x+1];
m_pcBMP[ind++] = m_pcIBuff[m_uiHeight - y -1][x];
}
}
}
}
You need to pad the number of bytes in each line out to a multiple of 4.
void CImage_MyClass::Class_MakeRGB(void)
{
m_BMPheader.biHeight = m_uiHeight;
m_BMPheader.biWidth = m_uiWidth;
//Pad buffer width to next highest multiple of 4
const int bmStride = m_uiWidth * 3 + 3 & ~3;
m_pcBMP = new UCHAR[m_uiHeight * bmStride];
//Clear buffer so the padding bytes are 0
memset(m_pcBMP, 0, m_uiHeight * bmStride);
//RGB Image
{
for(UINT y = 0; y < m_uiHeight; y++)
{
for(UINT x = 0; x < m_uiWidth * 3; x += 3)
{
const int bmpPos = y * bmWidth + x;
m_pcBMP[bmpPos + 0] = m_pcIBuff[m_uiHeight - y - 1][x + 2];
m_pcBMP[bmpPos + 1] = m_pcIBuff[m_uiHeight - y - 1][x + 1];
m_pcBMP[bmpPos + 2] = m_pcIBuff[m_uiHeight - y - 1][x];
}
}
}
}
I also changed the inner for loop to use m_uiWidth instead of m_uiHeight.
#Retired Ninja, Thanks anyway for your answer... you showed me a simple way for this...
But by the way, I have fixed mine as well with different way.. here is it:
void CImage_MyClass::Class_MakeRGB(void)
{
m_BMPheader.biHeight = m_uiHeight;
m_BMPheader.biWidth = m_uiWidth;
int padding = 0;
int scanline = m_uiWidth * 3;
while ( ( scanline + padding ) % 4 != 0 )
{
padding++;
}
int psw = scanline + padding;
m_pcBMP = new UCHAR[m_uiHeight * m_uiWidth * 3 + m_uiHeight * padding];
//RGB Image
int ind = 0;
for (UINT y = 0; y < m_uiHeight; y++)
{
for (UINT x = 0; x < m_uiHeight*3; x+=3)
{
m_pcBMP[ind++] = m_pcIBuff[m_uiHeight - y -1][x+2];
m_pcBMP[ind++] = m_pcIBuff[m_uiHeight - y -1][x+1];
m_pcBMP[ind++] = m_pcIBuff[m_uiHeight - y -1][x];
}
for(int i = 0; i < padding; i++)
ind++;
}
}
Okay, I'm trying to get my fps to 60, but right now it's at around 20. What can I do to this code to speed it up? Note: this is c++ using sfml.
App.Clear();
for(int x = 0; x < lv.width; x++){
for(int y = 0; y < lv.height; y++){
int tileXCoord = 0;
int tileYCoord = 0;
int tileSheetWidth = tilemapImage.GetWidth() / lv.tileSize;
if (lv.tile[x][y] != 0)
{
tileXCoord = lv.tile[x][y] % tileSheetWidth;
tileYCoord = lv.tile[x][y] / tileSheetWidth;
}
tilemap.SetSubRect(sf::IntRect(tileXCoord * lv.tileSize, tileYCoord * lv.tileSize, (tileXCoord * lv.tileSize) + lv.tileSize, (tileYCoord * lv.tileSize) + lv.tileSize));
tilemap.SetPosition(x * lv.tileSize, y * lv.tileSize);
App.Draw(tilemap);
}
}
playerSprite.SetSubRect(sf::IntRect(player.width * player.frame, player.height * player.state,
(player.width * player.frame) + player.width, (player.height * player.state) + player.height));
playerSprite.SetPosition(player.x, player.y);
App.Draw(playerSprite);
if(player.walking){
if(player.frameDelay >= 0)
player.frameDelay--;
if(player.frameDelay <= 0){
player.frame++;
player.frameDelay = 10;
if(player.frame >= 4)
player.frame = 0;
}
}
for(int x = 0; x < lv.width; x++){
for(int y = 0; y < lv.height; y++){
int tileXCoord = 0;
int tileYCoord = 0;
int tileSheetWidth = tilemapImage.GetWidth() / lv.tileSize;
if (lv.ftile[x][y] != 0)
{
tileXCoord = lv.ftile[x][y] % tileSheetWidth;
tileYCoord = lv.ftile[x][y] / tileSheetWidth;
}
tilemap.SetSubRect(sf::IntRect(tileXCoord * lv.tileSize, tileYCoord * lv.tileSize, (tileXCoord * lv.tileSize) + lv.tileSize, (tileYCoord * lv.tileSize) + lv.tileSize));
tilemap.SetPosition(x * lv.tileSize, y * lv.tileSize);
App.Draw(tilemap);
}
}
App.Display();
It looks like you're iterating over the pixels of your level, instead of over the tiles. Rewrite it like
///get the width of a tile
// get the height of a tile
int tileWidth = tilemapImage.getWidth();
int tileHeight = tilemapImage.getHeight();
//find the number of tiles vertically and horizontally, by dividing
// the level width by the number of tiles
int xTiles = lv.width / tileWidth;
int yTiles = lv.height / tileHeight();
for (int x = 0; x < xTiles; x++) {
for (int y = 0; y < yTiles; y++) {
// Do your calculations here
//ie: if(Walking) { draw_walk_anim; }
// draw_tile[x][y];
tilemap.SetPosition(x * tileWidth, y * tileHeight);
}
}
I lack expertise in the area, but you're drawing your tilemap for every tile, based on the parameters it's taking, it looks like it's redrawing the entire tilemap even though it's changed at most a single tile.
How would only calling App.Draw(tilemap); after every row, or perhaps after you've set the entire screen affect things.