Quick Time Event
Posted: 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.
########################################################################################
[hr]
And below the following is an explanation of the attached Renpy files (an implemented version of the QTE)
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).
Setting variables that were carried through the call, and then calling the screen. _return is what's returned by Return() (the screen function).
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.
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
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
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
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.qte.rpy
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%
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