Click here to Skip to main content
Click here to Skip to main content
Go to top

Intel x86 Android Game Development using RAD

, 7 Feb 2013
Rate this:
Please Sign up or sign in to vote.
Design of an x86 Android game that is cross-platform compatible


The .zip file also contains the compiled "MonkeyGame-debug.apk" binary that can be run in the emulator. There is an HTML5 build in the folder "game.build". To test the game run the MonkeyGame.html in the Chrome browser.

Introduction 

There are several RAD cross-platform game development tools/engines  that have support for Android on x86 as listed here http://software.intel.com/en-us/blogs/2012/03/13/game-engines-for-android

We will be using Monkey game engine to build a new, NDK-based Android game for Intel® architecture based devices.  It has the advantage of having pre-compiled  NativeGL shared libraries for Android on ARM and x86 architectures or we would have to use the NDK toolchain to re-compile them. You can find these in the "jni" folder in the  accompanying source. The Android packager includes both the x86 and ARM shared libraries in the .apk and during deployment, installs the necessary libs depending on whether the target device is ARM or x86.
The generated .apk is therefore cross-platform compatible  and doesn't need a native re-compile for the two different architectures. 

Background

Memory Game is a variation on the classic game where you uncover cards two at a time to find matching pairs. When all matching pairs have been uncovered the game is over. The objective is to expose all pairs using the least number of moves. A partial deck of playing cards is used in this variation of the game.

Game Features:

  • 24 cards for increased difficulty
  • Animated cards with sound and particle effects
  • Tween based front end 

Technical Features:

  • Game state class
  • Collision class
  • Procedural font generation class 
  • Autofit class using hard coded virtual resolution for scaling to differing actual device aspect ratios and resolutions - very important since Android device fragmentation is a major issue 
  • Tween class
  • Particle engine class 
  • Highscore class
  • Timer class
  •  
    I chose this game as a pedagogic tool for this article because it contains all essential game elements and clearly demonstrates the real-time nature of the game loop and the design principles to be used. It is a 2D game because, for modern touchscreen based mobile devices, interacting with 2D sprites provides for a more intuitive interface. 

Technical Information

Some requirements for rapid prototyping which the engine has:

  • Fast Debug - Compile - Run cycles can be executed in any standards compliant HTML5 browser.
  • The game loop is well defined with OnCreate(), OnUpdate(), and OnRender() methods.
  • The scripting language is object oriented. It has basic language constructs for sprite manipulation and game data structures. Automatic garbage collection.

Using the code

The GameState variable cycles the state machine through its various stages. It is initialized at start to the STATE_MENU. This variable also controls the update and rendering sections of code.

Method SetState (state:Int)
     GameState = state
     Select GameState
           Case STATE_MENU
               //The initial menu layer
           Case STATE_PLAYING
               //The game layer
           Case STATE_PAUSED
               //The game layer paused
           Default
               Print "ERROR: Unknown game state!"
     End
End

Let's check for input and update game state:

In the OnUpdate() Method we call the Card[i].Update() Method of the Collision class. Depending on whether the pointer collides with the card sprite, it returns the visible or hidden state of the card. If two cards have been clicked we increment the tries count.

Case STATE_PLAYING
//check for two card clicks. show cards that were clicked by hiding corresponding cardback
 For Local i : Int = 0 Until NUM_CARDS
  Card[i].Update()
  If Card[i].Pressed = True And Card[i].Visible = True And click < 2 Then 
    Card[i].Visible = False
    savecard[click] = i
    click = click + 1
        If click = 2 Then
        slowdown = Millisecs()
        turns = turns + 1   //increment tries after two cards have been clicked
        End If
    PlaySound boom

   End If                    
 Next

If a matching pair is found we leave those cards uncovered else if the pair doesn't match we make the corresponding cardbacks visible and hide the cards again. The delay of 1.5 seconds permits both cards to be visible long enough for the player to see that they don't match.

If click = 2  Then        
    If coinplace[savecard[0]] = coinplace[savecard[1]] Then  //a matching pair is found
    click =0
    Else            
       If  Millisecs()-slowdown > slowlimit Then  // wait before covering cards again        
      Card[savecard[0]].Visible = True
      Card[savecard[1]].Visible = True
      click =0                          // reset to accept clicks on next two cards
       Endif            
    Endif
End If

Local drawncard:Bool = False
For Local i : Int = 0 Until NUM_CARDS
    If Card[i].Visible = True Then                
    drawncard = True
    End If            
    Next
If drawncard = False Then Restart()    // If no cards are left to uncover End game

When none of the cards will have a backcard covering it because the collision class returns backcard visible state as False, drawncard Boolean will change state to False and the game has ended.

Shake up those cards:

A game without animations isn't much fun. Lets make the eye candy. The int variable n does the magic. n = -1*n toggles n between +1 and -1. The DrawImage() Method has rotation and scaling parameters. We adjust the card sprite rotation between +1 degree and -1 degree to create the vibrating card effect.

//refactored because the renderscreen method appeared to work in the pause state, and halts 
// game update, except for cards vibrating

Method RenderScreen()

     Cls
    
         // for a resolution of 800x600 render cards in 6 columns and 4 rows, starting at 
        // x offset 33 pixels and y offset 30 pixels
     For Local i:Int =  0 Until NUM_CARDS        
      DrawImage coins[coinplace[i]], 33+((i Mod 6)*100), 30 +(Int(i/6)*140)
     Next
                        
    //as n toggle between +-1, the card sprites oscillate(animation) between +-1 degree
    //if collision check returns visible attribute show cardback else hide it
     For Local i : Int = 0 Until NUM_CARDS                        
      If Card[i].Visible = True                         
                     n = -1*n
            DrawImage (card, Card[i].PositionX, Card[i].PositionY, n*1.0, 1.0, 1.0)
      Else
        DrawImage (cardclick, Card[i].PositionX, Card[i].PositionY, 0, 1.0, 1.0)
      End If
     Next
                        
     DrawImage (sidebar, 620, 0)

     DrawImage pointer.image, pointer.x, pointer.y
                        
    font.Draw( turns, 710, 290, 3, 3, 0.5, 1.0 )  //render the procedural font for number of tries
    
End
The code in the download is heavily commented and requires little explanation, however class members and methods are detailed below.
  • MyGame Class :
  • OnCreate() Method : Instantiate game objects - images, sounds, members and variables.
  • OnUpdate() Method : Poll / Interrupt check for mouse/ touchscreen/ keyboard input and change game states and object states accordingly.
  • OnRender() Method : Render graphics depending on game state being Menu, Playing or Paused and the state attributes of game objects.
  • Collision Class : Takes touch/ mouse co-ordinates and colliding sprites and returns a visible or hidden attribute for the corresponding sprite object.
  • Font Class : This is a procedurally generated font. 
  • Tween Class: Tweens sprite objects, easing them in or out using different equations
  • Particle Class: Spawns particles on touch and "deletes" them after the particle life expires
  • Highscore Class: Sorts high scores in ascending or descending order
  • Timer Class: For delays and synchronization  
  • Autofit Class : Provides a hard coded "virtual" resolution and scales the graphics to different screen resolutions (aspect ratios) without causing distortion along x,y screen space co-ordinate axes. Black borders will appear to the left/ right or top/ bottom if
  1. The physical device aspect ratio is different from the "virtual" aspect ratio.
  2. The screen orientation is changed.

Issues Faced

For mobile devices with less horsepower I attempted to implement a particle engine because the integrated particle class is a bit heavy on resources. The compiler didn't like me creating a list of sprite objects at a particular point in the game loop! But I'm sure there's a workaround to it, given time. Finally implemented the particle class. The particle sprites are statically created in the OnCreate() method. Instead of destroying sprite objects after the particle life expires we "remove" them by swapping them dynamically in an array. 

I also sorely missed an integrated debugger. 

Development and Testing

Initial development/ debugging was done in the browser for fast turnaround times. Device testing for scaling and actual run time performance was done on a 1024x600, 7" Android tablet. Final testing was on the x86 AVD in the Android emulator. Although the HTML5 compile was smooth, when testing on the Android target, a null object exception was thrown when returning handles to graphics objects from the collision class, but a suitable workaround was implemented.

Screenshot - game running on x86 AVD in the Android emulator

Credits 

My thanks to all the guys on the Monkey coder forums who were always ready to help out when issues popped up.

Wrapping up

The source code is there for you to play with, and I hope you can take it further in your own games on the x86 Android platform. If any clarification or explanations are required please ask. Also, if you find anything that needs correcting do let me know.

You can play around with the particle engine by changing parameters and use different tweens to see how they work. 

History 

10/11/2012 
1.1.0
- Added highscores and timer class


8/11/2012
1.0.1
- Added tween class - the front end looks snazzier now with the start button easing into place
- Added particle engine class - clicking on a card spawns particles


5/11/2012 
MemoryGame 1.0.0 

 To Do  

- Online global high scores
- Avoid feature creep  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Kurosh F.
Software Developer
India India
No Biography provided

Comments and Discussions

 
QuestionTechnolgy Pinmemberdavidfrnco9-Nov-12 18:44 
AnswerRe: Technolgy [modified] PinmemberKurosh F.9-Nov-12 23:34 
GeneralMy vote of 1 Pinmemberpip0105-Nov-12 23:05 
GeneralRe: My vote of 1 PinmemberKurosh F.6-Nov-12 0:53 
GeneralRe: My vote of 1 Pinmemberpip0106-Nov-12 1:40 
GeneralRe: My vote of 1 PinmemberKurosh F.6-Nov-12 5:18 
GeneralRe: My vote of 1 Pinmemberpip0106-Nov-12 5:47 
GeneralRe: My vote of 1 PinmemberKurosh F.6-Nov-12 5:50 
GeneralRe: My vote of 1 Pinmemberpip0107-Nov-12 4:14 
GeneralRe: My vote of 1 PinmemberKurosh F.7-Nov-12 5:14 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140926.1 | Last Updated 7 Feb 2013
Article Copyright 2012 by Kurosh F.
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid