Jump to content
  • Advertisement
Sign in to follow this  
c_fried_rice

Time Sensitive Buttons Presses

This topic is 1636 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

Hey guys!

 

Sorry for the poorly titled thread. Basically I'm working on a music game, and want there to be an accuracy factor to when the player hits the note. My current code is as follows:

void Gameplay::detectHit(note_buttons pressed, double time)
{
	if ((note_gems_left.empty() && current_track == &note_gems_left) ||
		(note_gems_right.empty() && current_track == &note_gems_right))
	{
		return;
	}

	if (current_track == &note_gems_left)
	{
		if (pressed == notes_left_s.front()->getButton())
		{
			if (time <= notes_left_s.front()->getTimeStamp()  + great_t
				&& time >= notes_left_s.front()->getTimeStamp()  - great_t)
			{
				score += points * great;
				note_hit = GREAT;
				note_gems_left.erase(note_gems_left.begin());
				notes_left_s.erase(notes_left_s.begin());
			}
			else if (time <= notes_left_s.front()->getTimeStamp()  + nice_t
				&& time >= notes_left_s.front()->getTimeStamp()  - nice_t)
			{
				score += points * nice;
				note_hit = NICE;
				note_gems_left.erase(note_gems_left.begin());
				notes_left_s.erase(notes_left_s.begin());			
			}
			else if (time <= notes_left_s.front()->getTimeStamp()  + good_t
				&& time >= notes_left_s.front()->getTimeStamp() - good_t)
			{
				score += points * good;
				note_hit = GOOD;
				note_gems_left.erase(note_gems_left.begin());
				notes_left_s.erase(notes_left_s.begin());
			}			
			else if (time <= notes_left_s.front()->getTimeStamp()  + poor_t
				&& time >= notes_left_s.front()->getTimeStamp()  - poor_t)
			{
				score += points * poor;
				note_hit = POOR;
				note_gems_left.erase(note_gems_left.begin());
				notes_left_s.erase(notes_left_s.begin());
			}
			else
			{
				note_hit = MISS;
				note_gems_left.erase(note_gems_left.begin());
				notes_left_s.erase(notes_left_s.begin());
			}
		}
		else
		{
			note_hit = MISS;
		}
	}
	else if (current_track == &note_gems_right)
	{
		if (pressed == notes_right_s.front()->getButton())
		{
			if (time <= notes_right_s.front()->getTimeStamp()  + great_t
				&& time >= notes_right_s.front()->getTimeStamp()  - great_t)
			{
				score += points * great;
				note_hit = GREAT;
				note_gems_right.erase(note_gems_right.begin());
				notes_right_s.erase(notes_right_s.begin());
			}
			else if (time <= notes_right_s.front()->getTimeStamp()  + nice_t
				&& time >= notes_right_s.front()->getTimeStamp()  - nice_t)
			{
				score += points * nice;
				note_hit = NICE;
				note_gems_right.erase(note_gems_right.begin());
				notes_right_s.erase(notes_right_s.begin());
			}
			else if (time <= notes_right_s.front()->getTimeStamp() + good_t
				&& time >= notes_right_s.front()->getTimeStamp()  - good_t)
			{
				score += points * good;
				note_hit = GOOD;
				note_gems_right.erase(note_gems_right.begin());
				notes_right_s.erase(notes_right_s.begin());
			}			
			else if (time <= notes_right_s.front()->getTimeStamp()  + poor_t
				&& time >= notes_right_s.front()->getTimeStamp()  - poor_t)
			{
				score += points * poor;
				note_hit = POOR;
				note_gems_right.erase(note_gems_right.begin());
				notes_right_s.erase(notes_right_s.begin());
			}
			else
			{
				note_hit = MISS;
				note_gems_right.erase(note_gems_right.begin());
				notes_right_s.erase(notes_right_s.begin());
			}
		}
		else
		{
			note_hit = MISS;
		}
	}
}

My main issue is that I feel like this could be done in a MUCH better way. I'm just not sure how to go about it. Basically there are different accuracy levels for hitting the note - ranging from MISS to GREAT (with POOR, GOOD, & NICE in between). It affects the score, and the amount of "life" the player has.

 

Anyone got any suggestions?

 

Thanks a ton!

Share this post


Link to post
Share on other sites
Advertisement
Data-driven is always the answer.
A table would be best.
 
 
enum HIT_TYPE {
    HIT_GREAT,
    HIT_NICE,
    HIT_GOOD,
    HIT_POOR,
    HIT_MISS,
};
struct TIMINGS {
    UINT64 ui64Range;
    DWORD dwPoints;
    HIT_TYPE htHitType;
};
 
 
 
static const TIMINGS tTimes[] = {
    { great_t, great, HIT_GREAT },
    { nice_t, nice, HIT_NICE },
    { good_t, good, HIT_GOOD },
    { poor_t, poor, HIT_POOR },
    { miss_t, 0, HIT_MISS },  // miss_t = 100000000 or something safe for your needs.
};
 
UINT64 ui64TimeStamp = pressed == notes_left_s.front()->getButton() ? notes_left_s.front()->getTimeStamp() : notes_right_s.front()->getTimeStamp();
std::vector<BLAH> * pvGemsErase = pressed == notes_left_s.front()->getButton() ? &note_gems_left : &note_gems_right;
std::vector<BLAH> * pvNotesErase = pressed == notes_left_s.front()->getButton() ? &notes_left_s : &notes_right_s;
 
for ( DWORD I = 0; I < sizeof( tTimes ) / sizeof( tTimes[0] ); ++I ) {
            if (time <= ui64TimeStamp + tTimes[I].ui64Range
                && time >= ui64TimeStamp - tTimes[I].ui64Range)
            {
                score += points * tTimes[I].dwPoints;
                note_hit = tTimes[I].htHitType;
                pvGemsErase->erase(pvGemsErase->begin());
                pvNotesErase->erase(pvNotesErase->begin());
                break;
            }
}

I could be more elegant with a bit more knowledge of the overall design but you get the idea.


L. Spiro

Share this post


Link to post
Share on other sites

Oooh that makes sense. My only remaining question then is where/how to define the table if I'm reading in the values for for great_t, etc. and great, etc. from a script? Because as it stands I can't define the table in a header file, because the values will not have been read in, and defining it in my init() function gives me a syntax error about incomplete types when I go to use sizeof(timing_table).

 

Thanks!

Share this post


Link to post
Share on other sites
Then you should have some way of reading it at load-time and storing it for later use.
If not, something is wrong.


L. Spiro

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!