Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon

How-To Tutorials - 2D Game Development

64 Articles
article-image-developing-and-deploying-virtual-world-environment-flash-multiplayer
Packt
16 Aug 2010
7 min read
Save for later

Developing and Deploying Virtual World Environment for Flash Multiplayer

Packt
16 Aug 2010
7 min read
(For more resources on Flash, see here.) Comparing SmartFoxServer Lite, Basic, and Pro SmartFoxServer is a commercial product by gotoAndPlay(). There are three package options of SmartFoxServer. They are Lite version, Basic version, and Pro version. The demo license of the SmartFoxServer provides full features with 20 concurrent users maximum without time limitation. We will use the demo license to build the entire virtual world throughout the article. SmartFoxServer Lite The Lite version was the original SmartFoxServer since 2004. The maximum concurrent connection is limited to 50. It supports some core features like message passing, server-side user/room variables, and dynamic room creation. However, the lack of ActionScript 3.0greatly limits the performance and functionality. Moreover, it is being updated slowly so that many new features from Basic and Pro version are missing in Lite version. When we compare the version number of the three options, we will know that Lite version is developing at a slow pace. The version of SmartFoxServer Pro is 1.6.6 at the time of writing. The Basic version is 1.5.9 and the Lite version is only 0.9.1. Because of the slow update, not supporting ActionScript 3 and lack of features, it is not recommended to use Lite version in production. SmartFoxServer Basic SmartFoxServer Basic supports ActionScript 3 and a bunch of advanced features such as administration panel, game room spectators, and moderators. The administration panel lets moderators configure the zones, rooms, and users when the server is running. However, the lack of server-side extension support limits the customizability of the socket server. It also means that all logic must reside on the client side. This raises a security issue that the client may alter the logic to cheat. The Basic version provides enough features to build a Flash virtual world in small scale that does not require high security. If you need a specific server logic and room management or want to put logic in server side to prevent client-side cheating, Pro version is the choice. SmartFoxServer Pro There is a long list of features that are supported in Pro version. There are three features amongst all that distinguish the Pro version, they are: Server-side extension that modifies the server behavior JSON/Raw data protocol message passing Direct database connection Modifying the behavior of server Server-side extension is some server logic that developers can program to modify the default behavior of the internal event handler and add server-side functions to extend the server for specific usage. For example, we may want to override the "user lost" event so that we can save the user properties, telling others that someone is disconnected and something else. In this case, we can write a function in server-side extension to handle all these things when the user lost, instead of running the default behavior that was provided by SmartFoxServer. The SmartFoxServer is written in Java. Therefore the native support language of server-side extension is Java. In order to reduce the development difficulties, SmartFoxServer supports Python and ActionScript as a server-side extension. The support of ActionScript makes it much more convenient for most Flash developers to develop the server-side extension without even knowing Java. Please note that the version of ActionScript supported in server-side extension is ActionScript 1, instead of ActionScript 3. Take a look at the following code snippet on a server-side extension. The functions in server-side extensions are often similar to this one. It comes with arguments to know which user is calling this command at which room. In this snippet there is a command called getSomething and it will use the provided command parameters to get the result and return the result to the corresponding user. function handleRequest(cmd, params, user, fromRoom){ var response = {}; switch (cmd) { case "getSomething": var cpu = params['cpuType’]; response.something = "A Powerful Computer with CPU "+cpu; // send the response back to the client. _server.sendResponse(response,-1,null,[user]); break }} JSON/Raw data protocol JSON (http://www.json.org) is a light-weight text-based data-interchange format. It is designed for both humans and machines to read and write the data easily. For example, we can format a list of users and their information with the following JSON code. {"users": [ { "name" : "Steve", "level" : 12, "position" : { "x" : 6, "y" : 7 }, { "name" : "John", "level" : 5, "position" : { "x" : 26, "y" : 12 }} The default data protocol supported by SmartFoxServer Lite and Basic is XML. The Pro version added support of JSON and raw data protocol make it possible to compress the transfer of data between clients and server. The length of messages between clients and server is much shorter and it means the transmission speed is much faster. Take an example of a client sending data to a server with different protocols. We are now trying to fetch some data from the server, and this is what it looks like when sending a command to the server via different protocol. XML: <dataObj><var n=’name’ t=’s’>extension</var><var n=’cmd’t=’s’>getSomething</var><obj t=’o’ o=’param’><var n=’cpuType’t=’n’>8</var></obj></dataObj> The length of this command is 148 bytes. JSON: {"b":{"p":{"cpuType":8},"r":1,"c":"getSomething","x":"extension"},"t":"xt"} The length of this command is 75 bytes. Raw Data: %xt%extension%getSomething%8% The length of this command is 29 bytes. When comparing with the bytes used to send a command over the network, XML is two times the JSON and five times the raw protocol. We are talking about several byte differences that may not be considered in a broadband Internet. However, it is a must to consider every byte that was sent to the network because we are not talking about 29 bytes versus 148 bytes in the real applications. Imagine there are 2000 players in the virtual world, sending similar commands every second. We are now talking about 2.4Mbit/s versus 500Kbit/s, and this rough statistic already ignores those commands that fetch a long list of results, for example, a long list of items that are owned by the player. The raw protocol format takes less bytes to represent the command because it does not contain the field name of the data. All parameters are position-dependent. In the preceding command, the first parameter stands for an extension message and the second stands for the command name. Other command-specific parameters follow these two parameters. Raw protocol is position-dependent on the passing parameters while JSON is not. It is recommended to use JSON protocol in most case and use the raw data protocol in real-time interaction parts. Also, we should state clearly in comments code what each parameters stands for because others cannot get the field information from the raw data. Accessing the database directly Flash does not provide any database access functions. Flash applications always connect to database via server-side technique. The Pro version of SmartFoxServer provides direct database connectivity in server-side extension. The Flash virtual world will call a function in sever-side extension and it will handle the database connection for the Flash. As the database connectivity is handled in server-side extension, Basic and Lite version does not contain this handy feature. We have to wrap the database access in other server-side technique, such as PHP, to connect database in Basic and Lite version. The two graphs compare the architecture of the database access in SmartFoxServer Pro, Basic, and Lite.
Read more
  • 0
  • 0
  • 1402

article-image-flash-10-multiplayer-game-game-interface-design
Packt
28 Jul 2010
10 min read
Save for later

Flash 10 Multiplayer Game: Game Interface Design

Packt
28 Jul 2010
10 min read
(For more resources on Flash and Games, see here.) Overview of Pulse library components The Pulse package includes two components Pulse.swc and PulseUI.swc.The Pulse.swc offers the API required for you to build a multiplayer game. While PulseUI offers the game screen management, both aid in the rapid development of your game. The Pulse.swc is required in order to communicate with the server and with other clients. The usage of PulseUI, on the other hand, is optional. It is recommended to use the PulseUI since it allows you to focus only on the game implementation and leaves the standard feature set of a multiplayer game to be taken care of by the PulseUI package. Once you have the implementation of your game done and working well, you can then replace the PulseUI package with something of your own that is more suited to your game. The following is a block diagram that shows the dependencies among different components: The Pulse API design The interaction of the game client with the server and other clients happens primarily via two classes that expose the Pulse features: GameClient GameClientCallback The GameClient is primarily used to send request to the server while creating a room, joining a room, or sending a message to other players such as chat or game state updates during game play. The GameClientCallback is an AS3 interface class for which one of the classes within the GameClient must implement. All notifications from the server are processed by the Pulse layer and corresponding notifications are called on the implementation of the callback class—for example, when a create room request was successful or when a chat message was received, etc. Creating the Hello World sample Let us now explore the Hello World sample that is included in the Pulse package. The Hello World sample and the rest of the samples rely heavily on the game screen management framework package, PulseUI, which is also included in the Pulse package along with the source code. In this article, we will focus on the code contained in the Hello World sample and how the sample makes use of the PulseUI. In order to explore the Hello World sample, we first need to create a project in Flash Builder—all the required source files already exists in the sample folders. The Hello World sample does the following: create a room or join an existing game room, then add, remove, or modify a game state—the changes done on one client instance are then reflected on all other clients that are in the same room. Think it is too much for a Hello World sample? It is not! These are just the basic functionalities for any multiplayer game. Moreover, we don't need to write the code for every bit of functionality because we heavily rely on Pulse SDK to do all the dirty work. Setting up the project Fire up the Flash Builder 4 IDE and let us start by creating an ActionScript project called Hello World: From the main menu, navigate to File | New | ActionScript Project. You will see the following screenshot. Enter a project name HelloWorld or any other name of your choice. Since we already have the entire source required for Hello World from the Pulse package, click on Next to specify that the source folder is already on the disk. This will bring up the following screen where we choose the Hello World src folder as shown. Note that the screenshot shows that Pulse was installed under F:Gamantra. This path may be different on your computer. Once we have chosen the source folder, we still need to choose the main source folder and main application file. Unfortunately, in order to do this, we need to navigate a bug in Flash Builder 4. You need to click on the Back button and then again on the Next button, bringing us back to where we were. We now click on the Browse button, as shown in the screenshot, and choose the [source path] src and click on OK. Next we choose the main application file—this determines the main class file that the execution will start with. We need to tell the Flash Builder to use the Pulse libraries for this project. In the Flash world, the library files come with an extension .swc, which stands for shockwave component. Once you make it available to your project, you can start using the classes and functions that are exposed from within the library. In order to do so, choose the Library Path tab view and click on the Add SWC… button; navigate to the lib folder within the Pulse installation folder and choose Pulse.swc and once again do the same procedure for PulseUI.swc. Click on the Finish button. As a final step, before attempting to run the sample, we also need to set the stage size to 800 (width) by 600 (height). The PulseUI requires the stage size to be exactly this size. We may also set the background color of our choice as shown in the following screenshot: After this step, Flash Builder 4 should be able to crunch all the code in folders and report no problems. This will also create the swf files under the project folder within the workspace ready for you to take it for a spin. At this point, you may also use the debugger to step through the code. But make sure the Pulse server is running so that you may login and explore all the screens. The Hello World specification The Hello World client will be able to create a new HelloGameState and share it with other players, and any player may change the x and y and have that change reflected in every player's screen. Here is the final screen that we will end up with: The screenshot is that of the game screen. The circles are a visual representation of the game states, the position of the circle comes from the corresponding game states x and y values and so does the color from the color property. We will have two buttons: one to add new game states and another to remove them. To add a new circle (a game state), we click on the Add button. To remove an existing game state, we click on any of the circles and click on the Remove button. The selected circle appears to be raised like the one on the far right-hand side of the screenshot. We may also modify an existing game state by moving the circles by clicking and dragging them to a different position—doing that on one client, we can observe the change in every other player's screen as well. The schema file For any Pulse-based game development, we first start out with an XML-formatted schema file. Let's now explore the schema file for the Hello World sample. The game developer must create a schema file that specifies all the needed game states, avatars, and game room objects. After you have created the schema file, we then use a Pulse modeler tool to create the class files based on the schema to be used within the game. So first let's examine the schema file for the Hello World project: <ObjectSchema> <import> <client import="pulse.gsrc.client.*" /> </import> <class name="HelloGameState" parent="GameState" classId="601" > <public> <property index="0" name="x" count="1" type="int"/> <property index="1" name="y" count="1" type="int"/> <property index="2" name="color" count="1" type="int"/> </public> </class></ObjectSchema> Navigate to the project folder where you have created the project and create a file called GameSchema.xml with the above content. We will not go through the details of the XML file in greater detail since it is out of the scope of this article. For the Hello World sample, we will define a game state object that we can use to share game states among all the players within a game room. We will name the class as HelloGameState, but you are welcome to call it by any name or something that makes sense to your game. You may also define as many game state classes as you like. For the HelloGameState in the schema file, each game state instance will define three properties, namely, x, y, and color. Code generator In order to create the AS3 class files from the schema file, you need to run the batch file called PulseCodeGen.bat found in the $bin folder. It takes the following three parameters: Path to schema file Namespace Output directory In order to make our life easier, let us create a batch file that will call the PulseCodeGen and pass all the required parameters. The reason for creating the batch file is that you have to code generate every time you modify the schema file. As you progress through your game implementation, it is normal to add a new class or modify an existing one. The convenience batch file may look like what's shown next. Let's call it .init.bat and save it in the same root folder for the sample along with the schema file. @ECHO OFFIF EXIST .srchwgsrcclient del .srchwgsrcclient*.asCALL "%GAMANTRA%"binPulseCodeGen.bat .GameSchema.xml hw.gsrc .srchwgsrcIF NOT %ERRORLEVEL% == 0 GOTO ERRORECHO Success!GOTO END:ERRORECHO oops!:ENDpause The schema file parameter to the Pulse code generator is specified as .GameSchema.xml because the schema file and the batch file are in the same folder. The second parameter is the package name for the generated classes—in this example, it is specified to be hw.gsrc. You specify the directory that the generated classes will be saved to as the last parameter. Note that the code generator appends client to both the package and directory into which it will be saved. It is also important to match the package name and directory structure as required by the AS3 compiler. Upon running the code gen successfully, there is one AS3 class generated for each class in the schema file and two additional supporting class files. One is a factory class called GNetClientObjectFactory, which is responsible for creating new instances of generated classes, and the other is GNetMetaDataMgr, which aids in serializing and de-serializing the transmitting data over the network. The data carried is what resides in the instances of generated classes. You don't need to deal with these two extra classes first hand; it is mostly used by the underlying Pulse runtime system. As for the generated classes for what is defined in the schema file, the name of the class would be identical to what is specified in the schema file plus the suffix Client. In this example, there would be a class generated with the name HelloGameStateClient.as. Go ahead and try running the batch file called init.bat under $samplesHelloWorld. Project directory structure The Hello World that is part of the Pulse package is organized into the following directory structure: hw gsrc client rsrc ui The package hw being the root package contains the main class HelloWorld.as, and the gsrc as you see contains the generated class. The rsrc folder contains the skin files, which we will discuss in more detail later in this article. The skin files in Pulse consist of three PNG files that provide all the basic buttons and background for the game. You can simply replace these PNG files with your own set, provided the individual elements with the file are of the exact dimensions and are placed at the exact same positions.
Read more
  • 0
  • 1
  • 2336

article-image-flash-10-multiplayer-game-lobby-and-new-game-screen-implementation
Packt
27 Jul 2010
5 min read
Save for later

Flash 10 Multiplayer Game: The Lobby and New Game Screen Implementation

Packt
27 Jul 2010
5 min read
(For more resources on Flash and Games, see here.) The lobby screen implementation In this section, we will learn how to implement the room display within the lobby. Lobby screen in Hello World Upon login, the first thing the player needs to do is enter the lobby. Once the player has logged into the server successfully, the default behavior of the PulseGame in PulseUI is to call enterLobby API. The following is the implementation within PulseGame: protected function postInit():void { m_netClient.enterLobby();} Once the player has successfully entered the lobby, the client will start listening to all the room updates that happen in the lobby. These updates include any newly created room, any updates to the room objects, for example, any changes to the player count of a game room, host change, etc. Customizing lobby screen In the PulseUI, the lobby screen is the immediate screen that gets displayed after a successful login. The lobby screen is drawn over whatever the outline object has drawn onto the screen. The following is added to the screen when the lobby screen is shown to the player: Search lobby UI Available game rooms Game room scroll buttons Buttons for creating a new game room Navigation buttons to top ten and register screens When the lobby is called to hide, the lobby UI elements are taken off the screen to make way for the incoming screen. For our initial game prototype, we don't need to make any changes. The PulseUI framework already offers all of the essential set of functionalities of a lobby for any kind of multiplayer game. However, the one place you may want to add more details is in what gets display for each room within the lobby. Customizing game room display The room display is controlled by the class RoomsDisplay, an instance of which is contained in GameLobbyScreen. The RoomsDisplay contains a number of RoomDisplay object instances, one for each room being displayed. In order to modify what gets displayed in each room display, we do it inside of the class that is subclassed from RoomDisplay. The following figure shows the containment of the Pulse layer classes and shows what we need to subclass in order to modify the room display: In all cases, we would subclass (MyGame) the PulseGame. In order to have our own subclass of lobby screen, we first need to create class (MyGameLobbyScreen) inherited from GameLobbyScreen. In addition, we also need to override the method initLobbyScreen as shown below: protected override function initLobbyScreen():void { m_gameLobbyScreen = new MyGameLobbyScreen();} In order to provide our own RoomsDisplay, we need to create a subclass (MyRoomsDisplay) inherited from RoomsDisplay class and we need to override the method where it creates the RoomsDisplay in GameLobbyScreen as shown below: protected function createRoomsDisplay():void { m_roomsDisplay = new MyRoomsDisplay();} Finally, we do similar subclassing for MyRoomDisplay and override the method that creates the RoomDisplay in MyRoomsDisplay as follows: protected override function createRoomDisplay (room:GameRoomClient):RoomDisplay { return new MyRoomDisplay(room);} Now that we have hooked up to create our own implementation of RoomDisplay, we are free to add any additional information we like. In order to add additional sprites, we now simply need to override the init method of GameRoom and provide our additional sprites. Filtering rooms to display The choice is up to the game developer to either display all the rooms currently created or just the ones that are available to join. We may override the method shouldShowRoom method in the subclass of RoomsDisplay (MyRoomsDisplay) to change the default behavior. The default behavior is to show rooms that are only available to join as well as rooms that allow players to join even after the game has started. Following is the default method implementation: protected function shouldShowRoom(room:GameRoomClient):Boolean { var show:Boolean; show = (room.getRoomType() == GameConstants.ROOM_ALLOW_POST_START); if(show == true) return true; else { return (room.getRoomStatus() == GameConstants.ROOM_STATE_WAITING); }} Lobby and room-related API Upon successful logging, all game implementation must call the enterLobby method. public function enterLobby(gameLobbyId:String = "DefaultLobby"):void You may pass a null string in case you only wish to have one default lobby. The following notification will be received again by the client whether the request to enter a lobby was successful or not. At this point, the game screen should switch to the lobby screen. function onEnteredLobby(error:int):void If entering a lobby was successful, then the client will start to receive a bunch of onNewGameRoom notifications, one for each room that was found active in the entered lobby. The implementation should draw the corresponding game room with the details on the lobby screen. function onNewGameRoom(room:GameRoomClient):void The client may also receive other lobby-related notifications such as onUpdateGameRoom for any room updates and onRemoveGameRoom for any room objects that no longer exist in lobby. function onUpdateGameRoom(room:GameRoomClient):voidfunction onRemoveGameRoom(room:GameRoomClient):void If the player wishes to join an existing game room in the lobby, you simply call joinGameRoom and pass the corresponding room object. public function joinGameRoom(gameRoom:GameRoomClient):void In response to a join request, the server notifies the requesting client of whether the action was successful or failed via the game client callback method. function onJoinedGameRoom(gameRoomId:int, error:int):void A player already in a game room may leave the room and go back to the lobby, by calling the following API: public function leaveGameRoom():void Note that if the player successfully left the room, the calling game client will receive the notification via the following callback API: function onLeaveGameRoom(error:int):void
Read more
  • 0
  • 0
  • 2279
Banner background image

article-image-flash-10-multiplayer-game-introduction-lobby-and-room-management
Packt
14 Jul 2010
7 min read
Save for later

Flash 10 Multiplayer Game: Introduction to Lobby and Room Management

Packt
14 Jul 2010
7 min read
(For more resources on Flash and Games, see here.) A lobby, in a multiplayer game, is where people hang around before they go into a specific room to play. When the player comes out of the room, the players are dropped into the lobby again. The main function of a lobby is to help players quickly find a game room that is suited for them and join. When the player is said to be in a lobby, the player will be able to browse rooms within the lobby that can be entered. The player may be able to see several attributes and the status of each game room. For example, the player will be able to see how many players are in the room already, giving a hint that the game in the room is about to begin. If it is a four-player game and three are already in, there is a greater chance that the game will start soon. Depending on the game, the room may also show a lot of other information such as avatar names of all the players already in the room and who the host is. In a car race game, the player may be able to see what kind of map is chosen to play, what level of difficulty the room is set to, etc. Most lobbies also offer a quick join functionality where the system chooses a room for the player and enters them into it. The act of joining a room means the player leaves the lobby, which in turn means that the player is now unaware or not interested in any updates that happen in the lobby. The player now only receives events that occur within the game room, such as, another player has entered or departed or the host has left and a new host was chosen by the server. When a player is in the lobby, the player constantly receives updates that happen within the lobby. For example, events such as new room creation, deletion, and room-related updates. The room-related updates include the players joining or leaving the room and the room status changing from waiting to playing. A sophisticated lobby design lets a player delay switching to the room screen until the game starts. This is done so as to not have a player feel all alone once they create a room and get inside it. In this design, the player can still view activities in the lobby, and there's an opportunity for players to change their mind and jump to another table (game room) instantaneously. The lobby screen may also provide a chatting interface. The players will be able to view all the players in the lobby and even make friends. Note that the lobby for a popular game may include thousands of players. The server may be bogged down by sending updates to all the players in the lobby. As an advanced optimization, various pagination schemes may be adopted where the player only receives updates from only a certain set of rooms that is currently being viewed on the screen. In some cases, lobbies are organized into various categories to lessen the player traffic and thus the load on the server. Some of the ways you may want to break down the lobbies are based on player levels, game genres, and geographic location, etc. The lobbies are most often statically designed, meaning a player may not create a lobby on the fly. The server's responsibility is to keep track of all the players in the lobby and dispatch them with all events related to lobby and room activity. The rooms that are managed within a lobby may be created dynamically or sometimes statically. In a statically created room, the players simply occupy them, play the game, and then leave. Also in this design, the game shows with a bunch of empty rooms, say, one hundred of them. If all rooms are currently in play state, then the player needs to wait to join a room that is in a wait state and is open to accepting a new player into the room. Modeling game room The game room required for the game is also modeled via the schema file (Download here-chap3). Subclassing should be done when you want to define additional properties on a game room that you want to store within the game room. The properties that you might want to add would be specific to your game. However, some of the commonly required properties are already defined in the GameRoom class. You will only need to define one such subclass for a game. The following are the properties defined on the GameRoom Class: Property Notes Room name Name of the game room typically set during game room creation Host name The server keeps track of this value and is set to the current host of the room. The room host is typically the creator. If the host leaves the room while others are still in it, an arbitrary player in the room is set as host. Host ID Is maintained by the server similar to host name. Password Should be set by the developer upon creating a new game room. Player count The server keeps track of this value as and when the players enter or leave the room. Max player count Should be set by the developer upon creating a new game room. The server will automatically reject the player joining the room if the player count is equal to the max player count Room status The possible values for this property are GameConstants.ROOM_STATE_WAITING or GameConstants.ROOM_STATE_PLAYING The server keeps track of these value-based player actions such as PulseClient.startGame API. Room type The possible values for this property are value combinations of GameConstants.ROOM_TURN_BASED and GameConstants.ROOM_DISALLOW_POST_START The developer should set this value upon creating a new room. The server controls the callback API behavior based on this property. Action A server-reserved property; the developer should not use this for any purpose. The developer may inherit from the game room and specify an arbitrary number of properties. Note that the total number of bytes should not exceed 1K bytes. Game room management A room is where a group of players play a particular game. A player that joins the room first or enters first is called game or room host. The host has some special powers. For example, the host can set the difficulty level of the game, set the race track to play, limit the number of people that can join the game, and even set a password on the room. If there is more than one player in the room and the host decides to leave the room, then usually the system automatically chooses another player in the room as a host and this event is notified to all players in room. Once the player is said to be in the room, the player starts receiving events for any player entering or leaving the room, or any room-property changes such as the host setting a different map to play, etc. The players can also chat with each other when they are in a game room. Seating order Seating order is not required for all kinds of games, for example, a racing game may not place as much importance on the starting position of the player's cars, although the system may assign one automatically. This is also true in the case of two-player games such as chess. But players in a card game of four players around a table may wish to be seated at a specific position, for example, across from a friend who would be a partner during the game play. In these cases, a player entering a room also requests to sit at a certain position. In this kind of a lobby or room design, the GUI shows which seats are currently occupied and which seats are not. The server may reject the player request if another player is already seated at the requested seat. This happens when the server has already granted the position to another player just an instant before the player requested and the UI was probably not updated. In this case, the server will choose another vacant seat if one is available or else the server will reject the player entrance into the room.
Read more
  • 0
  • 0
  • 6774
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime