Page 1 of 2

Hidden Object Code

Posted: Sun Jul 24, 2011 5:33 pm
by SusanTheCat
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

Re: Hidden Object Code

Posted: Sun Jul 24, 2011 6:49 pm
by Camille
This is awesome, thank you! :D

Re: Hidden Object Code

Posted: Sun Jul 24, 2011 11:52 pm
by KimiYoriBaka
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.

Re: Hidden Object Code

Posted: Mon Jul 25, 2011 5:39 am
by SusanTheCat
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

Re: Hidden Object Code

Posted: Tue Aug 16, 2011 9:41 pm
by SusanTheCat
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

Re: Hidden Object Code

Posted: Wed Aug 17, 2011 5:56 am
by Alex
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?

Re: Hidden Object Code

Posted: Fri Aug 19, 2011 10:03 am
by OokamiKasumi
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!

Re: Hidden Object Code

Posted: Fri Aug 19, 2011 7:26 pm
by SusanTheCat
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

Re: Hidden Object Code

Posted: Fri Aug 19, 2011 9:31 pm
by OokamiKasumi
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.

Re: Hidden Object Code

Posted: Fri Aug 19, 2011 9:50 pm
by SusanTheCat
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

Re: Hidden Object Code

Posted: Fri Aug 19, 2011 10:40 pm
by OokamiKasumi
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
Parlor, ground

Re: Hidden Object Code

Posted: Sat Aug 20, 2011 8:20 am
by SusanTheCat
That is so gorgeous!

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

Susan

Re: Hidden Object Code

Posted: Sat Aug 20, 2011 7:19 pm
by OokamiKasumi
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!" 

Re: Hidden Object Code

Posted: Tue Sep 06, 2011 7:12 pm
by SusanTheCat
Added Hint Functionality:

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

Added current number of hints to item list

Susan

Re: Hidden Object Code

Posted: Wed Sep 07, 2011 2:07 am
by OokamiKasumi
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?