Hidden Object Code

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.
Message
Author
User avatar
SusanTheCat
Miko-Class Veteran
Posts: 952
Joined: Mon Dec 13, 2010 9:30 am
Location: New Brunswick, Canada
Contact:

Hidden Object Code

#1 Post by SusanTheCat » Sun Jul 24, 2011 5:33 pm

After an afternoon of hitting my head against the computer screen (And listening to Repo! the Genetic Opera) I made some code for a basic Hidden Object screen.

Code: Select all

init python:   
    showitems = True
   
    def display_items_overlay():
        if showitems:
            inventory_show = "Items to Find: "
            items = hidelist.keys()
            for i in range(0, len(items)):
                inventory_prefix = ""
                inventory_suffix = ""
                item_name = items[i]
                item_state = hidelist[items[i]]
                if i > 0:
                    inventory_show += ", "
                if item_state == 'Found':
                    inventory_prefix = "{s}"
                    inventory_suffix = "{/s}"
                inventory_show += inventory_prefix+item_name+inventory_suffix
            ui.frame()
            ui.text(inventory_show)
    config.overlay_functions.append(display_items_overlay)
    
    def is_all_found():
        newitem = hidelist.keys()
        for i in range(0, len(newitem)):
            if hidelist[newitem[i]] == 'Not found':
                return False
        return True
       
##
# The game starts here.
label start:
    $ hidelist = {'tshirt': 'Not found', 'girl': 'Not found'}
    call screen hidden_object
    "Result: %(_return)s!"
    
    return
    
   
screen hidden_object:
    tag hidden
    imagemap:
        auto "woods_%s.png"

        hotspot (530, 400, 90, 110) action If(hidelist['girl']=='Not found', SetDict(hidelist,'girl','Found'), None)
        hotspot (90, 70, 250, 270) action If(hidelist['tshirt']=='Not found', SetDict(hidelist,'tshirt','Found'), None)
        hotspot (175, 475, 250, 70) action If(is_all_found(), Return("All Found!"), None)
I would write more about this but I am rather tired of the code right now.

Basics:
woods_ground = is the background image
woods_idle = the objects in their normal state
woods_hover = what happens when you hover over an object
OPTIONAL
woods_insensitive = what happens when an object is found. If you leave this out, the objects disappear when found.

Next steps:
Make the code more generic so you can pass a list of objects

Any suggestions welcome!

EDIT:

Adding distributions if you want to play the LAMEST hidden object game ever:

http://www.thecatsweb.com/games/Hidden% ... st-all.zip (18 MB)
http://www.thecatsweb.com/games/Hidden% ... -win32.zip (8 MB)


Susan
Attachments
woods_insensitive.png
OPTIONAL: image when object found
woods_insensitive.png (8.43 KiB) Viewed 1990 times
woods_idle.png
Basic objects
woods_hover.png
The rollover image
woods_ground.png
The background
Last edited by SusanTheCat on Sun Jul 24, 2011 8:36 pm, edited 1 time in total.
" It's not at all important to get it right the first time. It's vitally important to get it right the last time. "
— Andrew Hunt and David Thomas

User avatar
Camille
Eileen-Class Veteran
Posts: 1226
Joined: Sat Apr 23, 2011 2:43 pm
Completed: Please see http://trash.moe
Projects: Spirit Parade
Organization: Cyanide Tea
Tumblr: narihira
Deviantart: crownwaltz
Skype: thievinghearts
Contact:

Re: Hidden Object Code

#2 Post by Camille » Sun Jul 24, 2011 6:49 pm

This is awesome, thank you! :D
1/2 of Cyanide Tea | Break Chance Memento (BL) | Spirit Parade (Otome) | Portfolio/List of Works/Contact
I'm not around LSF very much these days; please contact me via Skype/Twitter. Ask me things!

User avatar
KimiYoriBaka
Miko-Class Veteran
Posts: 636
Joined: Thu May 14, 2009 8:15 pm
Projects: Castle of Arhannia
Contact:

Re: Hidden Object Code

#3 Post by KimiYoriBaka » Sun Jul 24, 2011 11:52 pm

rather than using a dictionary, wouldn't it be faster to just use a pair of lists?

also, I think using imagebuttons instead of an imagemap would work better, if you want to pass a list of objects. that way you wouldn't need the items to be integrated into the main image.

User avatar
SusanTheCat
Miko-Class Veteran
Posts: 952
Joined: Mon Dec 13, 2010 9:30 am
Location: New Brunswick, Canada
Contact:

Re: Hidden Object Code

#4 Post by SusanTheCat » Mon Jul 25, 2011 5:39 am

I think you're right, a set of lists would likely work better. I'm just a fan of hash tables. :)

I tossed the idea back and forth about image buTtons rather than image maps. I went with imagemaps because it fit better with how I want to create the image - one big image rather than oddles of little ones. The image buttons have the advantage that they can be moved around for better replayability.

Susan
Typing in bed
" It's not at all important to get it right the first time. It's vitally important to get it right the last time. "
— Andrew Hunt and David Thomas

User avatar
SusanTheCat
Miko-Class Veteran
Posts: 952
Joined: Mon Dec 13, 2010 9:30 am
Location: New Brunswick, Canada
Contact:

Re: Hidden Object Code

#5 Post by SusanTheCat » Tue Aug 16, 2011 9:41 pm

I've written a more modular version of the Hidden Object code.

Feel free to use it. Let me know if you use the graphics.

Susan
Attachments
Hidden Object Test.zip
Zip of all the files
(80.23 MiB) Downloaded 123 times
" It's not at all important to get it right the first time. It's vitally important to get it right the last time. "
— Andrew Hunt and David Thomas

User avatar
Alex
Lemma-Class Veteran
Posts: 2188
Joined: Fri Dec 11, 2009 5:25 pm
Contact:

Re: Hidden Object Code

#6 Post by Alex » Wed Aug 17, 2011 5:56 am

Oh, it's looking nice...;)
two thoughts:
1) this will fix the problem with imagemaps mess http://lemmasoft.renai.us/forums/viewto ... 84#p133578
2) unfortunatelly, Ren'py leaves the player a possibility to cheat (just hit arrow key and one of hidden objects will be pointed, then just hit enter untill win). So, maybe it would be better to disable arrow keys and enter ingame and make them work again after finishing the action part of the game?

User avatar
OokamiKasumi
Eileen-Class Veteran
Posts: 1775
Joined: Thu Oct 14, 2010 3:53 am
Completed: 14 games released -- and Counting.
Organization: DarkErotica Games
Deviantart: OokamiKasumi
Location: NC, USA
Contact:

Re: Hidden Object Code

#7 Post by OokamiKasumi » Fri Aug 19, 2011 10:03 am

SusanTheCat wrote:I've written a more modular version of the Hidden Object code. Feel free to use it. Let me know if you use the graphics. -- Susan
I am in awe of your work on this code. Thank you so much!
-- A question. Is there a way to make the object selected disappear...?

Edit: I just figured it out. Save the _empty.png as the _insensitive.png and the selected objects disappear!
Ookami Kasumi ~ Purveyor of fine Smut.
Most recent Games Completed: For ALL my completed games visit: DarkErotica Games

"No amount of great animation will save a bad story." -- John Lasseter of Pixar

User avatar
SusanTheCat
Miko-Class Veteran
Posts: 952
Joined: Mon Dec 13, 2010 9:30 am
Location: New Brunswick, Canada
Contact:

Re: Hidden Object Code

#8 Post by SusanTheCat » Fri Aug 19, 2011 7:26 pm

If you hide it on the "insensitive" layer

*_ground: what it looks like at the start
*_hover: what it looks like if you hover over it
*_insensitive: what it looks like after it is found.

I use to have them hide, but then I got into trouble when the objects were too close together and the rectangles overlapped and weird things happened with shadows. That's when I change to have the objects go grey.

In my drawing I have the following layers
- objects on top of hidden objects
- hidden objects
- objects under hidden objects
- background

Then I can do different effects to just the hidden object layer.

Susan
" It's not at all important to get it right the first time. It's vitally important to get it right the last time. "
— Andrew Hunt and David Thomas

User avatar
OokamiKasumi
Eileen-Class Veteran
Posts: 1775
Joined: Thu Oct 14, 2010 3:53 am
Completed: 14 games released -- and Counting.
Organization: DarkErotica Games
Deviantart: OokamiKasumi
Location: NC, USA
Contact:

Re: Hidden Object Code

#9 Post by OokamiKasumi » Fri Aug 19, 2011 9:31 pm

SusanTheCat wrote:...I use to have them hide, but then I got into trouble when the objects were too close together and the rectangles overlapped and weird things happened with shadows. That's when I change to have the objects go grey. -- Susan
I understand. I'll just have to work around it by not sitting the objects too close together. I'm doing it all with photo-manipulation, so I kind of have to make them disappear just to compete with the big dogs for attention.

I'm still in the experimental stage though! One never knows what you or I might figure out in the mean time.
Ookami Kasumi ~ Purveyor of fine Smut.
Most recent Games Completed: For ALL my completed games visit: DarkErotica Games

"No amount of great animation will save a bad story." -- John Lasseter of Pixar

User avatar
SusanTheCat
Miko-Class Veteran
Posts: 952
Joined: Mon Dec 13, 2010 9:30 am
Location: New Brunswick, Canada
Contact:

Re: Hidden Object Code

#10 Post by SusanTheCat » Fri Aug 19, 2011 9:50 pm

I've seen some of your photo manipulation stuff. It is going to Rock!

Let me know if you need some help. The code is fairly straight forward, but I'm not known for my commenting abilities.

Susan
" It's not at all important to get it right the first time. It's vitally important to get it right the last time. "
— Andrew Hunt and David Thomas

User avatar
OokamiKasumi
Eileen-Class Veteran
Posts: 1775
Joined: Thu Oct 14, 2010 3:53 am
Completed: 14 games released -- and Counting.
Organization: DarkErotica Games
Deviantart: OokamiKasumi
Location: NC, USA
Contact:

Re: Hidden Object Code

#11 Post by OokamiKasumi » Fri Aug 19, 2011 10:40 pm

SusanTheCat wrote:I've seen some of your photo manipulation stuff. It is going to Rock! Let me know if you need some help. The code is fairly straight forward, but I'm not known for my commenting abilities. -- Susan
Oh, thank you!
-- I am going to need some help. I'm not anywhere near as bright as you are.

I only have three rooms complete, so to speak, at the moment. This is One:
parlor_ground.png
Parlor, ground
Last edited by OokamiKasumi on Mon Aug 29, 2011 7:33 pm, edited 11 times in total.
Ookami Kasumi ~ Purveyor of fine Smut.
Most recent Games Completed: For ALL my completed games visit: DarkErotica Games

"No amount of great animation will save a bad story." -- John Lasseter of Pixar

User avatar
SusanTheCat
Miko-Class Veteran
Posts: 952
Joined: Mon Dec 13, 2010 9:30 am
Location: New Brunswick, Canada
Contact:

Re: Hidden Object Code

#12 Post by SusanTheCat » Sat Aug 20, 2011 8:20 am

That is so gorgeous!

I'll check the code to see what I can do for introductions, etc.

Susan
" It's not at all important to get it right the first time. It's vitally important to get it right the last time. "
— Andrew Hunt and David Thomas

User avatar
OokamiKasumi
Eileen-Class Veteran
Posts: 1775
Joined: Thu Oct 14, 2010 3:53 am
Completed: 14 games released -- and Counting.
Organization: DarkErotica Games
Deviantart: OokamiKasumi
Location: NC, USA
Contact:

Re: Hidden Object Code

#13 Post by OokamiKasumi » Sat Aug 20, 2011 7:19 pm

Alex was kind enough to figure out what needed adjustment so I could use a splash screen and put in an opening scene. In other words, use this code as a mini game inside a story.
http://lemmasoft.renai.us/forums/viewto ... 78#p151952

Turns out that the problem was this bit:

Code: Select all

init python:
    class Item:
        def __init__(self, name, x,y,w,h):
            self.name = name
            self.x = x
            self.y = y
            self.w = w
            self.h = h
            self.found = False
            
    showitems = True
showitems needed to be set to False to allow a splash screen (or anything else,) to run before the game started.

Code: Select all

init python:
    class Item:
        def __init__(self, name, x,y,w,h):
            self.name = name
            self.x = x
            self.y = y
            self.w = w
            self.h = h
            self.found = False
            
    showitems = False
Then, right before the screen was called, set it to True.

Code: Select all

label parlor_game:    

    $ game = renpy.time.time()
    $ resetItems(parlor_items)
    $ hidden_files = "parlor_%s.png"
    $ hidden_items = renpy.random.sample(parlor_items,8)
    
    $ showitems = True
    call screen hidden_object
    
    scene bg parlor
    $ elapsed = (renpy.time.time() - game)
    "Result: %(_return)s in %(elapsed)d seconds!" 
Ookami Kasumi ~ Purveyor of fine Smut.
Most recent Games Completed: For ALL my completed games visit: DarkErotica Games

"No amount of great animation will save a bad story." -- John Lasseter of Pixar

User avatar
SusanTheCat
Miko-Class Veteran
Posts: 952
Joined: Mon Dec 13, 2010 9:30 am
Location: New Brunswick, Canada
Contact:

Re: Hidden Object Code

#14 Post by SusanTheCat » Tue Sep 06, 2011 7:12 pm

Added Hint Functionality:

For hints:
The Hint image is *_selected_idle
set num_hints > 0

Added current number of hints to item list

Susan
Attachments
Hidden Object Test.zip
(4.5 MiB) Downloaded 64 times
" It's not at all important to get it right the first time. It's vitally important to get it right the last time. "
— Andrew Hunt and David Thomas

User avatar
OokamiKasumi
Eileen-Class Veteran
Posts: 1775
Joined: Thu Oct 14, 2010 3:53 am
Completed: 14 games released -- and Counting.
Organization: DarkErotica Games
Deviantart: OokamiKasumi
Location: NC, USA
Contact:

Re: Hidden Object Code

#15 Post by OokamiKasumi » Wed Sep 07, 2011 2:07 am

Thank you so much, but although I copy-pasted your code in, something isn't quite right.

Code: Select all

I'm sorry, but an uncaught exception occurred.

While executing init code:
  File "game/screens.rpy", line 510, in script
    init -2 python:
  File "game/screens.rpy", line 555, in python
        parlor_items.append(Item("landscape,", 852,241,128,189))
  File "game/screens.rpy", line 549, in python
                self.hint = hint
NameError: global name 'hint' is not defined

-- Full Traceback ------------------------------------------------------------

Full traceback:
  File "I:\!Kenetic Novels\RenPy\renpy-6.12.2\renpy\execution.py", line 261, in run
  File "I:\!Kenetic Novels\RenPy\renpy-6.12.2\renpy\ast.py", line 630, in execute
  File "I:\!Kenetic Novels\RenPy\renpy-6.12.2\renpy\python.py", line 974, in py_exec_bytecode
  File "game/screens.rpy", line 555, in <module>
  File "game/screens.rpy", line 549, in __init__
NameError: global name 'hint' is not defined

Windows-post2008Server-6.1.7601-SP1
Ren'Py 6.12.2.1531
 
This is the code I'm using.

On the Screens page:

Code: Select all

#Hidden Object Game

screen hidden_object:
    tag hidden
    
    imagemap:
        auto hidden_files
        textbutton "Hint" xalign 1.0 yalign 0.0 action getHint()
        for index, item in enumerate(hidden_items):
            hotspot (item.x,item.y,item.w,item.h) action If(hidden_items[index].found==False, SetItem(hidden_items[index],"found",True), None)
        if is_all_found():
            textbutton "All Objects Found!" xalign 0.5 yalign 0.5 action Return("Completed") 
            
init -2 python:
    
    class getHint(Action):
        
        def __call__(self):
            global num_hints
            num_hints -= 1
            for index,i in enumerate(hidden_items):
                if i.found == False and i.hint == False:
                    i.hint = True
                    break
            renpy.restart_interaction()
            
        def get_sensitive(self):
            global num_hints
            return num_hints > 0
    
    class SetItem(Action):
        
        def __init__(self, object, field, value):
            self.object = object
            self.field = field
            self.value = value
        
        def __call__(self):
            setattr(self.object, self.field, self.value)
            renpy.restart_interaction()

        def get_selected(self):
            return getattr(self.object, "hint") == True
    
    class Item:
        def __init__(self, name, x,y,w,h):
            self.name = name
            self.x = x
            self.y = y
            self.w = w
            self.h = h
            self.found = False
            self.hint = hint
            
    showitems = False
    config.imagemap_cache = False
    
    parlor_items = []
    parlor_items.append(Item("landscape,", 852,241,128,189))
    parlor_items.append(Item("phonograph,", 834,493,149,183))
    parlor_items.append(Item("hat,", 782,407,78,73))
    parlor_items.append(Item("cake,", 786,615,50,36))
    parlor_items.append(Item("phone,", 721,492,105,85))
    parlor_items.append(Item("tick-tock,", 656,379,122,91))
    parlor_items.append(Item("fish,", 684,155,104,47))
    parlor_items.append(Item("boxing,", 611,244,60,128))
    parlor_items.append(Item("cane,", 589,366,29,148))
    parlor_items.append(Item("horse,", 355,501,244,171))
    parlor_items.append(Item("tea,", 295,486,75,43))
    parlor_items.append(Item("bottle,", 371,287,42,95))
    parlor_items.append(Item("car,", 220,164,122,60))
    parlor_items.append(Item("perfumes,", 285,562,69,52)) 
    parlor_items.append(Item("books,", 183,580,101,98))
    parlor_items.append(Item("cheese,", 74,631,87,48))
    parlor_items.append(Item("pillow,", 161,465,114,93))
    parlor_items.append(Item("vase,", 38,556,36,122))
    parlor_items.append(Item("Lady and Gent,", 36,244,136,182))
    
    parlor_special = Item("kitten,", 54,492,68,63)


    def display_items_overlay():
              
        if showitems:
            ui.frame(id="obj_list")
            ui.hbox(id="display_hbox",spacing=5,box_wrap = True)
            ui.text("Hints: %d" % (num_hints))
            ui.text("Items:" )
            for index,i in enumerate(hidden_items):
                inventory_prefix = ""
                inventory_suffix = ""
                item_name = i.name
                item_state = i.found
                if item_state == True:
                    inventory_prefix = "{s}"
                    inventory_suffix = "{/s}"
                item_text = inventory_prefix+item_name+inventory_suffix
                item_index = "object_%d" % (index)
                ui.text(item_text,id=item_index)
            ui.close()
            
    config.overlay_functions.append(display_items_overlay)
    
    def is_all_found():
        for i in hidden_items:
            if i.found == False:
                return False
        return True
        
    def resetItems(in_items):
        for i in in_items:
            i.found = False
On the script page:

Code: Select all

init:
    image bg bedroom = "bedroom_empty.png"
    image bg parlor = "parlor_empty.png"
    image bg study = "study_empty.png"

    image bg wallpaper = "bg_01.jpg" 
    image bg wood = "bg_02.jpg"

    image Miss01 = "Miss01.png"
    image house = "house.png"
    image splash = "splash2.png"
    
    $renpy.music.register_channel("nature", "music", True) 
    $ bedroom = False
    $ study = False

label start:
    
    scene bg wallpaper with fade
    show house with dissolve
    show Miss01 at right with dissolve 
    "I'm glad you stopped by! My house is a little untidy at the moment because I'm looking for something very important. I would be ever so grateful if you could help me find it?"
    "Unfortunately I can't quite remember what it was that I lost."
    "However, I've prepared a list of things it {i}might{/i} be. All you have to do is select the objects on the list at the top of the page. One of them is bound to be what I'm looking for."
    "Oh, one more thing...!"
    "I'm kind of in a hurry, so you're being timed. Thank you so much!"
    
label parlor_game:    
    $ showitems = False
    
    play music "02 - the dragonfly.mp3" fadeout 1.0 
    
    $ game = renpy.time.time()
    $ resetItems(parlor_items)
    $ hidden_files = "parlor_%s.png"
    $ hidden_items = renpy.random.sample(parlor_items,8)
    $ num_hints = 3
    $ hidden_items.append(parlor_special)
    
    $ showitems = True
    call screen hidden_object
    
    scene bg parlor
    $ elapsed = (renpy.time.time() - game)
    "Result: %(_return)s in %(elapsed)d seconds!"          
    $ showitems = False
    
    scene bg wallpaper with fade
    show house with dissolve
    show Miss01 at right with dissolve 
    "Oh dear, what I'm looking for wasn't in the parlor. Shall we look in another room?" 
    
    jump room_choice
    

label bedroom_game:  
    $ bedroom = True
    $ showitems = False
    
    play music "05 - aginst fate.mp3" fadeout 1.0 
        
    $ game = renpy.time.time()
    $ resetItems(bedroom_items)
    $ hidden_files = "bedroom_%s.png"
    $ hidden_items = renpy.random.sample(bedroom_items,10)
    $ num_hints = 3
    $ hidden_items.append(bedroom_special)
    
    $ showitems = True    
    call screen hidden_object
    
    scene bg bedroom
    $ elapsed = (renpy.time.time() - game)
    "Result: %(_return)s in %(elapsed)d seconds!" 
    $ showitems = False
     
    scene bg wallpaper with fade
    show house with dissolve
    show Miss01 at right with dissolve 
    "Oh dear... While we found many important things, what I'm really looking for wasn't in the bedroom either." 
    
    jump room_choice
    
    
label study_game:    
    $ study = True
    $ showitems = False
    
    play music "10 - half moon ball pianosolo version.mp3" fadeout 1.0     
    
    $ game = renpy.time.time()
    $ resetItems(study_items)
    $ hidden_files = "study_%s.png"
    $ hidden_items = renpy.random.sample(study_items,12)
    $ num_hints = 3
    
    $ showitems = True    
    call screen hidden_object
    
    scene bg study
    $ elapsed = (renpy.time.time() - game)
    "Result: %(_return)s in %(elapsed)d seconds!"
    $ showitems = False
    
    scene bg wallpaper with fade
    show house with dissolve
    show Miss01 at right with dissolve 
    "Oh dear... While we found many interesting things, what I'm really looking for wasn't in the study either."
    "I wish I could remember what it was that I lost." 
    
    jump room_choice

label room_choice: 
    
menu:
    "Search the Bedroom?" if bedroom == False:
         jump bedroom_game 
    
    "Search the Study?" if study == False:
         jump study_game  
    
        
         
label end: 
    play music "04 - Calm before.mp3" fadeout 1.0 
    
    scene bg wallpaper with fade
    show house with dissolve
    show Miss01 at right with dissolve
    
    "Thank you so much for helping me search!"
    
menu:
    "Play again?":
        jump start
     
    "No thanks. Show me the credits.":
        jump credits   
    
What did I miss?
Ookami Kasumi ~ Purveyor of fine Smut.
Most recent Games Completed: For ALL my completed games visit: DarkErotica Games

"No amount of great animation will save a bad story." -- John Lasseter of Pixar

Post Reply

Who is online

Users browsing this forum: No registered users