Long-time lurker and admirer of VN-games, I have always wanted to make a vn-game, but so far I haven't made any. But at the end of the year I saw myself making a simple game for a treasure hunt. Screenshots, crossover with other games, treasure maps and.....a hidden object game.
I looked around the forums/web but couldn't find any tutorial or even a lot of info about it. I found some using imagemaps but I wanted to use image buttons instead, so I figured I'd give it a try myself! After some struggling I managed to do it and get it installed. It was well received, although it was played by kids in elementary school so not that picky. Despite not having a lot of experience with renpy, I wanted to share what I figured out. I hope it can help someone like me.
Attached to this post is the example I made. In it I show 2 versions. Puzzle #1 with a timer and where the item you find make a difference(think "unique clues"). Puzzle #2 has you finding 15 items, which disappear upon finding. Please check the script.rpy file to see how it's done, I tried to comment as much as possible.
For the people who would rather read it here than checking the script.rpy, I will to post it here as well but with most of the "flow"-code stripped out.
Puzzle #1: Timed Hidden Object - 50 second timer to find 3 items.
#1 Variables: These register if an item has been found, how many points are earned and how much time is left to finish the puzzle.
Code: Select all
#puzzle 1 variables
$ puzzle1_a = 0 # 1st image found or not? 0 = not found, 1 = found
$ puzzle1_b = 0 # 2nd image
$ puzzle1_c = 0 # 3rd image
$ puzzle1_clues = 3 # number of clues to find
$ puzzle1_time_points = 0 # how many points have been earned by being fast enough
$ puzzle1_game_result = 0 # total number of points earned
$ puzzle1_clues_found = 0 # number of clues found
$ puzzle1_timer_range = 0 # puzzle 1 has a counter, this determines how much time you have
Code: Select all
transform barely_seen: # used to make the image button transparent, 80%. This may not be needed, depending on the background/game
alpha 0.8
transform barely_seen2: # 50%
alpha 0.5
transform alpha_dissolve: # used by the countdown bar, so it moves/disappears
alpha 0.0
linear 0.5 alpha 1.0
on hide:
linear 0.5 alpha 0
Code: Select all
screen countdown(): # the countdown bar - search for "Timed Menus" in the forums/cookbook
timer 0.01 repeat True action If(time > 0, true=SetVariable('time', time - 0.01), false=[Hide('countdown'), Jump("puzzle1_checktime")])
# it checks the time, if the time is bigger than 0, it does the stuf behind the true=, namely changing the time
# if that is false, it does the stuff behind the false=, namely hiding the countdown and jumping to the label puzzle1_checktime
bar value time range puzzle1_timer_range xalign 0.95 yalign 0.05 xmaximum 300 at alpha_dissolve # Timer bar, using the transformation above
screen s_puzzle1(): # screen for puzzle 1, three imagebuttons in 1 screen
imagebutton:
auto "clue_1_%s" # will look for an image called hidden1a_idle / hidden1a_hover / etc
action [ SetVariable("puzzle1_a", 1), Jump("puzzle1_checktime") ] # 1: sets the variable puzzle1_a to 1, 2: jumps to puzzle1_checktime
xpos 952 ypos 510 # location of the imagebutton
focus_mask True # makes it so the transparent parts of the image are not clickable
at barely_seen
imagebutton:
auto "clue_2_%s"
action [ SetVariable("puzzle1_b", 1), Jump("puzzle1_checktime") ]
xpos 512 ypos 432
focus_mask True
imagebutton:
auto "clue_3_%s"
action [ SetVariable("puzzle1_c", 1), Jump("puzzle1_checktime") ]
xpos 520 ypos 155
focus_mask True
at barely_seen2 # transformation with more transparency
Code: Select all
label puzzle1_checktime:
window hide
pause
$ puzzle1_clues_found = puzzle1_a + puzzle1_b + puzzle1_c # how many clues have been found already?
if puzzle1_clues_found == puzzle1_clues : # all clues found, finish
if time > 30: # award the points gained from finishing it within a certain number of time
$ puzzle1_time_points = 2 # 2 points get added
elif time > 10:
$ puzzle1_time_points = 1 # 1 point gets added
# if the time left over is less than 10 seconds, no bonus points are given
jump puzzle1_done
elif time < 1: # ran out of time
jump puzzle1_done
else: # not all clues have been found and time has not run out, continue
jump puzzle1_ongoing
Code: Select all
o "Example 1"
hide owlinera
scene crime_scene
$ time = 50
$ puzzle1_timer_range = 50
show screen s_puzzle1
show screen countdown
o "Find them all!"
window hide # to hide the text box
pause # pause things until the mouse is clicked
label puzzle1_ongoing: # puzzle1_checktime will jump here when the time hasn't run out yet. It serves as a loop of sorts.
jump puzzle1_checktime
label puzzle1_done: # puzzle1_checktime will jump here when the time runs out or all objects have been found
$ puzzle1_game_result = puzzle1_clues_found + puzzle1_time_points # tally of the score
hide screen countdown # the countdown bar
hide screen s_puzzle1 # the puzzle screen
Onwards to the second example I made!
This one is a bit different. There is no timer, instead there is a counter that shows how many items have been found. And unlike the previous example, the found items disappears/gets hidden.
Puzzle #2: Non-Timed Hidden Object - Find 15 items, with a counter.
#2 Variables:
Code: Select all
$ puzzle2_score = 0 # how many pieces have already been found in puzzle 2, used for the counter
$ puzzle2_total = 15 # how many pieces to find in puzzle 2 in total. Is used to show a counter/end the game.[/spoiler]
Code: Select all
transform barely_seen: # used to make the image button transparent, 80%. This may not be needed, depending on the background/game
alpha 0.8
transform barely_seen2: # 50%
alpha 0.5
Code: Select all
# screens for puzzle 2
# each image button has its own screen because this allows you to hide each item(image button) individually.
screen s_puzzle2a():
imagebutton:
idle "puzzle_animals/animal1.png" # mentions the specific name of the image, different from the previous puzzle
# also this time the images are saved in a sub-folder to make things more tidy
action [ Hide("s_puzzle2a"), SetVariable("puzzle2_score", puzzle2_score + 1), Jump("puzzle2_check_number") ]
#hides this imagebutton, adds 1 to the score and jumps to puzzle2_check_number
xpos 480 ypos 120
focus_mask True # makes it so the transparent parts of the image are not clickable
at barely_seen # calls the transform above, making the button itself a lot less visible
screen s_puzzle2b():
imagebutton:
idle "puzzle_animals/animal2.png"
action [ Hide("s_puzzle2b"), SetVariable("puzzle2_score", puzzle2_score + 1), Jump("puzzle2_check_number") ]
xpos 248 ypos 574
focus_mask True
at barely_seen
##Etc, etc, for as many screens as you have, in my case until o since the game has 15 images to find
# A counter that shows how many items have been found already
screen s_puzzle2_found_txt():
text "[puzzle2_score]/[puzzle2_total]" color "#ffffff" xpos 1170 ypos 40
Code: Select all
label puzzle2_check_number:
window hide
pause
if puzzle2_score == puzzle2_total: # all animals were found!
jump puzzle2_done
else: # not yet, keep going
jump puzzle2_ongoing
Code: Select all
show screen s_puzzle2_found_txt # the counter
show screen s_puzzle2a # all the animals to collect
show screen s_puzzle2b
etc
o "Find them all!"
window hide
pause
# It waits until an image button is pressed. When that happens, it does the following:
# action [ Hide("s_puzzle2q"), SetVariable("puzzle2_score", puzzle2_score + 1), Jump("puzzle2_check_number") ]
label puzzle2_ongoing: # it will go back here to continue
jump puzzle2_check_number
label puzzle2_done: # it will go here when all animals have been found
return
Thanks to the documentations, forum, cookbook and the [GxImagebuttons]-thread.