SFML community forums

Help => Graphics => Topic started by: Chay Hawk on August 30, 2014, 12:16:53 am

Title: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 12:16:53 am
Ok so in my tile editor it never draws the bottom right square. why is that?

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>

using namespace std;

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Tile Editor");
    sf::Event event;
    sf::Mouse mouse;
    sf::Clock clock;
    sf::Time time;
    sf::View scrollScreen;
    sf::View zoomScreen;
    vector<vector<sf::Sprite> > Grid;
    int GridSizeX = 50; //Anything higher than 200x200 tiles is bad
    int GridSizeY = 50;
    window.setFramerateLimit(60);

    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));

    sf::Texture blankGridTexture;
    sf::Sprite blankGridSprite;
    if(!blankGridTexture.loadFromFile("Resources/Tiles/Grid.png"))
    {

    }
    blankGridSprite.setTexture(blankGridTexture);
    blankGridSprite.setOrigin(0, 0);


    //Input grid into vector
    Grid.resize(GridSizeY);
    for(int x = 0; x < GridSizeX; x++)//Column
    {
        for(int y = 0; y < GridSizeY; y++)//Row
        {
            Grid[y].push_back(blankGridSprite);
            blankGridSprite.setPosition(x * 32, y * 32);
        }
    }

    while(window.isOpen())
    {
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                {
                    window.close();
                }break;
                case sf::Event::Resized:
                {
                    sf::FloatRect viewArea(0, 0, event.size.width, event.size.height);
                    window.setView(sf::View(viewArea));
                    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                    zoomScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                }break;
            }
        }
    window.clear(sf::Color::White);

    time = clock.getElapsedTime();

    scrollScreen.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));

    sf::Vector2i pixel_pos = sf::Mouse::getPosition(window);
    sf::Vector2f coord_pos = window.mapPixelToCoords(pixel_pos, scrollScreen);

    cout << "Row: " << rint(coord_pos.x / 32) << ",";
    cout << "Column: " << rint(coord_pos.y / 32) << endl;


    sf::Image mask;
    mask.loadFromFile("Resources/Tiles/EditSquare.png");
    mask.createMaskFromColor(sf::Color(200, 191, 231));

    sf::Texture editSquareTexture;
    sf::Sprite editSquareSprite;
    editSquareTexture.loadFromImage(mask);
    editSquareSprite.setTexture(editSquareTexture);
    editSquareSprite.setOrigin(16, 16);

    //Set position of edit square to the mouse
    editSquareSprite.setPosition(rint(coord_pos.x / 32) * 32 + 16, rint(coord_pos.y / 32) * 32 + 16);

    //Load Grass
    sf::Texture tileTexture;
    sf::Sprite tileSprite;
    if(!tileTexture.loadFromFile("Resources/Tiles/Grass.png"))
    {
        cout << "Couldnt load resources" << endl;
    }
    tileSprite.setTexture(tileTexture);
    tileSprite.setOrigin(16, 16);

    if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        scrollScreen.move(-10, 0);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        scrollScreen.move(10, 0);
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        scrollScreen.move(0, -10);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        scrollScreen.move(0, 10);
    }

    //Draw map
    for(int x = 0; x < Grid.size(); x++)
    {
        for(int y = 0; y < Grid[x].size(); y++)
        {
            window.draw(Grid[x][y]);
        }
    }

    int indexX = rint(coord_pos.x / 32);
    int indexY = rint(coord_pos.y / 32 + 1);

    if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if(indexY <= Grid.size())
        {
            Grid[indexY][indexX].setTexture(tileTexture);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
    if(sf::Mouse::isButtonPressed(sf::Mouse::Right))
    {
        if(indexY <= Grid.size())
        {
            Grid[indexY][indexX].setTexture(blankGridTexture);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }

    window.draw(editSquareSprite);
    window.setView(scrollScreen);
    clock.restart();
    window.display();
    }

    return 0;
}
 
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 01:33:03 am
This moves a tilemap with the mouse.

Could you supply the images so I can see what it's supposed to look like rather than using some of my own random images  ;D
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 01:57:36 am
Ok sure, the images are too big in file size so i put them on google drive.

https://drive.google.com/file/d/0B2dzHO9C0wPseEtwdVQ4VWhoaEE/edit?usp=sharing

Also when i try to draw on the bottom grid it crashes. I believe its becuase the original position is actually below the mouse and the placement sprite, but I changed the draw position so everything would line up so therefore its actually trying to access an element in the vector to draw to that is out of bounds, causing a crash. But if i draw above the grid it will draw tiles on the bottom. Very strange.
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 03:13:15 am
Much better now that I can see it with the right images  ;D

I'm going through your code (for fun 8)) and I'm noticing a few things here and there that should be fixed before it causes your problems later on.

Your grid iteration is mixed.
Quote
   Grid.resize(GridSizeY);
   for (int x = 0; x < GridSizeX; x++)//Column
   {
      for (int y = 0; y < GridSizeY; y++)//Row
      {
         Grid[y].push_back(blankGridSprite);
         blankGridSprite.setPosition(x * 32, y * 32);
      }
   }
That makes no sense as you are resizing the grid to hold rows and then go through them as columns. Then, when you're iterating the "y", you're pushing the new y's based on the y. That was not a very good explanation of what I mean. However, in your code-style, I think it should be this:
        Grid.resize(GridSizeX);
        for (int x = 0; x < GridSizeX; x++)//Column
        {
                for (int y = 0; y < GridSizeY; y++)//Row
                {
                        blankGridSprite.setPosition(x * 32, y * 32);
                        Grid[x].push_back(blankGridSprite);
                }
        }

You should replace all of your usage (you used it 6 times) of rint (as I found that it's rounding to the nearest integer, which is upwards when it hits halfway) with floor. Try it. Trust me  8)

Cases in a switch statement don't need block braces. Just so you know  ;)

You should probably handle the failures when loading textures. Returning from the application seems to make sense since you can't use it without them.

Your outputting of row and column are incorrect. Row should be y and column should be x.

You mix up X and Y access again in the Grid vector here:
Quote
Grid[indexY][indexX].setTexture(tileTexture);
and here:
Quote
Grid[indexY][indexX].setTexture(blankGridTexture);

You are only testing to make sure that Y is within boundary (the bottom of the grid). You aren't testing for the top, or testing the x for the sides. Also, if y equals Grid.size(), it's accessing an element that is not there.

You are loading in your images and creating your textures and sprites on every cycle. Take them outside the main window loop and load them just once.

As for the problem you mentioned about it drawing on the bottom and missing the last tile off, it's because you're setting the position of the temporary variable after assigning it to the grid, so each tile is getting the position of the previous one (the first two have the same position).

You'll need to swap them to this:
                        blankGridSprite.setPosition(x * 32, y * 32);
                        Grid[x].push_back(blankGridSprite);
and then remove the +1 from indexY.

After making these modifications myself, it works perfectly and never crashes  8)
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 03:39:00 am
Awesome :D I fixed most of the problems, but I cant seem to fix both sides of x it still crashes. Also even though I dont test for the top of Y it doesnt crash when i go up. I'll fix the texture loading error handling later, as right now my main focus is getting the editor up and running. Also with the x and y, i get confused a lot, I know that going left and up on the computer screen is a negative value, and down and right are positive but when I say something like if(indexY <= Grid[GridSizeY].size()) I get confused if its starting at the top or bottom.

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>

using namespace std;

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Tile Editor");
    sf::Event event;
    sf::Mouse mouse;
    sf::Clock clock;
    sf::Time time;
    sf::View scrollScreen;
    sf::View zoomScreen;
    vector<vector<sf::Sprite> > Grid;
    int GridSizeX = 10; //Anything higher than 200x200 tiles is bad
    int GridSizeY = 10;
    window.setFramerateLimit(60);

    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));

    sf::Texture blankGridTexture;
    sf::Sprite blankGridSprite;
    if(!blankGridTexture.loadFromFile("Resources/Tiles/Grid.png"))
    {

    }
    blankGridSprite.setTexture(blankGridTexture);
    blankGridSprite.setOrigin(0, 0);

    //Load Grass
    sf::Texture tileTexture;
    sf::Sprite tileSprite;
    if(!tileTexture.loadFromFile("Resources/Tiles/Grass.png"))
    {
        cout << "Couldnt load resources" << endl;
    }
    tileSprite.setTexture(tileTexture);
    tileSprite.setOrigin(16, 16);

    sf::Image mask;
    mask.loadFromFile("Resources/Tiles/EditSquare.png");
    mask.createMaskFromColor(sf::Color(200, 191, 231));

    sf::Texture editSquareTexture;
    sf::Sprite editSquareSprite;
    editSquareTexture.loadFromImage(mask);
    editSquareSprite.setTexture(editSquareTexture);
    editSquareSprite.setOrigin(16, 16);


    //Input grid into vector
    Grid.resize(GridSizeX);
    for (int x = 0; x < GridSizeY; x++)//Column
    {
        for (int y = 0; y < GridSizeY; y++)//Row
        {
            blankGridSprite.setPosition(x * 32, y * 32);
            Grid[x].push_back(blankGridSprite);
        }
    }

    while(window.isOpen())
    {
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                    window.close();
                break;

                case sf::Event::Resized:

                    sf::FloatRect viewArea(0, 0, event.size.width, event.size.height);
                    window.setView(sf::View(viewArea));
                    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                    zoomScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                break;
            }
        }
    window.clear(sf::Color::White);

    time = clock.getElapsedTime();

    scrollScreen.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));

    sf::Vector2i pixel_pos = sf::Mouse::getPosition(window);
    sf::Vector2f coord_pos = window.mapPixelToCoords(pixel_pos, scrollScreen);

    cout << "Row: " << floor(coord_pos.y / 32) << ",";
    cout << "Column: " << floor(coord_pos.x / 32) << endl;


    //Set position of edit square to the mouse
    editSquareSprite.setPosition(floor(coord_pos.x / 32) * 32 + 16, floor(coord_pos.y / 32) * 32 + 16);

    if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        scrollScreen.move(-10, 0);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        scrollScreen.move(10, 0);
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        scrollScreen.move(0, -10);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        scrollScreen.move(0, 10);
    }

    //Draw map
    for(int x = 0; x < Grid.size(); x++)
    {
        for(int y = 0; y < Grid[x].size(); y++)
        {
            window.draw(Grid[x][y]);
        }
    }

    int indexX = floor(coord_pos.x / 32);
    int indexY = floor(coord_pos.y / 32);

    if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if(indexY <= Grid[GridSizeY].size())
        {
            Grid[indexX][indexY].setTexture(tileTexture);
        }
        if(indexX <= Grid[GridSizeX].size())
        {
            Grid[indexX][indexY].setTexture(blankGridTexture);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
    if(sf::Mouse::isButtonPressed(sf::Mouse::Right))
    {
        if(indexY <= Grid.size())
        {
            Grid[indexX][indexY].setTexture(blankGridTexture);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }

    window.draw(editSquareSprite);
    window.setView(scrollScreen);
    clock.restart();
    window.display();
    }

    return 0;
}
 
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 03:43:25 am
        if(indexY <= Grid.size())
As I mentioned earlier, these should never be equal.
Also, the size of "Grid" is the x size. For y, you need Grid[0].size(). Better still, just use GridSizeX and GridSizeY  :P

I see that you copied my code. You should've typed it; you may have noticed the error ;) I fixed it now though; see if you can see what I changed  ;D

I fixed most of the problems
Lies! I fixed them  8)
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 03:51:05 am
Haha yeah I did copy this:

Grid.resize(GridSizeX);
    for (int x = 0; x < GridSizeX; x++)//Column
    {
        for (int y = 0; y < GridSizeY; y++)//Row
        {
            blankGridSprite.setPosition(x * 32, y * 32);
            Grid[x].push_back(blankGridSprite);
        }
    }
 

But I figured this out on my own:

blankGridSprite.setPosition(x * 32, y * 32);
            Grid[x].push_back(blankGridSprite);
 

I changed the if block to this:

if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if(indexY < Grid[GridSizeY].size())
        {
            Grid[indexX][indexY].setTexture(tileTexture);
        }
        if(indexX > Grid[GridSizeX].size())
        {
            Grid[indexX][indexY].setTexture(blankGridTexture);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
 

But it still doesnt work.

"Lies! I fixed them  8)"

Lol yeah that's true :P
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 03:55:26 am
 :o

GridSizeX instead of Grid.size()
GridSizeY instead of Grid[0].size()
They're the same values.

You should be testing to see if they (indexX and indexY) are less than the size, not greater than.
Also, test to make sure they're zero or higher. It can crash when they're below zero. (obviously e.g. Grid[-1]  :o)

This is just a vector of sprites with different textures, you know. The actual map isn't stored anywhere. How will you be saving this?  ;)
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 04:00:00 am
I'm terrible at error handling  for some reason, I have no idea why :( so like this?

if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if(indexY < GridSizeY)
        {
            Grid[indexX][indexY].setTexture(tileTexture);
        }
        if(indexX < GridSizeX)
        {
            Grid[indexX][indexY].setTexture(blankGridTexture);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
 

With this code I cant draw on the grid.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 04:02:31 am
"This is just a vector of sprites with different textures, you know. The actual map isn't stored anywhere. How will you be saving this?  ;)"

I dont know D: Can I do that like this? Oh god please tell me I can...
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 04:04:51 am
That's because you've moved the code that changes it to a blank tile into the left mouse button block so it's just setting to the new tile, and then removing it instantly.

In your original code, you have it doing things based on left and right buttons. Keep it there and test all four of the boundaries in both of the ifs.

Can I do that like this?
I guess you can. You'll need to go through them all and work out which texture they have, then decide on which tile it is based on that.

EDIT:
I caved and decided I was going to give you the answer  >:(

In your original code where you had the following code twice:
if(indexY <= Grid.size())
replace each of them with
if ((indexY < GridSizeY) && (indexY >= 0) && (indexX < GridSizeX) && (indexX >= 0))
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 04:20:47 am
"I caved and decided I was going to give you the answer  >:("

Well I'm glad you did, cause I never would have figured that out lol. but now I see how its done i'll be able to do it myself from now on. (Hopefully)

as for the saving thing, i'm kind of freaked out about it now cause im not doing this editor for fun, i'm building it to use and a map editor that cant save the map is useless, I mean it is fun building it and learning how to do 2d stuff but its not just for those reasons. Bu't i've saved vector contents to files before, but this is different, like you said i'll need to get the texture and their positions. How do you think I could do it? I'm going to work on that right now.

Also is there a picture representation of a 2d vector? I've been looking for one and I cant find one. If I can see a visual reprisentation a lot, if not all of the confusion will be cleared up.
Title: Re: Tile Editor is off center?
Post by: Jesper Juhl on August 30, 2014, 11:40:48 am
Tiled (http://www.mapeditor.org/)
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 01:54:59 pm
I never would have figured that out
It's just making sure that both indexX and indexY they are within the range of their respect vectors i.e. from 0 to size - 1. (you can do indexX <= (GridSizeX - 1) or indexX < GridSizeX. They are equivalent here.)

How do you think I could do it?
From your current way, you'd need to go through the entire vector of sprites, see which textures they use, and create a new vector representing which tiles they are. This other vector is usually int or unsigned int and is just an index of which tile that should be displayed. "Normally", this is the main vector and the display is created from this information. A 2D vector of ints is much easier to save  ;)

Also is there a picture representation of a 2d vector? I've been looking for one and I cant find one. If I can see a visual reprisentation a lot, if not all of the confusion will be cleared up.
I'm not sure what you mean. You need help visualising how it's stored?

im not doing this editor for fun, i'm building it to use and a map editor that cant save the map is useless, I mean it is fun building it and learning how to do 2d stuff but its not just for those reasons.
As Jesper has already shown, there are tile map editors out there already that have this functionality so that you can create and use tile maps in your programs easily. Other than Tiled that has already been mentioned, there is another called Mappy (http://www.tilemap.co.uk/mappy.php) that you may also want to consider.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 06:12:01 pm
Quote
It's just making sure that both indexX and indexY they are within the range of their respect vectors i.e. from 0 to size - 1. (you can do indexX <= (GridSizeX - 1) or indexX < GridSizeX. They are equivalent here.)

Ok I understand that, that really isnt too difficult, I'm just not used to working with 2d space, so I need to get familiar with it.

Quote
I'm not sure what you mean. You need help visualising how it's stored?

Yeah, I THINK I understand, but I want to be absolutly sure. Here is a drawing I did in MS paint of what I think a 2d vector would look like visually:

http://oi60.tinypic.com/11ifg2o.jpg


Quote
From your current way, you'd need to go through the entire vector of sprites, see which textures they use, and create a new vector representing which tiles they are. This other vector is usually int or unsigned int and is just an index of which tile that should be displayed. "Normally", this is the main vector and the display is created from this information. A 2D vector of ints is much easier to save  ;)

Ok, that shouldnt be too hard to do, i'll give it a shot right now.

Quote
As Jesper has already shown, there are tile map editors out there already that have this functionality so that you can create and use tile maps in your programs easily. Other than Tiled that has already been mentioned, there is another called Mappy that you may also want to consider.

I know about Tiled, also I own RPG Maker VX Ace and Game Maker 8. I don't want to use them. My program is going to have a lot more than just tile editing features. Besides, If I thought any of the other tile editors were any good, I wouldnt go to all the trouble of building my own now would I ;)
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 07:11:53 pm
I don't want to use them. My program is going to have a lot more than just tile editing features. Besides, If I thought any of the other tile editors were any good, I wouldnt go to all the trouble of building my own now would I ;)
I know what you mean. I like to work on the creation tools myself too. However, if your reason for making it is to use it rather than the actual making, then go with pre-made stuff. I'm not sure what you are going to be adding to your tile editors that others' cannot do - I like the fact they just give me the tile map numbers, for example - but if you want your editor to do more than that, good luck. Oh, and let us all use it!

Here is a drawing I did in MS paint of what I think a 2d vector would look like visually:
http://oi60.tinypic.com/11ifg2o.jpg
Most important thing to remember is that they start at 0, not 1.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 30, 2014, 07:15:57 pm
Here is a drawing I did in MS paint of what I think a 2d vector would look like visually:
http://oi60.tinypic.com/11ifg2o.jpg
Most important thing to remember is that they start at 0, not 1.

It's also important to point out that picture makes no distinction between pointers and values.

I would suggest a google image search for "ragged arrays", since that's what a std::vector of std::vectors effectively is.  Here's a few good pictures I see in the results.

This one is pretty language/type-agnostic, since it just shows the structure:
(http://ecomputernotes.com/images//thumb609-Non-Rectangular-array-table-855fdb0422a97fa9f57f1224ee3e7652.jpg)

This one shows C-strings:
(http://freshsources.com/HTML/11.09/ALLISON/figa.gif)

And this one shows 2D arrays in Java:
(http://www.isr.umd.edu/~austin/ence200.d/java-examples.d/basics-arrays.d/array-two-dimensional.gif)
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 07:39:45 pm
Quote
I know what you mean. I like to work on the creation tools myself too. However, if your reason for making it is to use it rather than the actual making, then go with pre-made stuff. I'm not sure what you are going to be adding to your tile editors that others' cannot do - I like the fact they just give me the tile map numbers, for example - but if you want your editor to do more than that, good luck. Oh, and let us all use it!

I would rather make m,y own tools to use, then if there is a feature i want or something I would like to add or change I can just do it right then and there, I don't need to ask for a feature request and hope and pray its added and then wait months for it to come out, ya know what I mean? I'm sure there's some open source tile editors out there but eh, it just feels more satisfying to me knowing that if i make a game it will be with the tools I created. I have some pretty good ideas for a tile map editor. I have used quite a few of them myself and I plan on using more just to see what they don't have and to gather ideas. I'm going to write down all of the features each one has and what they are all missing and what can be improved on. I't might sound like a huge task but I find it's just research and development, and that to me is fun to do as well. And as for sharing it, I definitely will!! :)


Quote
Most important thing to remember is that they start at 0, not 1.

Oh I forgot about that :P but other than that is it correct?

Quote
It's also important to point out that picture makes no distinction between pointers and values.

I would suggest a google image search for "ragged arrays", since that's what a std::vector of std::vectors effectively is.  Here's one good picture I see in the results:

Ok thank you I will search for that and see what else I can find.
Title: Re: Tile Editor is off center?
Post by: Hapax on August 30, 2014, 07:47:20 pm
Does this help?
It's similar to what Ixrec posted but aimed at describing the specific case you are using in your program...

(http://i.imgur.com/nOGFJaN.jpg)

You should still follow Ixrec's advice  ;)
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 30, 2014, 08:04:55 pm
Other good-to-know things about using arrays to store grids:

The terms "row major" and "column major" are used to describe whether you're storing a grid by rows or by columns.  I believe Hapax's image shows column major, if I'm reading it right.

When the grid's rows/columns are all guaranteed to be the same length, a ragged array is not necessarily the best way of storing it.  First, it makes certain operations harder than others for no apparent reason.  For instance, if you store it in row major format, then the code to move rows around is completely different from and much easier than the code to move columns around.  Second, it's guaranteed not to be stored in one contiguous block of memory, which usually isn't a big deal, but if you expect to work with large, complicated grids it's usually easier, faster and simpler to have just one block of memory so there's less indirection and reallocation going on.  Third, and theoretically speaking the most important, a ragged array can have each "row" or "column" be a different length, and you may not want that to be possible.

The alternative I'm hinting at is to store an X by Y grid by simply using a single vector of size X times Y.  You can then wrap this vector in a class with methods like get(x,y) and set(x,y) that abstract away all the row/column index conversion, so you get the simple contiguous memory without sacrificing the intuitive (row, column) notation.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 11:12:00 pm
Yeah that all makes sense, the images really help a ton. I seem to be having trouble with my code again -_-, I decided that I want to load a sprite sheet in, instead of individual tiles, because i'm going to have to do that anyways so why not do it now. I need to get the width and height of it and for some reason I cant seem to do it. Also The sprite sheet is on top of everything else, in the sense that when i go over it with my mouse it goes underneath it. I need to check and see if the mouse is IN the tile sheets boundaries, and I just cant seem to get it.

#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Tile Editor");
    sf::Event event;
    sf::Mouse mouse;
    sf::Clock clock;
    sf::Time time;
    sf::View scrollScreen;
    sf::View zoomScreen;
    vector<vector<sf::Sprite> > Grid;
    vector<vector<int> > saveGrid;
    int GridSizeX = 10; //Anything higher than 200x200 tiles is bad
    int GridSizeY = 10;
    window.setFramerateLimit(60);

    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));

    sf::Texture blankGridTexture;
    sf::Sprite blankGridSprite;
    if(!blankGridTexture.loadFromFile("Resources/Tiles/Grid.png"))
    {

    }
    blankGridSprite.setTexture(blankGridTexture);
    blankGridSprite.setOrigin(0, 0);

    //Load Grass
    sf::Texture tileTexture;
    sf::Sprite tileSprite;
    if(!tileTexture.loadFromFile("Resources/Tiles/Grass.png"))
    {
        cout << "Couldnt load resources" << endl;
    }
    tileSprite.setTexture(tileTexture);
    tileSprite.setOrigin(16, 16);

    //Load flower grass texture
    sf::Texture flowerGrassTexture;
    sf::Sprite flowerGrassSprite;
    if(!flowerGrassTexture.loadFromFile("Resources/Tiles/FlowerGrass.png"))
    {
        cout << "Couldnt load flower tiles" << endl;
    }

    //Set mask for editing square
    sf::Image mask;
    mask.loadFromFile("Resources/Tiles/EditSquare.png");
    mask.createMaskFromColor(sf::Color(200, 191, 231));

    sf::Texture editSquareTexture;
    sf::Sprite editSquareSprite;
    editSquareTexture.loadFromImage(mask);
    editSquareSprite.setTexture(editSquareTexture);
    editSquareSprite.setOrigin(16, 16);

    //Load TileSheet
    sf::Texture tileSheetTexture;
    sf::Sprite tileSheetSprite;
    if(!tileSheetTexture.loadFromFile("Resources/Tile Sheets/Outside_A5.png"))
    {

    }
    tileSheetSprite.setTexture(tileSheetTexture);

    //Input grid into vector
    Grid.resize(GridSizeX);
    for (int x = 0; x < GridSizeY; x++)//Column
    {
        for (int y = 0; y < GridSizeY; y++)//Row
        {
            blankGridSprite.setPosition(x * 32, y * 32);
            Grid[x].push_back(blankGridSprite);
        }
    }

    while(window.isOpen())
    {
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                    window.close();
                break;

                case sf::Event::Resized:

                    sf::FloatRect viewArea(0, 0, event.size.width, event.size.height);
                    window.setView(sf::View(viewArea));
                    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                    zoomScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                break;
            }
        }
    window.clear(sf::Color::White);

    time = clock.getElapsedTime();

    scrollScreen.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));

    sf::Vector2i pixel_pos = sf::Mouse::getPosition(window);
    sf::Vector2f coord_pos = window.mapPixelToCoords(pixel_pos, scrollScreen);

    cout << "Row: " << floor(coord_pos.y / 32) << ",";
    cout << "Column: " << floor(coord_pos.x / 32) << endl;


    if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        scrollScreen.move(-10, 0);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        scrollScreen.move(10, 0);
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        scrollScreen.move(0, -10);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        scrollScreen.move(0, 10);
    }

    //Draw map
    for(int x = 0; x < Grid.size(); x++)
    {
        for(int y = 0; y < Grid[x].size(); y++)
        {
            window.draw(Grid[x][y]);
        }
    }


    int indexX = floor(coord_pos.x / 32);
    int indexY = floor(coord_pos.y / 32);

    //Set position of edit square to the mouse
    editSquareSprite.setPosition(floor(coord_pos.x / 32) * 32 + 16, floor(coord_pos.y / 32) * 32 + 16);

    if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if((indexY < GridSizeY) && (indexY >= 0) && (indexX < GridSizeX) && (indexX >= 0))
        {
            Grid[indexX][indexY].setTexture(tileTexture);
            window.draw(editSquareSprite);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
    if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if((indexY > tileSheetSprite.getPosition().y) && (indexY > tileSheetSprite.getPosition().y) &&
           (indexX > tileSheetSprite.getPosition().x) && (indexX > tileSheetSprite.getPosition().x))
        {
            cout << "On new tile sheet" << endl;
            window.draw(editSquareSprite);
        }
        else
        {
            cout << "Out of bounds sprite sheet" << endl;
        }
    }
    if(sf::Mouse::isButtonPressed(sf::Mouse::Right))
    {
        if ((indexY < GridSizeY) && (indexY >= 0) && (indexX < GridSizeX) && (indexX >= 0))
        {
            Grid[indexX][indexY].setTexture(blankGridTexture);
            window.draw(editSquareSprite);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
    if(sf::Mouse::isButtonPressed(sf::Mouse::Middle))
    {
        if((indexY < GridSizeY) && (indexY >= 0) && (indexX < GridSizeX) && (indexX >= 0))
        {
            Grid[indexX][indexY].setTexture(flowerGrassTexture);
            window.draw(editSquareSprite);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::F))
    {
        string mapName;
        ofstream saveMap;

        cout << "Enter a name for your map" << endl;
        getline(cin, mapName);

        saveMap.open(mapName.append(".txt"));
    }
    tileSheetSprite.setPosition(350, 0);


    window.draw(tileSheetSprite);
    window.setView(scrollScreen);
    clock.restart();
    window.display();
    }

    return 0;
}
 
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 30, 2014, 11:20:07 pm
Quote
I need to get the width and height of it and for some reason I cant seem to do it.

This is a question you can very easily answer yourself by looking at the documentation.

So I won't tell you the answer.

(hint: it's probably on http://www.sfml-dev.org/documentation/2.1/classsf_1_1Texture.php)

Quote
Also The sprite sheet is on top of everything else, in the sense that when i go over it with my mouse it goes underneath it.

Are you talking about the OS cursor, or a sprite you draw at the cursor's location?  The former shouldn't be possible, and latter is a trivial fix (draw your sprite later).

Quote
I need to check and see if the mouse is IN the tile sheets boundaries, and I just cant seem to get it.

If you mean this as a fix to the previous problem: Don't draw things in a different order based on where one sprite happens to be right now.  That's completely overcomplicating the issue.  Just draw the sprite last if you want it to be on top of everything else.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 30, 2014, 11:28:46 pm
Quote
This is a question you can very easily answer yourself by looking at the documentation.

I know how to do that, I meant I cant figure out how to check if the cursor is within bounds of the tilesheet sorry, I said it differently twice.


Quote
Are you talking about the OS cursor, or a sprite you draw at the cursor's location?  The former shouldn't be possible, and latter is a trivial fix (draw your sprite later).

Yeah the sprite is drawing under the image, and no matter where i place it in my code it wont get fixed.

Quote
If you mean this as a fix to the previous problem, no, don't do that.  Just draw the sprite last if you want it to be on top of everything else.  Anything else is overcomplicating your code.

Well what i'm trying to do is make it so that I can copy an image from the tilesheet but I need to make sure it's within bounds of the tile sheet, I want to set each 32x32 area to a number within the tilesheet so that way I can output it to a file later. I've been trying to do that for a while but I cant seem to figure it out, any hints, I cant even get anywhere with it.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 12:00:57 am
I know how to do that, I meant I cant figure out how to check if the cursor is within bounds of the tilesheet sorry, I said it differently twice.
That one is also in the documentation and tutorials.  More hints:

Tutorial: http://sfml-dev.org/tutorials/2.1/window-inputs.php#mouse
Docs: http://sfml-dev.org/documentation/2.1/classsf_1_1Mouse.php

(if an sf::View is involved, there's another step you might have to do which is described in the View tutorial: http://sfml-dev.org/tutorials/2.1/graphics-view.php#coordinates-conversions)

If you need help with the actual bounds check after you get all the positions and sizes, sf::Rect::contains() and sf::Rect::intersects() might be useful: http://sfml-dev.org/documentation/2.1/classsf_1_1Rect.php  Though you can also do this trivially yourself.

Quote
Yeah the sprite is drawing under the image, and no matter where i place it in my code it wont get fixed.

That doesn't sound right at all.  Could you try to reduce your code to a complete and minimal example which demonstrates this problem and nothing else?  You are referring to where you place the draw() call for it, not where you declare the variable, right?

Quote
Well what i'm trying to do is make it so that I can copy an image from the tilesheet but I need to make sure it's within bounds of the tile sheet, I want to set each 32x32 area to a number within the tilesheet so that way I can output it to a file later. I've been trying to do that for a while but I cant seem to figure it out, any hints, I cant even get anywhere with it.

I *think* the hints I've given so far provide all the steps you need, though ask again if I missed a step.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 12:29:38 am
Quote
If you need help with the actual bounds check after you get all the positions and sizes, sf::Rect::contains() and sf::Rect::intersects() might be useful: http://sfml-dev.org/documentation/2.1/classsf_1_1Rect.php  Though you can also do this trivially yourself.

Yeah thats what i'm trying to do, but I cant seem to get it right.

if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if((indexY > tileSheetSprite.getPosition().y) && (indexY > tileSheetSprite.getPosition().y) &&
           (indexX > tileSheetSprite.getPosition().x) && (indexX > tileSheetSprite.getPosition().x))
        {
            cout << "On new tile sheet" << endl;
            window.draw(editSquareSprite);
        }
        else
        {
            cout << "Out of bounds sprite sheet" << endl;
        }
    }

As for the tilesheet, I fixed it, I dont know what was going on but I got my placement marker to draw over it.

Quote
I *think* the hints I've given so far provide all the steps you need, though ask again if I missed a step.

Well, what i'm confused on is how am I supposed to output the sprite grid to a text document if its a vector of sprites, I need to get the current grid and whats drawn on it and write that to a text document. If I can figure out the above if statement problem I can do width / 32 and height / 32 on the image, that should give me 8 squares wide and 16 tall my tile sheet is (256 x 512) but then from there i'm a little stumped on what to do with the numbers. any hints on the steps i should take to do this would be great, it's annoying because I know what I need to do it's just kind of vague how to do it.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 12:42:24 am
Quote
code

It's not obvious to me from looking at the code, but this is probably something simple you could easily find if you stepped through your code with a debugger and checked if the values of coord_pos, indexX/Y and so on are what you expect them to be.

By the way, those are terrible variable names.  Use names that makes it obvious what the actually mean, like mouseCoords, gridRow, and gridColumn.

Quote
Well, what i'm confused on is how am I supposed to output the sprite grid to a text document if its a vector of sprites, I need to get the current grid and whats drawn on it and write that to a text document. If I can figure out the above if statement problem I can do width / 32 and height / 32 on the image, that should give me 8 squares wide and 16 tall my tile sheet is (256 x 512) but then from there i'm a little stumped on what to do with the numbers. any hints on the steps i should take to do this would be great, it's annoying because I know what I need to do it's just kind of vague how to do it.

Ooooooh, you're asking how to serialize the tilemap.

Serialization of any type of data is a non-trivial problem with no easy answer.  Typically, if there are standard formats out there for this sort of data, you should use them.  Any remotely decent editor of X files will support as many X file formats as it possibly can, because none of them is objectively superior to the others.  I'm going to assume you know or can find out what file formats you want because you're the one making a tile map editor, and I've never used tile maps so I wouldn't know where to begin looking.  The documentation of those formats should tell you everything you need to know to serialize your tile maps in that format.

Even I can find at least one such format with a quick google (https://github.com/bjorn/tiled/wiki/TMX-Map-Format) so you shouldn't have to worry about making up a brand new file format yourself.  Unless your dissatisfaction for existing tile map editors also extends to existing tile map file formats...

If the format in question involves a standard data serialization language like XML or JSON, you should use an existing library to help you work with those formats efficiently.
Title: Re: Tile Editor is off center?
Post by: Hapax on August 31, 2014, 12:52:17 am
I believe Hapax's image shows column major, if I'm reading it right.
If the term means what I think it means then, yes, that's right  ???
It was because it seemed Chay was aiming to have the vector in the order "x before y" and this makes sense as this is how we usually describe 2D.
However, I think I'd personally always use row first ("major"?) when using 2D vectors.
That said, I'd almost always use a 1D vector for tile maps as you mentioned:
store an X by Y grid by simply using a single vector of size X times Y.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 12:55:58 am
Well, I just want to output the grid to a file like this


000001111111100000
011111222223233211
033321110000000000

Where each number is a tile, and I can just load it into the map. Of course I would save position info in there as well.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 01:00:09 am
That would be a custom file format.  If you don't care about your output being usable by anyone else's tools, and you think this format will be easier for you to work with than any of the standard stuff, then that's fine, as long as you make that decision consciously.

So what's stopping you from serializing a tilemap as a cryptic sequence of numbers like that?  Are you asking us for general advice on how to go about designing this cryptic sequence? (because my advice would be "use XML or JSON")  Are you asking us how to do file input and output? (C++ iostreams)  Are you asking how to get the image data from a sprite (well, a texture) into a sequence of bytes you can manipulate? (the key part is probably sf::Image::getPixelsPtr)
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 01:08:59 am
Well that depends on whats easier lol, if the xml or JSON thing is easier than i'll do that, but if not then yeah I would rather stick with a regular text file. What i'm having trouble with is looping through the vector and assigning a number to the different textures, if that's even possible. But the thing is I have to make it so it can do this without knowing the exact number of tiles or tile sheets and if there are other tile sheets it has to account for those and number those differently because if there are multiple tilesheets and each tile on those sheets at position 0,0 is assigned 0 and a number then when the editor tries to load the map it will be placing those tiles on top of each other. So yeah... but if there is an easier way to do that than i would like to know as well. All I want is for the tile editor to save the tiles with the textures assigned to a file, then load them when needed, how do i do that? that's what i'm trying to figure out. So yeah any kind of hints or clues, as to what exactly I should do would help me a lot i'm stumped at this point, because basically i have to convert a sprite object to an integer and that just isnt possible.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 01:18:16 am
Two things come to mind:

- I don't see the need to assign integers to everything.  Why not strings? (ie, names)

- The big question seems to be where the image files are getting stored.  Are you imagining a project as a folder that contains some .png files and a .chayhawktilemap file?  Or do you want the bytes of the images to be embedded in the .chayhawktilemap file?  Or something in between?


If I were doing something like this, my first thought would be a folder of .pngs and an .ixrectilemap file, which I might design as a JSON object like this:
{
    "textures": {
        "grass": "./grass.png",
        "snow": "./thick_snow.png",
        "water": "./clear_water.png"
   },
    "tiles": [
        [ "grass", "grass", "grass" ],
        [ "grass", "grass", "grass" ],
        [ "grass", "snow", "grass" ],
        [ "grass", "snow", "snow" ],
        [ "water", "snow", "snow" ]
    ]
}
Of course, I know bugger all about tile maps, so I assume there's a lot more data you'd want to put in here somehow, and I have no idea what it would look like, but hopefully this at least helps you start brainstorming.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 01:23:51 am
Oh, well I just thought integers might be easier but i'll do whatever is necessary to make it work. Well, this editor will be used by other people who will load their own tile sets into the editor so I want to be able to load differet tile sets and as many tile sets as i can without having to write a single line of code, the editor should do all that work for the user, so I need to write it in that fashion. But the .png images will be stored either in a specific hard coded folder location or i'll make a dialog box that lets them choose where its at.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 01:33:17 am
None of these things are really "necessary".  It's completely up to you how you go about implementing custom file formats.  It just sounds like integers would be a bit of wasted effort since the information you already have on the sprites doesn't contain any identifying integers (otherwise you wouldn't need to assign/generate them), while I assume you would have identifying filepaths or names for all of them.  And I think using JSON/XML/etc instead of a cryptic sequence of digits would make things a lot easier in the long run, but that's also something only you can properly judge.

Do you have any specific questions or is this now simply a matter of you designing your preferred format?

Quote
i'll make a dialog box that lets them choose where its at.
If you're imagining a full-blown filesystem browser popup, this may be something you need a proper GUI toolkit for.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 01:54:18 am
I just want to go the easiest route possible. Since i'll be using tile sheets and not individual tiles like before, I need to figure out how to copy tiles from the spritesheets I was thinking if i could get this if statement working:

if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if((indexY > tileSheetSprite.getPosition().y) && (indexY > tileSheetSprite.getPosition().y) &&
           (indexX > tileSheetSprite.getPosition().x) && (indexX > tileSheetSprite.getPosition().x))
        {
            cout << "On new tile sheet" << endl;
            window.draw(editSquareSprite);
        }
        else
        {
            cout << "Out of bounds sprite sheet" << endl;
        }
    }

What I can do is check to see if the mouse coords are within a tile and then copy that tile but I dont know how to copy tiles. I have to figure out this stuff first before I can do any file writing, because I have to have tiles to write to the grid. So if you could guide me through it without telling me outright what to do, like just give me hints and let me figure it out, that would help a lot. What I really need is a good GUI. I downloaded SFGUI and built it with Cmake but I dont know how to link to the correct files in Code blocks. I dont know what files or folders i need to link to. That GUI is just as easy as sfml to use and it would help a lot as i could put my tile sheets in a side window and my map editor next to it.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 02:08:58 am
If you're having trouble with SFGUI, ask for help on its forums.  I can't help with that part.

For copying tiles, what do you mean exactly?  Are you saying your tile editor would load spritesheet.png then break it up into a few dozen tiny .pngs, one for each tile?  Or do you want your tilemap file to use a filename plus a rectangle to identify a tile, not just a filename?  And since both of those seem fairly straightforward to me, what is the exact step you don't know how to do?

I'm wondering if you need to just play with your code for a while until you've figured things out in more detail and have a clear, specific question you can ask here.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 02:23:10 am
It's not SFGUI I'm having trouble with its linking to the libraries that i need to use it. Also I did ask on their forums and the guy helped me get it built with Cmake but then told me to figure out how to link to it on my own, which pissed me off because it took me 3 days to build it right and now i cant even use it.

Basically what I want to do is load the entire tilesheet then when i go over it with my mouse and click, I want it to copy that tile texture and replace whatever one is in tileTexture texture. that way I can get rid of a lot of these if statements near the bottom. Since i have to just slap my tile sheet in my window next to my grid, i'll just copy whatever is within a 32x32 area under my mouse.  I am unsure how to just put this in code form. I was thinking i could use an sf::Image and then copy what's under the mouse and then put it in a texture then set it but i'm not sure how to go about doing it.
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 02:41:00 am
I don't know anything about Code::Blocks or SFGUI building, so all I can suggest is looking at the Code::Blocks tutorial for SFML.  If you know what libraries you need to link, then the actual act of linking is strictly a question of how to use your chosen toolchain, so the SFML tutorial should answer that question.  And I doubt you'll ever find a better "getting started" tutorial for Code::Blocks than the SFML one (almost every build problem people ever have is their own failure to read those tutorials properly).

For the tile copying thing, it sounds like you need to think about it more.  That description simply isn't precise enough for me to tell what you actually need help with, and that's probably why you can't "put it in code form" yet.  I think we've hit the point where I just have to tell you to work on it by yourself for a while.  Incidentally, there are functions to copy an sf::Image to or from an sf::Texture, which can easily be found in the API documentation.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 02:56:33 am
Alright I'll give that code blocks tutorial in a little bit, as for the copying tile thing, I wrote it down step by step of what i need to do and i think it will work so i'll work on it for a while and see what i come up with.
Title: Re: Tile Editor is off center?
Post by: Chay Hawk on August 31, 2014, 04:14:40 am
I think I almost got it, It gives me a tile on the spritesheet but it gives me 2 different halfs of a sprite in one grid. Sometimes it even makes it's own textures... I've been at this for hours, please help, I tried as hard as I could.

#include <SFML/Graphics.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Tile Editor");
    sf::Event event;
    sf::Mouse mouse;
    sf::Clock clock;
    sf::Time time;
    sf::View scrollScreen;
    sf::View zoomScreen;
    vector<vector<sf::Sprite> > Grid;
    int GridSizeX = 10; //Anything higher than 200x200 tiles is bad
    int GridSizeY = 10;
    window.setFramerateLimit(60);

    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));

    sf::Texture blankGridTexture;
    sf::Sprite blankGridSprite;
    if(!blankGridTexture.loadFromFile("Resources/Tiles/Grid.png"))
    {

    }
    blankGridSprite.setTexture(blankGridTexture);
    blankGridSprite.setOrigin(0, 0);

    //Load Grass
    sf::Texture tileTexture;
    sf::Sprite tileSprite;
    if(!tileTexture.loadFromFile("Resources/Tiles/Grass.png"))
    {
        cout << "Couldnt load resources" << endl;
    }
    tileSprite.setTexture(tileTexture);
    tileSprite.setOrigin(16, 16);

    //Load flower grass texture
    sf::Texture flowerGrassTexture;
    sf::Sprite flowerGrassSprite;
    if(!flowerGrassTexture.loadFromFile("Resources/Tiles/FlowerGrass.png"))
    {
        cout << "Couldnt load flower tiles" << endl;
    }

    //Set mask for editing square
    sf::Image mask;
    mask.loadFromFile("Resources/Tiles/EditSquare.png");
    mask.createMaskFromColor(sf::Color(200, 191, 231));

    sf::Texture editSquareTexture;
    sf::Sprite editSquareSprite;
    editSquareTexture.loadFromImage(mask);
    editSquareSprite.setTexture(editSquareTexture);
    editSquareSprite.setOrigin(16, 16);

    sf::Vector2i pixel_pos = sf::Mouse::getPosition(window);
    sf::Vector2f coord_pos = window.mapPixelToCoords(pixel_pos, scrollScreen);
    tileTexture.create(floor(coord_pos.x / 32), floor(coord_pos.y / 32));

    //Input grid into vector
    Grid.resize(GridSizeX);
    for (int x = 0; x < GridSizeY; x++)//Column
    {
        for (int y = 0; y < GridSizeY; y++)//Row
        {
            blankGridSprite.setPosition(x * 32, y * 32);
            Grid[x].push_back(blankGridSprite);
        }
    }

    while(window.isOpen())
    {
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                    window.close();
                break;

                case sf::Event::Resized:

                    sf::FloatRect viewArea(0, 0, event.size.width, event.size.height);
                    window.setView(sf::View(viewArea));
                    scrollScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                    zoomScreen.reset(sf::FloatRect(0, 0, window.getSize().x, window.getSize().y));
                break;
            }
        }
    window.clear(sf::Color::White);

    time = clock.getElapsedTime();

    scrollScreen.setViewport(sf::FloatRect(0, 0, 1.0f, 1.0f));

    sf::Vector2i pixel_pos = sf::Mouse::getPosition(window);
    sf::Vector2f coord_pos = window.mapPixelToCoords(pixel_pos, scrollScreen);

    cout << "Row: " << floor(coord_pos.y / 32) << ",";
    cout << "Column: " << floor(coord_pos.x / 32) << endl;

    if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        scrollScreen.move(-10, 0);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        scrollScreen.move(10, 0);
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
    {
        scrollScreen.move(0, -10);
    }
    else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
    {
        scrollScreen.move(0, 10);
    }

    //Draw map
    for(int x = 0; x < Grid.size(); x++)
    {
        for(int y = 0; y < Grid[x].size(); y++)
        {
            window.draw(Grid[x][y]);
        }
    }


    int indexX = floor(coord_pos.x / 32);
    int indexY = floor(coord_pos.y / 32);


    //Set tile sheet in image
    sf::Image tileSheet;
    if(!tileSheet.loadFromFile("Resources/Tile Sheets/Outside_A5.png"))
    {
        cout << "Error" << endl;
    }

    //Set it in a sprite so i can see it on screen.
    sf::Texture drawTSheet;
    drawTSheet.loadFromImage(tileSheet);
    sf::Sprite spr;
    spr.setTexture(drawTSheet);

    spr.setPosition(352, 0);
    window.draw(spr);

    //Create another image to copy tile from position on tilesheet.
    sf::Image copyImg;
    //copyImg.create(32, 32);

    //Set position of edit square to the mouse
    editSquareSprite.setPosition(floor(coord_pos.x / 32) * 32 + 16, floor(coord_pos.y / 32) * 32 + 16);

    if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
    {
        if((indexY < GridSizeY) && (indexY >= 0) && (indexX < GridSizeX) && (indexX >= 0))
        {
            //Copy tile from tilesheet at mouse position.
            copyImg.copy(tileSheet, floor(coord_pos.x / 32), floor(coord_pos.y / 32));
            tileTexture.loadFromImage(copyImg);
            //Grid[indexX][indexY].setTexture(tileTexture);
            window.draw(editSquareSprite);
        }
        else
        {
            cout << "Out of bounds" << endl;
        }
    }
    if(sf::Mouse::isButtonPressed(sf::Mouse::Right))
    {
        if((indexY < GridSizeY) && (indexY >= 0) && (indexX < GridSizeX) && (indexX >= 0))
        {
            //Set image to texture
            //tileTexture.create(floor(coord_pos.x / 32) * 32 + 16, floor(coord_pos.y / 32) * 32 + 16);

            //Set texture to grid
            Grid[indexX][indexY].setTexture(tileTexture);
            window.draw(editSquareSprite);
        }
        else
        {
            //cout << "Out of bounds" << endl;
        }
    }

    if(sf::Keyboard::isKeyPressed(sf::Keyboard::F))
    {
        string mapName;
        ofstream saveMap;

        cout << "Enter a name for your map" << endl;
        getline(cin, mapName);

        saveMap.open(mapName.append(".txt"));

        for(int x = 0; x < Grid.size(); x++)
        {
            for(int y = 0; y < Grid[x].size(); y++)
            {

            }
        }
    }


    //window.draw(tileSheetSprite);
    window.setView(scrollScreen);
    clock.restart();
    window.display();
    }

    return 0;
}
 
Title: Re: Tile Editor is off center?
Post by: Ixrec on August 31, 2014, 12:23:54 pm
Unfortunately I don't have my toolchain set up these days so I can't debug your code directly.  Even if I could, I'd probably still tell you that you have to figure this out yourself, since this is what programming is all about.  But after browsing your new code for a minute, I think at least part of the problem is with this line:

copyImg.copy(tileSheet, floor(coord_pos.x / 32), floor(coord_pos.y / 32));

So if the user clicks on tile (1,2), then we expect this to turn into copyImg.copy(tileSheet, 1, 2);  This doesn't look right to me, because pixel (1,2) is not the same thing as tile (1,2), and I'm pretty sure these functions take pixels, not clayHawkGridTileIndices.  Plus, the documentation says the 2nd and 3rd parameters are the *destination* x and y, not the source.  And it would probably be a good idea to given an explicit value for the sourceRect parameter.

P.S. Be aware that sf::Image::copy() is slow.  Not sure if it's a problem here, but when moving pixels around it's important to know what operations are fast and slow even if they aren't causing trouble yet.