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