#118479 - Sabr3wulf - Tue Feb 13, 2007 9:12 pm
Hey, I'm having a problem with a scoring system.
I have the following code:
Code: |
answer = 2;
CheckAnswer();
|
Which gets the value of what's been shot then checks to see if it's the correct answer.
Code: |
void CheckAnswer(void)
{
if (a + b == answer)
{
score ++;
}
else
{
score --;
}
}
|
Which adds 1 to the score if it's correct.
The score is displayed by getting the value of score and moving a sprite for that number into the score area as follows:
Code: |
if (score == 0)
{
xscorezero = 210;
xscoreone = 240;
}
.
.
.
.
.
.
.
.
else if (score == 9)
{
xscoreeight = 240;
xscorenine = 210;
} |
However, instead of incrementing by one when the answer is correct, it cycles through the sprites from 1 until it gets to 9. Anyone know what's up? Sorry for the poor code, I'm only a beginner :(
#118482 - Miked0801 - Tue Feb 13, 2007 9:35 pm
Is score initialized to 0?
Also, you might be better off posting all the code to make sure there isn't a hidden gotcha.
#118495 - tepples - Tue Feb 13, 2007 11:29 pm
Another tip: Instead of using separate sprites for the digits 0 through 9, you can use one sprite and change its attribute 2 to point to different sprite cels in VRAM.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#118587 - KayH - Wed Feb 14, 2007 12:33 pm
In the CheckAnswer() method there should be also a range check similar to:
Code: |
if(score < 0)
{
score = 0;
}
if(score > 9)
{
score = 9;
}
|
Otherwise the score could cycle through all numbers inside the range of your type (int?)
If this method is called at regular timebase (e.g. vblank) the mentioned effect could occur.
It would be also good to have the answer (and maybe other variables too) as method parameter instead of global variables. e.g.:
Code: |
int CheckAnswer(int answer)
{
...
return score;
}
|
HTH
KaY
#118605 - sgeos - Wed Feb 14, 2007 3:44 pm
KayH wrote: |
It would be also good to have the answer (and maybe other variables too) as method parameter instead of global variables. e.g.: |
I agree with KayH in that parameters make for a better architecture. If you insist on global variables, please, at the very least, mark them as such:
Code: |
// globals - g for global
int gA;
int gB;
int gAnswer;
int gScore;
void checkScore(void)
{
if (gA + gB == gAnswer)
gScore++;
else
gScore--;
} |
This way when variables pop out of nowhere, people know that they are global. This becomes very important in longer functions. ("Where did *that* come from? No, it's not at the top of the function...")
-Brendan
#118701 - neilio - Thu Feb 15, 2007 9:29 pm
I see that you're using IF functions to do different things depending on the value of score (your code for this is shown below).
Code: |
if (score == 0)
{
xscorezero = 210;
xscoreone = 240;
}
.
.
.
.
.
.
.
.
else if (score == 9)
{
xscoreeight = 240;
xscorenine = 210;
} |
I've found that when doing this kind of thing it's better to use the SWITCH statement, which in your case would go something like...
Code: |
switch(score)
{
case 0:
xscorezero = 210;
xscoreone = 240;
break;
case 1;
xscorezero = 210;
xscoreone = 240;
break;
'
'
'
'
'
case 9:
xscoreeight = 240;
xscorenine = 210;
break;
}
|
I think I had a similar problem to you and this helped solve it, though I never figured out what caused the problem! Hope this helps.
_________________
I'd like to think this signature is under development, but it isn't.
#118707 - Miked0801 - Thu Feb 15, 2007 10:51 pm
Actually, a ROM table would be even cleaner.
Code: |
static const u32 ScoreTab[MAX_SCORE_VALUES][2] =
{
{210, 240},
...
{240, 210},
};
int foo(void)
{
xScorezero = ScoreTab[0][0];
xScorenine = ScoreTab[0][1];
}
|
#118806 - Sabr3wulf - Fri Feb 16, 2007 10:56 pm
Miked0801 wrote: |
Is score initialized to 0? |
Yup.
Miked0801 wrote: |
Also, you might be better off posting all the code to make sure there isn't a hidden gotcha. |
I wish I could as it'd be a great help but unfortunately I can't.
KayH wrote: |
In the CheckAnswer() method there should be also a range check similar to:
Otherwise the score could cycle through all numbers inside the range of your type (int?) |
Cheers, didn't think of that!
KayH wrote: |
If this method is called at regular timebase (e.g. vblank) the mentioned effect could occur.
|
CheckAnswer is being called when the laser hits one of the targets (I think)
Code: |
void HitNine(void) // check if the laser sprite has hit the 9 sprite
{
if ((xlaser >= xnine - 5) && (xlaser <= xnine + 9)) // the shot will have hit the 9 sprite
{
if (ylaser < ynine + 16)
{
xnine = 240; // move the 9 sprite off the screen, making it 'disappear'
xlaser = 240; // move the laser sprite off the screen, making it 'disappear'
shots = 0; // set shots back to 0
c = 9; // set c to hold the value of the sprite (9)
CheckAnswer();
}
}
} |
It doesn't help that the code is very hacked together and gets quite confusing.
#118814 - KayH - Sat Feb 17, 2007 12:48 am
well ...
You have (at least) two sprites: the laser (bullet) and the target (ship). What you probably do is to move the laser from one position on the screen to the next position. This is done on regular timebase (I hope you use the VBlank for timing this! Although it does not matter for the following.)
Now, you regularly make a hittest. Your target has 14 pixel in the x dimension. After the first hit your test and score is positive started. But now you should either stop the propagation of the laser or you should tweak your hittest! Otherwise you get a positive hittest on each following propagation cycle, which result in continuously increasing the score ... and you get a cycling score value.
Please make you also familiar with "struct" element of C/C++. This will make your code a lot better to understand. :-)
Also there are a lot of very good hittest threads in the forum. Please search for these and you will get a better impression of how you should do this.
HTH
KaY