Implementing the Sudokumaster layout

Dynamic layout control in Sudokumaster involves two steps:

  • Detecting the current screen resolution at start-up and detecting orientation changes during runtime

  • Setting the correct layout for the current screen resolution and orientation

Detecting the current screen resolution and orientation

Sudokumaster uses a stage listener that detects the screen resolution at application start-up and monitors the stage for orientation changes during application runtime. Orientation changes are detected by monitoring the SWF stage size, which equals the screen resolution when in full screen mode.

The listener monitors the stage for onResize events, which are triggered when the stage is resized (the resolution changes). Calling the FullScreen command of the fscommand2() method also triggers an onResize event, which is how the listener detects the resolution at start-up. When an onResize event is triggered, the listener calls the adjustLayout() method to set the correct layout for the new resolution.

Note: onResize events are only detected when Stage.scaleMode is set to "noScale".

The following ActionScript 2.0 code implements the stage listener in Sudokumaster:

function initSizeListener():Void {
    // Add size listener
    var sizeListener:Object = new Object();
    sizeListener.onResize = function() {
        //display correct layout according to screen size [layout.as]
        adjustLayout();
    };
    Stage.addListener(sizeListener);
}

For the full source code covering the stage listener implementation, see file listener.as in the Sudokumaster package.

Setting the correct layout

In Sudokumaster, the layout for each supported screen resolution is defined in its own state frame on the stage. Each layout has its own configuration of the common layout placeholders, positioned and scaled according to the layout design for the corresponding resolution. When the stage is resized, either at start-up or during runtime, the adjustLayout() method moves the playhead to the correct frame for the new resolution, allowing the application to load the layout defined in that frame. If the new resolution is 240 x 320 pixels, for example, the adjustLayout() method jumps to frame 240x320 and the layout is restructured according to the placeholders in that frame.

The following figure shows the layout frames on the timeline in Adobe Flash and the placeholder configurations for two layouts (resolutions).

Figure: Layout frames in Adobe Flash with two example placeholder configurations

Defining each layout in its own, clearly labelled frame is an intuitive solution that makes it possible to quickly inspect and evaluate the layout design for each resolution. The solution also makes it easy to modify the layouts when a better design is created or when a particular layout does not perform well on a device.

Setting a layout involves repositioning and scaling the UI elements according to the layout placeholders. In addition, the placeholders themselves need to be hidden, so that they are not visible to the user. For each layout, Sudokumaster performs the following actions at the beginning of the frame (corresponding method in parentheses):

  1. Hide the layout placeholders, so that they are not visible to the user on the device screen (hideLayoutPlaceholders()).

  2. Reset the UI elements in case any of them needs to be adjusted before repositioning and scaling (resetComponents()).

  3. Move each UI element on the stage to the X and Y coordinates of its placeholder (placeComponents()).

  4. Set the correct element state for the game information element (setComponentLayout()). This must be done before the element is scaled, because the target size can only be known after the correct state is selected. The game information element uses state frames to adjust its proportions for different layouts.

  5. Resize each UI element to fit into its placeholder (adjustComponents()). This mostly involves scaling the UI element so that its dimensions match the dimensions of its placeholder.

  6. Redraw the UI elements in case any of them needs initialization (initializeComponents()).

The following ActionScript 2.0 code is run at the beginning of frame 240x320 and sets the layout for the 240 x 320 pixel resolution:

stop();

hideLayoutPlaceholders();
resetComponents();
placeComponents();

setComponentLayout(gameinfo, "VERTICAL");

adjustComponents();
initializeComponents();

The following figure shows the contents of frame 240x320 as it is shown on the stage in Adobe Flash (left) and on a device screen after application start-up (right).

Figure: Contents for the 240 x 320 pixel resolution in Adobe Flash and on a device screen

For the full source code covering the layout implementation, see files SudokuMaster.fla and layout.as in the Sudokumaster package.