Drag an object with the mouse SFML

I want to know how to grab an object with the mouse and drag it to a location and drop it there, i tried doing it but it doesnt seem to work :( The code for it is within the test block movement block. I would ask this stuff on the SFML forums but they keep directing me to documentation that is really skimpy and incomplete so i would rather ask here.

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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <SFML/Graphics.hpp>
#include <iostream>
#include <fstream>

#include "WinVarsStruct.h"
#include "GameVariablesStruct.h"
#include "Prototypes.h"
#include "PlayerStruct.h"

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

void MainGame(WinVars &winVars, GameVariables &gameVars, Player &player, std::ifstream &mapList)
{
    sf::View cameraZoom(sf::Vector2f(250, 200), sf::Vector2f(400, 300));

    TileMapGenerator(winVars, gameVars, player, mapList);

    //Set main window properties
    winVars.videoMode.height = winVars.windowHeight;
    winVars.videoMode.width = winVars.windowWidth;
    winVars.window.create(winVars.videoMode, winVars.windowName);
    winVars.window.setFramerateLimit(60);
    winVars.window.setTitle("Sapphire Engine Test Build 1.0");

    LoadCharacter(winVars, gameVars, player);

    //Test Block
    sf::Texture Block;
    if(!Block.loadFromFile("Resources/Tiles/blueBlock.png"))
    {
        std::cout << "Error" << std::endl;
    }
    sf::Sprite blockB;
    blockB.setTexture(Block);
    blockB.setPosition(80, 80);

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

        gameVars.frameCounter += gameVars.frameSpeed * gameVars.clock.restart().asSeconds();
        if(gameVars.frameCounter >= gameVars.switchFrame)
        {
            gameVars.frameCounter = 0;
            CropPlayer(winVars, gameVars, player);
        }
        DebugOutput(winVars, gameVars, player);

         //Test Block Movement

        sf::Vector2i BS(32, 32);

        blockB.setTextureRect(sf::IntRect(gameVars.source.x * 32, gameVars.source.y * 32, 32, 32));


        float square = sqrt((BS.x * BS.x) + (BS.y * BS.y));

        //if(gameVars.mouse.getPosition().x <= square && gameVars.mouse.getPosition().y <= square)
        //{
            if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
            {
                cout << "Lclick" << endl;
                blockB.setPosition(gameVars.mouse.getPosition().x, gameVars.mouse.getPosition().y);
            }
            else
            {
                cout << "Let go" << endl;
                blockB.setPosition(blockB.getPosition().x, blockB.getPosition().y);
            }
        //}

        //End Block movement test

        //MouseInput(winVars, gameVars, player);
        winVars.window.draw(blockB);
        WindowBoundsCollision(winVars, gameVars, player);
        DrawMap(winVars, gameVars, player, mapList);
        KeyboardInput(winVars, gameVars, player);
        winVars.window.draw(gameVars.playerSprite);
        //winVars.window.setView(cameraZoom);
        //cameraZoom.setCenter(gameVars.currPlayerPosition.x, gameVars.currPlayerPosition.y);
        //ScreenScrolling(winVars, gameVars);
        //winVars.window.setView(gameVars.scrollScreen);
        winVars.window.display();
    }
}


Edit: I sort of got it working but when i click on the screen the square isnt under the mouse cursor its way to the bottom right.
Last edited on
Nevermind I got it :D Oh my god i cant believe i actually figured something out myself :DDDD

Now something a little more complicated, how do i make a grid and drop the square on it so it fits in the spot its placed in? Im not asking for code but if you could give me psuedo code that would help. I know I have to make a vector and draw it, then when I let go of the mouse i have to set it in the area of the grid? Also how do i only drag the square when the mouse is in the rectange bounds?

Current 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
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <SFML/Graphics.hpp>
#include <iostream>
#include <fstream>

#include "WinVarsStruct.h"
#include "GameVariablesStruct.h"
#include "Prototypes.h"
#include "PlayerStruct.h"

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

void MainGame(WinVars &winVars, GameVariables &gameVars, Player &player, std::ifstream &mapList)
{
    sf::View cameraZoom(sf::Vector2f(250, 200), sf::Vector2f(400, 300));

    TileMapGenerator(winVars, gameVars, player, mapList);

    //Set main window properties
    winVars.videoMode.height = winVars.windowHeight;
    winVars.videoMode.width = winVars.windowWidth;
    winVars.window.create(winVars.videoMode, winVars.windowName);
    winVars.window.setFramerateLimit(60);
    winVars.window.setTitle("Sapphire Engine Test Build 1.0");

    LoadCharacter(winVars, gameVars, player);

    //Test Block
    sf::Texture Block;
    if(!Block.loadFromFile("Resources/Tiles/blueBlock.png"))
    {
        std::cout << "Error" << std::endl;
    }
    sf::Sprite blockB;
    blockB.setTexture(Block);
    blockB.setPosition(80, 80);

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

        gameVars.frameCounter += gameVars.frameSpeed * gameVars.clock.restart().asSeconds();
        if(gameVars.frameCounter >= gameVars.switchFrame)
        {
            gameVars.frameCounter = 0;
            CropPlayer(winVars, gameVars, player);
        }
        DebugOutput(winVars, gameVars, player);

         //Test Block Movement

        sf::Vector2i BS(32, 32);

        blockB.setTextureRect(sf::IntRect(BS.x * 32, BS.y * 32, 32, 32));


        float square = sqrt((BS.x * BS.x) + (BS.y * BS.y));

        if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
        {
            //cout << "Lclick" << endl;
            blockB.setPosition(gameVars.mouse.getPosition(winVars.window).x, gameVars.mouse.getPosition(winVars.window).y);
        }
        else
        {
            //cout << "Let go" << endl;
            blockB.setPosition(blockB.getPosition().x, blockB.getPosition().y);
        }
        //End Block movement test


        //Draw Grid to Window Test
        int gridWidth = 2;
        int gridHeight = 2;

        sf::Texture texGrid;
        sf::Sprite gridSprite;
        gridSprite.setTexture(texGrid);

        gridSprite.setColor(sf::Color::Blue);

        std::vector<std::vector<sf::Vector2i> > Grid;
        std::vector<sf::Vector2i> tempGrid;

        //tempGrid.push_back(sf::Vector2i(gridWidth, gridHeight));

        for(int i = 0; i < gridWidth; i++)
        {
            for(int j = 0; j < gridHeight; j++)
            {
                tempGrid.push_back(sf::Vector2i(gridWidth, gridHeight));
                Grid.push_back(tempGrid);
            }
        }


        for(int i = 0; i < Grid.size(); i++)
        {
            for(int j = 0; j < Grid[i].size(); j++)
            {
                if(Grid[i][j].x != -1 && Grid[i][j].y != -1)
                {
                    gridSprite.setPosition(j * 32, i * 32);
                    gridSprite.setTextureRect(sf::IntRect(Grid[i][j].x * 32, Grid[i][j].y * 32, 32, 32));
                    winVars.window.draw(gridSprite);
                }
            }
        }


        //End Draw Grid to Window Test

        //MouseInput(winVars, gameVars, player);
        winVars.window.draw(blockB);
        WindowBoundsCollision(winVars, gameVars, player);
        //DrawMap(winVars, gameVars, player, mapList);
        KeyboardInput(winVars, gameVars, player);
        winVars.window.draw(gameVars.playerSprite);
        //winVars.window.setView(cameraZoom);
        //cameraZoom.setCenter(gameVars.currPlayerPosition.x, gameVars.currPlayerPosition.y);
        //ScreenScrolling(winVars, gameVars);
        //winVars.window.setView(gameVars.scrollScreen);
        winVars.window.display();
    }
}
Last edited on
You will need to keep track of the positions of all the objects for ease. So say you'd let go the mouse button, you will want to get the coords of the coursor, and compare it to the various positions of the boxes, then if it intersects, you position the square in the box.
Using the same method, if you want to move the square again, when the mouse button is pressed, get the coords of the cursor and compare it to the various positions we are keeping track of, so you will know what to move if it intersects.

Aceix.
Ok I think I understand that, but i'm having trouble drawing my grid to the screen, my code above is current. it only draws one square.

EDIT: Ok holy crap i think I almost got the grid drawing down, however when it draws, it turns into a flight of stairs instead of a grid lol, it looks liek this when drawn on the screen:

*
**
***
****
*****
Last edited on
Bump Please help
Topic archived. No new replies allowed.