Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Weird - Collision not occuring  (Read 8363 times)

0 Members and 2 Guests are viewing this topic.

WDR

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Weird - Collision not occuring
« on: August 26, 2013, 07:55:05 pm »
Hi... I am making this space game. Everything's going well so far. I managed to draw the player, the lasers and the enemies. I set the collisions such that when the laser hits the enemy, the laser and the enemy are both erased (lasers and enemy are both declared as sprite lists). The collision works... But only for the first 3 or 4 enemies. After that, the lasers don't affect the enemies. Is there anything wrong in the code? I failed to find any mistake. Here's my code:

if(!enemytex.loadFromFile("images/enemy.png"))
        return EXIT_FAILURE;

std::list<sf::Sprite> enemy(MAX, sf::Sprite(enemytex));

for(std::list<sf::Sprite>::iterator enemyit = enemy.begin(); enemyit != enemy.end(); enemyit++)
{
        enemyit->setOrigin(enemyit->getGlobalBounds().width/2, enemyit->getGlobalBounds().height/2);
}
 
std::list<sf::Sprite>::iterator enemyit = enemy.begin();
int dist = (int)(resolution.getDesktopMode().width - enemyit->getGlobalBounds().width);
int wastage = (int)enemyit->getGlobalBounds().width/2;

srand((unsigned int)time(NULL));
float y = -200;
for(std::list<sf::Sprite>::iterator enemyit = enemy.begin(); enemyit != enemy.end(); enemyit++)
{
        int x = rand() % dist + wastage;
        enemyit->setPosition((float)x, y);
        y = y - enemyit->getGlobalBounds().height * 2;
}

if(!greenlasertex.loadFromFile("images/playerlaser.png"))
        return EXIT_FAILURE;

std::list<sf::Sprite> greenlaser;

float enemyspeed = 100.f;

float playerspeed = 400.f;

float laserspeed = 800.f;

sf::Clock clock;

long double score = 0;
long double lvlnum = 1;

int shots = 0;

while(window.isOpen())
{              
        float timer = clock.restart().asSeconds();

        window.clear();

        for(std::list<sf::Sprite>::iterator enemyit = enemy.begin(); enemyit != enemy.end(); enemyit++)
        {
                enemyit->move(0.f, enemyspeed * timer);
                window.draw(*enemyit);
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
        {
                shots++;
        }

        if((shots != 0) && (shots % 19 == 0))
        {
                sf::Sprite newgreenlaser(greenlasertex);
                newgreenlaser.setOrigin(newgreenlaser.getGlobalBounds().width/2, newgreenlaser.getGlobalBounds().height/2);
                newgreenlaser.setScale(0.1f, 0.1f);
                newgreenlaser.setPosition(player.getPosition().x, player.getPosition().y);
                greenlaser.push_back(newgreenlaser);
        }
                       
        for(std::list<sf::Sprite>::iterator greenlaserit = greenlaser.begin(); greenlaserit != greenlaser.end(); greenlaserit++)
        {
                greenlaserit->move(0.f, -laserspeed * timer);
                window.draw(*greenlaserit);
        }
       
        int erased = 0;
        std::string str, line, word, level, lvl, number;

        str = std::to_string(score);
        word = "Score: ";
        line = word + str;
        ScoreText.setString(line);

        number = std::to_string(lvlnum);
        lvl = "Level ";
        level = lvl + number;
        LevelText.setString(level);

***INSIDE THIS BOX***
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        std::list<sf::Sprite>::iterator enemyit = enemy.begin(), next;
        std::list<sf::Sprite>::iterator greenlaserit = greenlaser.begin(), reload;
        while(enemyit != enemy.end())
        {
                next = enemyit;
                next++;
                while(greenlaserit != greenlaser.end())
                {
                        reload = greenlaserit;
                        reload++;
                        if(enemyit->getGlobalBounds().intersects(greenlaserit->getGlobalBounds()))
                        {
                                enemy.erase(enemyit);
                                greenlaser.erase(greenlaserit);
                                ++erased;
                                score = score + 10;
                                int diff = (int)score;
                                if(diff % 500 == 0)
                                {
                                        enemyspeed = enemyspeed + 25.f;
                                        lvlnum++;
                                        number = std::to_string(lvlnum);
                                        level = lvl + number;
                                        LevelText.setString(level);
                                }
                                str = std::to_string(score);
                                line = word + str;
                                ScoreText.setString(line);
                        }
                        greenlaserit = reload;
                }
                enemyit = next;
        }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
***INSIDE THIS BOX***

        for(int i = 0; i < erased; ++i)
        {
                sf::Sprite temp(enemytex);
                temp.setOrigin(temp.getGlobalBounds().width/2, temp.getGlobalBounds().height/2);
                float y = -200;
                int x = rand() % dist + wastage;
                temp.setPosition((float)x, y);
                y = y - temp.getGlobalBounds().height * 2;
                enemy.push_back(temp);
        }

        window.display();
}

I apologize if the code is too long. That is as minimal and complete as it can get. I wanted to show the whole code of the enemy and laser because I can't pinpoint the problem, and it is pretty big. Nevertheless, I highlighted the collision part inside the code for easier reference. Please help. Thank you.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #1 on: August 26, 2013, 08:30:24 pm »
This would probably be a good time to learn to use a debugger.  In all likelihood if you set a breakpoint inside your collision code and just step through it while looking at all the relevant variables (especially those lists) you can probably figure it out yourself.

WDR

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Weird - Collision not occuring
« Reply #2 on: August 26, 2013, 08:38:40 pm »
OK... Thanks. I'll do that. But, in the code above... Are there any anomalies in it not related to debugging? Any coding mistakes that causes the collision not to happen? I just want to make sure of that before I start debugging. Thanks.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #3 on: August 26, 2013, 09:27:27 pm »
Nothing jumped out at me, and this sounds like exactly the kind of problem I'd never be able to find without using a debugger myself, which is why I recommended that.

WDR

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Weird - Collision not occuring
« Reply #4 on: August 26, 2013, 09:42:09 pm »
Alright... OK, I'll try that. Thanks.  :)

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #5 on: August 27, 2013, 05:02:33 am »
In my opinion one of the best debugging options one has is to 'cout << ' any and all variables in a given method, just to make sure that method/function is doing what it should.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #6 on: August 27, 2013, 05:09:13 am »
It's one option, and sometimes an indispensable one, but for the vast majority of problems it's a lot faster and easier to use a real debugger.  There are also many problems that cout<< just cannot help with at all, which are extremely common when doing graphics or timing of any sort (ie pretty much anything you'd use SFML for).  The only downside is you have to learn how to use the debugger first.

The Hatchet

  • Full Member
  • ***
  • Posts: 135
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #7 on: August 27, 2013, 05:16:52 am »
Indeed a good debugger can do much more than a simple 'cout <<' but it just saddens me that these kids nowadays just post online "MY CODE NO WORK WHY IT NOW WORK!?!?' without even checking to make sure the method/function even gets entered and its variables get changed to what they should be first. 

One of the reasons I LOVE programming is it is problems solving half the time...but some of these kids nowadays... Hell, my first c++ book for a class was literally "How to be a good debugger".  nothing on the actual language, just a 200 page book on how to debug shit yourself.  It was the most valuable class I've ever taken.

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #8 on: August 27, 2013, 05:29:02 am »
Yeah, definitely.  It's a little annoying that the vast majority of the questions asked here seem to come from people who clearly either haven't learned C++ at all yet (I still don't get why people do that), or can't be bothered to debug/read tutorials/check documentation.

Though it helps to remember that there's probably a huge silent majority doing all sorts of cool stuff with SFML without ever needing to ask silly questions here.

WDR

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Weird - Collision not occuring
« Reply #9 on: August 27, 2013, 04:47:12 pm »
"MY CODE NO WORK WHY IT NO WORK!?!?"

OK, dude... I did not say that!  ;D
I did do a bit of tweaking myself before posting the question.

Yeah, definitely.  It's a little annoying that the vast majority of the questions asked here seem to come from people who clearly either haven't learned C++ at all yet (I still don't get why people do that), or can't be bothered to debug/read tutorials/check documentation.

I am actually very much interested to learn C++ from scratch. The only reason I'm skipping and doing all this is purely for the sake of marks. It's a college project and I'm already kind of overdue. I'm not saying this is anybody's fault. But time constraints are preventing me from learning anything properly. So, I'm just doing what I can and submit it. But on a personal level and for my future career, I will definitely learn all the A - Z of programming. It's my passion. But for the time being, please show some mercy or leniency or whatever the word is, and don't judge me. I'm not like all the morons out there. :)

Back on topic:-
I did some debugging. Found out that the "list iterator is not dereferencable". Did some tweaking with the code and still got the same error. I guess it may be in the collision code. Something to do with greenlaserit and enemyit. I'm unable to tell. Definitely somewhere in here:

std::list<sf::Sprite>::iterator enemyit = enemy.begin(), next;
std::list<sf::Sprite>::iterator greenlaserit = greenlaser.begin(), reload;
while(enemyit != enemy.end())
{
        next = enemyit;
        next++;
        while(greenlaserit != greenlaser.end())
        {
                reload = greenlaserit;
                reload++;
                if(enemyit->getGlobalBounds().intersects(greenlaserit->getGlobalBounds()))
                {
                        enemy.erase(enemyit);
                        greenlaser.erase(greenlaserit);
                }
                greenlaserit = reload;
        }
        enemyit = next;
}

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #10 on: August 27, 2013, 07:48:50 pm »
When you get an error you don't understand always try googling it first.  There's plenty of stackoverflow questions about that exact one.  Basically, when you use erase() on an iterator, it becomes invalid (for obvious reasons).  The good news is erase() itself returns a valid iterator for you.

WDR

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Weird - Collision not occuring
« Reply #11 on: August 27, 2013, 08:05:14 pm »
I did try googling it. That's how I ended up with the while loop that is used to increment the iterator, instead of the generic for loop with its increment counter. But, thanks for the advice. I will search a bit deeper, see what I can find. Your reply actually helped narrow down the possibilities of errors. I'll see what I can do. I shall post again if I hit any dead ends or if I have any queries. Thanks.  :)

WDR

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Weird - Collision not occuring
« Reply #12 on: August 30, 2013, 04:02:21 am »
OK... I am officially admitting defeat!  >:(

I am not at all getting this! Is collision between two sprite lists even possible? Because, if it isn't, I am literally barking up the wrong tree. I have tried every solution I found on my search. So far, nothing. I even read a lot of material related to it. I am not able to apply it. Can someone explain to me, please.

Gobbles

  • Full Member
  • ***
  • Posts: 132
    • View Profile
    • Email
Re: Weird - Collision not occuring
« Reply #13 on: August 30, 2013, 06:20:24 am »
of course it's possible. A list of sprites is the same as a sprite, just more of them, and sprite to sprite collision is certainly possible.

Quit trying to use techniques you don't fully understand, it only leads to these issues. My advice, access each element of the lists using objects and loop over the lists using for loops. Something nice and basic. Get that working and then you can move on to more complicated stuff.

WDR

  • Jr. Member
  • **
  • Posts: 82
    • View Profile
Re: Weird - Collision not occuring
« Reply #14 on: August 30, 2013, 09:05:56 am »
How do I access list elements using objects? I googled it but could not find any thing relevant to it. Does it also use iterators to access the elements in the list. I don't want you to tell me any code or anything. Please just elaborate on that so I have an idea on how I can implement it. Please tell me this. Thank you.  :)

 

anything