Sign in to follow this  
bjorny

Rhythm game mechanics (audio/body velocity sync)

Recommended Posts

Hi everyone,

 

I want to make a basic rhythm game in Phaser where the user has to hit specified keys to 'catch' the incoming notes while staying in rythm. So far the main game area roughly looks like this:

 

post-10138-0-46482100-1441373955.png

 

 

The idea is that the key must be hit (and the corresponding note played) when the note sprite fully overlaps the key sprite, and the score is calculated based of how close the note sprite is to the top edge of the key sprite. I have an array of percussion loops with various BPMs I made in a DAW  which change after each level to increase the difficulty. When the level starts this function is called:

beginPlaying: function(l){this.noteCount = 25;this.currentLoop = this.loops[l];this.currentLoop.play();this.maxInterval = this.currentLoop.durationMS/4;this.timer.add(0, this.generateNotes, this);this.timer.start();},

generateNotes function goes like this:

generateNotes: function(){if(this.noteCount > 0){var num = this.game.rnd.integerInRange(0, 4);var note = this.notes.create(this.noteFlags.getAt(num).x, this.game.height - 20, 'note');this.game.physics.arcade.enable(note);var distance = note.y - this.noteFlags.getAt(num).y;note.body.velocity.y = -(distance/(this.currentLoop.duration/2));this.noteCount--;this.timer.add(this.maxInterval, this.generateNotes, this);}},

I'm planning to make it more complicated by spawning notes not only at maxInterval, but so far I'm facing a problem: even though the first few notes seem to land perfectly in rhythm with the currentLoop, later they stop keeping up with the drums and the whole thing goes completely out of sync. I suppose this has something to do with the sound duration in ms and the fact that this.maxInterval is not a whole number.  

 

I tried rounding the numbers using Math.round and Math.floor and I also tried alternative methods of calculating note positions, like 

n.y -= (distance/(this.currentLoop.duration/2))/60;

called using this.notes.forEachAlive method from the update function. Right now I'm completely lost (I guess that's the price you pay when you start programming while not being very good at maths smile.png). Is there any way to deal with the audio/velocity sync problem? I would very much appreciate any suggestions :)

Thanks!

post-10138-0-46482100-1441373955.png

Share this post


Link to post
Share on other sites

A general answer.

 

Incremental movements (e.g. y += (velocity * deltaAge)) will tend towards cumulative variations over time, and therefore become out of sync with a linear thread of the same age (e.g. the audio).

This will become more apparent as the game continues.

 

Instead, define position using overall duration instead (e.g. y = startOffset + (velocity * age) ).

 

Working backwards so the notes land on the beat should be trivial if you know the bpm - and some minor correction is often needed to make it feel "perfect" (to allow for visual and input lag).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.