App – The Eye in the Sky


The App object is basically the great eye-in-the-sky controller of the game engine that controls the game logic, rendering update and handling of various events such as input. The App takes care of many things including::

  • Manages global resources
  • Manages a collection of Scenes
  • Manages a collection of Action Lists
  • Handles touch input and keyboard
  • Finds which Actor was touched when user touches the screen
  • Logic loop processing
  • Rendering
  • Manages global animation Timelines via a TimelineManager
  • Controls rescaling of canvas to best fit to different display sizes
  • Tracks time and measures frame rate


Creating the App

The first task that must be carried out when developing a game with Booty5 is create the main app (The App) object. This object is the main game controller and takes care of processing the entire game. Below is a short piece of example code showing how to set up the app:

In the above code we assign a new function to the windows onload event, so it is called once the page has finished loading. Within our onload function we begin by creating an instance of the main app object (App) passing in a reference to the HTML5 canvas that will receive the apps rendering (we created a canvas in our HTML5 page index.html). Note that you can gain a reference to the canvas at any point via b5.App.canvas.

We assign the created app object to because some areas of Booty5 look there for it later.

We set up a number of initial properties of the app such as no debugging, a target frame rate to aim for, no canvas clearing to save a bit of rendering time and the method of scaling that will be used to fit the canvas to the screen.

Finally we start the app going so that the game can play.

We can set up various properties of the app before calling start() to modify how the app behaves. A complete list of those features are listed below:

  • debug – If set to true then debug information will be output to the console
  • target_frame_rate – The rate at which to update game logic, pass 0 for variable
  • clear_canvas – If set to true then the canvas background will be cleared each frame before the next frame is drawn
  • canvas_scale_method – Set via setCanvasScalingMethod() sets how the HTML5 canvas will be scaled to fit the browser window
  • allow_touchables – If true then app will search to find Actors that were touched y the user, this can be disabled in apps that have no use for touch input
  • adaptive_physics – If true then physics update will be ran more than once per frame if frame rate falls much below target frame rate
  • loading_screen – An object that contains properties that affect how the loading screen appears
  • use_web_audio – If set to true then Booty5 will attempt to use the Web Audio API to play audio, if not available then it will fall back to standard HTML5 audio


Game Logic and Rendering

Most games have a main loop that runs game logic. The main logic loop is the central heart beat of the game and is often responsible for updating the game world, game objects, reading input, and so on.

Most games also have a second main loop called the render loop. The render loop defined by App.mainDraw() is ran as often as is possible via requestAnimationFrame().

Logic and rendering are decoupled in Booty5 to allow the games logic loop to be updated at a different rate to the display.

Booty5 runs both main loops separately, the game logic loop is ran on a timer at a rate determined by App.target_frame_rate, executing code that is ran in Scene / Actor update code. The game rendering loop is ran as fast as the browser window can update and executes code that is part of the App / Scene / Actor draw cycle.

Game logic is processed by b5.App.mainLogic() using b5.App.timer, whilst game rendering is processed by b5.App.mainDraw() using requestAnimationFrame().


The Main Canvas

Booty5 has to be able to render its content to a variety of different screen sizes, catering for a huge range of different sizes on a size by size basis is impossible. Instead, Booty5 renders to a virtual canvas of a specific size then scales the canvas to fit to the browser window. So for example, we can render to a fixed sized canvas of 1200×800 but have Booty5 scale that canvas to best fit the target device display. In Booty5 world the virtual canvas is the fixed size that the game will render to. This enables you to lay out your game levels and art work to fit a specific virtual resolution, saving heaps of time and money.

The following canvas fit options are available:

  • b5.App.FitNone- No scaling or resizing of the HTML5 canvas will occur
  • b5.App.FitX – The HTML5 canvas will be resized to the full size of the display and the virtual canvas will be scaled so that the entire x-axis is fit onto the display
  • b5.App.FitY – The HTML5 canvas will be resized to the full size of the display and the virtual canvas will be scaled so that the entire y-axis is fit onto the display
  • b5.App.FitBest – The HTML5 canvas will be resized to the full size of the display and the virtual canvas will be scaled either on the X or Y axis depending on which axis keeps the most of the information on the display
  • b5.App.FitSize – The HTML5 canvas will be resized to the full size of the display
  • b5.App.FitGreatest – The HTML5 canvas will be resized to the greatest axis of the client window
  • b5.App.FitSmallest – The HTML5 canvas will be resized to the smallest axis of the client window

The main canvas will be cleared each time the game is ready to start rendering the game. If your game covers the entire area of the window then you can disable canvas clearing by setting b5.App.clear_canvas to false, saving a little rendering time.


Working with Resources

Resources that are stored within the main App’s resource lists will persist throughout the lifetime of the app, these resources are known as global resources and are accessible to all other objects within the game.

Booty5 supports the following types of resources:

  • Bitmaps – Bitmap images
  • Brushes – ImageAtlas and Gradients that are used to render game objects
  • Shapes – Shapes that can be used for paths, clipping, rendering and physics fixtures
  • Materials – Physics materials
  • Sounds – Sound effects

When a resource is created its best to add the resource to a resource manager to be managed. Lets take a look at an example that shows how to create a resource and add it to the apps global resource manager:

In the above code we create a physics material then add it to the apps resource manager. Later we can search for this material by calling App.findResource():

Note that as the App can store resources of different types we must specify the type of resource that we wish to find.

If we need to manually destroy a resource at some point in the future then we can either call App.destroyResource() or we can call destroy() on the resource itself, e.g.:

Note that the Booty5 game maker exports a JSON data format called XOML which the Booty5 game engine reads and converts to resources, scenes, actors etc..


Setting up a loading screen

As many HTML5 games are hosted on a server and assets are loaded asynchronously, its usually a good idea to delay game start until all resources have been loaded from the server. During this time it is customary to display a loading screen to provide feedback to the user so they know that the game is doing something and hasn’t crashed.

Booty5 provides a resources loading screen feature out of the box. Calling b5.App.waitForResources() instead of b5.App.start() at the start of the app causes Booty5 to wait for all global and loaded scene resources to load before starting the game engine. In addition, a loading screen will be displayed that shows how far the game data is through being loaded. The loading screen can be customised to your product using the b5.App.loading_screen object. This contains the following properties:

  • background_fill – Loading background fill style
  • background_image – Loading background image
  • bar_background_fill – Loading bar background fill style
  • bar_fill – Loading bar fill style

Lets take a quick look at an example:

Note that only resources that are marked to be preloaded will be included when the app determines which resources should be waited for. None preloaded resources will be loaded when they are first requested.


Working with Scenes

The main purpose of the app is to process and display scenes; scenes are containers for game objects. The main App object contains and manages a collection of scenes. All scenes that are currently loaded will be processed every game logic frame, but only ran if their state is set to active and rendered every render update if their visible state is visible. This system allows you to disable scenes that are not currently in view or not being used, cutting down on overall processing overhead.

Scenes are created and added to the App object using b5.App.addScene(), e.g.:

Once the scene is added to the app the app will begin processing and rendering it. When we are done with a scene we can remove / destroy it by calling b5.App.removeScene(), e.g.:

You can also remove / destroy a scene by calling destroy() on the scene object:

Note that the scene will not be removed until the end of the apps processing loop.

You can search for scenes by name using b5.App.findScene();


Handling App Events

The App takes care of receiving and passing on a variety of input events that it receives such as touch and keyboard events.

At any given time, only a single scene can have the primary focus (App.focus_scene), any events that are received are passed on to this scene and its contained actors. A secondary focus scene (App.focus_scene2) can also be specified which will receive touch events. Note that game objects within the secondary focus scene will only receive such events if they are “not” processed by an actor in the primary focus scene.

Note that you can change the focus and secondary focus scenes at any time by simply re-assigning them.

The App currently responds to the following events:

  • touchstart / mousedown – Touch started
  • touchmove / mousemove – Touch moved
  • touchend / mouseup – Touch ended
  • mouseout – Mouse moved out of control
  • keypress – A key was pressed
  • keydown – A key is down
  • keyup – A key is up
  • resize – Window resized, Booty5 will automatically resize the canvas to fit the new size

The App supports a number of properties which allow you to test for certain touch conditions at any time or modify the way the system works:

  • touched – True if a touch has occurred in any scene
  • touch_pos – The last screen position that was touched
  • touch_drag_x and touch_drag_y – The last touch drag delta x and y
  • touch_focus – The actor that currently has touch focus
  • touch_supported – If touch is supported then this property is set to true
  • allow_touchables – Setting this property to false will disable checks for touching actors globally


Working with Variable Frame Rates

Its essential when creating games that run across a variety of different speed devices and platforms that we take into account the speed of the device that the game is being played on. (in game development terms we usually refer to this measurement as frame rate and is measured in frames per second or fps for short) The app tracks how much time the last game logic frame took to update so we know how fast our next frame will run. Knowing this information we can adjust how fast things move to ensure that the game play seems consistent and fluid.

The app automatically tracks how long the last game frame took to render via b5.App.dt (delta time), this value, measured in seconds is also passed on to all scenes, actors, timelines and anything else that relies on time synchronisation. All movement and animation is scaling by this value to ensure that it plays back at a consistent speed regardless of frame rate.

The app also measures the average frame rate in fps via b5.App.avg_fps, measured every 60 frames. You can use this value to determine how fast the device is that you are running your game on. This value is also used with adaptive physics (b5.App.adaptive_physics) which when set to true will run the physics system multiple times during a single game frame to help ensure that constant time step physics behaves better at lower frame rates (it attempts to match the value set in b5.App.target_frame_rate).


Next Topic:


6,185 total views, 1 views today