سؤال

Okay so I've been tearing my hair out over this problem after several different attempts at it. To give some background and hopefully get an appropriate insight into this problem I'll explain how my code is set out.

  • I have a list of pointers to players_, which contains two HumanPlayer class objects.
  • Each HumanPlayer contains a Snake_List list attribute, and the pieces of these lists contain x and y data. I want to check the front of the first HumanPlayer's Snake_List's x and y co-ordinates against every piece of the second HumanPlayer's Snake_List's x and y co-ordinates.

My current code looks a little like this in the function that should do this:

    for(Entity* player : entityList)
{
    Player* p = dynamic_cast<Player*>(player);
    Player* p2 = dynamic_cast<Player*>(player++);
    if(p)
    {
        i=p->Snake_List.begin();
        for(m=p2->Snake_List.begin(); m != p2->Snake_List.end(); m++)
        {
            if (i!=m)
            {
                if ((i->x == m->x) && i->y == m->y)
                {
                    p->respawn();
                    return;
                }
            }
        }
    }
}

this compiles and runs fine but the collisions don't give me the desired effect. Nothing actually happens. I really don't think I'm referencing the second HumanPlayer's list properly, but if someone could help shine some light it would be hugely appreciated :)

هل كانت مفيدة؟

المحلول

If there are (and only ever will be) only two Player objects in the list, then you can get the two players like this:

auto itPlayer = entityList.begin();
Player* p1 = *(itPlayer++);
Player* p2 = *itPlayer;

This doesn't do any error checking so if there are less than two players in the list, it will crash. if you can ever have more than two players in the list, you would need to use a nested loop to compare each player against every other player.

The reason your original version wasn't working (apart from the post-increment in the wrong place) was that the range-based-for (for x : y) returns the actual objects in the list, not their iterators. You need the iterators to allow you to increment to move from one item in the list to the next, as the pointers themselves could be anywhere in memory.

نصائح أخرى

I think the main issue is at the very top of your code snippet:

for(Entity* player : entityList)
{
    Player* p = dynamic_cast<Player*>(player);
    Player* p2 = dynamic_cast<Player*>(player++);

You iterate entryList and then check whether the head of p ran into any of the snake pieces of p2. However, you have to play some unusual tricks with the post-increment operator here.

I think what you actually want to do is to check whether the head of the snake of some given player ran into the snake of any other player. Writing the code with that idea in mind will probably avoid the post-increment operator usage, and it will scale nicely to more players.

Don't you want '++player' instead?

Sorry, I should have been more verbose. I believe the problem is you're indexing player after you use it in

Player* p2 = dynamic_cast(player++);

when what you really want something like '++player'. So something like

Player* p2 = dynamic_cast<Player*>(player) + 1;

So you cast to Player first then index to the next player.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top