iPhone Game Development - Chris Craft [101]
Now let's take time to look at the application in detail. The full source code for AmuckPuck can be found at http://appsamuckcom/airhockey.
FIGURE 7.17
The completed menu screen for AmuckPuck
FIGURE 7.18
The completed About Us screen for AmuckPuck
In AmuckPuck we are going to focus on the key class and structures that bring it to life. There are several other files in the application, but these are the standard menu and support files you should already be familiar with. The three items we will focus on are:
StateData and EventData. These are structures defined in HockeyData.h. They are used to store the state of the hockey table and are sent as GKSession messages between the host and the client.
HockeyTableView. This is the most important file in the application. It renders the paddles based on touch. It handles the physics necessary to animate the puck. It changes the way it behaves depending on how you connect.
HockeyViewController. This is the controller that plays host to the HockeyViewTable. This controller is responsible for standing up the HockeyTableView, managing, and delegating peer-to-peer duties.
Understanding the data
StateData and EventData are used to store and communicate data. StateData stores the current state of one of the paddles and the puck. The HockeyTableView uses two of these structures—one for each of the paddles it hosts. This is also sent between the client and host as a GKSession message:
#import Typedef struct { int packetType; int player; int step; bool intersect; CGPoint paddleLocation; CGPoint paddleVelocity; CGPoint puckLocation; CGPoint puckVelocity; double puckRotation; double puckAngle; } StateData; EventData is used only to communicate major system events. When a goal is scored, this message is sent from the host to the client to communicate the event: typedef struct { int packetType; int eventType; int clientScore; int hostScore; } EventData; What is needed to draw the hockey table Next is the first piece of the HockeyTableView header—this is the big one. The following definitions supply several knobs to turn so you can fine-tune the behavior and physics of the hockey table: #define ANIMATION_INTERVAL 1.0 / 60.0 #define MAX_TOP_PLAYER_Y 200 #define MIN_BOTTOM_PLAYER_Y 280 #define MAX_PADDLE_STRIKE 15.0 #define MIN_PADDLE_STRIKE 2.5 #define PADDLE_STRIKE 1.5 #define PUCK_DECAY_RATE 0.10 #define PUCK_SPIN_DECAY_RATE 0.05 #define PUCK_DIAMETER 40 #define PUCK_RADIUS 20 #define PADDLE_DIAMETER 80 #define PADDLE_RADIUS 40 #define GOAL_START 80 #define GOAL_END 240 The following enumerations are used to define and communicate the different states that the table can assume: typedef enum { NO_CONNECTION = 0, HEADTOHEAD_CONNECTION, HOST_CONNECTION, CLIENT_CONNECTION } ConnectionType; typedef enum { BOTTOM_PLAYER = 0, TOP_PLAYER } PlayerCode; typedef enum { SCORE_MESSAGE = 0, WIN_MESSAGE } MessageCode; HockeyTableViewDelegate is a protocol that is used to send an alert when a goal has been scored. This protocol is needed by the HockeyViewController so it can send out a message when a goal is scored: @protocol HockeyTableViewDelegate @optional - (void)hockeyTableDidScore:(PlayerCode)playerCode; @end Next is the remaining “public” definition for the HockeyTableView interface: @interface HockeyTableView : UIView { id ConnectionType connectionType; CALayer *bottomPaddleLayer;