Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm looking to develop a game for Windows Phone to explore an idea I had which involves the user building notes into a sequencer while playing a puzzle game.

The issue I'm running into is that, while my implementation is very close to being on-beat, there is the occasional pause between beats which makes the whole thing sound sloppy. I'm just not sure how to get around this inside XNA's infrastructure.

Currently I'm running this code in the Update method of my GameBoard:

public void Update(GameTime gameTime)
{
    onBeat = IsOnBeat(gameTime);
    [...]
    if (onBeat)
        BeatUpdate();
}

private bool IsOnBeat(GameTime gameTime)
{
    beatTime += gameTime.ElapsedGameTime.TotalSeconds;
    if (Math.Abs(beatTime - beatLength) < 0.0166666)
    {
        beatTime -= beatLength;
        return true;
    }
    return false;
}

private void BeatUpdate()
{
    cursor.BeatUpdate();
    board.CursorPass((int)cursor.CursorPosition % Board.GRID_WIDTH);
}

Update checks to see if the time is on beat, and if it is, it calls the BeatUpdate method which moves the cursor over the board (sequencer). The cursor reports its X position to the board, which then plays any notes which are in that position on the sequencer. Notes are SoundEffectInstances, preloaded and ready to play. Oh, and TargetElapsedTime is set to 166666, or 60FPS target.

Obviously totaling up the time and then subtracting isn't the most accurate way to go but I can't figure out a way to work within XNA's system in order to overcome this issue. This current system is just horribly unstable. Beats lag and fire too early and it's obvious. I thought about perhaps some sort of threaded solution but I'm not familiar enough with multithreading to figure out how that would work. Any ideas?

share|improve this question
    
What's TargetElapsedTime meant to store? 166,666 isn't a number with any immediately obvious significance, except that it's 1/6th of a second in microseconds, or something. 1/60th of a second is 16.66 milliseconds or 16,667 microseconds. –  Jonathan Hobbs Jun 4 '12 at 3:09
    
Sorry, it creates a TimeSpan from ticks. I only remembered that I changed the default value (333333, for 30fps) to 166666. The set itself is a TimeSpan, created with TimeSpan.FromTicks(). I think the refresh rate might be a red herring though. –  A-Type Jun 4 '12 at 20:35
    
How are you getting the number of ticks? The preferred method is using QueryPeformanceCounter and QueryPerformanceFrequency, as far as I know. The Systems.Diagnostics.StopWatch class should be making use of those –  melak47 Jun 5 '12 at 2:17
    
When you make an XNA Game project, it fills it in as a magic number for you in Game1.cs. –  A-Type Jun 5 '12 at 3:33
    
@A-Type hm, the accuracy of that could be worth testing. In the mean time though maybe try this instead: Create an instance of System.Diagnostrics.StopWatch, Restart() it when IsOnBeat(yourStopWatch.ElapsedMilliseconds) is true, and bool IsOnBeat(long long time) should return true if (time >= targetInterval), where targetInterval would be the time between one sound starting and the next one starting in thousandths of a second –  melak47 Jun 5 '12 at 12:49
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.