Jump to content
  • Advertisement
Sign in to follow this  
evilsanta

Problems with classes interacting

This topic is 4439 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, im currently writing a space invaders clone using allegro, I can fire and everything however im having trouble getting collisions to work, I currently have a enemy ship member function called isHit which makes the checks... well heres my code... I really need help with this.
#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) );
       }
   } 
   //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 (int i = 0; i < ships.size(); i++) {
            ships.update();
        }
        for (int i = 0; i < bullets.size(); i++) {
            bullets.update();
            bullets.isDestroyed();
        }
        for (int i = 0; i < bullets.size(); i++) {
            for (int i = 0; i < ships.size(); i++) {
                ships.isHit(bullets.returnX);
            }
        }
		//for_each(ships.begin(), ships.end(), mem_fun_ref(&Ship::update));
		//for_each(bullets.begin(), bullets.end(), mem_fun_ref(&bullet::update));
           //bullets.erase(remove_if(bullets.begin(), bullets.end(), mem_fun_ref(&bullet::isDestroyed)), bullets.end());
		rotate_sprite(screen, playerImage, player_x+100, player_y-100, itofix(player_x));
		
		draw_sprite(screen, playerImage, player_x, player_y);
	

        textout_ex(screen, font, "BLAH", 10, 590,makecol(255, 255, 255), -1);
		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 heres the siheader include...
class Ship {
private:       // We don't want external code to access the coordinates directly
   int x, y;
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;
     } 
   } 
   void isHit(bulletX){
        if (bulletX = x){
           exit(-1);
        }
   }  
};

class bullet {
private:       // We don't want external code to access the coordinates directly
   int x, y;
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.
   }
   bool isDestroyed() {
       if (y<-10) {
          return true;
       }
       return false;
   }
   void update() { 
     circlefill( screen, x, y, 15, makecol(255,255,255));
     y=y-5;  
     //if (y<400) {
      //x=0;
      //y=0;
     //}
   }
   int returnX() {
       return x;
   }
};

Is there a better way to do this? Or any way to get it working?

Share this post


Link to post
Share on other sites
Advertisement
Say, in the isHist function:

void isHit(bulletX){
if (bulletX = x){
exit(-1);
}
}

Why = and not == ??
I don't know what the idea behind the function, but if you use = instead of ==
you will always get true and the exit(-1) will be executed.

Share this post


Link to post
Share on other sites
Thanks for the reply, see I had gone a long period of not using C++ and using another language where just one = is valid, but I changed it and im still getting these errors...


Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\Dawn's\Desktop\Brian\Programming\C++\space invaders\Makefile.win"
Executing make...
make.exe -f "C:\Documents and Settings\Dawn's\Desktop\Brian\Programming\C++\space invaders\Makefile.win" all
g++.exe -D__DEBUG__ -c main.cpp -o main.o -I"C:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"C:/Dev-Cpp/include/c++/3.4.2/backward" -I"C:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"C:/Dev-Cpp/include/c++/3.4.2" -I"C:/Dev-Cpp/include" -g3

In file included from main.cpp:6:
siheader.h:20: error: variable or field `isHit' declared void
siheader.h:20: error: expected `;' before '(' token
siheader.h:25: error: expected `;' before '}' token

main.cpp: In function `int _mangled_main()':
main.cpp:58: error: 'class Ship' has no member named 'isHit'

make.exe: *** [main.o] Error 1

Execution terminated

Share this post


Link to post
Share on other sites
I dont have allegro installed so I cant debug it, but the line

ships.isHit(bullets.returnX);

should be

ships.isHit(bullets.returnX());

and the function

void isHit(bulletX){
...

shoud be

void isHit(int bulletX){
...

Share this post


Link to post
Share on other sites
Ok now I have a new problem, in order to remove a vector element I need to cycle through them with iterators, I can iterate just fine to draw the bullets, and when I incorporated deleting after they got past a certain Y value I find that the program crashes when the last bullet is about to be deleted... this is hard to explane but heres the code thats causing the trouble (probably, as there are no error messages).



for (bulletIter = bullets.begin(); bulletIter != bullets.end(); ++bulletIter) {
bulletIter->update();
if (bulletIter->isDestroyed()) {
bullets.erase(bulletIter);
}
}



and heres the member function isDestroyed...


bool isDestroyed() {
if (y<110) {
return true;
}
return false;
}

Share this post


Link to post
Share on other sites
Erasing an iterator invalidates that iterator, which means you cannot use it again.

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.



for (bulletIter = bullets.begin(); bulletIter != bullets.end(); ++bulletIter) {
bulletIter->update();
if (bulletIter->isDestroyed()) {
bulletIter = bullets.erase(bulletIter);
}
}


Share this post


Link to post
Share on other sites
You can make sure you dont erase anything from an already empty vector

if(bullets.size())
for (bulletIter = bullets.begin(); bulletIter != bullets.end(); ++bulletIter) {
bulletIter->update();
if (bulletIter->isDestroyed()) {
bullets.erase(bulletIter);
}
}


If you try to erase from an empty vector the program seems to crash

edit:
rip-off's method might be slicker though

Share this post


Link to post
Share on other sites
Quote:
Original post by pulpfist
You can make sure you dont erase anything from an already empty vector

if(bullets.size())
for (bulletIter = bullets.begin(); bulletIter != bullets.end(); ++bulletIter) {
bulletIter->update();
if (bulletIter->isDestroyed()) {
bullets.erase(bulletIter);
}
}


If you try to erase from an empty vector the program seems to crash


The original code will not "erase from an empty vector", as the condition "bulletIter != bullets.end()" would make it break the loop before the first iteration.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!