SFML How to draw sprites to a grid(Non SFML Question)

In SFML I'm trying to draw sprites to a grid, but I want to draw them to the position I choose on the grid and I want them to snap to it, but I cant get it to do it, I have been working on it for a while and I just dont know what to do anymore. The problem isnt with my SFML code though its with my C++ code. I cleaned it up too so you *should* be able to just paste it in your compiler with little to no cleanup. any help is much appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <SFML/Graphics.hpp>
#include <iostream>
#include <fstream>

using std::cout;
using std::endl;

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Window");

    sf::Mouse mouse;
    while(window.isOpen())
    {
        window.clear(sf::Color::White);
        sf::Event event;
        while(window.pollEvent(event))
        {
            switch(event.type)
            {
                case sf::Event::Closed:
                {
                    window.close();
                }break;
                case sf::Event::Resized:
                {
                    sf::FloatRect visibleArea(0, 0, event.size.width, event.size.height);
                    window.setView(sf::View(visibleArea));
                }break;
            }
        }

        //Set Tiles to Grid Test
        sf::Texture setGridTexture;
        sf::Sprite setGridSprite;
        setGridSprite.setTexture(setGridTexture);
        setGridSprite.setColor(sf::Color::Black);

        sf::Vector2i Grid(15,15);

        sf::Texture tempGridTexture;
        sf::Sprite tempGridSprite;
        tempGridSprite.setTexture(tempGridTexture);
        tempGridSprite.setColor(sf::Color::Green);

        sf::Vector2i setTilesOnGridX(mouse.getPosition(window).x, Grid.x);
        sf::Vector2i setTilesOnGridY(mouse.getPosition(window).y, Grid.y);

        //Draw Grid
        for(int i = 0; i < Grid.x; i++)
        {
            for(int j = 0; j < Grid.y; j++)
            {
                tempGridSprite.setPosition(j * 32, i * 32);
                tempGridSprite.setTextureRect(sf::IntRect(Grid.x * 32, Grid.y * 32, 32, 32));
                window.draw(tempGridSprite);
            }
        }

        //Place Tiles
        if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            cout << "Clicked" << endl;
            window.draw(setGridSprite);
            setGridSprite.setPosition(setTilesOnGridX.x * 32, setTilesOnGridY.y * 32);
            setGridSprite.setTextureRect(sf::IntRect(Grid.x * 32, Grid.y * 32, 32, 32));
            }
            else
            {
                cout << "Let go" << endl;
            }

        //End set tiles to Grid Test.
        window.display();
    }
}
Last edited on
bump, please help.
I didn't look at the code, but snapping to a grid is just a matter of making sure the coordinates are multiples of X ... where X is the grid size.

Keep track of where the object is normally... but also where it is on the grid. Use the latter for drawing. You can calculate the position on the grid from the actual position with a bit of math.
ah, math... hopefully not too complicated math, but how do I make it so that when the mouse is in the grid it wil not draw outside of it? I'm having trouble with stuff like that, I do something like if(characterPosition.x <= Grid.x && characterPosition.y >= Grid.y)

And that doesnt work. How would I get the area of a square? I cant do it with <= >= that messes everything up. Unless im doing it wrong.
Last edited on
ah, math... hopefully not too complicated math, but how do I make it so that when the mouse is in the grid it wil not draw outside of it?


Is this question related to your earlier grid question? Or is this a separate question?

You are [hopefully] in control of what you are drawing. SFML will not draw anything unless you specifically tell it to. So if you only want to draw certain things under certain circumstances... but just write the code to do that. It's a basic if() statement.

1
2
3
4
if( the_condition_in_which_the_object_is_drawn )
{
    draw_the_object();
}



I do something like if(characterPosition.x <= Grid.x && characterPosition.y >= Grid.y)

And that doesnt work


These are logic problems. You have to work them out. Taking a stab in the dark and tinkering with the hopes that it will magically works is not going to happen and is going to ultimately frustrate you -- and you'll have to post every hurdle you run into on these boards ;P.

I'm not saying I don't want to help, but I don't want to dish out direct answers. I want to show you how to solve the problem yourself. Teach a man to fish, etc, etc.


How would I get the area of a square?


? You mean the geometric area? The area of a square is its Width * Height.




But let's back up a minute and tackle these problems one at a time. You seem to have 3 separate questions going on here, let's focus on one of them... specifically the original one.

From glancing at the code, it looks like you want to click/drag an object around the screen... but you only want it to move on a grid... is that right?
Last edited on
"I'm not saying I don't want to help, but I don't want to dish out direct answers. I want to show you how to solve the problem yourself. Teach a man to fish, etc, etc."

I don't want you to give me direct answers, I like figuring stuff out, just giving me hints and clues is fine with me :)

"From glancing at the code, it looks like you want to click/drag an object around the screen... but you only want it to move on a grid... is that right?"

Well, I want to select a sprite and then draw it on the grid and i want it to snap to the grid as well. The thing is the grid is 15 x 15 and is made up of 32x32 sprites which are all one object, which is this:

sf::Texture tempGridTexture;
sf::Sprite tempGridSprite;
tempGridSprite.setTexture(tempGridTexture);
tempGridSprite.setColor(sf::Color::Green);

That sprite is drawn to the screen and fills the grid. Also by saying "15 x 15 and is made up of 32x32" makes me think that i need to do some math using those numbers. This program is a tile editor so I need to be able to select different sprites. Right now thats not a concern, I haven't made the tools window yet so just doing this is fine.

EDIT: I solved one problem, there was a square that I was trying to move and it kept resetting becuase i hade the part where it loads the file in the while loop, so thats solved, not just to get the grid...
Last edited on
Ok I almost got it, I think I got it to set on a grid, it snaps to one location but it wont budge after that.

1
2
3
4
5
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            setMapTileSprite.setPosition(gameVars.mouse.getPosition(winVars.window).x, gameVars.mouse.getPosition(winVars.window).y);
            setMapTileSprite.setPosition(Grid.x * Grid.y, Grid.x * Grid.y);
        }


I'm stuck :/
Last edited on
What, specifically, are you trying to do?

Like... describe it to me in detailed terms. Is the goal here to move the object to where the user clicks? But snapped to a grid?


EDIT: Also I don't think I understood you when you asked for the area. I was thinking of the geometric area.
Last edited on
MAke it snap to a 32x32 grid and when i click left on the mouse, have it draw something.


"Also I don't think I understood you when you asked for the area. I was thinking of the geometric area."

Oh I see, so how would i calculate a grid?
Last edited on
MAke it snap to a 32x32 grid


I'm assuming "it" is some Sprite.

This is a simple math problem. You have an input position... and an output position. The output position is just the input position snapped to a grid. So now... the question becomes... what is the math that we can perform on the input to produce that output?

When faced with these kinds of problems, I try to find the pattern by laying out a bunch of different inputs and seeing what I would want the output to be:


INPUT - OUTPUT
______________
0       0
1       0
2       0
...
30      0
31      0
32      32
33      32
34      32
...
62      32
63      32
64      64
65      64
...
etc



Is this the output you want? If it is... think about what math you can do on the input to produce that output.

when i click left on the mouse, have it draw something.


You want to seperate logic code from drawing code. When it is time to do your drawing, you should already know everything you want to draw... and where you want to draw it.

Doing something when you left click is logic code.
Drawing something is drawing code.

So we want to split these up into two separate parts. First... when the user clicks... change some variable or something. Then, when you draw, you can look at the contents of that variable or whatever to see whether or not to draw the object in question.


Oh I see, so how would i calculate a grid?


This question is oddly worded =P
I'm going to assume you're asking the same thing as what I'm already covering above.
Last edited on
Alright, well i'll work on it later its late here and i havent slept in 22 hours.
Ok so I think I might be getting close, I have this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for(int i = 0; i < Grid.x; i++)
        {
            for(int j = 0; j < Grid.y; j++)
            {
                tempMapTileSprite.setPosition(j * 32, i * 32);
                tempMapTileSprite.setTextureRect(sf::IntRect(Grid.x * 32, Grid.y * 32, 32, 32));
                winVars.window.draw(tempMapTileSprite);
            }
        }

        //Set tiles on grid - setMapTileSprite
        if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            cout << "Mouse X " << gameVars.mouse.getPosition(winVars.window).x << endl;
            cout << "Mouse Y " << gameVars.mouse.getPosition(winVars.window).y << endl;
            sum = Grid.x * Grid.y / 32;
            //cout << sum * 32<< endl;;
            //setMapTileSprite.setPosition(setMapTileSprite.getPosition().x, setMapTileSprite.getPosition().y);
            setMapTileSprite.setPosition(gameVars.mouse.getPosition(winVars.window).x - gameVars.mouse.getPosition(winVars.window).x / 32 * 32 +
                                         gameVars.mouse.getPosition(winVars.window).x + gameVars.mouse.getPosition(winVars.window).x,
                                         gameVars.mouse.getPosition(winVars.window).y - gameVars.mouse.getPosition(winVars.window).y / 32 * 32 +
                                         gameVars.mouse.getPosition(winVars.window).y + gameVars.mouse.getPosition(winVars.window).y);
            tempMapTileSprite.setTexture(setMapTileTexture);
        }


And the square seems like it wants to snap to the grid, its jittery and it moves like it is trying to snap but it wont do it and its down below my cursor.
1
2
            setMapTileSprite.setPosition(gameVars.mouse.getPosition(winVars.window).x - gameVars.mouse.getPosition(winVars.window).x / 32 * 32 +
                                         gameVars.mouse.getPosition(winVars.window).x + gameVars.mouse.getPosition(winVars.window).x,


This is all just the calculations for the X coordinate.

You are adding the mouse position 3 times, and subtracting a modified version of it once.



Don't try to jump into code. Come up with the translation first. Going back to my previous post... think about what your input will be and what you want your output to be:


INPUT - OUTPUT
______________
0       0
1       0
2       0
...
30      0
31      0
32      32
33      32
34      32
...
62      32
63      32
64      64
65      64
...
etc


Do not write code yet -- just figure out what equation will perform this conversion.

Only after you have the equation should to put it in code.


EDIT: To clarify...

Your code is doing:

 
output = input - input/32*32 + input + input


Now plug in some input for that and see if it generates the desired output
1
2
3
4
5
6
7
8
9
10
11
12
// plug-in input = 52
// desired output = 32

output = 52 - 52/32*32 + 52 + 52
output = 52 -   1  *32 + 52 + 52
output = 52 -    32    + 52 + 52
output = 20 + 52 + 52
output = 72 + 52
output = 124

// 124 is your actual output.  The desired output is 32
//   so this calculation is incorrect 


EDIT: fixed ... I had + instead of - in the equation
Last edited on
I was told by someone this:

"You've a grid of 15 x 15 tiles. Your indices range from 0 to 14 for the X and Y axis. Each tile is 32px x 32px in size. So the first tile is at the position (0, 0), because 0*32. The 15th tile is at the position (448, 0) because 14*32 = 448. Your 225th tile is at the position (448, 448).
When your mouse is for example at the position (236, 132), you subtract the offset which is 0, you then divide by the tile size so you do 236/32 and 132/32 and then round down to integers, which gives you (7, 4). (7, 4) is your position on the grid itself. To get the position of your new sprite you have to multiply it by the tile size, that is (7,4) x 32 = (224, 128). If you had any offset to your grid, you'd now add it back to the position."

I dont know how to get the offset. My current offset is 0 because my map is against the wall. Other than that I can probably get it from there.
I got it working!!! No I just need to figure out how to replace the textures on the grid.
Topic archived. No new replies allowed.