renpy/doc/cookbook/CG Gallery

From Ren'Py

Jump to: navigation, search

This extra implements an image gallery, complete with automatic unlocking of the images that have been shown to the user. The images are divided into pages, with a fixed number of images on each page.

To use it, copy the code into a .rpy file into the game directory. There are two parts to the code: A part that should be customized for your game, and a part that it isn't necessary to touch.

# Configuration.
init:

    python:

        # The number of columns and rows of images to show in the
        # gallery.
        store.gallery_cols = 3
        store.gallery_rows = 4

        # The size that each image should be scaled to, and that
        # thumbnails should be.
        store.gallery_width = 160
        store.gallery_height = 120

        # The contents of each of the page. Each of these is a list of
        # tuples with the first component of the tuple being an image
        # filename and the second component being the name of the image
        # that will unlock the image with this filename. (That is,
        # the name that is used in show or scene statements, as a
        # string.)
        #
        # If the third element of the tuple exists, it's a filename
        # corresponding to this image, used for computing the
        # thumbnail by the method given below.
        #
        #
        # The first component may consist of:
        # - A string, which is taken to be an image filename.
        # - A displayable, which is shown to the user.
        # - A tuple, which is used to display multiple of the above.
        # - A list, which is used to show things one after another.
        #
        # When displaying an image as a thumbnail, this code first
        # looks for the file thumbnail_<filename>. If that file
        # exists, it should be a gallery_width x gallery_height
        # thumbnail. Otherwise, a thumbnail is automatically
        # generated, but it may screw up the aspect ratio of the
        # image.
        #
        # You probably want to create thumbnails for most images, to
        # limit memory consumption.
        page1 = [
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ]

        page2 = [
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ( "carillon.jpg", "bg carillon" ),
            ]

        page3 = [
            ( "whitehouse.jpg", "bg whitehouse" ),
            ( "washington.jpg", "bg washington" ),
            ]

        page4 = [
            ( "9a_happy.png", "eileen happy" ),
            ( "9a_vhappy.png", "eileen vhappy" ),
            ( "9a_concerned.png", "eileen concerned" ),
            ]

        # This is the actual list of gallery pages. It's a list
        # of tuples, with the first element being the name of the
        # page, the second being the contents of the page (one of
        # the lists created above), and the third image being the
        # image used as the background of the page.
        store.gallery_pages = [
            ("Backgrounds 1", page1, "washington.jpg"),
            ("Backgrounds 2", page2, "whitehouse.jpg"),
            ("Backgrounds 3", page3, "carillon.jpg"),
            ("Character Art", page4, "washington.jpg"),
            ]

        # A window containing the gallery page buttons.
        style.gallery_pages.xpos = 0.99
        style.gallery_pages.xanchor='right'
        style.gallery_pages.ypos = 0.02
        style.gallery_pages.yanchor = 'top'

        # The button that returns people to the main menu.
        style.gallery_return_button.xpos = 0.99
        style.gallery_return_button.xanchor='right'
        style.gallery_return_button.ypos = 0.98
        style.gallery_return_button.yanchor = 'bottom'

        # Right now, the backgrounds are all solids, but in a more
        # professional version, the insensitive background would
        # probably be a placeholder image that indicates that a
        # picture has yet to be unlocked.
        style.gallery_button.insensitive_background = "#ccc"
        style.gallery_button.idle_background = "#fff"
        style.gallery_button.hover_background = "#ffc"

        style.gallery_button.left_margin = 5
        style.gallery_button.right_margin = 5
        style.gallery_button.top_margin = 5
        style.gallery_button.bottom_margin = 5

        style.gallery_button.left_padding = 5
        style.gallery_button.right_padding = 5
        style.gallery_button.top_padding = 5
        style.gallery_button.bottom_padding = 5


        # The transition used when switching gallery pages.
        store.gallery_transition = Dissolve(0.5)

The following is the code that actually implements the gallery. You need to include it, but you probably don't need to change it.

init -1:

    python:
        style.create('gallery_pages', 'default')
        style.create('gallery_page_button', 'button')
        style.create('gallery_page_button_text', 'button_text')
        style.create('gallery_return_button', 'button')
        style.create('gallery_return_button_text', 'button_text')
        style.create('gallery_button_image', 'default')
        style.create('gallery_image', 'image_placement')
        style.create('gallery_grid', 'default')
        style.create('gallery_button', 'default')


        # The function that actually manages the display of the image
        # gallery.
        def gallery():

            def show_things(what):
                if isinstance(what, tuple):
                    for i in what:
                        show_things(i)

                elif isinstance(what, (str, unicode)):
                    ui.image(what)
                else:
                    ui.add(what)

            page = 0

            while True:

                images = gallery_pages[page][1]
                ui.image(gallery_pages[page][2])

                # Show the names of the various gallery pages.

                ui.window(style='gallery_pages')
                ui.vbox(focus="gallery_pages")

                for i in range(0, len(gallery_pages)):
                    if i == page:
                        clicked = None
                    else:
                        clicked = ui.returns(("page", i))

                    ui.textbutton(gallery_pages[i][0],
                              style='gallery_page_button',
                              text_style='gallery_page_button_text',
                              clicked=clicked)
                ui.close()

                # Show the return button.
                ui.textbutton('Return',
                              style='gallery_return_button',
                              text_style='gallery_return_button_text',
                              clicked=ui.returns(("return", None)))

                # Show the grid for this page.
                ui.grid(gallery_cols, gallery_rows, style='gallery_grid')

                # For each grid cell.
                for i in range(0, gallery_cols * gallery_rows):

                    # Fill empty space with nulls.
                    if i >= len(images):
                        ui.null()
                        continue

                    # Otherwise, get the filename and spec and see if
                    # we've unlocked it.
                    if len(images[i]) == 2:
                        filename, spec = images[i]
                        toshow = filename
                    elif len(images[i]) == 3:
                        toshow, spec, filename = images[i]

                    if spec:
                        spec = spec.split()

                    if spec and tuple(spec) not in persistent._seen_images:
                        filename = None
                        clicked = None
                    else:
                        clicked = ui.returns(('show', toshow))

                    # Create the button, containing the appropriate
                    # image or a null if we haven't unlocked it yet.

                    ui.button(style='gallery_button', clicked=clicked)

                    if not filename:
                        ui.null(width=gallery_width, height=gallery_height)
                    else:

                        if renpy.loadable("thumbnail_" + filename):
                            ui.image("thumbnail_" + filename,
                                     style="gallery_button_image")
                        else:
                            ui.add(im.Scale(filename,
                                            gallery_width,
                                            gallery_height))

                ui.close()

                # Interact with the user.
                renpy.transition(gallery_transition)
                cmd, arg = ui.interact(suppress_overlay=True, suppress_underlay=True)

                # Process the user's commands.
                if cmd == "show":

                    if not isinstance(arg, list):
                        arg = [ arg ]

                    for i in arg:
                        ui.add(Solid((0, 0, 0, 255)))
                        show_things(i)
                        ui.saybehavior()
                        renpy.transition(gallery_transition)
                        ui.interact(suppress_overlay=True, suppress_underlay=True)

                if cmd == "page":
                    page = arg

                if cmd == "return":
                    renpy.transition(gallery_transition)
                    return


        library.main_menu.insert(2, ("CG Gallery", ui.jumps("gallery"), 'True'))


label gallery:

    $ gallery()

    jump _main_menu
Personal tools