Create a 3D Flight Simulator App for iOS and Android - Simulator Programming

In this tutorial series, we will create a flight simulator application using ShiVa3D Suite. In order to build this application, we will cover all the topics necessary for creating 3D games, educational applications, and novelty 3D apps. This tutorial, part 3 of the series, will focus on programming the simulator functions.


Also available in this series:

  1. Create a 3D Flight Simulator App for iOS and Android - Theoretical Overview
  2. Create a 3D Flight Simulator App for iOS and Android - Environment Creation
  3. Create a 3D Flight Simulator App for iOS and Android - Simulator Programming
  4. Create a 3D Flight Simulator App for iOS and Android – Project Export

Enter Code For MainAI

Before entering the code for MainAI, let us first introduce the basic concepts of Handler and Function in the Shiva3D environment. (this follows the Shiva3D Editor help documentation).

  • A handler is a method to process a particular event, e.g. sent by a user or the game engine.
  • A function is a 'private' method that is accessible via other functions or handlers.

Two important handlers are onInit and onEnterFrame. Those are built-in handlers, in other words, they always exist and are called by the game engine as needed. By default, a built-in handler has no statements in its body.

The onInit handler is called once when the application starts. This is where you would do necessary initialization tasks. The onEnterFrame handler is called at every frame of the game. In the Simulator, onEnterFrame calls various other functions for particular tasks, like moving the plane forward.

The following three handlers, which are also built-in handlers, work in conjunction:

  • onTouchSequenceBegin handler notifies the application that the touch events have started.
  • onTouchSequenceChange handler provides detailed information about the number of touches on the screen by user and the coordinates of each touch.
  • onTouchSequenceEnd handler notifies the application when the touch event ends.

For those touch event handlers to work, multitouch must be enabled in the application via input.enableMultiTouch(). This is done in the onInit handler.

In the Simulator, in addition to the built-in handlers we also have several custom handlers.

  • onRestart is the entry point when the application needs to be restarted. It displays a descriptive message on the screen notifying the user that the application is restarting. It then queues an event to call the onRequestRestart handler below, to actually restart the application.
  • onRequestRestart handler restarts the application.
  • onManeuverRequest is an event handler called by the HUD buttons on the screens. It interprets the input parameter as one of up, down, left or right and then calls the appropriate function to start the maneuver.

Having discussed the handlers in the Simulator, a summary of the functions are given below.

  • displayMessage function displays a message on the screen. The message is passed as an input parameter.
  • reset function resets the variables used in onTouchSequenceChange handler.
  • startBanking function starts a banked turn maneuver to left or right.
  • startPitching function starts a pitch maneuver up or down.
  • bank function performs a particular succession of a banked turn maneuver at each frame.
  • pitch function performs a particular succession of pitch maneuver at each frame.
  • move function moves the plane at each frame.

For individual details of each of the methods, please see the comments in method definitions.

The following is a list of global variables used by the functions and handlers in our code.

  • counter is a variable used to keep track of sequence of movements during pitch or banked turn maneuvers.
  • dP is a constant that determines rate of change of the pitch angle, mainly used in pitch() function.
  • dR is a constant that determines rate of change of the bank and yaw angles, mainly used in bank() function.
  • prevTouchCount stores number of screen touches received previously and is needed to compare that variable to the current number of screen touches received in onTouchSequenceChange event handler.
  • prevX0 and prevY0 are used in the onTouchSequenceChange event handler to determine direction of user's thumb movement.
  • V is a constant and represents speed of the plane.
  • yg stores the rotation of the plane around the global Y axis.
  • isAppRestarting is a boolean. It is set to true when application restart operation is initiated.
  • isBanking is a boolean. It is set to true when the plane starts making a banked turn maneuver.
  • isBankingLeft is a boolean. It is set to true when the plane starts making a banked turn maneuver to left.
  • isBThresholdReached is a boolean. It is set to true if the plane is currently making a banked turn and has reached a maximum absolute value of the bank angle (either left or right).
  • isPitching is a boolean. It is set to true when the plane starts making a pitch maneuver.
  • isPitchingUp is a boolean. It is set to true when the plane starts making a pitch maneuver upwards.
  • isPThresholdReached is a boolean. It is set to true when the plane is currently making a pitch maneuver and has reached a maximum absolute value of the pitch angle (either up or down).

Now, we are ready to enter the code. Bring up the AIModel editor. In Data Explorer AIModel's folder, double click MainAI. The MainAI is now loaded in the AIModel Editor as shown below:


In the Variables section click on Add Variable. In the Variable dialog, name the variable counter, select its type as number and set the init value as 0, as shown below (For number types, even if you enter an Init Value of 0, the value will show up as a float, that is, with decimals).


Press OK to create the variable. In a similar way, create the other variables.

  • Name: dP
  • Type: number
  • Init Value: 0.040
  • Name: dR
  • Type: number
  • Init Value: 0.050
  • Name: prevTouchCount
  • Type: number
  • Init Value: 0
  • Name: prevX0
  • Type: number
  • Init Value: 0
  • Name: prevY0
  • Type: number
  • Init Value: 0
  • Name: V
  • Type: number
  • Init Value: 0.25
  • Name: yg
  • Type: number
  • Init Value: 0
  • Name: isAppRestarting
  • Type: boolean
  • Init Value: false
  • Name: isBanking
  • Type: boolean
  • Init Value: false
  • Name: isBankingLeft
  • Type: boolean
  • Init Value: false
  • Name: isBThresholdReached
  • Type: boolean
  • Init Value: false
  • Name: isPitching
  • Type: boolean
  • Init Value: false
  • Name: isPitchingUp
  • Type: boolean
  • Init Value: false
  • Name: isPThresholdReached
  • Type: boolean
  • Init Value: false

Now, having all the variables created, we will create the functions for the Simulator. In AIModel Editor's Functions section click on Add Function. In the dialog, enter the name as "bank".


Bring up the AIModel Editor and the Script Editor side-by-side. Double-click on the newly created function bank() on the AIModel Editor. In the Script Editor, the skeleton code for the function will be displayed.


Copy the following and paste it into the Script Editor. Press Ctrl+S to save.

In a similar way, create each of the following functions in the AIModel Editor and copy and paste the corresponding code in the Script Editor. Press Ctrl+S to save after creating each function.

displayMessage

move

pitch

reset

startBanking

startPitching

Having created the functions, now we will create the handlers. In the AIModel Editor, under the Handlers section click on Add Handler. In the menu, choose Custom:


In the text field, enter ManeuverRequest. Because of the preceding 'on', the name of the handler will be onManeuverRequest:


In Script Editor, copy and paste the following for the code of onManeuverRequest handler. Make sure to save the code via Ctrl+S:

In a similar way, create each of the following custom handlers in the AIModel Editor and copy and paste the corresponding code in the Script Editor. Press Ctrl+S to save after creating each handler.

onRequestRestart

onRestart

We will create several more handlers. However, those are built-in handlers in Shiva3D, rather than custom handlers. In the Handlers section, click on Add Handler and select onInit from the menu.


Copy and paste the following code for onInit handler in Script editor. Save the code via Ctrl+S.

Now, we will create onEnterFrame handler. In the Handlers section, click on Add Handler and select onEnterFrame from the menu.


Copy and paste the following code for onEnterFrame handler in Script editor. Save the code via Ctrl+S.

Three more handlers are left, onTouchSequenceBegin, onTouchSequenceChange, and onTouchSequenceEnd, which are all user handlers. In the Handlers section, click on Add Handler. In the menu, select User Handler -> onTouchSequenceBegin.


In a similar way, create the other two handlers, onTouchSequenceChange and onTouchSequenceEnd. Now, in the AIModel editor, double click on the onTouchSequenceBegin handler. Copy and paste the following code in the Script Editor for the corresponding code.

Similarly, copy and paste the following code for onTouchSequenceChange and onTouchSequenceEnd, respectively.

onTouchSequenceEnd

Having created all the code we need, click inside the Script Editor and press F7 to compile. You should see 0 errors and 0 warnings, as below.


Create The Control Buttons

There are a few other UI elements we need to create before we start playing the Simulator. Those are the buttons displayed on top of the screen. We will create those buttons and hook them up with some of the previously created event handlers using the HUD Editor. There are three main steps we will follow:

  • Using the HUD Editor, we will create a template that consists of the buttons. This step has two sub-sections in it:
    • For every button, define an action to take place, i.e. an event to fire. When the button is pressed, specify the event handler to handle that event.
    • Create each button, specify its visual attributes, and associate it with the corresponding action created.
  • We will then add the newly created buttons template to the Simulator game.
  • Finally, in our code we will initiate an instance of the buttons template. This is already done in the onInit handler (see the section named 'Enter Code For MainAI' above). Note that the onInit handler successfully compiled when we created the code even though the template it referenced did not exist at the time. This is because the template was referenced by its name and the compiler only checks the correct call syntax not the existence of the template with the referenced name. However, had we attempted to run the code without the template actually existing, we would get a run time error.
Create The Buttons Template

Bring up the HUD Editor. From HUD menu, select Create.


Name the template buttons.


Right click on Actions, select Add Action.


Name the action goDownAction.


Right click on goDownAction and select the Add Command.


In the Action Command dialog, select

  • Command type: SendEventToUser
  • User: RuntimeValue CurrentUser
  • AIModel: String MainAI
  • Event: String onManeuverRequest
  • Call Parameter0: String D

Press OK. You should see the following in HUD Editor.


Similar to above, create the actions goUpAction, leftTurnAction and rightTurnAction, with the only difference being value of the Call Parameter0. You should use string values U, L and R for goUpAction, leftTurnAction and rightTurnAction, respectively.

The final Action we need to create is restartAction. This is created similarly to above with the only exceptions that the Event is onRestart and there are no Call parameters.


With all the actions created, you should see the following in the HUD Editor.


Now we will create the button components to utilize those actions. Right click on Components and select Add Component.


Name the component goDown. In the General section, select the type as Button. Set the position as 64 and 88. Set the size as 11 and 19. Do not change the other selections.


Select the Appearance section. Set the shape to be RoundRectangle. In BackTexture, select top_crop. Let Opacity be 100. Change the ForeColor and BorderColor values as seen below.


Note: Setting opacity to 100 makes the button semi-transparent. We also let the top_crop.jpg be the background image for the button. This and the semi-transparency of the button creates a blending effect for the button and the sky.

Select the Button section. Type D in the Text area. Make the following changes and press OK.

  • Text Height: 85
  • Text Alignment: Center Center
  • Click Action: goDownAction.

Repeat the steps above to create the following components (buttons).

  • Name: goUp
  • General section
    • Type: Button
    • Position: 36 and 88
    • Size: 11 and 19
  • Appearance section:
    • Shape RoundRectangle
    • Opacity 100
    • BackTexture: top_crop
    • BackColor: 127 127 127
    • ForeColor R:255 G:0 B:0
    • BorderColor: R:0 G:127 B:0
  • Button Section:
    • Text: U
    • Text Height: 85
    • Text Alignment: Center Center
    • Click Action: goUpAction
  • Name: leftTurn
  • General section
    • Type: Button
    • Position: 7 and 88
    • Size: 11 and 19
  • Appearance section:
    • Shape RoundRectangle
    • Opacity 100
    • BackTexture: top_crop
    • BackColor: 127 127 127
    • ForeColor R:255 G:0 B:0
    • BorderColor: R:0 G:127 B:0
  • Button Section:
    • Text: L
    • Text Height: 85
    • Text Alignment: Center Center
    • Click Action: leftTurnAction
  • Name: rightTurn
  • General section
    • Type: Button
    • Position: 93 and 88
    • Size: 11 and 19
  • Appearance section:
    • Shape RoundRectangle
    • Opacity 100
    • BackTexture: top_crop
    • BackColor: 127 127 127
    • ForeColor R:255 G:0 B:0
    • BorderColor: R:0 G:127 B:0
  • Button Section:
    • Text: R
    • Text Height: 85
    • Text Alignment: Center Center
    • Click Action: rightTurnAction
  • Name: restart
  • General section
    • Type: Button
    • Position: 50 and 88
    • Size: 11 and 19
  • Appearance section:
    • Shape RoundRectangle
    • Opacity 100
    • BackTexture: top_crop
    • BackColor: 127 127 127
    • ForeColor R:255 G:255 B:0
    • BorderColor: R:255 G:255 B:0
  • Button Section:
    • Text: Re
    • Text Height: 85
    • Text Alignment: Center Center
    • Click Action: restartAction
Add The Buttons Template To The Simulator

Now, we have to add the newly created buttons template to the Simulator. Bring up Game Editor and Data Explorer side by side. In Data Explorer, under the Games folder double click on Simulator. The game is loaded in Game Editor. Select the Resources tab in Game Editor. You should see that it is empty.


In Data Explorer, open the HUD folder under Resources folder. You will see that the newly created buttons template is there.


Now, drag and drop buttons from HUD folder into the Resources tab in Game Editor.


Add Default Font

We need to add to the Simulator game a font. The font is needed because we display text messages on the screen and also the control buttons have text in them. ShiVa Editor provides a default font which should be sufficient for our purposes. While the Resources tab in Game Editor is open, in Data Explorer open the Fonts folder under Resources folder. You should see the DefaultFont.


Drag and drop DefaultFont from Fonts folder into the Resources tab in Game Editor.


Unit Testing

Everything must be ready to perform a unit test. From the Shiva Editor top level menu, select Preview.


From the display menu, select View Mode -> Runtime.


From the display menu, select Size -> Android -> 480x800. (You could select other display sizes; 480x800 is an example.)


In the top menu, press on the start button (or simply hit F9) to start Simulator game.


You should see that the Simulator will start as seen below.


Note: If, at any point during preview, you need to make changes, stop the game by pressing the stop button. After making the changes, press the Restart button and then press the Start button again. The stop and restart buttons are shown below.



Closing Remarks

Part 3 continued with adding the code and unit testing the end product. In part 4, the last installment of the series, we will export the application from the ShiVa Editor and import into the ShiVa Authoring Tool. Then, we will explain how to convert the application into a platform specific executable via the ShiVa Authoring Tool. The platforms we will consider are Android, iPad and iPhone. We will give screen images of the Simulator from actual devices used for testing, a Motorola Droid phone with Android OS 2.2, an iPad2 with iOS 4.3 and an iPod Touch with iOS 4.3. Finally, in 'Concluding Remarks', we will give conclusions of the series.

Tags:

Comments

Related Articles