Trying to display screens with input, and a timer

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
cskin
Newbie
Posts: 5
Joined: Mon Jul 12, 2021 9:51 am
Contact:

Trying to display screens with input, and a timer

#1 Post by cskin »

Ok, I officially need help. Truth is, I have no clue what I am actually doing. I've been slowly learning the code (both renpy and python), and trying to hack together whatever I can from what I can find in documentation, and snippets of code other people have written. Unfortunately I've reached a point where I have no idea how to get it to do what I want it to do - which honestly is probably easy and I just don't know enough yet, but I figured this was the right place to ask, since most of what I've learned I've gotten from threads on this site anyway. So first I'll share my code, then explain what I'm trying to actually accomplish.

Code: Select all

init:
    image upb = "upbutton.png"
    image downb = "downbutton.png"
    image leftb = "leftbutton.png"
    image rightb = "rightbutton.png"
    define xpy = 0
    define ypy = 0


screen Upbutton(xpos, ypos):
    button:
        image "upb"
        xpos xpos
        ypos ypos
        action SetVariable("exercise",exercise+1)
        keysym "K_UP"

screen Downbutton(xpos, ypos):
    button:
        image "downb"
        xpos xpos
        ypos ypos
        action SetVariable("exercise",exercise+1)
        keysym "K_DOWN"

screen Leftbutton(xpos,ypos):
    button:
        image "leftb"
        xpos xpos
        ypos ypos
        action SetVariable("exercise",exercise+1)
        keysym "K_LEFT"

screen Rightbutton(xpos,ypos):
        button:
            image "rightb"
            xpos xpos
            ypos ypos
            action SetVariable("exercise",exercise+1)
            keysym "K_RIGHT"


screen workout():
    timer 0.5 action [Return("loopy"), If (workout_timer>1, If(exercise > 8, Return("win"), SetVariable("workout_timer", workout_timer-0.4) ), Return("lose") ) ] repeat True


label start:

    "This is a test"

    $ exercise = 0

    $ workout_timer = 10

    show screen workout


    label worktime:
        $result = ui.interact()
        $ workout_timer = workout_timer
        $ randscr = renpy.random.randint(1,4)
        if (randscr == 1):
            call screen Upbutton(renpy.random.randint(200,1200),renpy.random.randint(200,750))
        elif (randscr == 2):
            call screen Downbutton(renpy.random.randint(200,1200),renpy.random.randint(200,750))
        elif (randscr == 3):
            call screen Leftbutton(renpy.random.randint(200,1200),renpy.random.randint(200,750))
        elif (randscr == 4):
            call screen Rightbutton(renpy.random.randint(200,1200),renpy.random.randint(200,750))
        if result == "loopy":
            jump worktime

    if result == "win":
        hide screen Upbutton
        hide screen Downbutton
        hide screen workout
        "Grats [exercise]"
        jump done

    if result == "lose":
        hide screen Upbutton
        hide screen Downbutton
        hide screen workout
        "Fail [exercise]"
        jump done


    label done:
        "Finished"

return


Ok so that is what I have atm, some of the display is debug stuff. I've tried about 15 different ways to do this so far, and while the above doesn't actually work properly, it's the closest I've managed to come. Also about 50% of that code is shamelessly stolen from other places.

Anyone who knows more than me can probably see what that does: Every 0.5s it displays a random image at a random location on the screen, if the correct key prompt (or click - I haven't figured out how to make it not clickable yet. I'll get there when I get the rest to work) is hit, it adds 1 to a counter. When the timer runs out, if enough have been hit, it advances to win, otherwise to lose.

What I want it to do: Run a timer in the background. Display a random image at a random location, and WAIT for a key press. If the correct key is hit, advance to another random image. (I also want to have it advance if an incorrect key is hit and just not increment the counter, but I'm not too worried about figuring that part out yet). If the target # of correct hits is achieved before time runs out, advance to win, if the timer runs out before that, advance to lose.

Basically I can not figure out how to have a timer run, but have it desynched from the actual key prompts, and still have them show up randomly. I've tried a bunch of different ways that all fail miserably. Some just make a single static image that never advances, some don't advance the count, some create infinite loops, some ignore the timer and advance images forever, some only advance the timer when a key press DOESN'T happen, and the rest just error out entirely because I'm still learning proper syntax.

If anyone can help me figure out how to do what I'm trying to do it'd be much appreciated. Also, if anyone can point me to good resources to learn how to do all this stuff properly, I'd appreciate that too. So far all I've found is the official documentation (which is useful, but lacking on a lot of explanations or examples which I find helps a ton), and these forums (I've been looking through the cookbook section a bit, I'd like to go through it more when I have some free time, but that's slightly more limited in that most of it is examples of specific tasks rather than how to use various functions, or stuff like that. Though maybe there's more too it, I just haven't had enough time to go through too much of it yet).

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2438
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Trying to display screens with input, and a timer

#2 Post by Ocelot »

Is this similar to what are you looking for?

Code: Select all

image upb    = Crop((0, 0, 100, 100), Solid("#f00"))
image downb  = Crop((0, 0, 100, 100), Solid("#0f0"))
image leftb  = Crop((0, 0, 100, 100), Solid("#00f"))
image rightb = Crop((0, 0, 100, 100), Solid("#ff0"))

screen Upbutton(coords):
    button:
        image "upb"
        pos coords
        action Return(True)
        keysym "K_UP"
    button:
        keysym ["K_DOWN", "K_LEFT", "K_RIGHT"]
        action Return(False)

screen Downbutton(coords):
    button:
        image "downb"
        pos coords
        action Return(True)
        keysym "K_DOWN"
    button:
        keysym ["K_UP", "K_LEFT", "K_RIGHT"]
        action Return(False)

screen Leftbutton(coords):
    button:
        image "leftb"
        pos coords
        action Return(True)
        keysym "K_LEFT"
    button:
        keysym ["K_UP", "K_DOWN", "K_RIGHT"]
        action Return(False)

screen Rightbutton(coords):
    button:
        image "rightb"
        pos coords
        action Return(True)
        keysym "K_RIGHT"
    button:
        keysym ["K_UP", "K_DOWN", "K_LEFT"]
        action Return(False)


screen loss_timer(workout_time):
    timer workout_time action Jump("worktime.lose")


label start:
    "This is a test"

label worktime:
    $ exercise = 0
    $ workout_timer = 10
    show screen loss_timer(workout_timer)

label .work:
    $ randscr = renpy.random.randint(1,4)
    $ coords = renpy.random.randint(200,1000), renpy.random.randint(200,600)
    if (randscr == 1):
        call screen Upbutton(coords)
    elif (randscr == 2):
        call screen Downbutton(coords)
    elif (randscr == 3):
        call screen Leftbutton(coords)
    elif (randscr == 4):
        call screen Rightbutton(coords)
    if _return:
        $ exercise += 1
    if exercise > 8:
        jump .win
    jump .work

label .cleanup:
    hide screen Upbutton
    hide screen Downbutton
    hide screen Leftbutton
    hide screen Rightbutton
    hide screen workout
    return

label .win:
    call .cleanup
    "Grats [exercise]"
    jump .done

label .lose:
    call .cleanup
    "Fail [exercise]"
    jump .done

label .done:
    "Finished"
    return
EDIT: Only accept correct buttons
< < insert Rick Cook quote here > >

cskin
Newbie
Posts: 5
Joined: Mon Jul 12, 2021 9:51 am
Contact:

Re: Trying to display screens with input, and a timer

#3 Post by cskin »

That does... literally exactly what I'm looking for. Thank you so much. Tbh I'm a bit annoyed with myself because i got like 80% of the way there, and then fell short. Now that I see what you did the solution was incredibly simple and I was just overthinking it since I'm not so familiar with the language yet.

Could you please explain something to me if you don't mind.

90% of what you changed, I tried. the ONE thing I didn't attempt, is NOT having a return in the timer. (the timer screen always had a return, the one time I tried without it, somehow I managed to create an infinite loop, so I put it back and moved on). I tried having returns in all the other screens, but they always messed one thing or another up.

was the return in that causing most of the issue? (as opposed to just having a static timer like you made, that jumps to lose and cleans up), or was it the fact that the timer was recurring? or something else, or both?

(as a note: i originally attempted something similar to what you have in one of my very early attempts, but it didn't work because there were a lot of other problems with it. Eventually I found the timer I did use somewhere on these boards, and just stuck with it).

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2438
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: Trying to display screens with input, and a timer

#4 Post by Ocelot »

Return just... wasn't nessesary for the most straightforward way to do it, so I didn't use it. I am sure there are ways to do it with a repeat timer, returns; but I don't like when screens contain actual game logic, so I went with this solution.
< < insert Rick Cook quote here > >

Post Reply

Who is online

Users browsing this forum: Google [Bot]