Question

In Rebol3 Saphir, I am writing a game and I had been poking about with the event handler functionality as well as actors, and I was wondering whether it would be a better idea to use an event handler to take keyboard controls for the game or to add an actor into one of the GUI elements.

If I use an actor, on what level? I'm currently using an image! type for the screen. Can I add an actor to the root(layout) face so even if I click (give focus) to a button also on the GUI the focus will be off the image and it won't take keyboard controls.

Was it helpful?

Solution

Below is an example how you could do it...You might also use just the built-in keyboard shortcuts feature if you don't need key-up events. In such case see example with shortcut keys here: https://github.com/saphirion/documentation/blob/master/r3/r3-gui/examples/layouts/layout-15.r3

This version is modified to work with the current (09/26/13) release of R3-GUI

REBOL [
    author: "cyphre@seznam.cz"
]

load-gui

;image for game screen
img: make image! 400x400

;just some example game object
game-object: context [
    offset: 0x0
    draw-block: [
        pen red
        fill-pen white
        line-width 5
        circle offset 20
    ]
    move: func [
        delta [pair!]
    ][
        offset: offset + delta
        img/rgb: black
        ;note: this is not optimal way how to render DRAW objects
        ;but I use image! here because the asking SO user uses image! as well
        ;better way is to just use DRAWING style for DRAW based graphics
        draw img to-draw draw-block copy []
        draw-face game-screen
        ;signal true move has been executed
        return true
    ]
]

stylize [
    ;backup the original window style to be able call the original key actor
    window-orig: window []

    ;override window style with our key actor
    window: window [
        actors: [
            on-key: [
                ;execute our key controls prior to 'system' key handling
                switch arg/type [
                    key [
                        ;here you can handle key-down events
                        moved?: switch/default arg/key [
                            up [
                                game-object/move 0x-5
                            ]
                            down [
                                game-object/move 0x5
                            ]
                            left [
                                game-object/move -5x0
                            ]
                            right [
                                game-object/move 5x0
                            ]
                        ][
                            false
                        ]
                    ]
                    key-up [
                        ;here you can handle key-up events
                    ]
                ]
                ;for example filter out faces that shouldn't get the system key events (for example editable styles)
                 unless all [
                    moved?
                    guie/focal-face
                    tag-face? guie/focal-face 'edit
                 ][
                    ;handle the system key handling
                    do-actor/style face 'on-key arg 'window-orig
                ]
            ]
        ]
    ]
]

view [
    title "Custom keyboard handling (whole window)"
    text "press cursor keys to move the box"
    game-screen: image options [min-size: 400x400 max-size: 400x400]
    text 400 "focus the field below and press to see these keys are filtered out, but other keys works normally"
    field "lorem ipsum"
    when [enter] on-action [
        ;initialize game object
        game-object/move 200x200
    set-face game-screen img
    ]
]

This version uses an as-of-yet unreleased version of R3-GUI:

REBOL [
    author: "cyphre@seznam.cz"
]

;image for game screen
img: make image! 400x400

;just some example game object
game-object: context [
    offset: 0x0
    draw-block: [
        pen red
        fill-pen white
        line-width 5
        circle offset 20
    ]
    move: func [
        delta [pair!]
    ][
        offset: offset + delta
        img/rgb: black
        ;note: this is not optimal way how to render DRAW objects
        ;but I use image! here because the asking SO user uses image! as well
        ;better way is to just use DRAWING style for DRAW based graphics
        draw img to-draw draw-block copy []
        draw-face game-screen
        ;signal true move has been executed
        return true
    ]
]

stylize [
    ;backup the original window style to be able call the original key actor
    window-orig: window []

    ;override window style with our key actor
    window: window [
        actors: [
            on-key: [
                ;execute our key controls prior to 'system' key handling
                switch arg/type [
                    key [
                        ;here you can handle key-down events
                        moved?: switch/default arg/key [
                            up [
                                game-object/move 0x-5
                            ]
                            down [
                                game-object/move 0x5
                            ]
                            left [
                                game-object/move -5x0
                            ]
                            right [
                                game-object/move 5x0
                            ]
                        ][
                            false
                        ]
                    ]
                    key-up [
                        ;here you can handle key-up events
                    ]
                ]
                ;for example filter out faces that shouldn't get the system key events (for example editable styles)
                 unless all [
                    moved?
                    guie/focal-face
                    tag-face? guie/focal-face 'edit
                 ][
                    ;handle the system key handling
                    do-actor/style face 'on-key arg 'window-orig
                ]
            ]
        ]
    ]
]

view [
    title "Custom keyboard handling (whole window)"
    text "press cursor keys to move the box"
    game-screen: image img options [min-size: 400x400 max-size: 400x400]
    text 400 "focus the field below and press to see these keys are filtered out, but other keys works normally"
    field "lorem ipsum"
    when [enter] on-action [
        ;initialize game object
        game-object/move 200x200
    ]
]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top