Creating a top-down game scene

Let us try to implement a sample Starling-based top-down level with provision to detect the tile on which we touch. We will use the source and the tile sheet given in the Chapter 1 folder from the shared source. The code for the TopDownScene class is shared in the following code snippet. You will need to initialize this class from the Starling document class using new Starling(TopDownLevel, stage).

package com.csharks.juwalbose
{
  import starling.display.DisplayObjectContainer;
  import starling.display.Image;
  import starling.events.Event;
  import starling.events.Touch;
  import starling.events.TouchEvent;
  import starling.textures.Texture;
  import starling.textures.TextureAtlas;
  public class TopDownLevel extends DisplayObjectContainer
  {
    //Texture Atlas image
    [Embed(source="../../../../assets/assets.png")]
    public static const AssetTex:Class;
    //Texture Atlas XML
    [Embed(source = "../../../../assets/assets.xml", mimeType = "application/octet-stream")]
  private static const AssetXml:Class;
    private var texAtlas:TextureAtlas;
    private var tileWidth:uint=50;
    private var borderX:uint=25;
    private var borderY:uint=50;
    private var touch:Touch;
    //LevelData as 2 dimensional array
    private var levelData:Array=[["14","21","21","21","21","21","21","13","21","21","21","21","21","21","17"],
      ["18","12","7","2","2","8","2","3","2","5","2","2","7","13","20"],
      ["18","3","3","2","2","2","2","2","2","2","2","2","3","2","20"],
      ["18","3","3","2","2","2","9","2","2","2","3","2","3","3","20"],
      ["18","5","2","2","5","2","2","2","4","2","2","2","2","5","20"],
      ["10","2","2","2","2","3","2","2","2","2","2","2","7","2","12"],
      ["18","2","8","2","2","2","2","3","2","5","2","2","2","5","20"],
      ["18","2","2","2","4","2","2","2","2","2","4","2","2","2","20"],
      ["18","11","2","3","2","2","2","3","2","2","2","2","2","10","20"],
      ["15","19","19","19","19","19","19","13","19","19","19","19","19","19","16"]];
  public function TopDownLevel()
  {
    super();
    this.addEventListener(Event.ADDED_TO_STAGE, init);
  }

  private function init(e:Event):void
  {
  this.removeEventListener(Event.ADDED_TO_STAGE, init);
  //Let us create a texture atlas
  var tex:Texture =Texture.fromBitmap(new AssetTex(),false);
  var img:Image;
  texAtlas=new TextureAtlas(tex,XML(new AssetXml()));
  //Loop through 2D array & add images to stage
  for(var i:int=0;i<levelData.length;i++){//i is for rows
  for(var j:int=0;j<levelData[0].length;j++){//j is for columns
  img=new Image(texAtlas.getTexture(paddedName(levelData[i][j])));
  addChild(img);
  //calculate position depending on i & j
  img.x=j*tileWidth+borderX;
  img.y=i*tileWidth+borderY;
  }
  }
  //Listener for touch
  this.addEventListener(TouchEvent.TOUCH, onTouch);
  }

  private function paddedName(id:String):String{
    //function to return '0' padded name
    var offset:uint=10000;
    offset+=int(id);
    var str:String="tiles";
    str+=offset.toString().substr(1,4);
    return str;
  }
  private function detectTile(valueX:int, valueY:int):void{
    //function to detect tile at given position
    var tileX:int=int(valueX-borderX)/tileWidth;
    var tileY:int=int(valueY-borderY)/tileWidth;
    trace(levelData[tileY][tileX]);
  }
  protected function onTouch(event:TouchEvent):void
  {
    for (var i:int = 0; i < event.getTouches(this).length; ++i)
      {
        touch = event.getTouches(this)[i];
        detectTile(touch.globalX,touch.globalY);
      }
    }
  }
}

Here we are using the Starling TextureAtlas class created from embedded assets. The embedded XML and PNG files are created using the TexturePacker application using the Sparrow/Starling export feature. The PaddedName function adds the zero padding to the tile names and the onTouch listener function traces out the tile value in the levelData array based on the touch position. The registration point of an image is at its top-left corner by default. This benefits us for placing them properly in the scene. Try working with this on your own by playing around with the level data. You can change the values in the level data and see the level scene updates accordingly. We have a total of 22 tiles to play with.

Applying the RenderTexture approach

In the preceding code, we have placed each tile as individual images on the scene. This will look fine but it is not necessarily the best approach. This creates a lot of independent entities on the scene, which may become a performance hog for a complicated game where we may need to manipulate each and every tile on every frame. An alternate approach is to use a RenderTexture class.

A RenderTexture class can be considered as a dynamically changeable Starling texture, which can be altered anytime via code. We can use methods to clear it, draw items onto it, or to fill it up completely. For our previous level scene, we can simplify everything by creating a single image based on a RenderTexture class, and then drawing all tiles onto it. This results in the scene having only one entity, thereby minimizing the effort on the Flash Player. Let us take a look at the changes in the code:

rTex=new RenderTexture(stage.stageWidth,stage.stageHeight);
var rTexImage:Image= new Image(rTex);
addChild(rTexImage);
for(var i:int=0;i<levelData.length;i++){
  for(var j:int=0;j<levelData[0].length;j++){
    img=new Image(texAtlas.getTexture(paddedName(levelData[i][j])));
    img.x=j*tileWidth+borderX;
    img.y=i*tileWidth+borderY;
    //draw to texture instead of adding new image
    rTex.draw(img);
  }
}

The detectTile function is also slightly altered to ignore invalid touch points which fall out at the side level area:

private function detectTile(valueX:int, valueY:int):void{
  var tileX:int=int(valueX-borderX)/tileWidth;
  var tileY:int=int(valueY-borderY)/tileWidth;
  if(tileX<0 ||tileY<0 ||tileX>levelData[0].length-1
  ||tileY>levelData.length-1)
  { //outside of tile area
    return;
  }
  trace(levelData[tileY][tileX]);
}

Use RenderTexture wherever possible for efficient resource management as well as performance boost. There is an additional method called RenderTexture.drawBundled, which can further speed things up considerably. We will be using this function a lot for our screen update.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.166.31