Cross-posted from tumblr

Happy new year! I did a lot of work over xmas. The most impressive thing being the new animated game menu using transforms!

After seeing a couple of tweets from Christine Love last week on game UI design I realised I really wanted to remake the UI to make more use of animations. Then I found out that it’s a bit more annoying than I thought it’d be.

First, the rotating magic circle is pretty simple:

init:
    image circle_spin:
        "gui/magic_circle_white.png"
        xpos -75 ypos -500 alpha 0.5
        parallel:
            pause 0.2
            ease .2 alpha 0.9
            ease .2 alpha 0.7

        parallel:
            linear 60.0 rotate 360
            rotate 0
            repeat

The parallel statement allows you to have two animations that run at the same time. I wanted this so I could have the circle appear to flash briefly on entering the menu (with the alpha change) but not have that interrupt the rotation. This way the first parallel statement only runs through once but the rotation repeats. Rotation is pretty simple - the animation above will take 60sec to rotate through a full 360 degrees then repeat.

The main menu also contains a few more different elements that are layered like this:

screen rc_menu:
    add "menu_multiply"
    add "circle_spin"
    add "menu_bg"
    window:
        imagebutton auto "gui/m_settings_%s.png" action ShowMenu("preferences") xpos 820 ypos 30 focus_mask True at slidein1
        imagebutton auto "gui/m_save_%s.png" action ShowMenu("save") xpos 880 ypos 170 focus_mask True at slidein2
        imagebutton auto "gui/m_load_%s.png" action ShowMenu("load") xpos 900 ypos 220  focus_mask True at slidein3
        imagebutton auto "gui/m_title_%s.png" action MainMenu() xpos 910 ypos 315  focus_mask True at slidein4
        imagebutton auto "gui/m_quit_%s.png" action Quit(confirm=True) xpos 890 ypos 390 focus_mask True at slidein5
        imagebutton auto "gui/m_back_%s.png" action Return() xpos 820 ypos 463 focus_mask True at slidein6

So menu_multiply will be at the bottom, circle_spin on top of that and so on. The slidein transforms aren’t the DRYest code but they work okay for now. Each slidein transform has a timing on it so 1 will come in first, 2 second, and so on:

transform slidein1:
    alpha 0.0
    ease 0.2 alpha 1.0
transform slidein2:
    alpha 0.0
    pause 0.05
    ease 0.2 alpha 1.0
transform slidein3:
    alpha 0.0
    pause 0.1
    ease 0.2 alpha 1.0

They’re called slidein because initially I prototyped a menu that had a horizontally aligned menu where each button slid in from one side of the screen one after the other, but then when I changed to the circular design I opted for a fade in to keep it simpler. In future I might recode these so that the buttons slide out from the middle of the circle.

Over xmas I really started thinking about what I could do to make this game feel more gamelike and realised the most obvious thing: games are all about interactions. So I decided to add more interactions. Here’s one that comes right at the end of the true route that asks you, the player to execute an important action:

Isaac "I'd rather die."
Carter "Fine."

menu:
    "Stab him":
        jump stab_him01

label stab_him01:
    scene cg5 with dissolve
    with flashred
    N "I bring the scissors up above my head and slam them down into his throat."

You’re asked to perform this action 3 more times in order to advance the scene.

Another cool thing I learned about is kind. It’s used when defining characters and can be used to refactor your code like this:

init:
    $ default = Character(None,
        what_prefix="\"",
        what_suffix="\"",
        window_left_padding = 70,
        window_right_padding = 375,
        window_top_padding = 5,
        what_xpos=160,
        what_ypos=-40,
        ctc="ctc_arrow")

    # CHARACTERS
    $ Isaac = Character("Isaac", kind=default)
    $ Doctor = Character("Doctor", kind=default)
    $ Jack = Character("Jack", kind=default)
$ Carter = Character("Carter", kind=default)

Using kind is like using a cookie cutter for characters - you define common parameters in the cutter then only change what’s different in the character that uses it. This is extremely useful when you have a lot of characters with similar parameters and the common parameters might change. Using kind you only need to update these in one place which avoids a load of copypaste errors.

I also learned (or realised) that when you type something like show carter at left, left is just a plain old transform which you can redefine if you want. Since I recently increased the resolution of the game I found the sprites were positioned too far left or right on the new screen size so I made these custom transforms for showing sprites:

transform left:
    xalign 0.25
    yalign 1.0
transform right:
    xalign 0.75
    yalign 1.0
transform farleft:
    xalign 0.1
    yalign 1.0
transform farright:
    xalign 0.9
    yalign 1.0

And that’s it for this week. Hoping I can continue these updates well into the new year.