아이폰어플개발정보2010. 6. 21. 18:31
[펌] iPhone Gaming Framework: Stage1 Turorial

출처:http://eguru.co.kr/775

Buckle in guys, this is going to be a rather large tutorial. The goal for this tutorial is to get a basic screen management system up and running, ready to start writing game code. I would like to start off by saying the following: This is not the only way to get a project up and running! There are many many many ways of solving problems in the programming world. Some people might prefer to use Cocos2D for the iPhone, while others might prefer to roll their own engine from scratch. I did this more as a learning process for myself, and now that I’ve learned what I could, i thought I should share the knowledge to everyone else who is struggling with the problems that I’ve solved.

Also, keep in mind that this screen management system is basically a port of the GameStateManagement demo from the XNA sample ( http://creators.xna.com/ ) from C# to Objective-C with some modifications. Anyone currently using XNA should have a fairly easy time porting this over, as a lot of the code should be recognizable to you.

So, now that I’ve got that out of the way, lets begin! Your first step is going to head over to Jeff’s blog iPhoneDevelopment and pick up the Updated OpenGL Xcode Project Template.

Next step, is to follow his directions and install it! Once you have it installed, load a new project using his template. You will find that a few things are different, and a whole lot is added. Open up the GLView.m in the classes subdirectory, and add the following four methods:

  1. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event   
  2. {   
  3.     [controller touchesBegan:touches withEvent:event InView:self  WithTimer:animationTimer];   
  4. }   
  5. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event   
  6. {   
  7.     [controller touchesMoved:touches withEvent:event InView:self  WithTimer:animationTimer];   
  8. }   
  9. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event   
  10. {   
  11.     [controller touchesEnded:touches withEvent:event InView:self  WithTimer:animationTimer];   
  12. }   
  13. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event   
  14. {   
  15.     [controller touchesCancelled:touches withEvent:event InView:self  WithTimer:animationTimer];   
  16. }  
  17. What this is going to do, is when your iPod touch or iPhone is touched, a message is sent to the GLView. We are going to capture that message, and send it to the GLViewController. Okay, got that done? GREAT! Now comes the fun stuff.

    Open up your GLViewController.h file. You are going to be putting in quite a bit of code, and i’ll explain everything when we do the .m file, so for right now just adjust your .h file to look like the following. You’ll see the .m file is HEAVILY commented to show what everything is and what it does, and i’ll make some additional notes here as well… so here is the GLViewController.h file.

    1. //
    2. //  The View Controller is a service which mananges one or more GameScreen
    3. //  instances. It maintains a stack of screens, calls their Update and Draw
    4. //  methods at the appropriate times, and automatically routes the input to
    5. //  the topmost active screen.
    6. //
    7. //  Created by XNA Development Team ( http://creators.xna.com/ ) as a
    8. //  ScreenManager.cs GameComponent.
    9. //
    10. //  Adapted for iPhone Game Development by Craig Giles on 1/1/09.
    11. //
    12. //
    13. //  Import statements
    14. //
    15. #import <UIKit/UIKit.h>
    16. #import <OpenGLES/EAGL.h>
    17. #import <OpenGLES/ES1/gl.h>
    18. #import <OpenGLES/ES1/glext.h>
    19. #import "Texture2D.h"
    20. #import "InputManager.h"
    21. #import "GameScreen.h"
    22. #import "TitleScreen.h"
    23. @class GLView;   
    24. @interface GLViewController : UIViewController   
    25. {   
    26.     NSMutableArray *screens;   
    27.     NSMutableArray *screensToUpdate;   
    28.     InputManager *input;   
    29.     Texture2D *blankTexture;   
    30. bool isInitialized;   
    31. bool traceEnabled;     
    32.     UIView *gameView;   
    33.     CGRect viewport;   
    34. }   
    35. //
    36. //  Properties
    37. //
    38. @property (nonatomic, retain) NSMutableArray *screens;   
    39. @property (nonatomic, retain) NSMutableArray *screensToUpdate;   
    40. @property (nonatomic, retain) InputManager *input;   
    41. @property (nonatomic, retain) Texture2D *blankTexture;   
    42. @property (nonatomic, readwrite) bool isInitialized;   
    43. @property (nonatomic, readwrite) bool traceEnabled;   
    44. @property (nonatomic, retain) UIView *gameView;   
    45. @property (nonatomic, readwrite) CGRect viewport;   
    46. //
    47. //  Methods
    48. //
    49. - (void) setupView:(GLView*)view;   
    50. - (void) loadContent;   
    51. - (void) addScreen:(GameScreen *)screen;   
    52. - (void) removeScreen:(GameScreen *)screen;   
    53. - (void) releaseScreen:(GameScreen *)screen;   
    54. - (void) updateView:(GLView *)view WithTime:(float)deltaTime;   
    55. - (void) drawView:(GLView *)view WithTime:(float)deltaTime;   
    56. - (void) traceScreens;   
    57. - (void) fadeBackBufferToBlack:(double)alpha;   
    58. //
    59. //  Touches events
    60. //
    61. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer;   
    62. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer;   
    63. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer;   
    64. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer;   
    65. @end  
    66. Its a good idea to look through the .h file to see what you can do with the screen manager. Obviously you can do the touch events (remember we connected those from the GLView?) but also, looking at the methods you will be able to add and remove screens from the screen manager, update and draw, fade back buffer to black, and a few other things. Lets see how it all works!

      1. //
      2. //  The View Controller is a service which mananges one or more GameScreen
      3. //  instances. It maintains a stack of screens, calls their Update and Draw
      4. //  methods at the appropriate times, and automatically routes the input to
      5. //  the topmost active screen.
      6. //
      7. //  Created by XNA Development Team ( http://creators.xna.com/ ) as a
      8. //  ScreenManager.cs GameComponent.
      9. //
      10. //  Adapted for iPhone Game Development by Craig Giles on 1/1/09.
      11. //
      12. //
      13. //  Import commands from Jeff's template
      14. //
      15. #import "GLViewController.h"
      16. #import "GLView.h"
      17. #import "OpenGLCommon.h"
      18. #import "ConstantsAndMacros.h"
      19. //
      20. //  This indicates weather or not the game will be played in
      21. //  landscape or portrait mode. While in landscape mode, the
      22. //  screen will be rotated, but also the input will be off.
      23. //  Touch coordinates for the screen will have to be converted
      24. //  before it reaches the input manager class.
      25. //
      26. constbool LANDSCAPE_MODE = NO;   
      27. //
      28. //  The time it takes for a game screen to transition
      29. //  These can be over written in the game screen init.
      30. //  If there is no values in the game screen itself, these
      31. //  will be used as the default values.
      32. //
      33. constfloat TRANSITION_ON_TIME = .70f;   
      34. constfloat TRANSITION_OFF_TIME = .20f;   
      35. //
      36. //  Implementation of the Screen Manager class
      37. //
      38. @implementation GLViewController   
      39. //
      40. //  Getters / Setters
      41. //
      42. @synthesize screens;   
      43. @synthesize screensToUpdate;   
      44. @synthesize input;   
      45. @synthesize blankTexture;   
      46. @synthesize isInitialized;   
      47. @synthesize traceEnabled;   
      48. @synthesize gameView;   
      49. @synthesize viewport;   
      50. //
      51. //  Setup View handles setting up OpenGL's Projection Matrix and
      52. //  enables all states needed for rendering the game to screen.
      53. //
      54. -(void)setupView:(GLView*)view   
      55. {   
      56. //  Set the view to the gameView
      57.     gameView = view;   
      58. //  Modify the Projection matrix
      59.     glMatrixMode(GL_PROJECTION);   
      60.     glLoadIdentity();   
      61. //
      62. //  Orthof projection is used for 2d games. This sets the coordinates to
      63. //  (0, 0) at the top left corner of the screen, and as you move downward
      64. //  your y value will increase. As you move to the right, your x value will
      65. //  increase.
      66. //  (left, right, bottom, top, near, far)
      67. //
      68. //  If the game is going to be played in landscape mode, enable
      69. //  it via the bool switch at the top of the GLViewController.m file.
      70. if ( LANDSCAPE_MODE )   
      71.     {   
      72.         viewport = CGRectMake(0, 0, 480, 320);   
      73.         glViewport(0, 0, viewport.size.height, viewport.size.width);   
      74.         glRotatef(-90, 0, 0, 1);   
      75.         glOrthof(0, viewport.size.width, viewport.size.height, 0, -10.0, 10.0);     
      76.     }   
      77. else//  Game is to be played in portrait
      78.     {   
      79.         viewport = CGRectMake(0, 0, 320, 480);   
      80.         glViewport(0, 0, viewport.size.width, viewport.size.height);   
      81.         glOrthof(0.0, viewport.size.width, viewport.size.height, 0.0, -1.0, 1.0);      
      82.     }   
      83. //
      84. //  Setup Model view matrix
      85. //  Load graphics settings
      86. //
      87.     glMatrixMode(GL_MODELVIEW);   
      88.     glDisable(GL_DEPTH_TEST);   
      89.     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);   
      90.     glEnable(GL_BLEND);    
      91. //  needed to draw textures using Texture2D
      92.     glEnable(GL_TEXTURE_2D);   
      93.     glEnableClientState(GL_TEXTURE_COORD_ARRAY);   
      94.     glEnableClientState(GL_VERTEX_ARRAY);   
      95. //  enables alpha for transparent textures
      96. //  I forget where I got these commands, iDevGames.net I think
      97.     glAlphaFunc(GL_GREATER, 0.1f);   
      98.     glEnable(GL_ALPHA_TEST);   
      99. //
      100. //  Setup clear color (cornflower blue'ish)
      101. //  Call me crazy, but I got so used to this color developing
      102. //  for XNA. This is a little nod to the Microsoft Development
      103. //  Team :)
      104. //
      105.     glLoadIdentity();   
      106.     glClearColor(.39f, 0.58f, 0.920f, 1.0f);    
      107. //
      108. //  Call the view controllers loadContent method
      109. //
      110.     [self loadContent];   
      111. }   
      112. //
      113. //  Loads all content needed to run the screen manager. This is seperated
      114. //  from the setupView method in order to seperate what is needed from OpenGL
      115. //  to setup the screen, and what is needed from the screen manager to set
      116. //  up the game structure.
      117. //
      118. - (void)loadContent   
      119. {   
      120. //
      121. //  Allocate memory for your arrays to hold the Screens "stacks."
      122. //  All game screens will be housed in this array for easy manipulation.
      123. //
      124.     screens = [[NSMutableArray alloc] init];   
      125.     screensToUpdate = [[NSMutableArray alloc] init];   
      126. //
      127. //  Allocate memory for the input manager and the blankTexture used
      128. //  to fade the screen in / out.
      129. //
      130.     input = [[InputManager alloc] init];   
      131.     input.isLandscape = LANDSCAPE_MODE;   
      132.     blankTexture = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"blankTexture.png"]];   
      133. for (GameScreen *screen in screens)   
      134.         [screen loadContent];   
      135. //
      136. //  Once we are initialized, set the bool values to appropriate values.
      137. //
      138.     isInitialized = YES;   
      139.     traceEnabled = NO;   
      140. //
      141. //  Adds a title screen to the game stack. This will be taken out
      142. //  later, and right now is only used for debugging purposes. It
      143. //  will be replaced with your splash screen or game introduction
      144. //  screen.
      145. //
      146.     TitleScreen *newScreen = [[TitleScreen alloc] init];   
      147.     [self addScreen:newScreen];   
      148.     [newScreen release];   
      149. }   
      150. //
      151. //  When the view controller exits, we will need to clean up any memory used.
      152. //
      153. - (void)dealloc   
      154. {   
      155. //
      156. //  setup a delete screens array and add all of the current game screens
      157. //  to this array. We will then cycle through all game screens, unloading
      158. //  their content, and releasing them from the view controller. After all
      159. //  is said and done, we will then remove the deleteScreens array, and
      160. //  continue on releasing any other memory allocated for the view controller.
      161. //
      162.     NSMutableArray *deleteScreens = [[NSMutableArray alloc] initWithArray:screens];   
      163. for (GameScreen *screen in deleteScreens)   
      164.     {   
      165.         [self removeScreen:screen];   
      166.         [self releaseScreen:screen];   
      167.     }   
      168.     [deleteScreens release];   
      169.     [screens release];   
      170.     [screensToUpdate release];   
      171.     [input release];   
      172.     [blankTexture release];   
      173.     [super dealloc];   
      174. }   
      175. //
      176. //  If the game is going over memory, this method will be called by the device
      177. //  warning that we are running low on memory and should release any un needed
      178. //  items.
      179. //
      180. - (void)didReceiveMemoryWarning   
      181. {   
      182. //  <<TODO: Unload any un-needed game content here>>
      183.     [super didReceiveMemoryWarning];   
      184. }   
      185. //
      186. //  Add a screen to the view controller
      187. //
      188. - (void) addScreen:(GameScreen *)screen   
      189. {   
      190. //
      191. //  When adding a screen to the view controller, we will be
      192. //  setting some default values for the screen, and then call
      193. //  the screens "loadContent" method. Once everything is loaded,
      194. //  the view controller will retain the screen and add it to the
      195. //  screens array.
      196. //
      197.     screen.controller = self;   
      198.     screen.viewport = self.viewport;   
      199.     screen.transitionOnTime = TRANSITION_ON_TIME;   
      200.     screen.transitionOffTime = TRANSITION_OFF_TIME;   
      201.     screen.currentScreenState = TransitionOn;   
      202.     screen.transitionPosition = 1;   
      203.     [screen loadContent];   
      204.     [screen retain];   
      205.     [screens addObject:screen];   
      206. }   
      207. //
      208. //  Unload all game content from the screen. This in turn
      209. //  sets a flag within the screen itself, that the content has
      210. //  been unloaded, and in the controllers Update method, all game
      211. //  screens that have been unloaded will be released from memory.
      212. //
      213. - (void) removeScreen:(GameScreen *)screen   
      214. {   
      215. //unload any content it has stored
      216.     [screen unloadContent];   
      217. }   
      218. //
      219. //  Release all game screens from memory, that have had their content
      220. //  unloaded. This will release all screens themselves, as well as remove
      221. //  them from the screens arrays.
      222. //
      223. - (void) releaseScreen:(GameScreen *)screen   
      224. {   
      225. //  remove the screen from all screen arrays
      226.     [screens removeObject:screen];   
      227.     [screensToUpdate removeObject:screen];   
      228. //  deallocate any memory used for the screen
      229.     [screen release];   
      230. }   
      231. //
      232. //  Update every screen in the screens stack, keeping track
      233. //  of which screens are covered and which are fully active.
      234. //  if a screen is fully active and "on top" of the stack, it
      235. //  should receive any input.
      236. //
      237. - (void) updateView:(GLView *)view WithTime:(float)deltaTime   
      238. {   
      239. //  Read the touch input
      240.     [input update:deltaTime];   
      241. //  make a copy of hte master screen list, to avoid confusion if
      242. //  the process of updating one screens adds or removes others.
      243.     [screensToUpdate removeAllObjects];   
      244. for(GameScreen *screen in screens)   
      245.         [screensToUpdate addObject:screen];   
      246. bool otherScreenHasFocus = NO;   
      247. bool coveredByOtherScreen = NO;   
      248. //  loop as long as there are screens waiting to be updated
      249. while ([screensToUpdate count] > 0)   
      250.     {   
      251. //  pop the topmost screen off the waiting list
      252.         GameScreen *screen = [screensToUpdate objectAtIndex:([screensToUpdate count] - 1)];   
      253.         [screensToUpdate removeObjectAtIndex:[screensToUpdate count] - 1];   
      254. //  update the screen
      255.         [screen update:deltaTime OtherScreenHasFocus:otherScreenHasFocus   
      256.                                 CoveredByOtherScreen:coveredByOtherScreen];   
      257. if ([screen currentScreenState] == TransitionOn ||   
      258.             [screen currentScreenState] == Active)   
      259.         {   
      260. //  if this is the first active screen we came across,
      261. //  give it a chance to handle input.
      262. if (!otherScreenHasFocus)   
      263.             {   
      264.                 [screen handleInput:input];   
      265.                 otherScreenHasFocus = YES;   
      266.             }   
      267. //  if this is an active non-popup, inform any subsequent
      268. //  screens that they are covered by it
      269. if (![screen isPopup])   
      270.                 coveredByOtherScreen = YES;   
      271.         }   
      272.     }   
      273. //  do we need to print the debug trace?
      274. if (traceEnabled)   
      275.         [self traceScreens];   
      276. //
      277. //  For every screen that had their content unloaded.. release
      278. //  the memory used for that screen here. We do this up front
      279. //  to ensure that any released screen doesn't get their update
      280. //  or draw methods called, when there is nothing to update or draw.
      281. //
      282. for (GameScreen *screen in screens)   
      283.     {   
      284. if (screen.hasBeenUnloaded)   
      285.         {   
      286.             [self releaseScreen:screen];   
      287.         }   
      288.     }   
      289. }   
      290. //
      291. //  Draw the game screens from "Bottom to Top." This is done
      292. //  in order to ensure that any pop'up screens are drawn on top
      293. //  of the full screen below it.
      294. //
      295. - (void) drawView:(GLView *)view WithTime:(float)deltaTime   
      296. {   
      297. //  Clear the screen to preset color before drawing
      298.     glClear(GL_COLOR_BUFFER_BIT);   
      299. //  Draw every screen in the screens array
      300. for (GameScreen *screen in screens)   
      301.     {   
      302. //if the screens content has been unloaded, don't draw
      303. if (screen.hasBeenUnloaded)   
      304. continue;   
      305.         [screen draw:deltaTime];   
      306.     }   
      307. }   
      308. //
      309. //  Helper method designed to draw the screen names currently
      310. //  in the game stack in order to see if they are being added
      311. //  and removed correctly.
      312. //
      313. - (void) traceScreens   
      314. {   
      315. //  <<TODO: Input code to draw the screen names>>
      316. }   
      317. //
      318. //  Helper method to draw a translecent black fullscreen sprite, used
      319. //  for fading screens in and out, and for darkening the background
      320. //  behind pop up screens.
      321. //
      322. - (void) fadeBackBufferToBlack:(double)alpha   
      323. {   
      324.     glColor4f(alpha,alpha,alpha,alpha);   
      325.     [blankTexture drawInRect:self.viewport];   
      326.     glColor4f(1, 1, 1, 1);   
      327. }   
      328. //
      329. //  When the screen is touched by the user, the GLView will pass along a message
      330. //  to the view controller that the screen has been touched. The view controller
      331. //  will take the message, and pass it along to the input manager where the
      332. //  necessary information will be stored and filtered to the game screen that
      333. //  will handle the user input.
      334. //
      335. //  In order for this to work, in your GLView, you need to write the following
      336. //  4 methods:
      337. //  - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
      338. //  - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
      339. //  - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
      340. //  - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
      341. //
      342. //  Those methods will call the methods below.
      343. //
      344. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer   
      345. {   
      346.     [input touchesBegan:touches withEvent:event InView:touchView  WithTimer:timer];   
      347. }   
      348. - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer   
      349. {   
      350.     [input touchesMoved:touches withEvent:event InView:touchView  WithTimer:timer];   
      351. }   
      352. - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer   
      353. {   
      354.     [input touchesEnded:touches withEvent:event InView:touchView  WithTimer:timer];   
      355. }   
      356. - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event InView:(UIView *)touchView WithTimer:(NSTimer *)timer   
      357. {   
      358.     [input touchesCancelled:touches withEvent:event InView:touchView  WithTimer:timer];   
      359. }   
      360. @end  
      361. As you can see, this is a pretty good sized class. What makes it bigger is I have a nasty habit of commenting everything to hell! I always believe it is best to comment heavily, because if you come back a year later and want to adjust your game, comments make it very helpful for remembering what does what.

        The comments in the GLViewController (screen manager) class explains what everything does, but if you have any questions feel free to post them here.

        So… now we need a game screen or two!! Remember, the following code should never be used to make a game screen directly. What I mean is, use this as a super class and inherit from it with your screens. For example, your TitleScreen should inherit from GameScreen. Make sense?

        here is the GameScreen.h file

        1. //
        2. //  A screen is a single layer that has update and draw logic, and which
        3. //  can be combined with other layers to build up a complex screen system
        4. //  or menu system, or even dialog system.
        5. //
        6. //  Developed by XNA Development Studio ( http://creators.xna.com/ )
        7. //  Modified for the iPhone Gameing Framework by Craig Giles on 1/1/09.
        8. //
        9. #import <Foundation/Foundation.h>
        10. #import <OpenGLES/EAGL.h>
        11. #import <OpenGLES/ES1/gl.h>
        12. #import <OpenGLES/ES1/glext.h>
        13. #import "InputManager.h"
        14. #import "Texture2D.h"
        15. //
        16. //  Enum to describe the screens transition state
        17. //
        18. enum ScreenState {   
        19.     TransitionOn = 0,   
        20.     Active,   
        21.     TransitionOff,   
        22.     Hidden   
        23. };   
        24. //
        25. //  Forward Declarations
        26. //
        27. @class GLViewController;   
        28. @interface GameScreen : NSObject   
        29. {   
        30. @private
        31.     GLViewController *controller;   
        32.     CGRect viewport;   
        33. bool hasBeenUnloaded;   
        34. bool isPopup;   
        35. float transitionOnTime;   
        36. float transitionOffTime;   
        37. float transitionPosition;   
        38. float transitionAlpha;   
        39. enum ScreenState currentScreenState;   
        40. bool isExiting;   
        41. bool isActive;   
        42. bool otherScreenHasFocus;   
        43. }   
        44. @property (nonatomic, retain) GLViewController *controller;   
        45. @property (readwrite) CGRect viewport;   
        46. @property (readwrite) bool hasBeenUnloaded;   
        47. @property (readwrite) bool isPopup;   
        48. @property (readwrite) float transitionOnTime;   
        49. @property (readwrite) float transitionOffTime;   
        50. @property (readwrite) float transitionPosition;   
        51. @property (readwrite) float transitionAlpha;   
        52. @property (readwrite) enum ScreenState currentScreenState;   
        53. @property (readwrite) bool isExiting;   
        54. @property (readwrite) bool isActive;   
        55. @property (readwrite) bool otherScreenHasFocus;   
        56. - (void) loadContent;   
        57. - (void) unloadContent;   
        58. - (void) handleInput:(InputManager *)input;   
        59. - (void) update:(float)deltaTime    OtherScreenHasFocus:(bool)otherFocus    CoveredByOtherScreen:(bool)coveredByOtherScreen;   
        60. - (bool) updateTransition:(float)deltaTime  TransitionTime:(float)transition    Direction:(int)direction;   
        61. - (void) draw:(float)deltaTime;   
        62. - (void) exitScreen;   
        63. @end  
        64. and the GameScreen.m file

          1. //
          2. //  A screen is a single layer that has update and draw logic, and which
          3. //  can be combined with other layers to build up a complex screen system
          4. //  or menu system, or even dialog system.
          5. //
          6. //  Developed by XNA Development Studio ( http://creators.xna.com/ )
          7. //  Modified for the iPhone Gameing Framework by Craig Giles on 1/1/09.
          8. //
          9. #import "GameScreen.h"
          10. @implementation GameScreen   
          11. //
          12. // Properties
          13. //
          14. @synthesize controller;   
          15. @synthesize viewport;   
          16. @synthesize hasBeenUnloaded;   
          17. @synthesize isPopup;   
          18. @synthesize transitionOnTime;   
          19. @synthesize transitionOffTime;   
          20. @synthesize transitionPosition;   
          21. @synthesize transitionAlpha;   
          22. @synthesize currentScreenState;   
          23. @synthesize isExiting;   
          24. @synthesize otherScreenHasFocus;   
          25. @dynamic isActive;   
          26. - (bool) isActive   
          27. {   
          28. return !otherScreenHasFocus &&   
          29.     (currentScreenState == TransitionOn ||   
          30.      currentScreenState == Active);   
          31. }   
          32. //
          33. // Constructor(s) / destructors
          34. //
          35. - (id) init   
          36. {   
          37.     self = [super init];   
          38. if (self != nil)   
          39.     {   
          40. //initializations go here
          41.         isExiting = NO;   
          42.     }   
          43. return self;   
          44. }   
          45. - (void) dealloc   
          46. {   
          47. //Deallocations go here
          48.     [super dealloc];   
          49. }   
          50. //
          51. // Loads all content associated with the current screen
          52. //
          53. - (void) loadContent   
          54. {   
          55. }   
          56. //
          57. // Unloads all content associated with the current screen
          58. //
          59. - (void) unloadContent   
          60. {   
          61. //  Release the screen manager
          62.     [controller release];   
          63. //  inidicate that the screens content has been unloaded
          64.     hasBeenUnloaded = YES;   
          65. }   
          66. //
          67. // Allows the screen to perform its update logic.
          68. //
          69. - (void) handleInput:(InputManager *)input   
          70. {   
          71. }   
          72. //
          73. //  Updates the base screen. Since any game screen
          74. //  wil be inheriting from this class, the game screen will
          75. //  call this update method. This update just helps with the
          76. //  transition between two screens, and if a screen is
          77. //  transitioning on and off.
          78. //
          79. - (void) update:(float)deltaTime    OtherScreenHasFocus:(bool)otherFocus    CoveredByOtherScreen:(bool)coveredByOtherScreen   
          80. {   
          81.     otherScreenHasFocus = otherFocus;   
          82. if (isExiting)   
          83.     {   
          84. //if the screen is going to die, it should transition off
          85.         currentScreenState = TransitionOff;   
          86. if (![self updateTransition:deltaTime TransitionTime:transitionOffTime Direction: 1])   
          87.         {   
          88. //when transition finishes, remove the screen
          89.             [controller removeScreen:self];   
          90.         }   
          91.     }   
          92. elseif (coveredByOtherScreen)   
          93.     {   
          94. //if the screen is covered by another, it should transition off
          95. if ([self updateTransition:deltaTime TransitionTime:transitionOffTime Direction: 1])   
          96.         {   
          97. //scren is still transitioning
          98.             currentScreenState = TransitionOff;   
          99.         }   
          100. else
          101.         {   
          102. //transition has finished
          103.             currentScreenState = Hidden;   
          104.         }   
          105.     }   
          106. else
          107.     {   
          108. if ([self updateTransition:deltaTime TransitionTime:transitionOnTime Direction: -1])   
          109.         {   
          110. //still busy transitioning
          111.             currentScreenState = TransitionOn;   
          112.         }   
          113. else
          114.         {   
          115. //transition finished
          116.             currentScreenState = Active;   
          117.         }   
          118.     }   
          119. }   
          120. //
          121. //  Helper method for updating the screen transition position
          122. //  (how much the screen has faded in / out)
          123. //
          124. - (bool) updateTransition:(float)deltaTime TransitionTime:(float)time Direction:(int)direction   
          125. {   
          126. //  how much should we move by?
          127. float transitionDelta;   
          128. if (time <= 0)   
          129.         transitionDelta = 1;   
          130. else
          131.         transitionDelta = deltaTime / time;   
          132. //update the transition position
          133.     transitionPosition += transitionDelta * direction;   
          134. //did we reach the end of the transition?
          135. if (direction < 0 && transitionPosition <= 0 ||   
          136.         direction > 0 && transitionPosition >= 1)   
          137.     {   
          138. //clamp transition position to 0, 1, or value;
          139. if (transitionPosition >= 1)   
          140.             transitionPosition = 1;   
          141. elseif (transitionPosition <= 0)   
          142.             transitionPosition = 0;   
          143. return NO;   
          144.     }//end "end of transition"
          145. //otherwise, we are still busy transitioning
          146. return YES;   
          147. }   
          148. //
          149. //  Each screen will have their own draw method. EVERY SCREEN
          150. //  should call [super draw:deltaTime] in order to draw
          151. //  the fade correctly when the screen manager wishes to fade
          152. //  the screen in or out.
          153. //
          154. - (void) draw:(float)deltaTime   
          155. {   
          156.     [self.controller fadeBackBufferToBlack:self.transitionPosition];   
          157. }   
          158. //
          159. // Tells the screen to go away. Unlike [controller removeScreen] which
          160. // instantly kills the screen, this method respects the transition timings
          161. // and will give the scren a chance to gradually transition off.
          162. //
          163. - (void) exitScreen   
          164. {   
          165. if (transitionOffTime == 0)   
          166.     {   
          167. //if the screen has zero transition time, kill it
          168.         [controller removeScreen:self];   
          169.     }   
          170. else
          171.     {   
          172. //otherwise flag that it should transition off and exit
          173.         isExiting = YES;   
          174.     }   
          175. }   
          176. @end  
          177. Well that does it for the screen manager and the game screen classes.. But keep in mind.. this will NOT build until the InputManager is built. Why don’t you try to fiddle with that for a while, see what you can come up with? I’ll post Part 2 of this tutorial detailing how I did my input manager and two screens (TitleScreen and PausedScreen) in my next update.

            Two thing before I go: I would really like to find a way to turn this into a template for anyone wishing to use it, but I simply do not know how. If you know how to do so, please send me an email at:
            CraigGiles9@yahoo.com

            Secondly, if you have any questions, comments, sly remarks, please post them. I am very good at reading everyones comments, and getting back to you if needed. You can either post a comment or send me an email and I’ll get back to you.

            EDIT:
            I just wanted to let everyone know that there have been a few changes to this article since first posting. I just modified the code within the GLViewController in several places. The following changes were made:
            - Added [self releaseScreen:screen]; in the dealloc method inside the for loop.
            - added const bool LANDSCAPE_MODE = NO; at the top of the view controller, and an if / else statement in the setup view method to help with setting up a landscape view rather than a portrait view. (The first screen manager was written for only portrait view)
            - added input.isLandscape = LANDSCAPE_MODE; to the loadContent method.

            Again, there are too many people to thank for helping me to get to where I am with my current knowledge. I hope this was informational to a few of you! Happy coding everyone!



출처 : http://blog.naver.com/PostView.nhn?blogId=minny0109&logNo=150052551485
Posted by 오늘마감

댓글을 달아 주세요