Advertisement

click and drag sprite

Started by January 11, 2025 12:23 AM
56 comments, last by JoeJ 2 hours, 30 minutes ago

cool thx this code works

			vector <Sprite> sprites;
			sprites.push_back(Sprite(1900, 725));
			sprites.push_back(Sprite(2005, 725));
			int dragSpriteIndex = -1;
//			Sprite sprites;
			int prevX=0, prevY=0;
			bool quit = false;
			int deltaX = 0, deltaY = 0;

			while (quit == false) {
				SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);

				SDL_Event event;
				while (SDL_PollEvent(&event)) {
					if (event.type == SDL_KEYDOWN)
					{
						Uint8 const* keys = SDL_GetKeyboardState(nullptr);
						if (keys[SDL_SCANCODE_ESCAPE] == 1)
							quit = true;

					}
					else if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT)
					{						prevX = event.button.x;
						prevY = event.button.y;
						dragSpriteIndex = -1;
						for (int i = 0; i < (int)sprites.size(); i++)
						{
							Sprite &sprite = sprites[i];

							if (prevX >= sprite.x&&prevX <= sprite.x + 45 && prevY >= sprite.y&&prevY <= sprite.y + 45)
							{
								dragSpriteIndex = i;
								break;
							}
						}
					}
					else if (event.type == SDL_MOUSEBUTTONUP && event.button.button == SDL_BUTTON_LEFT)
					{
						dragSpriteIndex = -1;
					}
					else if (event.type == SDL_MOUSEMOTION && dragSpriteIndex != -1)
					{
						Sprite &sprite = sprites[dragSpriteIndex];
						deltaX = event.motion.x - prevX;
						deltaY = event.motion.y - prevY;
						prevX = event.motion.x;
						prevY = event.motion.y;
						sprite.x += deltaX;
						sprite.y += deltaY;
					}
				
					SDL_Rect rect;
					rect.x = 2005;
					rect.y = 725;
					SDL_BlitSurface(gHelloWorld_one, NULL, gScreenSurface, &rect);

					SDL_Rect rect_one;
					rect_one.x = sprites[1].x;
					rect_one.y = sprites[1].y;
					SDL_BlitSurface(gHelloWorld_two, NULL, gScreenSurface, &rect_one);

					SDL_Rect rect_two;
					rect_two.x = sprites[0].x;
					rect_two.y = sprites[0].y;
					SDL_BlitSurface(gHelloWorld_one, NULL, gScreenSurface, &rect_two);
					SDL_UpdateWindowSurface((gWindow));
				
			}
			

pbivens67 said:
cool thx this code works

You did not listen, and you did not yet learn.
This is what you deserve:

The code only works under certain circumstances. We are not done yet.

I'll give you an exercise, leading to the problem:

Add one more sprite.

If the code would work, all you would need to do is adding one line of code:

			sprites.push_back(Sprite(1900, 725));
			sprites.push_back(Sprite(2005, 725));
			
			sprites.push_back(Sprite(2110, 725));
			

Do this, and you will see your code still can't deal with an arbitrary number of sprites. A change is needed.
If you do the right change, you can add or remove as many sprites os you want, without changing any other code.
Our goal is that you understand how to do this, and to realize what's the advantage.

I'm curious about your solution…

Advertisement

“All and all we're just another brick in the wall” - PF

Perhaps explain to our friend why the reference is unnecessary.

Dev careful. Pixel on board.
Buckle up. Everything will be revealed.

I have done a lot of research into screen to hex coordinates but I am still confused about how to proceed, any help would appreciated.

pbivens67 said:
I have done a lot of research into screen to hex coordinates but I am still confused about how to proceed, any help would appreciated.

Focus on mastering multiple objects first. That's something general you need for pretty much anything.

Hex grids are complicated and cumbersome, and i don't know the game you try to make. I guess it's a turn based board game.
Idk, but probably you need things like: Player drags a sprite, but then when he realeases it, the program should snap it to the closest hex grid position. This would be more a math problem than a programming problem.

So before that, make sure you can have any number of sprites on screen, and the player can see and drag any of them to any place.
If you follow my advise of adding one more sprite, you will still only see 2 sprites with the current code, not 3.
And that's the problem you should fix now, in a certain way that handles any number of sprites. Not just 3, but any number.
You should be able to come up with a solution yourself, which would be the Eureka moment i aim for.

If not, post the code with the attempted solution even if it does not work. After you tried and failed, we can help.
But if we help already know, you just copy the code without truly understanding it and move on, so you will fail on the same problem next time in a similar situation.

If we succeed on this, and you do learn how to work with multiple objects, you might still fail later on the hex grid complexity.
But you should be able to try Space Invaders again for example.

Your primary goal is learning programming, not yet implementing a specific game.
And that's not a matter of choice. It remains at this until you learned all the essential basics. Becasue no basics, no game at all.

NubDevice said:
Perhaps explain to our friend why the reference is unnecessary.

Idk which reference you mean, but just explain yourself.

whoops. I see the draw issue now.
sorry, my bad. SDL blit is so ugly, I didn't want to look at it.

Dev careful. Pixel on board.
Buckle up. Everything will be revealed.

Advertisement

I have got four sprites to move so this means that I can move any number of sprites

			vector <Sprite> sprites;
			sprites.push_back(Sprite(1400, 725));
			sprites.push_back(Sprite(1205, 725));
			sprites.push_back(Sprite(1035, 1005));
			sprites.push_back(Sprite(975, 725));

			int dragSpriteIndex = -1;
//			Sprite sprites;
			int prevX=0, prevY=0;
			bool quit = false;
			int deltaX = 0, deltaY = 0;

			while (quit == false) {
				SDL_BlitSurface(gHelloWorld, NULL, gScreenSurface, NULL);

				SDL_Event event;
				while (SDL_PollEvent(&event)) {
					if (event.type == SDL_KEYDOWN)
					{
						Uint8 const* keys = SDL_GetKeyboardState(nullptr);
						if (keys[SDL_SCANCODE_ESCAPE] == 1)
							quit = true;

					}
					else if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT)
					{						prevX = event.button.x;
						prevY = event.button.y;
						dragSpriteIndex = -1;
						for (int i = 0; i < (int)sprites.size(); i++)
						{
							Sprite &sprite = sprites[i];

							if (prevX >= sprite.x&&prevX <= sprite.x + 45 && prevY >= sprite.y&&prevY <= sprite.y + 45)
							{
								dragSpriteIndex = i;
								break;
							}
						}
					}
					else if (event.type == SDL_MOUSEBUTTONUP && event.button.button == SDL_BUTTON_LEFT)
					{
						dragSpriteIndex = -1;
					}
					else if (event.type == SDL_MOUSEMOTION && dragSpriteIndex != -1)
					{
						Sprite &sprite = sprites[dragSpriteIndex];
						deltaX = event.motion.x - prevX;
						deltaY = event.motion.y - prevY;
						prevX = event.motion.x;
						prevY = event.motion.y;
						sprite.x += deltaX;
						sprite.y += deltaY;
					}
				
					SDL_Rect rect;
					rect.x = sprites[2].x;
					rect.y = sprites[2].y;
					SDL_BlitSurface(gHelloWorld_six, NULL, gScreenSurface, &rect);

					SDL_Rect rect_one;
					rect_one.x = sprites[1].x;
					rect_one.y = sprites[1].y;
					SDL_BlitSurface(gHelloWorld_two, NULL, gScreenSurface, &rect_one);

					SDL_Rect rect_two;
					rect_two.x = sprites[0].x;
					rect_two.y = sprites[0].y;
					SDL_BlitSurface(gHelloWorld_one, NULL, gScreenSurface, &rect_two);
				
					SDL_Rect rect_six;
					rect_six.x = sprites[3].x;
					rect_six.y = sprites[3].y;
					SDL_BlitSurface(gHelloWorld_four, NULL, gScreenSurface, &rect_six);

					SDL_Rect rect_eight;
					rect_eight.x = 1010;
					rect_eight.y = 865;
					SDL_BlitSurface(gHelloWorld_four, NULL, gScreenSurface, &rect_eight);

					SDL_Rect rect_three;
					rect_three.x = 1000;
					rect_three.y = 865;
					SDL_BlitSurface(gHelloWorld_three, NULL, gScreenSurface, &rect_three);

					SDL_Rect rect_seven;
					rect_seven.x = 1115;
					rect_seven.y = 260;
					SDL_BlitSurface(gHelloWorld_four, NULL, gScreenSurface, &rect_seven);


					SDL_Rect rect_four;
					rect_four.x = 1105;
					rect_four.y = 260;
					SDL_BlitSurface(gHelloWorld_three, NULL, gScreenSurface, &rect_four);

					SDL_Rect rect_five;
					rect_five.x = 965;
					rect_five.y = 725;
					SDL_BlitSurface(gHelloWorld_three, NULL, gScreenSurface, &rect_five);

					SDL_Rect rect_nine;
					rect_nine.x = 965;
					rect_nine.y = 630;
					SDL_BlitSurface(gHelloWorld_five, NULL, gScreenSurface, &rect_nine);

					SDL_Rect rect_ten;
					rect_ten.x = 1000;
					rect_ten.y = 1050;
					SDL_BlitSurface(gHelloWorld_five, NULL, gScreenSurface, &rect_ten);

					SDL_Rect rect_eleven;
					rect_eleven.x = 1175;
					rect_eleven.y = 910;
					SDL_BlitSurface(gHelloWorld_five, NULL, gScreenSurface, &rect_eleven);

					SDL_UpdateWindowSurface((gWindow));
				}

Haha, hilarious. You have topped my expectations, by not only copy pasting 3 but even 4 times! \:D/

But no. Your code can not move any number of sprites. It can now only move 4 sprites. Not less, not more.

So think of it - how could you make it render all sprites which are currently in the vector, no matter how many there are?
Hint: There sould be only one code section to render one given sprite, but not X code sections to render X sprites.
There even already is one section in the code which solves a similar problem in the right way…

I am rendering in the vector and drawing the sprites

here is a screen shot of my game so far

Advertisement