Jump to content

View more

Image of the Day

Inventory ! Va falloir trouver une autre couleur pour le cadre D: #AzTroScreenshot #screenshotsaturday https://t.co/PvxhGL7cOH
IOTD | Top Screenshots

The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.


Sign up now

Time Sensitive Buttons Presses

4: Adsense

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.


  • You cannot reply to this topic
3 replies to this topic

#1 c_fried_rice   Members   

163
Like
0Likes
Like

Posted 26 December 2013 - 06:08 PM

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!



#2 L. Spiro   Members   

25464
Like
2Likes
Like

Posted 26 December 2013 - 07:29 PM

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

#3 c_fried_rice   Members   

163
Like
0Likes
Like

Posted 27 December 2013 - 10:46 AM

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!



#4 L. Spiro   Members   

25464
Like
0Likes
Like

Posted 27 December 2013 - 11:39 AM

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




Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.