Developing Flash Platform games with PushButton Engine
by Samuel Asher Rivello Articles this issue ●??????Edge?featured?video:?Onsite?at?FITC?/?Innovating?with?Flash ●??????Getting?started?with?Adobe?AIR?for?Android ●??????Preview:?Adobe?MAX?2010 ●??????The?edge?of?Flash ●??????OSMF:?Simplifying?the?media?player?development?process ●??????Working?with?CSS?starter?layouts?in?Adobe?Dreamweaver?CS5 ●??????Developing Flash Platform games with PushButton Engine ●??????Authoring?Adobe?Flash?content?for?DROID?X?and?DROID?2 With the recent release of the?PushButton?Engine?(PBE) from PushButton Labs,game developers finally have a community-created framework to help organize code and set industry standards. PBE is an open-source Flash game engine and framework that makes it easy to bring together great existing libraries and components for building Flash games. The idea is to spend less time on code,and more time on building fun games. In this article,we'll explore PBE technology,and then use it to create a simple game. As of Q2,2010 over 60 million player experiences have been served up on PBE technology. It is already in use inside many major game development companies such as?Zinga,?Playdom,?RockYou?Games,and?Game?House?as well as many indie-developers and freelance developers. The PBE website's game showcase has several games proving the technology too including the recently released?SocialCity?Facebook simulation game and the highly-anticipated?Grunts:?Skirmish?RTS game. The creators of PBE,?PushButton?Labs,have vast expertise in the console and PC game industry and decided to target the Flash Platform for the PBE project. They want to enable game developers to more rapidly create game projects of any genre. Fifteen developers have contributed to the code-base and the group of PBE developer community who is actively using the technology,writing on the forums,and creating tutorials is already 1500 strong.? Benefits of PBE PBE and the Flash Platform are a perfect combination. Professional game development teams can rapidly create rich,robust game experiences. Benefits include: ●??????The flexibility and power of PBE's?component-based development paradigm ●??????The standardization and interoperability of third-party game kits and add-ons; coupled with the vibrant,helpful community,game developers now have a way to contribute and utilize truly plug and play libraries ●??????Proven game-specific development tools,including a?Console,Logger,?Profiler,?ResourceManager,and more ●??????The ubiquity of the Flash Platform (it?is?everywhere!) and its tight integration with the?Adobe?Creative?Suite?(limitless asset creation!) Even a non-PBE project can be quickly modified to take advantage of these tools. See the following code for a simple "PBHelloWorld." A few of these lines added to the beginning of your existing project can empower you with some of PBE's benefits: /*************************************************************************************************** * Copyright (C) 2007 - 2010 : Rivello Multimedia Consulting * For more information email : presentations2010@RivelloMultimediaConsulting.com * For more information see : http://www.RivelloMultimediaConsulting.com * * This file and/or its constituents are licensed under the terms of the MIT license,* which is included in the License.html file at the root directory of this SDK. ***************************************************************************************************/ //Marks the right margin of code ******************************************************************* package { //-------------------------------------- // Imports //-------------------------------------- import com.pblabs.engine.PBE; import com.pblabs.engine.debug.Logger; import flash.display.Sprite; //-------------------------------------- // Class //-------------------------------------- /** * <p>CLASS : PBHelloWorld: Main Class</p> * * <p>DATE : May 02,2010</p> * <p>AUTHOR : Samuel Asher Rivello</p> * <p>CONTACT : presentations2010@RivelloMultimediaConsulting.com</p> * */ public class PBHelloWorld extends Sprite { //-------------------------------------- // Properties //-------------------------------------- //PUBLIC GETTER/SETTERS //PUBLIC CONST public static var WIDTH : Number = 800; public static var HEIGHT : Number = 600; //PRIVATE //-------------------------------------- // Constructor //-------------------------------------- /** * FLASH: Setup the Project! * */ [SWF(width="800",height="600",frameRate="60")] public function PBHelloWorld () { //SUPER super (); // STARTUP PBE: CONSOLE,LOGGER,& RESOURCE MANAGER PBE.startup(this); // TEST THE LOGGER Logger.print(this,"PB Hello World!"); } } } However these tools are just the start. One must develop a game from inception with PBE in mind to truly exploit its power. At the core of the PBE engine is a 'component-based' development paradigm and property referencing system that showcase the engines stated goal of providing a 'spectrum of rigidity'. Basically this means PBE gives you scalable tools to start your game prototypes fast and get a playable game ready quickly,yet continue to offer a clear migration path from a light-and-easy prototype to a robust,standards-compliant finished game project. Under the hood of PBE The PushButton engine is an ActionScript 3 library that can be added to any Flash or Flex Based project. The two projects included in this article for download feature the full editable source to facilitate learning,but PBE comes as a precompiled SWC file too for more rapid project compilation. The library is fit for deployment on the desktop,the browser,or on mobile devices.?Anywhere Flash can play,PBE can play! PBE is made of three general types of classes. There may be many of each type in each game project: ●??????Manager — Managers are the brains of the operation — each one has a unique task; for instance one focuses on the spatial area of the screen and the objects within it and one on graphics rendering of visible objects. Depending on its role in the game,a manager may or may not relate to entities and components directly. ●??????Entity — Each visual element in your game is represented by an entity. This could be anything; your player,the enemies,collectible items,etc.... ●??????Component — Each entity contains components. This is where the bulk of your game code lies. Each components handle a specific responsibility. For instance perhaps one component handles rendering the entity in which it resides. Managers can be created by developers,but PBE ships with managers for our most common needs. Here is a partial list of the managers packaged with the core PBE library: ●??????ProcessManager — Controls game logic and rendering logic and makes sure the right stuff is called at the right time. The API supports decelerating,accelerating,pausing,and stopping 'time' too. ●??????SpatialManager — Keeps track of simple objects in 2d space (width and height). The developer may choose a basic implementation or one with built-in Box2D physics. Plug-n-play game-physics? Yes! Developers can customize this manager to work in 3D too. ●??????ScreenManager — This is a simple way to swap game UI in and out as you move through your game. e.g. front menu screen,game screen with HUD,game-over screen,etc. ●??????SoundManager — Control all your game audio from a centralized location. Entities are essentially empty shells. As a developer you fill them with the components needed. Each component has access to?any?Flash API desired,custom PBE events,as well as the following built-in PBE events: ●??????onFrame — Best used just for graphics rendering-routines. Each PBE 'frame' occurs in sync with a Flash 'frame' (e.g. 60 frames per second) ●??????onTick — Ticks are guaranteed to happen at a fixed interval. If the Flash Player slows down due to some number-crunching or heavy rendering,PBE will attempt to 'catch up' by calling more ticks. It balances the run-time experience well. As Lavon Woods of?HybridMindset.com?points out "Finally,PBE has gotten around Flayer Player's well known?elastic?racetrack?issue". ●??????onThink — Based on an arbitrary,per-use timer. This is ideal for AI code which can be processed slowly (e.g. every 1–5 seconds) ●??????onCollision — Based on built-in collision checking routines. Highly customizable and very useful! PBE theory The core,unique difference with PBE game development is its 'component-based' code organization. Components here are not user interface components such as a Button or DropDownList,here components mean a reusable,modular class used for gaming. Typically flash game developers begin their career with inheritance-based game development and may evolve to creating a custom framework for their games. These Object-oriented styles are are different from the system in PBE. In the following sections we see 3 approaches to game development from least evolved to most. "Quick and dirty" game development OOP game development Figure 1.?Bloated classes in a game's class inheritance chain will become overburdened and difficult to maintain. OOP has drawbacks too. Using OOP for the Flyer game we'd likely start with two classes representing the onscreen objects; FlyerMC and BiPlaneMC. Both would take advantage of MovieClip,extending that built-in class to handle rendering and other tasks. Then game-specific,common code would necessitate the creation of a custom MoverItem class. What often happens is that so much of the game code is shared by classes that the 'MoverItem' gets very bulky. The bulky classes in the inheritance chain will become difficult to maintain and will become a challenge to debug. Adding new features is slow because new code must be added carefully. This is a simple example,but illustrates a problem that rings true in so many game projects; bloated overburdened parent-classes. A better solution is using component-based development for games. Component-based game development: The Flyer Game Ben Garney,Lead Developer of PBE knows from experience,"The biggest shift is thinking in terms of components,not monolithic classes. The rest is straightforward." To understand more about how the component-based game development works,let's continue with the examples above. I created a PBE version of the Flyer game. Here the game logic is spread between entities for Flyer,BiPlane,Blimp. The first two entities are shown in Figure 2. BlimpEntity works just like BiPlaneEntity so it is not shown. The two entities shown share a render component,but the flexibility of PBE allows them to vary greatly in the other components used. FlyerEntity has 4 components of its own. BiplaneEntity as two of its own (the same two used by BlimpEntity). What is evident from this simple example is by entities composed of reusable components we have great flexibility without creating any overly-bulky classes like in the OOP example above. Very nice! Figure 2.?The eight reusable components of the PBE Flyer game. Development This article shows the playable Flyer game below and also shows much of the code below too. To see even more you may download the source code too.
The resulting Flash application is shown in Figure 3. Use the arrow keys to play. Simple and fun! Figure 3.?The PBE Flyer Game. Click anywhere to play. Use the arrow keys to move to the top of the screen. Avoid hitting obstacles.?Refresh the page to restart. The core game code can be seen below. This is the main PBFlyerGame.as class containing the entry point into the coding. Reviewing the code and code-comments is a great introduction to PBE. More explanation follows in the article below the code: /*************************************************************************************************** * Copyright (C) 2007 - 2010 : Rivello Multimedia Consulting * For more information email : presentations2010@RivelloMultimediaConsulting.com * For more information see : http://www.RivelloMultimediaConsulting.com * * This file and/or its constituents are licensed under the terms of the MIT license,* which is included in the License.html file at the root directory of this SDK. ***************************************************************************************************/ //Marks the right margin of code ******************************************************************* package com.rmc.projects.pbflyergame { //-------------------------------------- // Imports //-------------------------------------- import com.pblabs.box2D.Box2DManagerComponent; import com.pblabs.engine.PBE; import com.pblabs.engine.debug.Logger; import com.pblabs.engine.entity.IEntity; import com.pblabs.engine.entity.PropertyReference; import com.pblabs.rendering2D.AnimationController; import com.pblabs.rendering2D.AnimationControllerInfo; import com.pblabs.rendering2D.SpriteSheetRenderer; import com.pblabs.rendering2D.spritesheet.SWFSpriteSheetComponent; import com.pblabs.rendering2D.ui.SceneView; import com.rmc.projects.pbflyergame.components.CollisionDetectComponent; import com.rmc.projects.pbflyergame.components.FaceForwardComponent; import com.rmc.projects.pbflyergame.components.GameOverComponent; import com.rmc.projects.pbflyergame.components.MoveByKeyboardInputComponent; import com.rmc.projects.pbflyergame.components.MoveHorizontallyComponent; import com.rmc.projects.pbflyergame.components.ScreenTrapComponent; import com.rmc.projects.pbflyergame.components.ScreenWrapComponent; import com.rmc.projects.pbflyergame.screens.GameScreen; import com.rmc.projects.pbflyergame.screens.IntroScreen; import com.rmc.utils.pbe.FlyerGameHelper; import flash.display.Sprite; import flash.geom.Point; //-------------------------------------- // Class //-------------------------------------- /** * CLASS : PBFlyerGame: Main Game Class * * DATE : May 02,2010 * AUTHOR : Samuel Asher Rivello * CONTACT : presentations2010@RivelloMultimediaConsulting.com * */ [SWF(width="800",frameRate="60")] public class PBFlyerGame extends Sprite { //-------------------------------------- // Properties //-------------------------------------- //PUBLIC GETTER/SETTERS //PUBLIC CONST public static var WIDTH : Number = 800; public static var HEIGHT : Number = 600; //PRIVATE //-------------------------------------- // Constructor //-------------------------------------- /** * FLASH: Setup the Game and Start Playing! * */ public function PBFlyerGame () { //SUPER super (); // START PBE PBE.startup(this); // 0.5 = HALF-SPEED,// 2.0 = DOUBLE SPEED (SMOOTHER ANIMATION) PBE.processManager.timeScale = 0.8; // TEST TRACING OUTPUT MESSAGE Logger.print(this,"PBFlyerGame - Press 'Alt/Option' + '~' to Open Debugger"); // LOAD EMBEDDED RESOURCS PBE.addResources(new PBFlyerGameResources()); // Set up our screens. PBE.screenManager.registerScreen ("intro_screen",new IntroScreen()); PBE.screenManager.registerScreen ("game_screen",new GameScreen()); // Show the intro_screen - Then wait for a user click and it calls 'restartGame()' PBE.screenManager.goto ("intro_screen"); } //-------------------------------------- // Methods //-------------------------------------- //PRIVATE /** * PBE: Restart Game * * @return void */ public function restartGame ( ) : void { //PLAY SOUND PBE.soundManager.play( PBFlyerGameResources.SOUNDTRACK_SOUND,"sfx",1,9999); //loop many times,'forever' // CLEAR SCREEN (IF 'RE'-STARTING). Not Fully Working So Restart is Disabled After Gameplay _clearEverything (); // CREATE SCENE ENTITY _createScene(); // CREATE BACKGROUND ENTITY _createBackgroundEntity(); // CREATE OBSTACLE ENTITIES _createObstacleEntities(); // CREATE FLYER ENTITY _createFlyerEntity(); } /** * PBE: CLEAR SCENE * * @return void */ private function _clearEverything ( ) : void { //clear any screen entities PBE.rootGroup.destroy(); PBE.rootGroup.clear(); } /** * PBE: CREATE SCENE ENTITY * * @return void */ private function _createScene ( ) : void { //make the scene var sceneView : SceneView = new SceneView(); sceneView.width = WIDTH; sceneView.height = HEIGHT; PBE.initializeScene (sceneView,FlyerGameHelper.SCENE,null,Box2DManagerComponent); // Adjust graphics for convenience PBE.scene.setWorldCenter ( new Point (-WIDTH,-HEIGHT)); //PHYSICS ARE NOT NEEDED SO WE DISABLE GRAVITY //BUT 'BOX2D' IS USED FOR ITS COLLISION DETECTION - NICE! (PBE.spatialManager as Box2DManagerComponent).gravity = new Point (0,0); } /** * PBE: CREATE FLYER ENTITY * * @return void */ private function _createFlyerEntity ( ) : void { ////////////////// // PROPERTIES ////////////////// var position_point : Point = new Point (WIDTH*.65,HEIGHT-50); var size_point : Point = new Point (.1,.1); var zIndex_uint : uint = 10; ////////////////// // ENTITY ////////////////// // Allocate an entity for our background sprite var flyer_entity:IEntity = PBE.allocateEntity(); FlyerGameHelper.createSpatialEntity ( flyer_entity,position_point,size_point); ////////////////// // COLLISION DETECTION ////////////////// var collisionType_str : String = "Flyer"; var collidesWithCollisionTypes_array : Array = ["Obstacle"]; FlyerGameHelper.enableCollisionDetection ( flyer_entity,collisionType_str,collidesWithCollisionTypes_array,true); ////////////////// // RENDER // COMPONENTS ////////////////// // LOAD MC ASSET var swfSpriteSheetComponent : SWFSpriteSheetComponent = new SWFSpriteSheetComponent(); FlyerGameHelper.loadMovieClipAsset (swfSpriteSheetComponent,PBFlyerGameResources.ASSETS_SWF,PBFlyerGameResources.MOVIE_CLIP_OBSTACLE_FLYER); // USE ASSET TO RENDER var spriteSheetRenderer:SpriteSheetRenderer = new SpriteSheetRenderer(); FlyerGameHelper.setupSpriteSheetRenderer ( spriteSheetRenderer,swfSpriteSheetComponent,zIndex_uint); // CREATE ANIMATION LOOP #1 var idle_animationControllerInfo:AnimationControllerInfo = new AnimationControllerInfo(); idle_animationControllerInfo.loop = false; idle_animationControllerInfo.frameRate = 1; idle_animationControllerInfo.spriteSheet = swfSpriteSheetComponent; // CREATE ANIMATION LOOP #2 var move_animationControllerInfo:AnimationControllerInfo = new AnimationControllerInfo(); move_animationControllerInfo.loop = true; move_animationControllerInfo.frameRate = 1; move_animationControllerInfo.maxFrameDelay = 250; move_animationControllerInfo.spriteSheet = swfSpriteSheetComponent; // SAVE ALL ANIMATION LOOPS var animationController : AnimationController = new AnimationController (); animationController.spriteSheetReference = new PropertyReference (FlyerGameHelper.RENDER_SPRITE_SHEET); animationController.currentFrameReference = new PropertyReference (FlyerGameHelper.RENDER_SPRITE_INDEX); animationController.animations [FlyerGameHelper.ANIMATION_IDLE] = idle_animationControllerInfo; animationController.animations [FlyerGameHelper.ANIMATION_MOVE] = move_animationControllerInfo; animationController.defaultAnimation = FlyerGameHelper.ANIMATION_IDLE; animationController.currentAnimationName = FlyerGameHelper.ANIMATION_IDLE animationController.changeAnimationEvent = FlyerGameHelper.ANIMATION_CHANGE_EVENT; animationController.currentAnimationReference = new PropertyReference (FlyerGameHelper.CURRENT_ANIMATION_REFERENCE); // ADD COMPONENTS flyer_entity.addComponent(animationController,FlyerGameHelper.ANIMATION_CONTROLLER); flyer_entity.addComponent(spriteSheetRenderer,FlyerGameHelper.RENDER); ////////////////// // MOVE-BY-KEYBOARD // COMPONENT ////////////////// // Create an instance of our hero controller component var moveByKeyboardInputComponent:MoveByKeyboardInputComponent = new MoveByKeyboardInputComponent(); flyer_entity.addComponent( moveByKeyboardInputComponent,MoveByKeyboardInputComponent.NAME); ////////////////// // SCREEN-TRAP/WRAP // COMPONENT ////////////////// var isScreenWrapping_boolean : Boolean = false; //Try (true) and see the flexibility of PBE if (isScreenWrapping_boolean) { //EXPERIMENT: WRAP AROUND SCREEN (From Left Edge to Right Edge,Etc...) var screenWrapComponent : ScreenWrapComponent = new ScreenWrapComponent(); flyer_entity.addComponent ( screenWrapComponent,ScreenWrapComponent.NAME ); } else { //EXPERIMENT: BE 'TRAPPED' AND STAY IN SCREEN'S BOUNDS var screenTrapComponent : ScreenTrapComponent = new ScreenTrapComponent(); flyer_entity.addComponent ( screenTrapComponent,ScreenTrapComponent.NAME ); } ////////////////// // FACE-FORWARD // COMPONENT ////////////////// var faceForwardComponent : FaceForwardComponent = new FaceForwardComponent(); flyer_entity.addComponent ( faceForwardComponent,FaceForwardComponent.NAME ); ////////////////// // COLLISION-DETECTION // COMPONENT ////////////////// var collisionDetectComponent : CollisionDetectComponent = new CollisionDetectComponent(); flyer_entity.addComponent ( collisionDetectComponent,CollisionDetectComponent.NAME ); ////////////////// // GAME-OVER // COMPONENT ////////////////// var gameOverComponent : GameOverComponent = new GameOverComponent (); flyer_entity.addComponent ( gameOverComponent,GameOverComponent.NAME ); ////////////////// // INITIALIZE ////////////////// flyer_entity.initialize ("flyer_entity"); } /** * PBE: CREATE OBSTACLE ENTITIES * * @return void */ private function _createObstacleEntities ( ) : void { // CREATE OBSTACLE ENTITY (MOVIE_CLIP_APPEARANCE,POSITION,AND DRAWING DEPTH) _createObstacleEntity ( PBFlyerGameResources.MOVIE_CLIP_OBSTACLE_BIPLANE,new Point (WIDTH*.0,HEIGHT*0.20),30); _createObstacleEntity ( PBFlyerGameResources.MOVIE_CLIP_OBSTACLE_BLIMP,new Point (WIDTH*.20,HEIGHT*0.40),2,-1,25); _createObstacleEntity ( PBFlyerGameResources.MOVIE_CLIP_OBSTACLE_BIPLANE,new Point (WIDTH*.35,HEIGHT*0.55),3,15); _createObstacleEntity ( PBFlyerGameResources.MOVIE_CLIP_OBSTACLE_BLIMP,new Point (WIDTH*.50,HEIGHT*0.70),4,35); } /** * PBE: CREATE OBSTACLE ENTITIES * * @return void */ private function _createObstacleEntity (aMovieClipName_str : String,aPosition_point : Point,aZIndex_uint : uint,aHorizontalDirection_int : int,aHorizontalSpeed_num : Number) : void { ////////////////// // ENTITY ////////////////// // Allocate an entity var obstacle_entity:IEntity = PBE.allocateEntity(); FlyerGameHelper.createSpatialEntity ( obstacle_entity,aPosition_point); ////////////////// // COLLISION DETECTION ////////////////// var collisionType_str : String = "Obstacle"; var collidesWithCollisionTypes_array : Array = ["Flyer"]; FlyerGameHelper.enableCollisionDetection (obstacle_entity,false); ////////////////// // RENDER // COMPONENTS ////////////////// // LOAD MC ASSET var swfSpriteSheetComponent : SWFSpriteSheetComponent = new SWFSpriteSheetComponent(); FlyerGameHelper.loadMovieClipAsset (swfSpriteSheetComponent,aMovieClipName_str); // USE ASSET TO RENDER var spriteSheetRenderer:SpriteSheetRenderer = new SpriteSheetRenderer(); FlyerGameHelper.setupSpriteSheetRenderer (spriteSheetRenderer,aZIndex_uint); // ADD AS RENDERER obstacle_entity.addComponent( spriteSheetRenderer,FlyerGameHelper.RENDER ); ////////////////// // MOVE-HORIZONTALLY // COMPONENT ////////////////// var moveHorizontallyComponent:MoveHorizontallyComponent = new MoveHorizontallyComponent(); moveHorizontallyComponent.horizontalDirection_int = aHorizontalDirection_int; moveHorizontallyComponent.horizontalSpeed_num = aHorizontalSpeed_num; obstacle_entity.addComponent ( moveHorizontallyComponent,MoveHorizontallyComponent.NAME ); ////////////////// // SCREEN-WRAP // COMPONENT ////////////////// var screenWrapComponent : ScreenWrapComponent = new ScreenWrapComponent(); obstacle_entity.addComponent ( screenWrapComponent,ScreenWrapComponent.NAME ); ////////////////// // FACE-FORWARD // COMPONENT ////////////////// var faceForwardComponent : FaceForwardComponent = new FaceForwardComponent(); obstacle_entity.addComponent ( faceForwardComponent,FaceForwardComponent.NAME ); ////////////////// // INITIALIZE ////////////////// obstacle_entity.initialize("obstacle_entity" + aZIndex_uint); } /** * PBE: CREATE BACKGROUND ENTITY * * @return void */ private function _createBackgroundEntity ( ) : void { ////////////////// // PROPERTIES ////////////////// var position_point : Point = new Point (0,0); var zIndex_uint : uint = 1; ////////////////// // ENTITY ////////////////// // Allocate an entity for our background sprite var background_entity:IEntity = PBE.allocateEntity(); background_entity.initialize ("background_entity"); FlyerGameHelper.createSpatialEntity ( background_entity,position_point); ////////////////// // RENDER // COMPONENTS ////////////////// // LOAD MC ASSET var swfSpriteSheetComponent : SWFSpriteSheetComponent = new SWFSpriteSheetComponent(); FlyerGameHelper.loadMovieClipAsset (swfSpriteSheetComponent,PBFlyerGameResources.MOVIE_CLIP_BACKGROUND_GAME_SCREEN); // USE ASSET TO RENDER var spriteSheetRenderer:SpriteSheetRenderer = new SpriteSheetRenderer(); FlyerGameHelper.setupSpriteSheetRenderer (spriteSheetRenderer,zIndex_uint); // ADD AS RENDERER background_entity.addComponent( spriteSheetRenderer,FlyerGameHelper.RENDER ); } } } Component communication In Figure 2 we see the four components used by FlyerEntity. Required of every PBE game,components must communicate. One component responsible for the rendering of the entity,must check the position and rotation from another component before drawing itself onscreen. PBE is flexible in this communication. Three types of component-to-component communication exist in PBE: ●??????Direct-Access — Here one component holds a reference to another component hard-coded and calls methods as needed. This is simple to use but it introduces dependencies and makes code less portable. Generally it is to be avoided. ●??????Events — Useful for broadcasting info,just like in ActionScript and Flex. Typically events are broadcast from a component via the Entity. Other components 'listen' to the Entity for those events. This is more favorable than direct-access because it requires less 'knowledge' between components; thus more independence. ●??????Property References — This is the best way to communicate. There is a simple syntax and there are no hard-coded dependencies. Code is more flexible and reusable. Property references are heavily used in the Flyer game. Available in the download to this article is the 'ScreenWrapComponent.as' class. Reviewing this class,it will be evident how a property reference to position and a property reference to size are used to keep the Flyer within the screen's bounds at all times. To recap,the PBE world is full of entities. Each entity has components. To communicate between any two components in the world the preferred manner is to use property references. Where to next? With deeper exploration into PBE its XML Level loading system and its ResourceManager the power of PBE become more evident. There is certainly much to learn but the rewards are many. To learn more,download and investigate the Flyer game from this article,checkout the PBE website,and then get started by developing a very simple game or two. There is a wealth of information available to PBE developers: ●??????Games?Showcase?— See great games created by the community to get inspired ●??????Community?Forum?— Post questions and learn from others; project leaders regularly offer advice and code samples,too ●??????Component?Store?— Download and upload free and premium components ●??????Documentation?— Learn basic and advanced info with tutorials,AsDocs,and more Conclusion I wish PBE existed in every [programming] language.-?Phil?Peron,Professional Game Developer PBE comes packed with great game-specific tools that are ready right out-of-the-box. We've seen the promise of power and flexibility in PBE's component-based development methodology. The scalability and speed-of-use of the property referencing systems is tricky at first will be well worth the effort. Get your feet wet with a simple game or two and then set out to create your next Flash Platform game masterpiece with the PushButton Engine. Acknowledgements: I want to offer a special thanks to the contributors of this article,to Autumn Rain Turkel ofTangledDreams?who created all art for the Flyer game,and to all of the developers and community leaders who provided valuable insight and expertise for this article. I'd also like to thank?Minimal?Noise?for providing the sound track used in the Flyer game. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |