Removing a pair from array of pairs

Im making a Breakout clone game and im stuck with deleting objects after they are hit. There are 3 rows. Each contains 12 blocks.

I'm trying to delete a pair in the array of pairs. The array contains coordinates of an object (texture) displayed, and if that object is hit with a ball I want to delete it and then my ball changes direction.

for each(pair<int, int> par in koordinateBlokova) {

if (provjeraKolizijeBloka(par.first, par.second, rectLoptica) == true) {
lopticaTrenutniY = -lopticaTrenutniY;

}
}


Array and SDL_Rects are defined like:

pair<int, int> koordinateBlokova[36];
SDL_Rect rectBlock01;
SDL_Rect rectBlock02;
SDL_Rect rectBlock03;


Their definition is:

for (int j = 0; j < brojBlokovaRed; j++) {

rectBlock01 = initRectBlock(j*sirinaBloka + j*razmakRedova, gornjiOdstoj, sirinaBloka, visinaBloka);
rectBlock02 = initRectBlock(j*sirinaBloka + j*razmakRedova, gornjiOdstoj + visinaBloka + razmakStupaca, sirinaBloka, visinaBloka);
rectBlock03 = initRectBlock(j*sirinaBloka + j*razmakRedova, gornjiOdstoj + 2 * visinaBloka + 2 * razmakStupaca, sirinaBloka, visinaBloka);

SDL_RenderCopy(renderer, block01, NULL, &rectBlock01);
SDL_SetRenderTarget(renderer, block01);
koordinateBlokova[j] = make_pair(rectBlock01.x, rectBlock01.y);

if ((j + 1) % 3 == 0) { // if its 3rd block, make it a impenetrable (not implemented yet, just drawn)
SDL_RenderCopy(renderer, blockNeprobojni, NULL, &rectBlock02);
SDL_SetRenderTarget(renderer, blockNeprobojni);
koordinateBlokova[j+12] = make_pair(rectBlock02.x, rectBlock02.y);
}
else {
SDL_RenderCopy(renderer, block02, NULL, &rectBlock02);
SDL_SetRenderTarget(renderer, block02);
koordinateBlokova[j+12] = make_pair(rectBlock02.x, rectBlock02.y);
}

SDL_RenderCopy(renderer, block01, NULL, &rectBlock03);
SDL_SetRenderTarget(renderer, block01);
koordinateBlokova[j+24] = make_pair(rectBlock03.x, rectBlock03.y);
}
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderPresent(renderer);


To make it easier to understand:

brojBlokovaRed = number of blocks in a row
sirinaBloka= block width
visinaBloka= block height
razmakRedova = space between rows
razmakStupaca = space between columns
gornjiOdstoj = space from top of the screen to first row of blocks


My question is how to delete that current pair from array?

• Deleting an item from an array doesn't sound like a task that's unique to games. Did you take some time to search for existing resources or Q&A about the topic or check whether this question has already been asked on our general programming sister site StackOverflow? Was there something you had difficulty understanding in the answers or resources you've consulted thus far, that we could use to target answers to help you better? Oct 9, 2018 at 19:37
• @DMGregory Thanks for tips, but I tried everything. Problem is I cannot find the way to delete a pair when using for each loop in C++. Kinda desperate... Oct 9, 2018 at 19:41

pair<int, int> koordinateBlokova[36];

This is an actual C++ array, which is a fixed-size structure. Elements cannot be added to or removed from such an array. It has 36 items and it will always have 36 items.

Instead, you probably want to store your pairs in a std::vector, which is C++'s standard library container implementing a resizable array. It would look like this:

std::vector<pair<int,int>> koordinateBlokova(36);


You can then use the member function erase to remove elements based on iterators; since vector's iterators are random-access you can erase an element at some arbitrary index i using koordinateBlokova.erase(koordinateBlokova.begin() + i).

That said, as noted in Garrett Gutierrez's answer, this may not be what you ultimately want to do (although it will directly address your question). Erasing from a vector invalidates (most) outstanding iterators referring to the vector and causes all elements above the erased one to be copied down. If you're going to erase many times from a vector at effectively-random interior indices, there are other broader solutions you can explore that won't have that overhead.

Garrett Gutierrez's suggests a linked list. Another option, if the order of your items is irrelevant, is to simply move the "dead" elements to the end of the array, swapping them with the first live element, and either erase them all there using remove or simply keeping a "live index" that refers to the last live element in your array. This has the advantage of keeping all your elements contiguous in memory (which you don't get with a linked list, per se) and also avoiding heap allocation/free operations when adding or removing elements.

It's a touch "less obvious" than a linked list, though, so if you do not need those criteria, that's also a viable path.

• I'll try it with a vectors, if that doesnt suit me i'll change my way of storing. I would ask you could you be so kind to show me how to add an element to that vector array? Oct 9, 2018 at 20:28
• push_back (or its cousin, emplace_back) are typically what you'd use. The snippet I posted in the answer itself uses the constructor that resizes the vector initially to have 36 default-constructed pairs in it.
– user1430
Oct 9, 2018 at 20:30
• call me dumb but I dont get it: koordinateBlokovaVektor.push_back(rectBlock01.x, rectBlock01.y);  doesnt work, neither does koordinateBlokovaVektor(j).push_back(rectBlock01.x, rectBlock01.y);. Definition is: vector<pair<int, int>> koordinateBlokovaVektor(36); Oct 9, 2018 at 20:37
• What you're trying to do there is call a function "push_back(int, int)" which doesn't exist. The function is "push_back(pair<int, int>)", in your case, basically. So you need to do something like "push_back(std::make_pair(block.x, block.y))."
– user1430
Oct 9, 2018 at 20:43
• If you have further issues with the syntax involved in using std::vector or any other C++ container, I recommend you post separate questions or ask about them in Game Development Chat. Comments aren't really suited for that kind of back-and-forth dialog.
– user1430
Oct 9, 2018 at 20:44

First of all, in general, you do not want to modify a vector in C++ while iterating through it. Even if you did take the trouble to write your loop such that it permitted this, this would make your collision detection something like a O(n^2) operation, in other words it would be quadratic with respect to the number of elements in the vector, and so it would grow to be prohibitively slow relatively quickly as you added more elements into the array.

What you should do is either consider a linked list structure (list) or do something like mark the elements in the vector for later deletion and then, after you have done all the collision detection, move only the objects not marked for deletion into a new vector that you replace the old vector with. This could be done by making the vector a vector of structs/classes that contain the pair as a member but also a bool for keeping track of if the object is deleted or not.

In the latter case you would have to decide: do you want multiple balls to be able to bounce off the same object in a single frame, or do you want only one to be able to do that, and then for the object to be deleted immediately and no other balls be able to bounce off if it in the same frame? If you are okay with multiple, then just do your collision detection as normal and delete the objects afterward. If you want the object to be deleted "immediately", then make your collision detection conditioned upon neither of the objects being marked for deletion.

• Well to make things clear, i'm making a Breakout clone game. The whole point of storing coordinates is to remove blocks if they are hit with a ball. Im trying to find a way to just "remove" an index in the array (doesnt have to delete it) so the next time I use my function for drawing/rendering, it excludes that index because the object has been hit, if that makes sense. Oct 9, 2018 at 19:48
• If you don't want to actually remove the object from the vector, and instead simply do not want to draw it, this might be as simple as making a struct/class like I mentioned before with a bool but instead of being a mark for deletion it is a mark for draw. If false, the block is not drawn. You probably want to condition collision detection on this being true too (you don't want the ball to collide with a block you aren't drawing). This is an acceptable solution if the number of blocks is soft-capped. Otherwise you waste memory with unused junk blocks sitting around. Oct 9, 2018 at 19:52
• I'd appreciate constructive criticism from whoever down voted my answer! Oct 9, 2018 at 20:00