Saturday, 17 September 2016

BPM in Ren'Py - Timing animations to your musics tempo

I keep meaning to write this up as a blog post! I'm sure somebody will find it useful, either directly, or make them think about some other possibilities when making VNs!

I decided I wanted to have backgrounds flicker in time with my games music and went about it in quite a long-winded manner. Now I have worked out a better way to achieve this type of effect, so I thought I would share it!

Using your music tempo / BPM in Ren'Py

Say you have some music at 130bpm and it is in a 4/4 time signature, what you want for a timed animation is the amount of time in seconds for 1 beat. Really, once you have a beat you can easily find the length of a bar and of half a beat, etc. with some simple math!

To work this out within Ren'Py you can add:

init -1 python:

    the_bpm = 130 #change the number to your musics bpm

    one_beat = 60 / float(the_bpm)

To the top of your script.rpy file.

Now python has worked out our time in seconds for one beat to be something like 0.4615384615384615 for this example and saved it as a variable called "one_beat". I also went ahead and got some more timings based on that with the following:

    two_beat = one_beat * 2

    three_beat = one_beat * 3

    one_eighth = one_beat / 2

    one_sixteenth = one_beat / 4

    one_bar = one_beat * 4

    two_bar = one_bar * 2

    four_bar = one_bar * 4

    eight_bar = one_bar * 8

Which in my script I placed under the code further up where we declare the BPM and work out the length of one beat.

Now when I create an animation with ATL I can use any of these variables instead of typing in 0.4615384615384615 or whatever! E.g.

image bpm-ani:

    "bpm ex fr1.png" with Dissolve(one_beat, alpha=True)

    pause two_beat

    "bpm ex fr2.png" with Dissolve(one_beat, alpha=True)

    pause two_beat

    "bpm ex fr3.png" with Dissolve(one_beat, alpha=True)

    pause two_beat

    "bpm ex fr4.png" with Dissolve(one_beat, alpha=True)

    pause two_beat


Now (for the first time in the history of this blog!) I'll add a video to show what this looks AND SOUNDS like! :D

Ren'py ATL to BPM / tempo animation example from sleepy agents on Vimeo.

Here is a link to view the full rpy script file:
(note: the indent spaces would actually be 4 spaces, not 1, in the actual rpy file)

But what about different time signatures!? Can I just have what I need in a separate .py file which I can re-use in other projects!?

Oh yeah! LydianChord made this handy tool!

Which has the directions for use on the page. It's just a matter of pasting a .py file into your base game folder and adding this into your script:

init python:
    from music_timing_calculator import MusicTimingCalculator
    calc = MusicTimingCalculator(tempo=120, beats_per_measure=4, num_measures=16)
    # Now you can use calc.one_beat, calc.one_measure, calc.song_length
    # and calc.song_length_min in your code

remembering to change the numbers on this line:

calc = MusicTimingCalculator(tempo=120, beats_per_measure=4, num_measures=16)

So that they are correct for your music. I'm planning on using this tool for future projects!

OK that was quite a long post! Just keep in mind some things in ren'py will already have a default time in seconds attached to them, e.g. dissolve takes 0.5 seconds unless you specify it's time. So you may need to look at how to change those in certain scenarios.

Have fun and let me know if you make anything with this!



Apartment Complex released for PC/Mac/Linux - android APK also available

Just a quick post to mention that my latest game, Apartment Complex, is now out. It has actually been for 2 weeks, but I've just got around to posting it here!

It's a short point-and-click / visual novel that takes place at about 5am after a heavy night.

I wanted to get a bit better at things like imagemaps/hotspots and animations, so it was good to have a project that focused on these a bit.

There is a bit more information about the game on the page, linked above.

And for discussions there is a Lemmasoft Forum thread here:

Or feel free to send me a message on twitter @sleepyagents