very basic problem here.

Started by
9 comments, last by Thomas Bartholemew 16 years, 1 month ago
Hello, I recently posted about a problem I was haveing triggering sound with a collision, but didin't get any replies, probably becuase I didn't explain myself very well and am a bit of a newcomer to this. However them prolem with my code still remains and I'm desperately trying to sort it out. So if anyone could have a quick look at this I would really appreciate it!! so here's the deal. As I said before I am tying to trigger an audio file from a collision in my game. The problem is that it works when the trutle and starfish collide, but not when the turtle and Jackfish collide. Sounds rediculous but that's what happens. the code for the startfish collision that works looks like this;
[source lang=cpp]

if (check_collision( stars.return_box(), myTurtle.return_box() )){
	
				if( Mix_PlayChannel(2, gulp, 0 ) == -1 ){
					return 1;
				}

Then, the code for the jackfish collision looks like this
[source lang=cpp]

if (check_collision( jacks.return_box(), myTurtle.return_box() )){
				collision = 1;
				}	
			}
			
			if (jacks.pos() < -200 - jack_rand_limit){
				//cout << i << " " << shoal.pos() << endl;
				jack_off_screen++;
			}		
		}
		if (jack_off_screen == 1){
			jacks.clear();
			jack_finished = 1;
		}
		if (collision){	
        	beta += 4;				
                if (Mix_PlayChannel(2, gulp, 0 ) == -1 ){
         	 return 1;
				}	

As you can see, the code that plays the sound is nested in a loop that also controls the screen fade out, beta, when the collision happens, but I get no sound. Nil. Can anyone see what I'm doing wrong here? Would really appreciate some kind of feedback if anyone has time. Thank you very much.
Advertisement
Are you sure you've got your curly brackets right?
If fixed the indentation in the second snippet, but I'm still can't make up what you're doing.

        if (check_collision( jacks.return_box(), myTurtle.return_box() ))        {            collision = 1;        }	    }			    if (jacks.pos() < -200 - jack_rand_limit)    {        //cout << i << " " << shoal.pos() << endl;    	jack_off_screen++;    }		}if (jack_off_screen == 1){    jacks.clear();    jack_finished = 1;}if (collision){	    beta += 4;				        if (Mix_PlayChannel(2, gulp, 0 ) == -1 )    {        return 1;    }


BTW, by 'fixed' I don't mean to say you have to start a new line for every bracket (that's just my personal coding style), but rather that I lined up the columns.
Thanks very much WanMaster. Unfortunately that didn't fix it. What other info do you need to understand what I'm trying to do?

T
Quote:Original post by Thomas Bartholemew
What other info do you need to understand what I'm trying to do?

Perhaps you could post the entire function, or even the entire source file, if that's reasonable. Right now, I have no idea what precedes the collision check. It could be something like this:

if (hellFreezesOver)     /* code added by me */{                        /* code added by me */   if (theEarthIsFlat)   /* code added by me */   {                     /* code added by me */        if (check_collision( jacks.return_box(), myTurtle.return_box() ))        {            collision = 1;        }	    }			    if (jacks.pos() < -200 - jack_rand_limit)    {        //cout << i << " " << shoal.pos() << endl;    	jack_off_screen++;    }		}etc..


It's probably not that bad of course. [smile]

Does it actually set the collision to 1? What happens inside check_collision that could be important? Could there be a problem in Mix_PlayChannel?

And most importantly, have you tried setting break point? This sounds like an ideal situation to use them.
Thanks again WanMaster. I have send you a a private message with a link where you can see what the hell I'm trying to do here. Look forward to hearing from you!!
Quote:Original post by Thomas Bartholemew
Thanks again WanMaster. I have send you a a private message with a link where you can see what the hell I'm trying to do here. Look forward to hearing from you!!

Well, the link wasn't in the PM.

Please post all the relevant code in this thread for at least three important reasons:

  1. Don't post or send all your code (unless it's only very little), only the relevant parts. I don't have the time to go through your entire code base. The source you posted initially lacked some parts that might be key to the problem, so make a new or edit your original post to include these bits.

  2. If you only send it to me, no one else can help you. First, I might be a total idiot that has know clue of what's wrong, but perhaps others can spot the problem right away. Secondly, I'll only be online for a limited time and I don't visit this site every day. In the mean time, others will see this thread and perhaps can give you a hand.

  3. If you or someone else figures out the problem, than future visitors can benefit from this information. Perhaps someone else has the exact same issues with their code.


Don't take it the wrong way: I love PM's, but in this case it's not the most practical medium. [smile]
Thanks very much for your reply! I will definitely take all things into account next time I post. So back to the code , and please forgive me if this is still not enough info. Here is more of the part that works:

[source lang=cpp]//Makes the starfish		if (stars.size() < MAX_STARFISH ){				Starfish *s = new Starfish();			stars.push_back(*s);			}		int star_off_screen = 0;		int star_rand_limit = rand() % 500;		for (int i = 0; i < stars.size(); i++){				stars.move();			stars.show();				//cout << "Starfish " << i << " vs Turtle: " << endl;			if (check_collision( stars.return_box(), myTurtle.return_box() )){					if( Mix_PlayChannel(2, gulp, 0 ) == -1 ){					return 1;				}					//cout << "Score!" << endl;				myTurtle.adjust_score(10);				stars.erase(stars.begin()+i);							}			if (stars.pos() < -200 - star_rand_limit){				star_off_screen++;			}		}		if (star_off_screen >= MAX_STARFISH){			stars.clear();		}	



and here is more of the part that doesn't

[source lang=cpp]/Makes a jack fish		if (jacks.size() < 1){			Jack *j = new Jack();			jacks.push_back(*j);			jack_finished = 0;		}		int jack_off_screen = 0;		int jack_rand_limit = rand() % 500;		for (int i = 0; i < jacks.size(); i++){				jacks.move();			jacks.show();				//cout << "Jack " << i << " vs Turtle: " << endl;		      if (check_collision( jacks.return_box(), myTurtle.return_box() ))        {            collision = 1;        }	    }			    if (jacks.pos() < -200 - jack_rand_limit)    {        //cout << i << " " << shoal.pos() << endl;    	jack_off_screen++;    }		}if (jack_off_screen == 1){    jacks.clear();    jack_finished = 1;}if (collision){	    beta += 4;				{    if (Mix_PlayChannel(2, gulp, 0 ) == -1 )    {        return 1;    }			}		collision = 0;	


does this make more sense?
Unfortunately, I can't tell from this code what's wrong. I wasn't going to mention it, but in order for you and others to understand your own code better it might be a good idea to do some refactoring.

  • Organize your code using more functions or methods. Place some of your recurring code in separate functions, pretty much like you did with check_collision. You can use a more OOP aproach here, but that's up to you.

  • Don't nest your code too deeply (if conditions and for loops). It makes it more difficult to follow the code path, and will introduce subtle problems that can't be spotted at a quick glance. For instance, you erase a star from the vector (stars.erase(stars.begin()+i);), and only two lines down you attempt to use it again (if (stars.pos() [..]). You probably didn't intend that.

  • If possible, try to split up the code into logical chunks. As it appears now, all the collision checking of objects, drawing of sprites, sound playback and entity management are done in one big procedure. Perhaps it's an idea to first do all the movement updates, then all the collision checks, then the removal of dead or out of range entities, then the spawning of new fish and finally all the drawing (just an example order). Your millage may vary.

  • Declare variables as close to the point where they are needed. The variable jack_rand_limit is not used in the for loop.

  • Not that it is critical at his point, but use bool data types instead of integers when they will only be used as true or false flag (jack_off_screen appears to be one of them).


And have you tried using break points (if your IDE supports them) and stepping through the code?
Thanks, WanMaster. You're right, my code is a mess. I think I'm trying to code beyond my knowledge here, but just trying to learn....It's down to this that my game wasn't working properly, and in the end I tried for ages to get those sounds to trigger properly and now they do! It was a simple curly bracket problem - a testament to your observations. I now have a couple more issues: the sounds trigger ok with the code examples I posted, except that the sound keeps re-triggering as the turtle moves through the shoal of fish as opposed to once (this is because collision is detected every time the turtle collides with a fish, and not every time the turtle goes past a group of fish). Can you see a way in which I can adapt the loop to make the sound not trigger again until the turtle has passed the shoal and not individual fish?

I do have another problem and I don't think it was helping me much in trying to make the changes yesterday to the loop, in that, My compiler (Dev-C++) does not seem to take into account all the changes I've made in the code each time I compile. So for example, I can delete a whole chunk of code, then compile, but the code I've just deleted is still having an effect on the game. Thanks in advance!!
Quote:Original post by Thomas Bartholemew
Thanks, WanMaster. You're right, my code is a mess. I think I'm trying to code beyond my knowledge here, but just trying to learn....It's down to this that my game wasn't working properly, and in the end I tried for ages to get those sounds to trigger properly and now they do! It was a simple curly bracket problem - a testament to your observations. I now have a couple more issues: the sounds trigger ok with the code examples I posted, except that the sound keeps re-triggering as the turtle moves through the shoal of fish as opposed to once (this is because collision is detected every time the turtle collides with a fish, and not every time the turtle goes past a group of fish). Can you see a way in which I can adapt the loop to make the sound not trigger again until the turtle has passed the shoal and not individual fish?

The most simple solution would be to store a reference to the last fish it collided with. The next time it collides, check if it's still the same fish. Or the other way around by making it a property of a fish (the latter would probably be better in case the turtle can collide with multiple fish simultaneously). In very naive pseudo code:
foreach (fish){  if ((turtle.collidesWith(fish))  {    if (fish.objectOfLastCollision != turtle)    {      fish.objectOfLastCollision = turtle;      playSound();    }  }  else  {    fish.objectOfLastCollision = null;  }}

Well, something like that.. :)
In any case, you want to somehow preserve or calculate the previous state(s) to be able to detect the relevant changes. How best to implement this is something you'll have to figure out for yourself.

Quote:I do have another problem and I don't think it was helping me much in trying to make the changes yesterday to the loop, in that, My compiler (Dev-C++) does not seem to take into account all the changes I've made in the code each time I compile. So for example, I can delete a whole chunk of code, then compile, but the code I've just deleted is still having an effect on the game. Thanks in advance!!

I'm not familiar with Dev-C++ or its quirks.

This topic is closed to new replies.

Advertisement