Moving-draging the sprite with mouse

Hello,
I am familiar with the SDL basics but I need some help with this. I have some sprite on screen
and I have to move it (drag it) with the mouse pointer around the screen. It should move when the mouse pointer is on the sprite and left button is pressed and mouse is moving. I would appreciate some copy/paste piece of code actually used for this if it is no bother. If not then some useful hint on this.

dekyco

To implement sprite dragging, you need to know which sprite is being
dragged, the change in the mouse’s coordinates, and whether the mouse
button is held. Usually, you also want a threshold of motion before
the dragging begins. I don’t do that here, but something like this
should get you started. Note that there are other ways to do it and
there are some things you have to fill in.

Sprite* mySprites = getMySpriteArray();
int numSprites = getNumSprites();

Sprite* dragSprite = NULL;

while(!done)
{
while(SDL_PollEvent(&event))
{
if(event.type == SDL_MOUSE_BUTTON_DOWN)
{
// This should loop over all the sprites available for grabbing
for(int i = 0; i < numSprites; i++)
{
if(isInBoundingRegion(event.button.x, event.button.y,
mySprites[i]))
dragSprite = mySprites[i];
else
dragSprite = NULL;
}
}
else if(event.type == SDL_MOUSE_BUTTON_UP)
{
dragSprite = NULL;
}
else if(event.type == SDL_MOUSE_MOTION)
{
if(dragSprite != NULL)
{
dragSprite->x += event.motion.xrel;
dragSprite->y += event.motion.yrel;
}
}
}

//  ...  Draw and flip

}

Jonny DOn Wed, Dec 2, 2009 at 8:54 AM, dekyco wrote:

Hello,
I am familiar with the SDL basics but I need some help with this. I have
some sprite on screen
and I have to move it (drag it) with the mouse pointer around the screen. It
should move when the mouse pointer is on the sprite and left button is
pressed and mouse is moving. I would appreciate some copy/paste piece of
code actually used for this if it is no bother. If not then some useful hint
on this.

dekyco


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Hello,
I am working on this problem of moving/dragging a sprite with a mouse, but due to my
inexpirience with this I did not came up with workable solution yet, although previous answer to my post was very helpful understanding the problem.
Maybe somebody can give me some more hint on how to finish this task. Here is my code for input handling done so far:

void My_Dot::handle_input()
{
int x = 0, y = 0;

//If a mouse button was pressed
if( event.type == SDL_MOUSEBUTTONDOWN )
{
    //If the left mouse button was pressed
    if( event.button.button == SDL_BUTTON_LEFT )
    {
        //Get the mouse offsets
        x = event.button.x;
        y = event.button.y;
        
    //temporary object
    My_Dot *some_dot = NULL;

        //If the mouse is over the button
//mark that
        d_pushed = true;
        for (int i = 0;i < 3;i++) //there are 3 My_Dot objects in My_Dot *array[]
        {
                //get collission box
                SDL_Rect box = array[i]->GetBox();
                //if the mouse pointer is within the bounds of collission box
                if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) )
                    {
                //put the array element in the temporary object
                        some_dot = array[i];
                    }
        }
    }
}
//If a mouse button was released
if( event.type == SDL_MOUSEBUTTONUP )
{
    //If the left mouse button was released
    if( event.button.button == SDL_BUTTON_LEFT )
        {
            //mark the left button release
            d_pushed = false;
    //make the object null
            some_dot = NULL;

        }
}

if( event.type == SDL_MOUSEMOTION && d_pushed)
{
    //Get the mouse offsets
    x = event.motion.x;
    y = event.motion.y;

            //now get the some_dot collission box
            SDL_Rect box = some_dot->GetBox();
    //and make it track the mouse offset
            box.x += x;
            box.y += y;

}

}

this code results in program segfaulting during the drag attempt.So I think it is the SDL_MOUSEMOTION part that is not working.If I am understanding this correctly, it is the collission box which is moving, tracking the mouse offset.

Some portions of this code are property of ‘Lazy Foo’ Productions’ SDL tutorial.

Hey,

This might not be as intensive of help as you’d like, but it should
help you out.

Your function, handle_input() gets called once for each separate
event. Mouse buttons and mouse motion are separate events, so you’re
getting a crash because ‘some_dot’ is always NULL when the mouse
motion code is run.

Make sure that ‘some_dot’ is not NULL when you use it:
if(some_dot != NULL)
{
SDL_Rect box = some_dot->GetBox();
//and make it track the mouse offset
box.x += x;
box.y += y;
}

This won’t make the code work, though. ‘some_dot’ is still always
NULL in the motion code. To change this, you need ‘some_dot’ to exist
outside of this function. That can be done using a global variable
(discouraged), a function argument, or a static variable. I suggest
you try it first with a static variable, since that is quick:
static My_Dot *some_dot = NULL;

You’re using C++, right? If you actually want the object pointed to
by ‘some_dot’ to be changed, you need to use either pointers or
references to that data. Does My_Dot::GetBox() return a reference?
The declaration would look like:
SDL_Rect& GetBox(); // Notice the &

If it does return a reference, then you need to receive it as a reference:
if(some_dot != NULL)
{
SDL_Rect& box = some_dot->GetBox(); // Use a reference variable
//and make it track the mouse offset
box.x += x; // Now some_dot’s box will actually be changed
box.y += y;
}

If it doesn’t return a reference or it stores the position data in
something other than an SDL_Rect (it is often a good idea to store it
in two floats instead), then you need to access the data another way,
like:
if(some_dot != NULL)
{
//and make it track the mouse offset
some_dot->setX(some_dot->getX() + x);
some_dot->setY(some_dot->getY() + y);
}

Good luck. Feel free to ask any more questions.
Jonny DOn Tue, Dec 8, 2009 at 10:38 AM, dekyco wrote:

Hello,
I am working on this problem of moving/dragging a sprite with a mouse, but
due to my
inexpirience with this I did not came up with workable solution yet,
although previous answer to my post was very helpful understanding the
problem.
Maybe somebody can give me some more hint on how to finish this task. Here
is my code for input handling done so far:

void My_Dot::handle_input()
{
int x = 0, y = 0;

//If a mouse button was pressed
if( event.type == SDL_MOUSEBUTTONDOWN )
{
//If the left mouse button was pressed
if( event.button.button == SDL_BUTTON_LEFT )
{
//Get the mouse offsets
x = event.button.x;
y = event.button.y;

//temporary object
My_Dot *some_dot = NULL;

//If the mouse is over the button
//mark that
d_pushed = true;
for (int i = 0;i < 3;i++) //there are 3 My_Dot objects in My_Dot *array[]
{
//get collission box
SDL_Rect box = array[i]->GetBox();
//if the mouse pointer is within the bounds of collission box
if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y +
box.h ) )
{
//put the array element in the temporary object
some_dot = array[i];
}
}
}
}
//If a mouse button was released
if( event.type == SDL_MOUSEBUTTONUP )
{
//If the left mouse button was released
if( event.button.button == SDL_BUTTON_LEFT )
{
//mark the left button release
d_pushed = false;
//make the object null
some_dot = NULL;

}
}

if( event.type == SDL_MOUSEMOTION && d_pushed)
{
//Get the mouse offsets
x = event.motion.x;
y = event.motion.y;

//now get the some_dot collission box
SDL_Rect box = some_dot->GetBox();
//and make it track the mouse offset
box.x += x;
box.y += y;

}
}

this code results in program segfaulting during the drag attempt.So I think
it is the SDL_MOUSEMOTION part that is not working.If I am understanding
this correctly, it is the collission box which is moving, tracking the mouse
offset.

Some portions of this code are property of ‘Lazy Foo’ Productions’ SDL
tutorial.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Thank you Jonny,
this clarified the thing even better. I am using C++ and I have managed to solve this problem.

I have yet another question which and I think is in line with previous question ( to avoid a new topic ): How to move a sprite clip with the mouse, i.e. how to choose the sprite we move?

To be more precise: we have a spritesheet and we clipped the spritesheet into clips. Then we put those clips into clips array of type SDL_Rect. Each clip respresents a state of image over some object in response to mouse events: for example button sprites (for mouseover, mousebuttonpress, mouseout).The problem is: how do we choose a clip from the spritesheet that we need to move and how do we move it?

I have yet another question which and I think is in line with previous
question ( to avoid a new topic ): How to move a sprite clip with the mouse,
i.e. how to choose the sprite we move?

To be more precise: we have a spritesheet and we clipped the spritesheet
into clips. Then we put those clips into clips array of type SDL_Rect. Each
clip respresents a state of image over some object in response to mouse
events: for example button sprites (for mouseover, mousebuttonpress,
mouseout).The problem is: how do we choose a clip from the spritesheet that
we need to move and how do we move it?

You’re speaking in some sort of a short hand. I must means something
to you and to the people you are working with, but it loses a lot when
I try to read it. To try to understand you I’m going to play that back
to you and then try to answer your question.

You have an an image that contains a bunch of sprites stored as
sub-images of the big image and they are laid out in a grid. You
created a vector of SDL_Rect structures to tell you where those
sub-images are in the large image.

If I got that right then the solution to your problem is to have
another vector of SDL_Rects that you use to keep track of where you
drew the sprite on the screen. You need more information that just the
SDL_Rect. You also need to know which sprite was drawn in which
rectangle, but that is just an index into the original sprite vector.

The trick to moving sprites is that you have to be able to draw a
sprite and erase the sprite. To erase the sprite you have to be able
to put pack what was on the screen before you drew the sprite. If you
are double buffering, then you just redraw everything in the back
buffer and don’t worry about. If you are using a single buffer you
have to either save what was on the screen, so you can put it back, or
be able to reconstruct the original state of the screen some other
way.

So, to move the sprite you draw it someplace, then erase it and draw
it someplace else. As long as you do that fast enough and you don’t
move it too far each time it will look like the sprite is moving
smoothly across the screen.

The way you tell if the mouse is over a sprite is simple. You compare
the current mouse location with the location of each sprite you have
on the screen. You do that by scanning through the vector that tells
you were your sprites are on the screen. If the mouse is over a sprite
when the a mouse button is pushed down, start moving that sprite and
keep moving it until the mouse button is released.

Am I close?

You must learn to be more precise in your use of language. When I see
something that says that you put a “clip”, which I would expect to be
an image, into an SDL_rect, which can only hold geometry, I’m inclined
to just not even try to answer the question because it doesn’t make
sense to me. And, since it doesn’t make sense I might waste 15 minutes
of my life answering the wrong question. It is very important that you
learn to be as precise in your use of human language as you are in
your use of a programming language.

I hope I helped you. If not, at least I tried.

Bob PendletonOn Mon, Dec 21, 2009 at 4:53 PM, dekyco wrote:


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


±----------------------------------------------------------