Scene Graph Basics

Scene graphs are useful for modern games using increasingly large worlds or levels.

A scene graph represent entities or objects in a scene.

Objects can be cameras, layers, layer objects such as sprites, shapes, group of objects and tiles.

Sprites

A sprite is a two-dimensional bitmap that is integrated into a larger scene.

Scene / sprite example:

#Import "scenegraph.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Field scene:Scene Method New( title:String,width:Int,height:Int,flags:WindowFlags=WindowFlags.Resizable ) Super.New( title,width,height,flags ) scene=New Scene( Self ) Local camera:=New Camera( scene ) Local layer:=New Layer( scene ) Local sprite:=New LayerSprite( layer,Image.Load( "asset::space_monkey.png" ) ) sprite.X=320 sprite.Y=240 End Method OnRender( canvas:Canvas ) Override App.RequestRender() scene.Update() scene.Draw( canvas ) End End Function Main() New AppInstance New MainWindow( "Pyro example",640,480 ) App.Run() End
Run scenegraph example | Download scenegraph example

The code above does the following:

Here are some quick and useful ways to clear a layer, remove a ( single ) sprite or prevent a sprite from beeeing removed when a layer is cleared.

To clear a layer:

layer.Clear()

To remove a sprite:

layer.Remove()

If you don't want a sprite to be removed when a layer is cleared you can set its Tatooed property to True.

sprite.Tattooed=True

Camera tricks

The camera can scroll, zoom, rotate, supports virtual resolutions and split screen technology.

Scrolling

Scrolling can be done by changing the X and Y properties.

Here is a scroll example:

#Import "scrolling.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Field camera:Camera Field logo:LayerSprite Field scene:Scene Method New( title:String,width:Int,height:Int,flags:WindowFlags=Null ) Super.New( title,width,height,flags ) Local backgroundImage:=Image.Load("asset::background.png" ) Local logoImage:=Image.Load( "asset::playniax.png" ) scene=New Scene( Self ) camera=New Camera( scene ) Local layer:=New Layer( scene ) Local background:=New LayerSprite( layer,backgroundImage ) background.X=320 background.Y=240 logo=New LayerSprite( layer,logoImage ) logo.X=320 logo.Y=240 End Method OnRender( canvas:Canvas ) Override App.RequestRender() logo.Rotation+=.01 If Keyboard.KeyDown( Key.Left ) camera.X-=5 If Keyboard.KeyDown( Key.Right ) camera.X+=5 If Keyboard.KeyDown( Key.Up ) camera.Y-=5 If Keyboard.KeyDown( Key.Down ) camera.Y+=5 scene.Update() scene.Draw( canvas ) canvas.DrawText( "Use cursor keys to scroll.",8,8 ) End End Function Main() New AppInstance New MainWindow( "Pyro example",640,480 ) App.Run() End
Run scrolling example | Download scrolling example

Parallax Scrolling

You can also create the illusion of depth ( parallax scrolling ) by using 2 layers and set diffrent values for the layer Multiplier property.

In the following example the background layer will scroll a bit slower because the Multiplier is set half 'speed':

#Import "parallax.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Field camera:Camera Field scene:Scene Method New( title:String,width:Int,height:Int,flags:WindowFlags=Null ) Super.New( title,width,height,flags ) Local backgroundImage:=Image.Load( "asset::background.png" ) Local foregroundImage:=Image.Load( "asset::foreground.png" ) scene=New Scene( Self ) camera=New Camera( scene ) Local backgroundLayer:=New Layer( scene ) backgroundLayer.Multiplier=New Vec2f( .5,1 ) Local foregroundLayer:=New Layer( scene ) For Local i:=0 Until 2 Local sprite:=New LayerSprite( backgroundLayer,backgroundImage ) sprite.X=Width*.5+i*sprite.Width sprite.Y=96 Next For Local i:=0 Until 4 Local sprite:=New LayerSprite( foregroundLayer,foregroundImage ) sprite.X=Width*.5+i*sprite.Width sprite.Y=96 Next End Method OnRender( canvas:Canvas ) Override App.RequestRender() If Keyboard.KeyDown( Key.Left ) camera.X-=5 If Keyboard.KeyDown( Key.Right ) camera.X+=5 If Keyboard.KeyDown( Key.Up ) camera.Y-=5 If Keyboard.KeyDown( Key.Down ) camera.Y+=5 scene.Update() scene.Draw( canvas ) canvas.DrawText( "Use cursor keys to scroll.",8,8 ) End End Function Main() New AppInstance New MainWindow( "Pyro example",320,192 ) App.Run() End
Run parallax example | Download parallax example

Zoom

Other useful features are the ability to zoom and rotate.

Zoom is done by changing the Zoom Property.

Zoom points ( for example the center of the screen ) can be set by changing the RotationPoint Property.

Rotate

Rotation is done by changing the Rotation property.

Rotation points ( for example the center of the screen ) can be set by changing the RotationPoint Property.

The following example shows zoom and rotation at work:

#Import "zoom and rotate.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Field camera:Camera Field logo:LayerSprite Field scene:Scene Method New( title:String,width:Int,height:Int,flags:WindowFlags=Null ) Super.New( title,width,height,flags ) Local backgroundImage:=Image.Load("asset::background.png" ) Local logoImage:=Image.Load( "asset::playniax.png" ) scene=New Scene( Self ) camera=New Camera( scene ) camera.RotationPointX=320 camera.RotationPointY=240 camera.ZoomPointX=320 camera.ZoomPointY=240 Local layer:=New Layer( scene ) Local background:=New LayerSprite( layer,backgroundImage ) background.X=320 background.Y=240 logo=New LayerSprite( layer,logoImage ) logo.X=320 logo.Y=240 End Method OnRender( canvas:Canvas ) Override App.RequestRender() logo.Rotation+=.01 scene.Update() If Keyboard.KeyDown( Key.LeftControl ) If Keyboard.KeyDown( Key.R ) camera.Rotation-=.05 If Keyboard.KeyDown( Key.Z ) camera.Zoom-=.01 Else If Keyboard.KeyDown( Key.R ) camera.Rotation+=.05 If Keyboard.KeyDown( Key.Z ) camera.Zoom+=.01 Endif scene.Draw( canvas ) canvas.DrawText( "Use R or Left Control+R to rotate.",8,8 ) canvas.DrawText( "Use Z or Left Control+Z to zoom in/out.",8,8+canvas.Font.Height ) End End Function Main() New AppInstance New MainWindow( "Pyro example",640,480 ) App.Run() End
Run zoom and rotate example | Download zoom and rotate example

Split screen

Split screen is the visible division of the screen in half mostly used for 2 player games.

Pyro can split the screen both horizontally or vertically.

The commands to setup a horizontal splitscreen is SetHorizontalSplitScreen

The commands to setup a vertical splitscreen is SetVerticalSplitScreen

Here is a working example of a horizonal split screen.

#Import "splitscreen.assets/" #Import "" #Import "" #Import "" Using std.. Using mojo.. Using pyro.framework.. Using pyro.scenegraph.. Class MainWindow Extends Window Field camera:=New Camera[2] Field logo:LayerSprite Field scene:Scene Method New( title:String,width:Int,height:Int,flags:WindowFlags=Null ) Super.New( title,width,height,flags ) Local backgroundImage:=Image.Load("asset::background.png" ) Local logoImage:=Image.Load( "asset::playniax.png" ) scene=New Scene( Self ) camera[0]=New Camera( scene ) camera[1]=New Camera( scene ) SetHorizontalSplitScreen( camera[0],camera[1],Rect.Size ) Local viewport:=camera[0].Viewport.Size camera[0].RotationPoint=viewport/2 camera[0].ZoomPoint=viewport/2 camera[1].RotationPoint=viewport/2 camera[1].ZoomPoint=viewport/2 Local layer:=New Layer( scene ) Local background:=New LayerSprite( layer,backgroundImage ) background.Location=viewport/2 logo=New LayerSprite( layer,logoImage ) logo.Location=viewport/2 End Method OnRender( canvas:Canvas ) Override App.RequestRender() logo.Rotation+=.01 scene.Update() If Keyboard.KeyDown( Key.LeftControl ) If Keyboard.KeyDown( Key.R ) camera[0].Rotation-=.05 If Keyboard.KeyDown( Key.Z ) camera[0].Zoom-=.01 Else If Keyboard.KeyDown( Key.R ) camera[0].Rotation+=.05 If Keyboard.KeyDown( Key.Z ) camera[0].Zoom+=.01 Endif scene.Draw( canvas ) canvas.DrawText( "Use R or Left Control+R to rotate.",8,8 ) canvas.DrawText( "Use Z or Left Control+Z to zoom in/out.",8,8+canvas.Font.Height ) End End Function Main() New AppInstance New MainWindow( "Pyro example",640,480 ) App.Run() End
Run splitscreen example | Download splitscreen example