Advertisement

click and drag sprite

Started by January 11, 2025 12:23 AM
1 comment, last by JoeJ 13 hours, 19 minutes ago

All I want to do is click and drag a sprite

else if (event.type == SDL_MOUSEBUTTONDOWN||SDL_MOUSEMOTION) {
						if (event.button.button == SDL_BUTTON_LEFT) {
							int mouseX, mouseY;
							SDL_GetMouseState(&mouseX, &mouseY);
							cout << mouseX << " " << mouseY << endl;
							if (mouseX > 522 && mouseX < 567 && mouseY>394 && mouseY < 439)
							{
								SDL_Rect rect_two;
								rect_two.x = 567;
								rect_two.y = 394;
								SDL_BlitSurface(gHelloWorld_one, NULL, gScreenSurface, &rect_two);
								SDL_UpdateWindowSurface((gWindow));
							}
						}

pbivens67 said:
All I want to do is click and drag a sprite

A good exercise regarding realtime applications.

It's clear that you need some persistent data that lives not just for a single frame, or within a single function call.
Examples are the sprites position and the state of the mouse button.
SDL already does the latter for you, but you need to cara about the sprite. The easiest way would be to use a global variable. (Global variables are bad practice in general. It works for the simple test case, but if the program gets more complex global variables usually become a nightmare.)

Your code looks like you can click within some area, and if you do so it draws a rectangle over that area. But you can not yet move it, i guess.

I can give some example, but i don't know SDL, so you'd need to do some things differently, at the right callbacks SDL provides.

struct Sprite
{
	SDL_Rect rect;
	SDL_Color color; // idk if sdl has such type for color
};

Sprite globalSprite; // bad practice, but i know you love global variables and magic numbers, so...
Sprite *dragSprite = NULL; // if the user is dragging some sprite, this pointer will point to it. Otherwise pointer is zero.

void main()
{
	// set some initial state at application startup...
	
	globalSprite.rect.left = 522;
	//globalSprite.rect.right = ....
	globalSprite.color = white;
	
	// setup SDL, create Window, and all that...
	
	while (true) // some loop, not using callbacks for input, which SDL probably does
	{
		if (SDL_MouseButtonPressed()) // eventually grab the sprite and make it red
		{
			if (dragSprite == NULL && MouseCoordsInsideRectangle(globalSprite))
			{
				dragSprite = &globalSprite;
				dragSprite->color = RED;
			}
		}
		if (SDL_MouseButtonReleased()) // releasing the sprite - make it white again and set pointer to zero
		{
			if (dragSprite) dragSprite->color = WHITE;
			dragSprite = NULL;
		}
		if (dragSprite && SDL_MouseMoved()) // move the dragged Sprite
		{
			dragSprite->rect.left += SDL_MouseDeltaX();
			dragSprite->rect.up += SDL_MouseDeltaY();
			// assuming rect also has width and height which stays the same. 
			// If it has right and bottom we need to change that too ofc.
		}
		
		SDL_RenderRect (globalSprite.rect, globalSprite.color);
		
		SDL_Wait(60 fps);
	}
}

You need to figure out how to do this with SDL, but the code should help to see what global state is needed, and where in the loop this state is affected by what.

By using a pointer (not just a bool for example), the example can be easily extended to handle… multiple sprites! \:D/

Advertisement