The title is a bit of a misnomer, as we’re still a way away from actually creating what most would recognise, or refer to, as a game. In this article we’ll be looking at how you create objects within your game – in Pushbutton Engine parlance they are referred to as Entities.
Performance, Performance, Performance
Unlike other forms of development, performance and speed are the cornerstones of game development. If a game does not perform well or it’s sluggish and unresponsive then it doesn’t matter how great the game concept, most people will go and look for something better. With that in mind game entities tend to be composited objects and have very shallow inheritance chains.
This provides numerous benefits. By keeping the inheritance chain shallow (once or twice removed from the base class) you don’t run the risk of bloating your objects with code that they may never require or use. It also avoids heavy refactoring should you need to add discrete functionality to two or more inheritance chains that are unrelated but need the same functionality. This is where composition comes in. By working with composited objects you can easily add or remove the functionality that each entity type requires. This makes for a more robust and efficient model than working with potentially bloated inheritance chains.
I’ll be covering this in more detail in a future article, but I just wanted to provide a brief explanation of the theory behind the Pushbutton Engine approach to game item creation and management. With that bit covered off let’s look at how you can get started with PBE by creating a simple entity.
Firing up PBE
The first thing you need to do is create a base ActionScript file as per the set up instructions in my previous article “Setting Up Your IDE” (If you want to use MXML I’ll be covering that off in another article soon). Like a lot of libraries, the Pushbutton Engine provides as much or as little assistance as you require; and as you get more comfortable with it you can start to dig in to it to tweak it to your heart’s content. For the time being though let’s just use the basic building blocks to create a simple interactive demo.
To start with we are going to create two items – a scene and the player (we’ll come to enemies later on). Think of the scene view as the container in which you can place all of your game objects. You’re not limited to just one either, you can have numerous scene views if you so choose. Creating a sceneView instance is pretty painless. First up you need to create a new instance of the SceneView class, then set its width and height – simple. You can optionally provide a name for your scene and once you are ready you pass it to the main PBE class for initialization (as the code below illustrates)
1 2 3 4 5 6 7 8 9 | protected function initializeScene():void { _sceneView = new SceneView(); _sceneView.name = "mainView"; _sceneView.width = 800; _sceneView.height = 480; PBE.initializeScene(_sceneView); } |
You may be wondering what PBE is. Well that is the main Pushbutton Engine class that manages the entire game. As you can see the scene view has been passed in to the initializeScene() method of the PBE class. As the documents put it:
“This class makes some assumptions about what components and modules are present. If you are doing strange things, then you may need to directly access things this class does for you. However if you are just getting started this is likely to be a useful toolkit.”
Adding The Last Few Missing Pieces
Before you can test your newly added scene, you need to add a couple of things to your base class. First up you need to define the actual dimensions of the SWF you are creating. You can achieve this by setting the SWF metadata tag at the top of your document class like so:
1 | [SWF(width="800", height="480", frameRate="60")] |
Note that the dimensions used by the scene and the actual SWF size are usually identical, hence the slight value overlap. The last step is to tell PBE that you want to start up the engine. To do this you just need to call PBE.startup() and pass in the main class of your game, like so:
1 | 
PBE.startup(this); |
One thing to be aware of is that the main class needs to inherit from Sprite – again like most things, this shouldn’t be an issue as you’ll more than likely just pass in a reference to the main document class of your application via the this keyword. You also need to make sure that PBE.startup() is called first (usually in the constructor). If you don’t call it first then you are likely to get a plethora of null reference exceptions – as none of the built in helpers will have been created. Obvious I know, but still worth mentioning.
Here is what the code now looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 
package { import com.pblabs.engine.PBE; import com.pblabs.engine.entity.IEntity; import com.pblabs.engine.entity.allocateEntity; import com.pblabs.rendering2D.ui.SceneView; import flash.display.Sprite; [SWF(width="800", height="600", frameRate="60")] public class Main extends Sprite { public function Main() { PBE.startup(this); initializeScene(); } protected function initializeScene():void { var _sceneView:SceneView = new SceneView(); _sceneView.name = "MainView"; _sceneView.width = 800; _sceneView.height = 600; PBE.initializeScene(_sceneView); } } } |
Go ahead and test it. Impressive eh? I know you were just looking at a blank screen. That’s because we haven’t added anything to the screen yet. Let’s add in a simple sprite to represent the player next.
Adding Entities
As I mentioned earlier, all objects in Pushbutton Engine are referred to as Entities. Not only that but you’ll soon see that there is a common vernacular to how certain entities are named / referred to. For example it is common to see the player entity referenced in code as hero. Plus when we start looking at the composition of entities you’ll see that this common naming practice extends to these elements as well. If you don’t like it, don’t feel like you have to adhere to it. Feel free to declare and name your variables using whatever naming convention you like. It’s helpful to be aware that there is a common naming parlance for when you’re looking at example code.
So let’s look at how you draw an entity and add it to the scene. To start with you need to allocate your entity. This is achieved by calling allocateEntity() instead of using the new keyword. The reason for this is twofold. Firstly, creating objects is an expensive process (remember what I said about speed and performance), using allocateEntity provides access to the hidden Entity class and allocates an instance of it for use instead. Secondly, and this is where the benefit comes in, it provides the flexibility of reuse via pooling. While not a big deal for a single item like the player entity, it’s very helpful if you have numerous enemies on screen. When they are destroyed, instead of creating new ones to replace them you just reuse ‘dead’ ones from the pool.
Once you have allocated the entity you need to initialize it so it is ready to use. To do this you just need to invoke the entity’s initialize() method. Looking at the code below you can see the hero entity being allocated and initialized.
1 2 3 4 5 6 | 
protected function initializePlayer():void { var _hero:IEntity = allocateEntity(); _hero.initialize("Hero"); } |
That’s fine and dandy, but it is just an empty object at the moment so let’s give it some attributes by way of composition. The first thing to do is provide it with some form via a Spatial component–in this case a SimpleSpatialComponent. The principle behind spatial components is that they deal with actually placing the entity in to the environment–providing it with its own space if you will.
1 2 3 4 5 6 7 8 9 10 11 12 13 | protected function initializePlayer():void { var _hero:IEntity = allocateEntity(); var _spatial:SimpleSpatialComponent = new SimpleSpatialComponent(); _spatial.size = new Point(100, 100); _spatial.position = new Point(0, 0); _spatial.spatialManager = PBE.spatialManager; _hero.addComponent(_spatial, "Spatial"); _hero.initialize("Hero"); } |
If you look at the spatial code that has been added you can see the basic steps required to add a component to an entity:
- Create an instance of the component
- Set the required component parameters
- Add the component to the entity
- Rinse and repeat :p
Looking at the spatial code in a bit more detail I want to highlight one difference between normal ActionScript applications and that’s to do with position. Position within Pushbutton Engine is different due to the fact that the registration point 0,0 is actually the dead centre of the visible area and not top left as it is in traditional Flash-based content. Therefore when setting the initial position of an entity, if you need to position it top left of centre remember to use negative values.
Now that our entity exists in the actual scene view we need to give it some form as it doesn’t have any graphical representation and therefore is currently ‘invisible’. To do this we just add another component to it. In this case a renderer component. Renderer components come in multiple guises but the one we’ll look at today is the SimpleShapeRenderer. This, as the name implies, makes it easy for you to add a shape to your entity. I’m going to just create a square like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 
var _renderer:SimpleShapeRenderer = new SimpleShapeRenderer(); _renderer.fillColor = 0x000000; _renderer.fillAlpha = 1; _renderer.lineAlpha = 0; _renderer.isSquare = true; _renderer.isCircle = false; _renderer.scene = PBE.scene; _renderer.sizeProperty = new PropertyReference("@Spatial.size"); _renderer.positionProperty = new PropertyReference("@Spatial.position"); _renderer.rotationProperty = new PropertyReference("@Spatial.rotation"); _hero.addComponent(_renderer, "Renderer"); |
These allow your renderer component to respond to changes in the spatial component–in this case a change to its size, position or rotation. While you could create your own method of controlling these (and other properties) within your components, doing it in this manner makes the actual component and any references it contains easy to ‘hot swap’ in and out of your entity should you need to. It also promotes a level of reusability and avoids making a brittle relationship with the entity in question and its components.
Wrapping It All Up
Now that you have both your scene view and your ‘hero’ entity you are ready to run your game again. Once you run the code you will be presented with a beautiful black square in the centre of the screen. I know it’s not that groundbreaking, but as I said at the beginning, you have to learn to walk before you attempt to run.
I’ve included the entire code listing below as well as the actual Flash Builder project
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | 
package { import com.pblabs.engine.PBE; import com.pblabs.engine.entity.IEntity; import com.pblabs.engine.entity.PropertyReference; import com.pblabs.engine.entity.allocateEntity; import com.pblabs.rendering2D.SimpleShapeRenderer; import com.pblabs.rendering2D.SimpleSpatialComponent; import com.pblabs.rendering2D.ui.SceneView; import flash.display.Sprite; import flash.geom.Point; [SWF(width="800", height="600", frameRate="60")] public class Main extends Sprite { public function Main() { PBE.startup(this); initializeScene(); initializePlayer(); } protected function initializeScene():void { var _sceneView:SceneView = new SceneView(); _sceneView.name = "MainView"; _sceneView.width = 800; _sceneView.height = 600; PBE.initializeScene(_sceneView); } protected function initializePlayer():void { var _hero:IEntity = allocateEntity(); var _spatial:SimpleSpatialComponent = new SimpleSpatialComponent(); _spatial.size = new Point(100, 100); _spatial.position = new Point(0, 0); _spatial.spatialManager = PBE.spatialManager; _hero.addComponent(_spatial, "Spatial"); var _renderer:SimpleShapeRenderer = new SimpleShapeRenderer(); _renderer.fillColor = 0x000000; _renderer.fillAlpha = 1; _renderer.lineAlpha = 0; _renderer.isSquare = true; _renderer.isCircle = false; _renderer.scene = PBE.scene; _renderer.positionProperty = new PropertyReference("@Spatial.position"); _renderer.rotationProperty = new PropertyReference("@Spatial.rotation"); _hero.addComponent(_renderer, "Renderer"); _hero.initialize("Hero"); } } } |
I’ve included the ActionScript project below (this was created in Flash Builder Burrito although it should work in Flash Builder 4). If you’re using Flash Professional, just grab the main ActionScript class out of the zip – or use the code above.
Related Files
PBE001_GettingStarted.zip
2 Comments