Problems with classes interacting

Started by
15 comments, last by evilsanta 17 years, 11 months ago
Quote:
However, std::vector::erase returns a brand new iterator which is valid and is pointing to the element next to the one you just erased.

With the for loop at hand, wouldnt the iterator make two steps each cycle?

One when the iterator is assigned the the return value of erase and another when the loop update it with ++
Advertisement
Don't do the looping yourself. Instead, make use of the "erase-remove idiom", combining two 'algorithms' from the standard library. I was going to give code showing how, but you already seem to have some commented out in your original sample. Was it not working for you? What seems to be the problem with it?
Quote:Original post by Zahlman
Don't do the looping yourself. Instead, make use of the "erase-remove idiom", combining two 'algorithms' from the standard library. I was going to give code showing how, but you already seem to have some commented out in your original sample. Was it not working for you? What seems to be the problem with it?



Yes it was working, but the way im used to programming is that I run through all the iterations of one object type or class is that I delcare my forloop then do everything within that, im not sure, it just seems odd and unorganized to me to do it that way... unless of course there is a way to do that... but I guess ill just put that back in the code and use that way till later so for now I can work on collisions...

And ive hit another problem... basically just for testing purposes im only checking detection on the X axis, and the coordinates have to be exact... but this bit of code is causing problems...

        for (bulletIter = bullets.begin(); bulletIter != bullets.end(); ++bulletIter) {            for (shipIter = ships.begin(); shipIter != ships.end(); ++shipIter) {                if (shipIter->isHit(bulletIter->returnX())) {                   bullets.erase(bulletIter);                   ships.erase(shipIter);                }            }        }


This doesnt cause errors, it causes the program to crash, but if I comment out this line bullets.erase(bulletIter); it works just fine... the same thing happens if I destroy the last ship that was created, and its the same problem I had above, just wondering if I have to use this to remove it... bullets.erase(remove_if(bullets.begin(), bullets.end(), mem_fun_ref(&bullet::isDestroyed)), bullets.end());

Also when working with iterators was I correct to declare one for ships and bullets? Is there a better way to do this?

[Edited by - evilsanta on May 22, 2006 3:04:49 PM]
If you're going to do the looping yourself, it should be something like:

for (iter_bullet=bullets.begin();iter_bullet!=bullets.end();){if (iter_bullet->ShouldBeRemoved()) iter_bullet=bullets.erase(iter_bullet);else ++iter_bullet;}


And no offence, but DesignerX corrected your mispelling from "==" to "=", and 9 minutes later you return with a list of compiler errors. Don't you think you should at least spend some time debugging yourself instead of instatenously posting "OMG I have errors fix please"?

[Edited by - mikeman on May 22, 2006 4:25:11 PM]
Apologies, sometimes I can just get so frustrated that I give up and ask for people to "give me da codz" but I couldnt get your loop code to work so I just went with the built in one and changed my code around a bit... and it works fine now so thanks everyone, but just wondering if there is anything ineficient about my code as it just doesnt feel right to me, do I have to declare one iterator for every vector? and I think my class member functions may be a bit much...

Im just wondering if my code is repetative at all, if you dont want to look over my code and tell me noob mistakes dont worry about it... I just dont want to learn the wrong way to do something as I had a major incident with that the first language I learned...

#include <allegro.h>#include <vector>   // To use the vector class#include <algorithm>    // To use for_each#include <functional>   // To use mem_fun_ref#include "siheader.h"using namespace std;void init();void deinit();int main() {    	init();    vector<Ship> ships;    vector<bullet> bullets;   // Create a new ship and add it to the end of the vector   for (int x=50; x<750; x=x+35) {       for (int y=20; y<200; y=y+35) {           ships.push_back( Ship(x, y) );       }   }    vector<Ship>::iterator shipIter;   vector<bullet>::iterator bulletIter;   //playervariables   int player_x=400;   int player_y=500;   BITMAP *playerImage;   playerImage = load_bitmap( "test.bmp", NULL);      BITMAP *backGround;   backGround = load_bitmap( "back.bmp", NULL);       	while (!key[KEY_ESC]) {		acquire_screen();		draw_sprite(screen, backGround, 0,0);		if (key[KEY_RIGHT]) {           player_x=player_x+4;        }		if (key[KEY_LEFT]){           if (player_x > 0){              player_x=player_x-4;           }        }		if (key[KEY_SPACE]) {           bullets.push_back( bullet(player_x, player_y) );        }        for (shipIter = ships.begin(); shipIter != ships.end();shipIter++) {            shipIter->update();        }        for (int i = 0; i < bullets.size(); i++) {             bullets.update();        }        for (bulletIter = bullets.begin(); bulletIter != bullets.end(); ++bulletIter) {            for (shipIter = ships.begin(); shipIter != ships.end(); ++shipIter) {                if (shipIter->isHit(bulletIter->returnX(),bulletIter->returnY())) {                   bulletIter->setDestroyed();                   shipIter->setDestroyed();                }            }        }		bullets.erase(remove_if(bullets.begin(), bullets.end(), mem_fun_ref(&bullet::isDestroyed)), bullets.end());		ships.erase(remove_if(ships.begin(), ships.end(), mem_fun_ref(&Ship::isDestroyed)), ships.end());        rotate_sprite(screen, playerImage, player_x+100, player_y-100, itofix(player_x));				draw_sprite(screen, playerImage, player_x, player_y);	        		release_screen();	}	deinit();	return 0;}END_OF_MAIN()void init() {	int depth, res;	allegro_init();	depth = desktop_color_depth();	if (depth == 0) depth = 32;	set_color_depth(depth);	res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0);	if (res != 0) {		allegro_message(allegro_error);		exit(-1);	}	install_timer();	install_keyboard();	install_mouse();	/* add other initializations here */}void deinit() {	clear_keybuf();	/* add other deinitializations here */}


and the header...

class Ship {private:       // We don't want external code to access the coordinates directly   int x, y;   bool destroy;public:        // We do want external code to be able to call these functions   // This creates a Ship object with the appropriate coordinates   Ship(int xpos,int ypos) :       x(xpos),  // Sets the ship's x to xpos      y(ypos)   // Sets the ship's y to ypos   {      // No code is currently required here.       // Things may change as your class grows.   }   void update() {      circlefill( screen, x, y, 15, makecol(255,255,255));     if (mouse_b & 1) {        y=y+1;     }    }    bool isHit(int bulletX, int bulletY) {        if (bulletX < x + 25){           if (bulletX > x - 25) {              if (bulletY == y+10) {                 return true;              }           }        }        return false;   }     int returnX() {       return x;   }   int returnY() {       return y;   }   void setDestroyed() {        destroy = true;   }   bool isDestroyed() {        if (destroy == true) {           return true;        }        return false;   }};class bullet {private:       // We don't want external code to access the coordinates directly   int x, y;   bool destroy;public:        // We do want external code to be able to call these functions   // This creates a Ship object with the appropriate coordinates   bullet(int xpos,int ypos) :       x(xpos),      y(ypos)    {      // No code is currently required here.       // Things may change as your class grows.   }      void update() {      circlefill( screen, x, y, 15, makecol(255,255,255));     y=y-5;       if (y<40) {        destroy = true;     }   }   int returnX() {       return x;   }   int returnY() {       return y;   }   void setDestroyed() {        destroy = true;   }   bool isDestroyed() {        if (destroy == true) {           return true;        }        return false;   }};


As I said, something just feels wierd with my code...
Quote:
...but I couldnt get your loop code to work...


Sorry, I mispelled the name of the iterator two times(one as "iter" and one as "bullet_iter"). But that errors would be easy to correct. Please don't tell me you went ahead and copy/pasted my code as is, with the "ShouldBeRemoved()" dummy and everything!
Quote:Original post by mikeman
Quote:
...but I couldnt get your loop code to work...


Sorry, I mispelled the name of the iterator two times(one as "iter" and one as "bullet_iter"). But that errors would be easy to correct. Please don't tell me you went ahead and copy/pasted my code as is, with the "ShouldBeRemoved()" dummy and everything!


Of course not. I put the code in changed the variables, and yes I did notice your mispelling but I changed it, I didnt get any errors but the program crashed on runtime.

This topic is closed to new replies.

Advertisement