What is FANG? - go to fangengine.com and look around - Freely Available Networked Gaming engine - Written specifically for making game development simple - makes things like graphics, collision handling, etc much easier - leads to some limitations though How does FANG work? 1. Applet/Application initialization 2. Connects all players (if necessary) 3. Starts/initializes the game 4. Gameplay 5. End of game 6. Quit Applet/Application initialization 1. Constructor of class that extends GameLoop is called 2. Reads parameters from HTML for applets only. Sets parameters for the game for number of players, server, and game name. 3. Sets default values for input fields Connects all players - the screen that comes up where you must press "Connect & Start Game" button 1. If # of players is one or all fields are NOT selectable, skips the stage. 2. Sets the game server to the input domain for applets and localhost for applications. 3. Client connects when the button is pressed. 4. Waits for all players to connect (game server and game name must be exactly the same). Starts/initializes the game 1. Calls startGame method of the primary class (the one that extends GameLoop) - startGame should create and add Sprites and explicitly initialize all variables. - startGame is also called when starting over Gameplay 1. All interrups (keyboard, mouse, player, etc) are sent to game server. 2. Client receives this info from server along with current game time. 3. Alarms set to go off at the time have their methods called. 4. All sprites update via their tracker 5. advanceFrame in primary class is called 6. advanceFrame is called on the current Level is the game has levels Game over 1. Starts when there are no more levels or when setGameOver( true) is called for the first time. 2. If using Levels and getGameOverLevel is defined, the returned level is set as the current Level. 3. This is a good way to have the game start over by having the game over level call startOver. The Big Three: Sprites - the graphical objects you will use Trackers - how to make things move Alarms - how to make things happen at certain times Sprites - the term comes from the early days of gaming, when it meant a 2D image of something, today people sometimes use it to mean 3D objects though they shouldn't - basically sprites are everything in the classic games like asteroids, centipede, galaga, mario, etc up until N64/Dreamcast/PS came out - several basic types: OvalSprite, RectangleSprite, ImageSprite, PolygonSprite, and StringSprite - OvalSprite - makes an oval, OvalSprite( radius_width, radius_height ) - RectangleSprite - makes a rectangle, RectangleSprite( width, height ) - PolygonSprite - makes a regular polygon, PolygonSprite( number_of_sides ) - ImageSprite - makes a sprite using an image you supply, ImageSprite( "resources/yourfile.extension" ) - note you need to place the image inside the resources folder that is in your project folder - there are many supported image formats, I suggest sticking to png, jpg, or gif (for animated images) - other than specific cases, when creating a sprite start with a transparent background - StringSprite - makes a sprite using text, StringSprite( "your text here" ) - Wackadot's score is a good example of using StringSprite - common Sprite creation: Sprite s = new RectangleSprite( 2, 3 ) ; s.setUseBoundingBox( true ) ; s.setScale( 0.4 ) ; s.setLocation( 0.5, 0.5 ) ; s.setColor( Color.RED ) ; - attributes: shape, location, size, rotation, color - can have a Tracker if desired - other methods typically used: - test if something has hit a sprite: yourSprite.intersects( anotherSprite ) - making something invisible: yourSprite.setVisible( false ) ; - note: even if invisible collisions still happen - use removeSprite or move sprite offscreen to stop collisions - remove completely: removeSprite( yourSprite ) - move: either setLocation( x, y ) or translate( deltaX, deltaY ) Trackers - these make Sprites move, usually easier than calling setLocation or translate all the time - common methods: 1. getTranslation( ) -> returns Point2D.Double 2. getScaleFactor( ) -> returns double 3. getRotation( ) -> returns double 4. advanceTime( double timePassed ) -> returns nothing (void) - the important one is advanceTime - if writing your own tracker you will need to override advanceTime to make it work with how you want the tracker to behave - ProjectileTracker from Pong is a good "starting point" for creating a tracker and in most cases will not even need to be edited - +[TrackerExample]+ Alarms - way to set up timing in a game - ex. having Wackadot end after 30 seconds - ex. having something happen every x seconds - +[Wackadot example]+ So how do I use it? - download (from our class homepage or fangengine.com) FANG - assuming you are starting from a simple class with main written already: - add "import fang.* ;" to the top of your java file - add "extends GameLoop" after "public class YourClassName" - add "YourClassName something = new YourClassName( ) ;" and "something.runAsApplication( ) ;" to your main method - that's it!... well technically - usually want makeSprites, addSprites, and sometimes handleCollisions and advanceFrame methods - inside your class constructor you should do other setup along with calling makeSprites, then have either the constructor or makeSprites call addSprites FANG's Window - the window's coordinates go as follows: - top left corner is (0,0) - x increases from 0 to 1 going left to right - y increases from 0 to 1 going top to bottom Random Numbers - because of networking issues FANG has its own random number generator - fortunately, this makes things easier on us - random.nextDouble( ) -> gives a double between 0 (inclusive) and 1 (exclusive) - random.nextInt( max ) -> gives an int between 0 (inclusive) and max (exclusive) AdvanceFrame - this gets called every frame (25 times per second) - usually has code to handle collisions, input, and anything else that occurs frequently ------------------------------------------------------------------------------- A typical template for a FANG engine game: package yourclass ; import fang.* ; import java.awt.Color ; import java.geom.* ; public class YourClass extends GameLoop { // put class variables here private Sprite example ; public void startGame( ) { // want to make sprites, add them to canvas, and initialize any class variables makeSprites( ) ; addSprites( ) ; } public void makeSprites( ) { // create sprites here like example = new OvalSprite( 1, 1 ) ; example.setLocation( .5, .5 ) ; example.setScale( .1 ) ; example.setColor( Color.RED ) ; } public void addSprites( ) { // add sprites to the canvas canvas.addSpte( example ) ; } public void advanceFrame( double timePassed ) { // handle the gameplay here, called every frame // usually a "handleCollisions" method is called from here when needed } public static void main( String[ ] args ) { YouClass yc = new YourClass( ) ; yc.players = 1 ; yc.playerSelectable = false ; // whether you want the user to be able to change the number of players when the game starts up yc.runAsApplication( ) ; } }