Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Tile Editor is off center?  (Read 12255 times)

0 Members and 1 Guest are viewing this topic.

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Tile Editor is off center?
« 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;
}
 
« Last Edit: August 30, 2014, 01:02:57 am by Chay Hawk »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Tile Editor is off center?
« Reply #1 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
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #2 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.
« Last Edit: August 30, 2014, 02:35:46 am by Chay Hawk »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Tile Editor is off center?
« Reply #3 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)
« Last Edit: August 30, 2014, 03:43:42 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #4 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;
}
 
« Last Edit: August 30, 2014, 03:44:55 am by Chay Hawk »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Tile Editor is off center?
« Reply #5 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)
« Last Edit: August 30, 2014, 03:47:49 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #6 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

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Tile Editor is off center?
« Reply #7 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?  ;)
« Last Edit: August 30, 2014, 04:00:46 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #8 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.

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #9 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...
« Last Edit: August 30, 2014, 04:04:10 am by Chay Hawk »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Tile Editor is off center?
« Reply #10 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))
« Last Edit: August 30, 2014, 04:08:20 am by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #11 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.
« Last Edit: August 30, 2014, 04:27:58 am by Chay Hawk »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #12 on: August 30, 2014, 11:40:48 am »

Hapax

  • Hero Member
  • *****
  • Posts: 3351
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Tile Editor is off center?
« Reply #13 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 that you may also want to consider.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Chay Hawk

  • Full Member
  • ***
  • Posts: 101
    • View Profile
    • Email
Re: Tile Editor is off center?
« Reply #14 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 ;)