Tile Basics

Pyro has a tile engine that does things a bit differently.

It uses sprites ( or any other layer object ) for tiles and has a simple map system that manages the sprites so no performance is lost.

Have a look at the Scene Graph Basics first before you start to play with tiles.

Plotting a tile

The first thing you will need to do is to create a layer and set the tile size

layer=New Layer( scene ) layer.TileSize=New Vec2i( 32,32 )

Now you can begin 'plotting' tiles

Local image:=Image.Load( "asset::tile.png" ) Local tile:=New LayerSprite( layer,image ) ToTilePos( tile,2,2 )

Tiles can be at pixel position but we use ToTilePos to translate it to tile positions.

Getting a tile from a position

To get a tile we can use the GetLayerObjects command.

GetLayerObjects returns a list ( Stack ) with layer objects.

GetLayerObjects is usually used when you want to detect collisions or to read the properties of a tile.

Multiple tiles can occupy a 'cell' so the stack can contain more than one object.

When you are a beginner it may be wise to use a separate layer for your 'tile' sprites and a separate layer for your 'character' sprites.

Getting a tile from the mouse position may look something like this

Local tiles:=layer.GetLayerObjects( Mouse.Location ) If tiles<>Null And tiles.Length>0 tile=tiles.Get(0) If tile<>Null Print tile.Position EndIf Endif

Here is a complete example

#Import "set and get.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Field layer:Layer Field scene:Scene Field tile:LayerObject Field tiles:=New Image[5] Method New( title:String,width:Int,height:Int,flags:WindowFlags=Null ) Super.New( title,width,height,flags ) ' Load/create tileset: For Local i:=0 Until tiles.Length tiles[i]=Content.GetImage( "asset::gid_"+i+".png" ) Next scene=New Scene( Self ) Local camera:=New Camera( scene ) layer=New Layer( scene ) layer.TileSize=New Vec2i( 32,32 ) Local tile1:=New LayerSprite( layer,Content.GetImage( "asset::gid_1.png" ) ) ToTilePos( tile1,2,2 ) Local tile2:=New LayerSprite( layer,Content.GetImage( "asset::gid_3.png" ) ) ToTilePos( tile2,5,8 ) End Method OnRender( canvas:Canvas ) Override App.RequestRender() scene.Update() If tile tile.Selected=False ' Grab tile from mouse pos: Local tiles:=layer.GetLayerObjects( Mouse.Location ) If tiles<>Null And tiles.Length>0 tile=tiles.Get(0) If tile<>Null tile.Selected=True Endif scene.Draw( canvas ) canvas.DrawText( "Move the mouse over a tile",8,8 ) End End Function Main() New AppInstance New MainWindow( "Pyro example",640,480 ) App.Run() End
Run set and get example | Download set and get example

Adding user properties to a tile

Pyro has a great system to add local and global properties to a layer object.

Properties can be stored in a Config object using the Config Class.

To assign local properties to a tile the code might look something like this.

Local image:=Image.Load( "asset::tile.png" ) Local tile:=New LayerSprite( layer,image ) ToTilePos( tile,2,2 ) tile.Properties=New Config tile.Properties.WriteString( "grass","green" )

So if you would use the GetLayerObjects to get a tile from the mouse position you can also read the tile properties

Local tiles:=layer.GetLayerObjects( Mouse.Location ) If tiles<>Null And tiles.Length>0 tile=tiles.Get(0) If tile<>Null And tile.Properties<>Null Print tile.Properties.ToString() Endif Endif

To assign Global properties you can create a shared Config object and use the GlobalProperties property instead of the Properties properties.

Here is a complete example:

#Import "properties.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Field layer:Layer Field scene:Scene Field tile:LayerObject Field tiles:=New Image[5] Method New( title:String,width:Int,height:Int,flags:WindowFlags=Null ) Super.New( title,width,height,flags ) ' Load/create tileset: For Local i:=0 Until tiles.Length tiles[i]=Content.GetImage( "asset::gid_"+i+".png" ) Next scene=New Scene( Self ) Local camera:=New Camera( scene ) layer=New Layer( scene ) layer.TileSize=New Vec2i( 32,32 ) ' Create global properties: Local globalProperties:=New Config() globalProperties.WriteString( "type","tile" ) ' Plot a tile: Local tile1:=New LayerSprite( layer,Content.GetImage( "asset::gid_1.png" ) ) ' Pyro tiles can be at pixel position but for this example we use tile positions: ToTilePos( tile1,2,2 ) ' Give the tile some properties: tile1.Properties=New Config() tile1.Properties.WriteString( "grass","green" ) tile1.GlobalProperties=globalProperties ' Plot another tile: Local tile2:=New LayerSprite( layer,Content.GetImage( "asset::gid_10.png" ) ) ToTilePos( tile2,5,8 ) ' Give the tile some properties: tile2.Properties=New Config() tile2.Properties.WriteString( "poison","orange" ) tile2.Properties.WriteBool( "kill",True ) tile2.GlobalProperties=globalProperties End Method OnRender( canvas:Canvas ) Override App.RequestRender() scene.Update() ' Read keys: Local key_P:=Keyboard.KeyHit( Key.P ) Local key_G:=Keyboard.KeyHit( Key.G ) If tile tile.Selected=False ' Grab tile from mouse pos: Local tiles:=layer.GetLayerObjects( Mouse.Location ) If tiles<>Null And tiles.Length>0 tile=tiles.Get(0) If tile<>Null tile.Selected=True If tile<>Null And tile.Properties<>Null If key_P Print tile.Properties.ToString() ; Print "" If key_G Print tile.GlobalProperties.ToString() Endif Endif scene.Draw( canvas ) canvas.DrawText( "Move mouse over a tile and press key P for properties or key G for global properties",8,8 ) End End Function Main() New AppInstance New MainWindow( "Pyro example",640,480 ) App.Run() End
Run properties example | Download properties example

And finally a little tile editor:

#Import "tiny editor.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Const TILE_SIZE:=32 Field camera:Camera Field id:=0 Field layer:Layer Field scene:Scene Field tiles:=New Image[170] Method New( title:String,width:Int,height:Int,flags:WindowFlags=Null ) Super.New( title,width,height,flags ) For Local i:=0 To tiles.Length tiles[i]=Image.Load( "asset::gid_"+( i+1 ) +".png" ) Next scene=New Scene( Self ) camera=New Camera( scene ) layer=New Layer( scene ) layer.TileSize=New Vec2i( TILE_SIZE,TILE_SIZE ) End Method OnRender( canvas:Canvas ) Override App.RequestRender() scene.Update() Local x:Int=layer.GetMouseLocation( camera ).X Local y:Int=layer.GetMouseLocation( camera ).Y If Mouse.ButtonDown ( MouseButton.Left ) Local tile:=layer.GetLayerObject( camera,x,y ) If tile tile.Remove() RoundTilePos( New LayerSprite( layer,tiles[id] ),x,y ) End If Mouse.ButtonDown ( MouseButton.Right ) Local tile:=layer.GetLayerObject( camera,x,y ) If tile tile.Remove() End If Keyboard.KeyReleased( Key.PageUp ) id+=1 If Keyboard.KeyReleased( Key.PageDown ) id-=1 If id<0 id=0 If id>tiles.Length-1 id=tiles.Length-1 scene.Draw( canvas ) If Mouse.ButtonDown ( MouseButton.Right ) canvas.DrawRect( x/TILE_SIZE*TILE_SIZE,y/TILE_SIZE*TILE_SIZE,TILE_SIZE,TILE_SIZE ) Else canvas.DrawImage( tiles[id],x/TILE_SIZE*TILE_SIZE,y/TILE_SIZE*TILE_SIZE ) Endif canvas.DrawText( "Use left / right mouse to plot / delete a tile. Page up / down to select a tile", 8,8 ) End End Function Main() New AppInstance New MainWindow( "Pyro example",640,480 ) App.Run() End
Run tiny editor example | Download tiny editor example