Quick Time Event

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
Message
Author
User avatar
papiersam
Veteran
Posts: 231
Joined: Fri Aug 12, 2016 2:24 pm
Completed: Gem Hunt Beta, 1/Probably, Animunch
Projects: The Panda Who Dreamed
Contact:

Quick Time Event

#1 Post by papiersam » Mon Jul 02, 2018 10:55 pm

So,

I've scraped up a bare-bones quick time event (qte) sort of thing - where you have to press a button before time runs out - in a (I hope) reusable way (It's written a bit like a function, so all you really have to do is carry over two screens and a label, and you're good to go!).

Below is the basic code (ready to use), and attached is a demo with commented code. There are a few things that should be improved (more modularity, better UI/visuals), but I'll get to that if I can.

Code: Select all

label start:

    $ cont = 0 #continue variable
    $ arr_keys = ["a", "c", "e", "K_UP", "K_SPACE"] #list of keyboard inputs to be selected from. See https://www.pygame.org/docs/ref/key.html for more keys

    call qte_setup(0.5, 0.5, 0.01, renpy.random.choice(arr_keys), renpy.random.randint(1, 9) * 0.1, renpy.random.randint(1, 9) * 0.1)
    # "Function Call" - see label qte_setup for detail on "function"
    # in the above, I randomly select a key from a previously defined set of keys (arr_keys), and randomise the location

    while cont == 1:
        call qte_setup(0.5, 0.5, 0.01, renpy.random.choice(arr_keys), renpy.random.randint(1, 9) * 0.1, renpy.random.randint(1, 9) * 0.1)
        # to repeat the qte events until it is missed

    "{b}GAME OVER{/b}"

    return

Code: Select all

#########################################
FUNCTION
#########################################
'''
"Function"/pseudo-function
calls the qte screen
parameters are:
    - amount of time given
    - total amount of time (is usually the same as above)
    - timer decreasing interval
    - the key/keyboard input to hit in the quick time event
    - the x alignment of the bar/box
    - the y alignment of the bar/box
'''
label qte_setup(time_start, time_max, interval, trigger_key, x_align, y_align):

    $ time_start = time_start
    $ time_max = time_max
    $ interval = interval
    $ trigger_key = trigger_key
    $ x_align = x_align
    $ y_align = y_align

    call screen qte_simple
    # can change to call screen qte_button to switch to button mode

    $ cont = _return
    # 1 if key was hit in time, 0 if key not

    return

############################################
SCREEN
############################################
screen qte_simple:
    #key input qte

    timer interval repeat True action If(time_start > 0.0, true=SetVariable('time_start', time_start - interval), false=[Return(0), Hide('qte_simple')])
    # timer, using variables from label qte_setup
    # false is the condition if the timer runs out - and this will be reached if the user doesn't get hit the key on time

    key trigger_key action ( Return(1) )
    # the "key detector" (ends qte_event by returning 1)

    vbox:
        xalign x_align
        yalign y_align
        spacing 25
        # vbox arrangement

        text trigger_key:
            xalign 0.5
            color "#fff"
            size 36
            #outlines [ (2,"#000000",0,0) ]
            # text showing the key to press

        bar:
            value time_start
            range time_max
            xalign 0.5
            xmaximum 300
            if time_start < (time_max * 0.25):
                left_bar "#f00"
                # this is the part that changes the colour to red if the time reaches less than 25%


########################################################################################
[hr]
And below the following is an explanation of the attached Renpy files (an implemented version of the QTE)
script.rpy

Code: Select all

label start:

    scene airplane animated at fullsize

    $ cont = 0 #continue variable
    $ arr_keys = ["a", "c", "e", "K_UP", "K_SPACE"] #list of keyboard inputs to be selected from. See https://www.pygame.org/docs/ref/key.html for more keys

    call qte_setup(0.5, 0.5, 0.01, renpy.random.choice(arr_keys), renpy.random.randint(1, 9) * 0.1, renpy.random.randint(1, 9) * 0.1)
    # "Function Call" - see label qte_setup for detail on "function"
    # in the above, I randomly select a key from a previously defined set of keys (arr_keys), and randomise the location

    while cont == 1:
        call qte_setup(0.5, 0.5, 0.01, renpy.random.choice(arr_keys), renpy.random.randint(1, 9) * 0.1, renpy.random.randint(1, 9) * 0.1)
        # to repeat the qte events until it is missed

    play sound "sounds/miss.mp3"
    "{b}GAME OVER{/b}"
    # basic game over sound + message

    return
Setup, mostly. the arr_keys is just a list of keys you want to be used to trigger the QTE pass (it can even be just one key, but I randomise through a list). After, I "call" the QTE setup label - the one that acts like a function.

The while loop just loops until a 0/False is returned, and the game over sound plays right after (for simplicity's sake. You could always have it played in screen, etc).

Code: Select all

#'''
#"Function"/pseudo-function
#calls the qte screen
#parameters are:
#    - amount of time given
#    - total amount of time (is usually the same as above)
#    - timer decreasing interval
#    - the key/keyboard input to hit in the quick time event
#    - the x alignment of the bar/box
#    - the y alignment of the bar/box
#'''

label qte_setup(time_start, time_max, interval, trigger_key, x_align, y_align):

    $ time_start = time_start
    $ time_max = time_max
    $ interval = interval
    $ trigger_key = trigger_key
    $ x_align = x_align
    $ y_align = y_align

    call screen qte_button
    # can change to "call screen qte_button" to switch to button mode

    $ cont = _return
    # 1 if key was hit in time, 0 if key not

    return
Setting variables that were carried through the call, and then calling the screen. _return is what's returned by Return() (the screen function).
qte.rpy
Note that you can separate these in different files or combine them into one. Renpy reads all the scripts at load time and treats it as a whole.

Code: Select all

screen qte_keyboard:
    #key input qte

    timer interval repeat True action If(time_start > 0.0, true=SetVariable('time_start', time_start - interval), false=[Return(0), Hide('qte_keyboard')])
    # timer, using variables from label qte_setup
    # false is the condition if the timer runs out - and this will be reached if the user doesn't get hit the key on time

    key trigger_key action ( Play("sound", "sounds/hit.mp3"), Return(1) )
    # the "key detector" (plays sound and ends qte_event by returning 1)

    vbox:
        xalign x_align
        yalign y_align
        spacing 25
        # vbox arrangement

        text trigger_key:
            xalign 0.5
            color "#fff"
            size 36
            #outlines [ (2,"#000000",0,0) ]
            # text showing the key to press

        bar:
            value time_start
            range time_max
            xalign 0.5
            xmaximum 300
            if time_start < (time_max * 0.25):
                left_bar "#f00"
                # this is the part that changes the colour to red if the time reaches less than 25%
Mostly explained in comments: start a timer, visualise that in a bar (that changes colour dynamically at 25%), read key inputs, and return 0 or 1. The letter that is shown over the bar can be changed by changing the text trigger_key in the vbox.

Code: Select all

screen qte_button:
    #button press qte

    button:
        action Return(0) #miss
        align 0.5, 0.5
        background "images/transparent.png"
        #to add a click sensor *outside* of button (if player presses outside button area) and return false


    timer interval repeat True action If(time_start > 0.0, true=SetVariable('time_start', time_start - interval), false=[Return(0), Hide('qte_button')])
    #see above

    vbox:
        xalign x_align yalign y_align spacing 25

        button:
            action Return(1)
            xalign 0.5
            xysize 100, 100
            background Animation("#000", 0.5, "#fff", 0.5) #change to image, etc
            activate_sound "sounds/hit.mp3"
            #same function as the key input


        bar:
            value time_start
            range time_max
            xalign 0.5
            xmaximum 300
            if time_start < (time_max * 0.25):
                left_bar "#f00"


Similar to the keyboard screen, except this one contains an invisible "mouse detector" outside of the button that returns a False/0 if hit (i.e, if anywhere outside the button is hit). Granted, instead of using a transparent.png, you could use any image/colour and set AlphaMask to 0, but I went with this way.

And that's about it. If you have any questions or find any bugs, it's best to comment on this thread I guess.

~rsami
Attachments
qte.zip
Renpy Ready File Pack
(4.88 MiB) Downloaded 239 times

norrissang
Newbie
Posts: 1
Joined: Tue Jul 03, 2018 9:17 am
Contact:

Re: Quick Time Event

#2 Post by norrissang » Tue Jul 03, 2018 9:23 am

sorry for my bad english. How to change it to limited (just 10 click => end game, instead of loop forever)

User avatar
papiersam
Veteran
Posts: 231
Joined: Fri Aug 12, 2016 2:24 pm
Completed: Gem Hunt Beta, 1/Probably, Animunch
Projects: The Panda Who Dreamed
Contact:

Re: Quick Time Event

#3 Post by papiersam » Tue Jul 03, 2018 10:43 pm

Add a counter.

Go to

Code: Select all

    while cont == 1:
        call qte_setup(0.5, 0.5, 0.01, renpy.random.choice(arr_keys), renpy.random.randint(1, 9) * 0.1, renpy.random.randint(1, 9) * 0.1)
        # to repeat the qte events until it is missed
and change it to

Code: Select all

    $ counter = 0 #counter variable
    while cont == 1 and counter < 10: 
        call qte_setup(0.5, 0.5, 0.01, renpy.random.choice(arr_keys), renpy.random.randint(1, 9) * 0.1, renpy.random.randint(1, 9) * 0.1)
        $ counter = counter + 1 #increment/increase the counter each time. When it reaches 10, it will exit the loop
        # to repeat the qte events until it is missed
Also, if you want to change the game over message after 10 rounds, change

Code: Select all

    play sound "sounds/miss.mp3"
    "{b}GAME OVER{/b}"
    # basic game over sound + message
to

Code: Select all

    if counter == 10: #if we reached 10 rounds without missing
        "10 rounds done"
    
    else:
        play sound "sounds/miss.mp3"
        "{b}GAME OVER{/b}"

User avatar
gas
Veteran
Posts: 450
Joined: Mon Jan 26, 2009 7:21 pm
Contact:

Re: Quick Time Event

#4 Post by gas » Wed Jul 04, 2018 3:18 am

After the qte_setup label you can avoid to reassign attributes to variables, they are already in the store.
10 ? "RENPY"
20 GOTO 10

RUN

User avatar
papiersam
Veteran
Posts: 231
Joined: Fri Aug 12, 2016 2:24 pm
Completed: Gem Hunt Beta, 1/Probably, Animunch
Projects: The Panda Who Dreamed
Contact:

Re: Quick Time Event

#5 Post by papiersam » Wed Jul 04, 2018 8:18 pm

True, but I figure this is easier in terms of basic visualization for beginners.

kully00000
Newbie
Posts: 7
Joined: Fri Jun 08, 2018 9:00 pm
Deviantart: kelly00000
Contact:

Re: Quick Time Event

#6 Post by kully00000 » Sat Sep 01, 2018 12:45 pm

Hi, first of this I would just like to say that this is a great piece of code.
What I wanted to ask was, is it possible to change the black QTE box (the thing you click on before the timer runs out) with another icon/image?

kully00000
Newbie
Posts: 7
Joined: Fri Jun 08, 2018 9:00 pm
Deviantart: kelly00000
Contact:

Re: Quick Time Event

#7 Post by kully00000 » Sat Sep 01, 2018 1:34 pm

kully00000 wrote:
Sat Sep 01, 2018 12:45 pm
Hi, first of this I would just like to say that this is a great piece of code.
What I wanted to ask was, is it possible to change the black QTE box (the thing you click on before the timer runs out) with another icon/image?
I figured out how to do it so never mind

Nightwolf
Newbie
Posts: 1
Joined: Mon Nov 05, 2018 5:05 am
Contact:

Re: Quick Time Event

#8 Post by Nightwolf » Sun Dec 30, 2018 2:18 pm

Wow! To get the whoe thin started, I really want to thank you for sharing this piece of code. I'd be very pleased, if you could take a minute to answer a (hopefully) simple question. Is there any possibility to use the code more then one time? I would like to use it as some kind of minigame, that occurs multiple times throughout the course of the main game, while getting slightly more difficult with each occurrence (e.g. by needing more "hits" to get past the mini game or shortening the amount of time available for pressing the right button)? I tried several things to accomplish this effect, I rewrote/copied labels and/or changed variables, but I simply couldn't do it. Is there anything I could do to make this work?
Best wishes
Nightwolf

Foureyedfloozy
Newbie
Posts: 2
Joined: Tue Jan 29, 2019 10:00 am
Tumblr: Four-eyed-floozy
Contact:

Re: Quick Time Event

#9 Post by Foureyedfloozy » Wed Mar 13, 2019 2:27 pm

How do you adjust the speed of the timer? It's way too fast for me and i'd like to make it slower. I am very new to ren'py let alone coding, so I hope this isn't annoying of anything.
Thanks
Foureyedfloozy

reena27
Newbie
Posts: 2
Joined: Mon Jun 17, 2019 7:55 am
Contact:

Re: Quick Time Event

#10 Post by reena27 » Mon Jun 17, 2019 8:00 am

kully00000 wrote:
Sat Sep 01, 2018 1:34 pm
kully00000 wrote:
Sat Sep 01, 2018 12:45 pm
Hi, first of this I would just like to say that this is a great piece of code.
What I wanted to ask was, is it possible to change the black QTE box (the thing you click on before the timer runs out) with another icon/image?
I figured out how to do it so never mind
Hello. This is late, but If I may ask, were you able to load your image at the right position where you can click on it? I tried loading mine but I don't know how to position it well.

TOTALLYNOTGENERATED
Newbie
Posts: 7
Joined: Sat Jul 06, 2019 6:39 am
Contact:

Re: Quick Time Event

#11 Post by TOTALLYNOTGENERATED » Sat Jul 06, 2019 6:50 am

How do you adjust the timer? :)

TOTALLYNOTGENERATED
Newbie
Posts: 7
Joined: Sat Jul 06, 2019 6:39 am
Contact:

Re: Quick Time Event

#12 Post by TOTALLYNOTGENERATED » Sat Jul 06, 2019 6:54 am

Foureyedfloozy wrote:
Wed Mar 13, 2019 2:27 pm
How do you adjust the speed of the timer? It's way too fast for me and i'd like to make it slower. I am very new to ren'py let alone coding, so I hope this isn't annoying of anything.
Thanks
Foureyedfloozy
did you find out?

User avatar
Per K Grok
Miko-Class Veteran
Posts: 541
Joined: Fri May 18, 2018 1:02 am
Completed: the Ghost Pilot, Sea of Lost Ships, Bubbles and the Pterodactyls, Defenders of Adacan Part 1
Projects: Defenders of Adacan Part 2
Deviantart: pekj
itch: per-k-grok
Location: Sverige
Contact:

Re: Quick Time Event

#13 Post by Per K Grok » Sat Jul 06, 2019 10:59 am

TOTALLYNOTGENERATED wrote:
Sat Jul 06, 2019 6:54 am
Foureyedfloozy wrote:
Wed Mar 13, 2019 2:27 pm
How do you adjust the speed of the timer? It's way too fast for me and i'd like to make it slower. I am very new to ren'py let alone coding, so I hope this isn't annoying of anything.
Thanks
Foureyedfloozy
did you find out?
If you open script.rpy you will find on line 71 a code text that starts like this
call qte_setup(0.5, 0.5, ----
on line 76 you will find a similar code text
call qte_setup(0.5, 0.5, ----

If you change 0.5 on all four places to a different number the speed of time-out will change.
Image Visual Story Telling, DeviantArt Group for animations, comics, games and illustrations https://www.deviantart.com/acgi

TOTALLYNOTGENERATED
Newbie
Posts: 7
Joined: Sat Jul 06, 2019 6:39 am
Contact:

Re: Quick Time Event

#14 Post by TOTALLYNOTGENERATED » Sat Jul 06, 2019 11:27 am

thank you! :D

User avatar
Andredron
Veteran
Posts: 340
Joined: Thu Dec 28, 2017 2:37 pm
Location: Russia
Contact:

Re: Quick Time Event

#15 Post by Andredron » Mon Jul 08, 2019 3:29 pm

papiersam wrote:
Mon Jul 02, 2018 10:55 pm
It would be cool if you could add examples of semi round bars (they look beautiful)


viewtopic.php?f=8&t=27159&p=328819#p328841
I know, I'm writing terribly in English.

I'm writing a Renpy textbook (in Russian). https://yadi.sk/d/ZX_DonP63USRru Update 22.06.18

Honest Critique

Post Reply

Who is online

Users browsing this forum: No registered users