рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ iOS рдХреЗ рддрд╣рдд рдлреБрдЯрдмреЙрд▓реЛрд▓реЙрдЗрдб рд▓рд┐рдЦрд╛ рд╣реИ

рд╕рдмрд╕реЗ рд╕рдореНрдорд╛рдирдЬрдирдХ рд╣реИрдмрд░рд╛рд▓реБрдбреА рдХреЛ рдмрдзрд╛рдИ!


рдмрд╣реБрдд рд╕рдордп рдкрд╣рд▓реЗ рдирд╣реАрдВ, рдирдИ рдиреМрдХрд░реА рдХреА рдЦреЛрдЬ рдХрд░рддреЗ рд╕рдордп, рдореБрдЭреЗ ZeptoLab рд╕реЗ рдПрдХ рдмрд╣реБрдд рд╣реА рджрд┐рд▓рдЪрд╕реНрдк рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдорд┐рд▓рд╛: рдПрдХ рдкрд╛рд░реНрдЯреА рдореЗрдВ рдХреБрдЫ рджрд┐рдиреЛрдВ рдХреЗ рд▓рд┐рдП Cocos2d / Box2d, рдЗрддреНрдпрд╛рджрд┐ рдЬреИрд╕реЗ рдХрд┐ "рдХреНрд▓реАрди" рдУрдкрдирдЬреАрдПрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛ iOS рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд░рдХрд╛рдиреЙрдЗрдб рд▓рд┐рдЦреЗрдВред рдЬреЛ рдореБрдЭреЗ рдмрд╣реБрдд рджрд┐рд▓рдЪрд╕реНрдк рд▓рдЧрд╛ред рд╡реИрд╕реЗ, рд╣реЛрдмреЗ рдкрд░ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдЦрд╛ рдерд╛ , рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдбрд┐рдмреНрд░реАрдлрд┐рдВрдЧ рдХреА рд╡реНрдпрд╡рд╕реНрдерд╛ рднреА рдХреАред рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рднрд╛рдЧреНрдп рдХреЛ рдЪреБрдиреМрддреА рджреА рдФрд░ рдЧреНрд░рд╛рдлрд┐рдХ рдореЛрдб рдореЗрдВ рд╡рд╛рд╕рд┐рдХ рдХреЗ рд╕рд╛рде рд╕реНрдХреВрд▓ рдЕрднреНрдпрд╛рд╕ рдХреЗ рдмрд╛рдж рдкрд╣рд▓реА рдмрд╛рд░ gameev рд▓рд┐рдпрд╛!

рдореИрдВ рд╕реНрдкрд╖реНрдЯ рдХрд░реВрдВрдЧрд╛ рдХрд┐ рдореБрдЭреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдУрдкрдирдЬреАрдПрд▓ рдХрд╛ рдХреБрдЫ рдЬреНрдЮрд╛рди рдерд╛, рд▓реЗрдХрд┐рди рдмрд╣реБрдд, рдмрд╣реБрдд рд╕рддрд╣реАред рд╣рдо рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рд▓рдЧрднрдЧ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдирд╣реАрдВ рдереЗ, рдореБрдЭреЗ рд╕рд┐рд░реНрдл рдпрд╣ рдкрддрд╛ рдерд╛ рдХрд┐ рдПрдХ рд╡реНрдпреВрдкреЛрд░реНрдЯ рдХреНрдпрд╛ рд╣реИ рдФрд░ рд╡рд╣рд╛рдВ рдХреБрдЫ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рд╣реИрдВ, рдХрд┐ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдореЗрд╢рди рдореИрдЯреНрд░рд┐рд╕реЗрд╕ рд╣реИрдВ ... рдЗрд╕рд▓рд┐рдП рдпрд╣ рдЖрд░реНрдЯрд┐рдХрд▓ " рдУрдкрди рдУрдкрди рдкрд░ iOS рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд░рд▓ рдЧреЗрдо рдХреИрд╕реЗ рд▓рд┐рдЦреЗрдВ " рд╢реАрд░реНрд╖рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЙрд╕реЗ рдЬрд╛рдиреЗ рдмрд┐рдирд╛, "рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рд▓рдВрдмрд╛ рд╣реИред

рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрджрд┐ рдЖрдк рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ рдХрд┐ рдореИрдВрдиреЗ рдпрд╣ ~ 10 рдШрдВрдЯреЗ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдФрд░ ~ 2 рдШрдВрдЯреЗ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдХрд┐рдпрд╛, рддреЛ рдореИрдВ рдмрд┐рд▓реНрд▓реА рдХреЗ рд▓рд┐рдП рдкреВрдЫрддрд╛ рд╣реВрдВред (рд╕рд╛рд╡рдзрд╛рдиреА! рдХреЛрдб рдХрд╛ рдПрдХ рдмрд╣реБрдд! рдЫреЛрдЯреА рддрд╕реНрд╡реАрд░реЗрдВ! рдЕрдВрдд рдореЗрдВ рдЧрд┐рддреВрдм рдФрд░ рдЖрд░рд╛рдо рд╡реАрдбрд┐рдпреЛ рдХреЗ рд▓рд┐рдП рд▓рд┐рдВрдХ!)

рд╣рдо рдИрдорд╛рдирджрд╛рд░ рд╣реЛрдВрдЧреЗред Image_to_attract_attention тДв рдореЗрд░реЗ рд▓рд┐рдП рдХреНрдпрд╛ рд╣реБрдЖ рдХрд╛ рд╕реНрдХреНрд░реАрдирд╢реЙрдЯ рдирд╣реАрдВ рд╣реИред рдФрд░ рдпрд╣рд╛рдБ рдореЗрд░реЗ рд╕рд╛рде рдХреНрдпрд╛ рд╣реБрдЖ:


рдореБрдЭреЗ рдЗрд╕ рдзреЛрдЦреЗ рдХреЗ рд▓рд┐рдП рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдЕрднреА рднреА рдореЗрд░реЗ рд▓реЗрдЦ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рд╣реИ рдирд╛? )

рдЖрдкрдХреЗ рд▓рд┐рдП рдирдИ рддрдХрдиреАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦрдирд╛ рдХреИрд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ? рдпрд╣ рд╕рд╣реА рд╣реИ, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг, рдЙрджрд╛рд╣рд░рдг рдФрд░ рд▓реЗрдЦ (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдЖрдкрдХреЗ рд╕рд╛рдордиреЗ рдПрдХ рдЬреИрд╕реЗ) рдкрдврд╝рдиреЗ рд╕реЗред Google рдореЗрдВ рдмреИрдардиреЗ рдХреЗ рдХреБрдЫ рдорд┐рдирдЯреЛрдВ рдХреЗ рдмрд╛рдж, рдПрдХ рдЕрджреНрднреБрдд рд▓реЗрдЦ (рд▓реЗрдЦрдХ рд░реЗ рд╡реЗрдВрдбрд░рд▓рд┐рдЪ) рдХреА рдЦреЛрдЬ рдХреА рдЧрдИ, рдЬрд┐рд╕рдиреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдЦрд┐рд▓реМрдирд╛ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреА рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЬрд╛рдВрдЪ рдХреАред рдпрд╣рд╛рдВ, рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ рдЖрдк рдореЗрд░реЗ рд▓реЗрдЦ рдХреЛ рдмрдВрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рд░реЗ рдХреЗ рд▓реЗрдЦ рдХреЛ рдкрдврд╝рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдЕрднреА рднреА рдЕрдкрдиреА рдореВрд▓ рднрд╛рд╖рд╛ рдореЗрдВ рдПрдХ рдкреБрд░рд╛рд▓реЗрдЦ рдФрд░ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдЖрдП рд╣реИрдВ, рдореИрдВ рдХрд╣рд╛рдиреА рдЬрд╛рд░реА рд░рдЦреВрдВрдЧрд╛ред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЦреЗрд▓ рдХреЗ рд▓рд┐рдП рдПрдХ рдЦрд╛рд▓реА рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдмрдирд╛рдПрдВред Xcode рдореЗрдВ, рдлрд╝рд╛рдЗрд▓ -> рдирдпрд╛ -> рдкреНрд░реЛрдЬреЗрдХреНрдЯ ... рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ, iOS рдЯреЗрдореНрдкреНрд▓реЗрдЯ -> рдПрдкреНрд▓рд┐рдХреЗрд╢рди -> рдУрдкрдирдЬреАрдПрд▓ рдЧреЗрдо рдЪреБрдиреЗрдВ ред рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ, рдореИрдВрдиреЗ рдПрдЖрд░рд╕реА рдХреЗ рд╕рд╛рде рдФрд░ рдмрд┐рдирд╛ рд╕реНрдЯреЛрд░реАрдмреЙрд░реНрдб рдХреЗ рдПрдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЛ рдЪреБрдирд╛, рд▓реЗрдХрд┐рди рдЖрдк, рдкреНрд░рд┐рдп рдкрд╛рдардХ, рдЖрдк рдЬреИрд╕реЗ рдЪрд╛рд╣реЗрдВ рд╡реИрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВред рдареАрдХ рд╣реИ, рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдЧрдИ рд╣реИ, рдЕрдм рд╣рдо рддреБрд░рдВрдд рд░рди рджрдмрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХрддрд╛рдИ рдХреНрдпреВрдмреНрд╕ рдХрд╛ рдЖрдирдВрдж рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рдмрд┐рд▓реНрдХреБрд▓ рд╡реИрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдЬреИрд╕рд╛ рд╣рдо рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рдереЗ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд▓рдЧрднрдЧ рд╣рд░ рдЪреАрдЬ рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдбрд╛рд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ, рд╣рдо рдХреЗрд╡рд▓ рдЖрд╡рд╢реНрдпрдХ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЬреЛрдбрд╝реЗ рдЧрдП рд╢реЗрдбреНрд╕ рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВ, ViewController.m рд╕реЗ рд╣рдо interface ViewController () рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдПрдирдо рдФрд░ рдЧреНрд▓реЛрдмрд▓ рд╡реИрд░рд┐рдПрдмрд▓реНрд╕ рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВ interface ViewController () рдЕрдм рд╣рдо рдЕрддрд┐рд░рд┐рдХреНрдд рддрд░реАрдХреЛрдВ рдХреЛ loadShaders, compileShader:type:file:, linkProgram:, validateProgram: : loadShaders, compileShader:type:file:, linkProgram:, validateProgram: рд╣рдорд╛рд░реЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдореЗрдВред рд╣рдо shaders рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░реЗрдВрдЧреЗред рдмреЗрд╢рдХ, рдЖрдк рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрджрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреИрд╕реЗ рдФрд░ рдХреНрдпреЛрдВ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕ рдХреЗ рд╕рд╛рде рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛ =)ред

рдЕрдЧрд▓рд╛, рд╣рдо рд╕рднреА рд╢реЗрд╖ рд╡рд┐рдзрд┐рдпреЛрдВ рд╕реЗ рд╕рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рдмрд╛рд╣рд░ рдлреЗрдВрдХ рджреЗрддреЗ рд╣реИрдВред setupGL рдФрд░ tearDownGL рд╣рдо рдПрдХ рдирдЬрд╝рд░ рдореЗрдВ рд▓рд╛рдПрдВрдЧреЗ:
 - (void)setupGL { [EAGLContextsetCurrentContext:self.context]; self.effect = [[GLKBaseEffectalloc] init]; } - (void)tearDownGL { [EAGLContextsetCurrentContext:self.context]; self.effect = nil; } 

рдЕрдЧрд▓рд╛ред рд╣рдо рдПрдХ рдЖрджрд┐рдо рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдЖрджрд┐рдо рдЦреЗрд▓ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдорд╛рд░реЗ ViewController рдкреВрд░реЗ рдЦреЗрд▓ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рд╕реМрд╣рд╛рд░реНрджрдкреВрд░реНрдг рддрд░реАрдХреЗ рд╕реЗ, рдпрд╣ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЧреЗрдордХрдВрдЯреНрд░реЛрд▓рд░ рдмрдирд╛рдиреЗ рдФрд░ рдЗрди рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдм рд╣рдо рдЗрд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░реЗрдВрдЧреЗ рдФрд░ рдРрд╕рд╛ рдХрд░реЗрдВрдЧреЗред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЕрдкрдиреЗ ViewController рдХреЗ рд▓рд┐рдП рдРрд╕реЗ рдЧреБрдг рдФрд░ рддрд░реАрдХреЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:

 #define kGameStateNone 0 #define kGameStateLose 1 #define kGameStateWon 2 @property (assign) int gameState; // see kGameState... @property (assign) BOOL gameRunning; - (void)loadBricks; - (void)startGame; - (void)endGameWithWin:(BOOL)win; 

рд╡реЗ рдХрд┐рд╕рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИрдВ - рдФрд░ рдХреЛрдИ рдЯрд┐рдкреНрдкрдгреА рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИред рдЦреИрд░, рдЕрдм рдЦреЗрд▓ рдХреЗ рддрд░реНрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХрд╛ рд╕рдордп рд╣реИ, рдЕрдзрд┐рдХ рд╕рдЯреАрдХ, рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рддрд░реНрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВред рд╣рдо рдХреНрдпрд╛ рдФрд░ рдХреИрд╕реЗ рдХрд░реЗрдВрдЧреЗ? рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рд╡рд╕реНрддреБрдПрдВ рд╣реЛрдВрдЧреА? рдЗрд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдХреНрдпрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ?

рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рд╡рд╛рд▓, рд╣рд╛рдБред рд▓реЗрдХрд┐рди рд╕рд░рд▓ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде (рдФрд░ рдЬреНрдЮрд╛рди рд╣реИ рдХрд┐ рдХреБрдЫ рдкреНрд░реЗрдд рд╣реИрдВ ) рд╣рдо рдЗрд╕ рдореЙрдбрд▓ рдкрд░ рдЖрддреЗ рд╣реИрдВ: рдПрдХ "рдмрд▓реНрд▓рд╛" рд╣реИ рдЬрд┐рд╕реЗ рдЦрд┐рд▓рд╛рдбрд╝реА рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдРрд╕реА рдИрдВрдЯреЗрдВ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рддреЛрдбрд╝рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдФрд░ рдПрдХ рдЧреЗрдВрдж рд╣реИ рдЬреЛ рд╕рдм рдХреБрдЫ рдЙрдЫрд╛рд▓ рджреЗрддреА рд╣реИ рдФрд░ рдИрдВрдЯреЛрдВ рдХреЛ рддреЛрдбрд╝ рджреЗрддреА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдкреГрд╖реНрдарднреВрдорд┐ рд╣реИ, рдФрд░ рдПрдХ рдореЗрдиреВ рд╣реИ - рдЬрд╣рд╛рдВ рд╣рдо рдЧреЗрдо рд▓реЙрдиреНрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ (рд╣рдо рдЬреАрдд рдЧрдП рдпрд╛ рд╣рд╛рд░ рдЧрдП)ред рд╕реНрдХреНрд░реАрди рдкрд░ рд╣рдо рдЬреЛ рдХреБрдЫ рднреА рджреЗрдЦрддреЗ рд╣реИрдВ рд╡рд╣ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рддреИрдпрд╛рд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдореВрд▓ рд╡рд╕реНрддреБрдПрдВ рд╣реИрдВ, рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬрд╝ рдЬреИрд╕реА рдХреБрдЫред рдЦреИрд░, рдпрд╛ рдЦрд┐рдбрд╝рдХреА рдореЗрдВ рдмрдЯрдиред рдЙрдирдХреЗ рдкрд╛рд╕ рд╡рд┐рднрд┐рдиреНрди рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдВ рд╣реЛ рд╕рдХрддреА рд╣реИрдВ: рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ, рдЖрдХрд╛рд░, рдЪрд┐рддреНрд░ рдЬреЛ рд╡реЗ рдЦреАрдВрдЪрддреЗ рд╣реИрдВред рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдо рдЧрддрд┐ рдХреА рдЧрддрд┐ рдФрд░ рджрд┐рд╢рд╛ рдХреЛ рдпрд╣рд╛рдВ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдЦреИрд░, рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдЗрди рдЧреБрдгреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╛рдВрдзрд╛ рдФрд░ рд╕рд╛рд╣рд╕рдкреВрд░реНрд╡рдХ Xcode рдореЗрдВ theseN рджрдмрд╛рдПрдВ! рдЪрд▓реЛ NSObject рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдПрдХ рдирдпрд╛ рд╡рд░реНрдЧ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЪрд▓реЛ рдЗрд╕реЗ GameSprite рдХрд╣рддреЗ рд╣реИрдВред рдФрд░ рдЗрд╕рдореЗрдВ рдРрд╕реЗ рдЧреБрдг рдФрд░ рддрд░реАрдХреЗ рдЬреЛрдбрд╝реЗрдВ:

 @interface GameSprite : NSObject - (id)initWithTexture:(GLKTextureInfo *)textureInfo effect:(GLKBaseEffect *)effect; - (id)initWithImage:(UIImage *)image effect:(GLKBaseEffect *)effect; - (void)render; - (void)update:(float)dt; - (CGRect)boundingRect; @property (assign) GLKVector2 position; @property (assign) CGSize contentSize; @property (assign) GLKVector2 moveVelocity; // points/sec @end 

рдЕрд╕рд▓ рдореЗрдВ, рд╣рдо рдПрдХ рдЪрд┐рддреНрд░ рдпрд╛ рдмрдирд╛рд╡рдЯ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдмрдирд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗ, рдЙрдиреНрд╣реЗрдВ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░реЗрдВрдЧреЗ, рд╕рдордп рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рдХреА рд╕реАрдорд╛рдПрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред рдФрд░ рдЗрд╕рдХреА рд╕реНрдерд┐рддрд┐, рдЖрдХрд╛рд░ рдФрд░ рдЧрддрд┐ рднреА рдкреВрдЫреЗрдВ рдФрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рд▓реЗрдХрд┐рди рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ, рдордЬрд╝рд╛ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ! рд╣рдореЗрдВ рд╡рд░реНрдЯреЗрдХреНрд╕ рдФрд░ рдХреНрд╡реИрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдХреНрдпрд╛ рд╣реИ рдареАрдХ рд╣реИ, рдЕрдЧрд░ рд╕рд░рд▓ рд╣реИ, рддреЛ рдПрдХ рд╢реАрд░реНрд╖ рд╕реНрдерд╛рди рдореЗрдВ рдПрдХ рдмрд┐рдВрджреБ рд╣реИ, рдФрд░ рдПрдХ рдХреНрд╡рд╛рдб рдЪрд╛рд░ рдХреЛрдиреЗ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╡рд░реНрдЯреЗрдХреНрд╕ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреЛ рдмрд┐рдВрджреБ рд╣реИрдВ - рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рдФрд░ рдЗрд╕рдХреА рдмрдирд╛рд╡рдЯ рдХреЗ рд▓рд┐рдПред рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВ:

 typedef struct { CGPoint geometryVertex; CGPoint textureVertex; } TexturedVertex; typedef struct { TexturedVertex bl; TexturedVertex br; TexturedVertex tl; TexturedVertex tr; } TexturedQuad; 

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрд┐рд╕реА рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП: рдмрдирд╛рд╡рдЯ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рд╣реЛрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рд╡реЗ рд╣рдореЗрд╢рд╛ 0 рд╕реЗ 1 рддрдХ рдХреА рд╕реАрдорд╛ рдореЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВред рд╣рдореЗрдВ рдЕрдкрдиреА рдмрдирд╛рд╡рдЯ рдХреЛ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рд╕рд╛рде рдЦреАрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдХреНрд╡рд╛рдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЧреЗрдордкреНрд░рд┐рдЯ рдХреНрд▓рд╛рд╕ рдХреЗ рд▓рд┐рдП рд╣рдо рдРрд╕реЗ рдирд┐рдЬреА рдЧреБрдгреЛрдВ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВрдЧреЗ:

 @interface GameSprite() @property (strong) GLKBaseEffect *effect; @property (assign) TexturedQuad quad; @property (strong) GLKTextureInfo *textureInfo; - (void)initQuadAndSize; @end 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкреНрд░рднрд╛рд╡ рд╣реИ рдФрд░ рдмрдирд╛рд╡рдЯ рдХреА рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдкрддреНрддрд┐рдпреЛрдВ рдореЗрдВ рдЙрд╕реА рддрд░рд╣ рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рдПрдЧреА, рд▓реЗрдХрд┐рди рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдирд╣реАрдВред рдЦреИрд░, рдЕрдм рдЖрдк рд╕реНрдкреНрд░рд╛рдЗрдЯ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 - (id)initWithTexture:(GLKTextureInfo *)textureInfo effect:(GLKBaseEffect *)effect { if ((self = [super init])) { self.effect = effect; self.textureInfo = textureInfo; if (self.textureInfo == nil) { NSLog(@"Error loading texture! Texture info is nil!"); return nil; } [self initQuadAndSize]; } return self; } - (id)initWithImage:(UIImage *)image effect:(GLKBaseEffect *)effect { if ((self = [super init])) { self.effect = effect; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil]; NSError *error; self.textureInfo = [GLKTextureLoader textureWithCGImage:image.CGImage options:options error:&error]; if (self.textureInfo == nil) { NSLog(@"Error loading image: %@", [error localizedDescription]); return nil; } [self initQuadAndSize]; } return self; } - (void)initQuadAndSize { self.contentSize = CGSizeMake(self.textureInfo.width, self.textureInfo.height); TexturedQuad newQuad; newQuad.bl.geometryVertex = CGPointMake(0, 0); newQuad.br.geometryVertex = CGPointMake(self.textureInfo.width, 0); newQuad.tl.geometryVertex = CGPointMake(0, self.textureInfo.height); newQuad.tr.geometryVertex = CGPointMake(self.textureInfo.width, self.textureInfo.height); newQuad.bl.textureVertex = CGPointMake(0, 0); newQuad.br.textureVertex = CGPointMake(1, 0); newQuad.tl.textureVertex = CGPointMake(0, 1); newQuad.tr.textureVertex = CGPointMake(1, 1); self.quad = newQuad; } 

рдХреБрдЫ рднреА рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИ, рдмрд╕ рдПрдХ рддрд╕реНрд╡реАрд░ рд╕реЗ рдмрдирд╛рд╡рдЯ рдЕрд╕рд╛рдЗрди рдХрд░рдирд╛ рдпрд╛ рд▓реЛрдб рдХрд░рдирд╛ рдФрд░ рдПрдХ рдХреНрд╡рд╛рдб рдЕрд╕рд╛рдЗрди рдХрд░рдирд╛ред рдпрд╣рд╛рдВ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЪрд╛рд░ рдХреЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЬреНрдпрд╛рдорд┐рддрд┐ рдФрд░ рдмрдирд╛рд╡рдЯ рдХреЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЗрдХрд╛рдЗрдпреЛрдВ рдореЗрдВ рд╕реЗрдЯ рдХрд┐рдП рдЧрдП рд╣реИрдВред

рдЕрдм рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рднрд╛рдЧ рдкрд░ рдЪрд▓рддреЗ рд╣реИрдВ - рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХрд╛ рдкреНрд░рддрд┐рдкрд╛рджрди, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП render рд╡рд┐рдзрд┐ рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ!

 - (void)render { self.effect.texture2d0.name = self.textureInfo.name; self.effect.texture2d0.enabled = YES; self.effect.transform.modelviewMatrix = self.modelMatrix; [self.effect prepareToDraw]; long offset = (long)&_quad; glEnableVertexAttribArray(GLKVertexAttribPosition); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, geometryVertex))); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(TexturedVertex), (void *) (offset + offsetof(TexturedVertex, textureVertex))); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } 

рдпрд╣рд╛рдВ рд╣рдо рдкреНрд░рднрд╛рд╡ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдмрдирд╛рд╡рдЯ рддреИрдпрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ (рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ - рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж, рдЬрдм рддрдХ рдЖрдк рдЗрд╕ рдкрдВрдХреНрддрд┐ рдХреЛ рдирд╣реАрдВ рдкрдврд╝рддреЗ рд╣реИрдВ), рдЖрд╡рд╢реНрдпрдХ рдУрдкрдирдЬреАрдПрд▓ рдорд╛рдкрджрдВрдбреЛрдВ (рд╕реНрдерд┐рддрд┐ рдФрд░ рдмрдирд╛рд╡рдЯ) рдХреЛ рдЪрд╛рд▓реВ рдХрд░реЗрдВ, рдЪрд╛рд▓рд╛рдХ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреА рдорджрдж рд╕реЗ рдУрдкрди рдХреНрд╡рд╛рдб рдореЗрдВ рд╣рдорд╛рд░реЗ рдХреНрд╡рд╛рдб рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ, рдФрд░ рдЕрдВрдд рдореЗрдВ рдбреНрд░рд╛ рдХрд░реЗрдВ! рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдПрдХ рд╡рд┐рд╕реНрддреГрдд рд╡рд┐рд╡рд░рдг рдЗрд╕ рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИ, рдореИрдВ рдмрд╕ рдЖрдкрдХреЛ рдкреНрд░рд┐рдп рдкрд╛рдардХ, рдкреНрд░рд▓реЗрдЦрди ( glVertexAttribPointer рдФрд░ glDrawArrays ) рдХреЛ рднреЗрдЬреВрдВрдЧрд╛ ред

рдЕрдм рд╣рдо рдкрд░рд┐рд╡рд░реНрддрди рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреА рдУрд░ рдореБрдбрд╝рддреЗ рд╣реИрдВ, рдЬреЛ рд╕рдм рдХреБрдЫ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реЛрдЧрд╛: рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ, рд░реЛрдЯреЗрд╢рди, рд╕реНрдХреЗрд▓рд┐рдВрдЧ рдФрд░ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдПред рд▓реЗрдХрд┐рди, рдЕрднреА рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдЦреЗрд▓ рдХреЗ рдореИрджрд╛рди рдХреЗ рд╡рд╛рдВрдЫрд┐рдд рднрд╛рдЧ рдореЗрдВ рд▓реЗ рдЬрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рдЪрд▓рд┐рдП рдЪрд▓рддреЗ рд╣реИрдВ:

 - (GLKMatrix4)modelMatrix { GLKMatrix4 modelMatrix = GLKMatrix4Identity; modelMatrix = GLKMatrix4Translate(modelMatrix, self.position.x, self.position.y, 0); modelMatrix = GLKMatrix4Translate(modelMatrix, -self.contentSize.width / 2, -self.contentSize.height / 2, 0); return modelMatrix; } 

рдпрд╣рд╛рдВ рднреА, рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ: рдЖрдЗрдбреЗрдВрдЯрд┐рдЯреА рдореИрдЯреНрд░рд┐рдХреНрд╕ (рдкрд╣рдЪрд╛рди рдПрдХ, рдЬреЛ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ) рдХреЛ рд▓реЗ рд▓реЛ, рд╕реНрд╡рдпрдВ рдирд┐рд░реНрджреЗрд╢рди рдореЗрдВ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреА рдЙрддреНрдкрддреНрддрд┐ рдХрд╛ рдЕрдиреБрд╡рд╛рдж рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдЗрд╕реЗ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЗ рдмреАрдЪ рдореЗрдВ рд▓реЗ рдЬрд╛рдПрдВред рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЗ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдореЗрдВ рд╣реЗрд░рдлреЗрд░ рдХрд░рддреЗ рд╕рдордп рдпрд╣ рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред рдЕрдм, update: рд▓рд┐рдП рдПрдХ рд╕реНрдЯрдм рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ update: рд╣рдо рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрд╕рдореЗрдВ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рд╕реЗ рдПрдХ рддрд╕реНрд╡реАрд░ рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдФрд░ рд╣рдорд╛рд░реЗ ViewController рдореЗрдВ, рдЗрд╕реЗ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░реЗрдВ:

 - (void)viewDidLoad { [super viewDidLoad]; self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; if (!self.context) { NSLog(@"Failed to create ES context"); } [self setupGL]; GLKView *view = (GLKView *)self.view; view.context = self.context; GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(0, 320, 0, 480, -1024, 1024); self.effect.transform.projectionMatrix = projectionMatrix; // initializing game state self.gameRunning = NO; self.gameState = kGameStateNone; // initializing sprites self.testSprite = [[GameSpritealloc] initWithImage:[UIImageimageNamed:@"myImage"] effect:self.effect]; self.testSprite .position = GLKVector2Make(160, 35); } - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(1.f, 1.f, 1.f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); [self.testSprite render]; } 


рдЕрдЪреНрдЫрд╛, рдмреБрд░рд╛ рдирд╣реАрдВ? рдПрдХ рддрд╕реНрд╡реАрд░ рдЕрдм рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдореИрджрд╛рди рдкрд░ рдЦреАрдВрдЪреА рдЬрд╛ рд░рд╣реА рд╣реИред рд╣рд╛рдВ, рд╣рдо рджреЛрд╕реНрддреЛрдВ рдХреЛ рдмреБрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рджрд╛рд╡рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдордиреЗ рд▓рдЧрднрдЧ рдЦреЗрд▓ рд▓рд┐рдЦрд╛ рд╣реИ! =)

рд▓реЗрдХрд┐рди, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдЦреБрд╢реА рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЬрд▓реНрджреА рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрднреА рднреА рдПрдХ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╣реИ рдФрд░ рдпрд╣ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред рд╣рдо рдЗрд╕реЗ рдЕрднреА рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛ рджреЗрдВрдЧреЗ рдФрд░ рдХреБрдЫ рджрд┐рд▓рдЪрд╕реНрдк рдХрд░реЗрдВрдЧреЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ рдХрд┐ рд╣рдореЗрдВ рдХреМрди рд╕реЗ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдереЛрдбрд╝рд╛ред рджреВрд╕рд░реА рдмрд╛рдд, рдЧреЗрдВрджред рддреАрд╕рд░рд╛, рдИрдВрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ред рдФрд░ рдХреБрдЫ? рдЕрд░реЗ рд╣рд╛рдБ, рдЕрдзрд┐рдХ рдкреГрд╖реНрдарднреВрдорд┐ред рдФрд░ рдпрд╣ рднреА - рдореЗрдиреВ! рдФрд░ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИ? рдЕрдВрдзреЗрд░реЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЗрдд, рд╢рд┐рд▓рд╛рд▓реЗрдЦ "рдЬреАрддрд╛" рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЗрдд, рд╢рд┐рд▓рд╛рд▓реЗрдЦ "рдЦреЛ" рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЗрдд, рд╢рд┐рд▓рд╛рд▓реЗрдЦ "рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ" рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЗрдд, "рдЦреЗрд▓рдиреЗ" рдмрдЯрди рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░реЗрддред рдЦреИрд░, рд╕рдм рдХреБрдЫ рдлреВ, рд▓рдЧрддрд╛ рд╣реИред рдареАрдХ рд╣реИ, рдЪрд▓реЛ рдЪрд▓рддреЗ рд╣реИрдВ, рд╣рдорд╛рд░реЗ рдирд┐рдпрдВрддреНрд░рдХ рдХреЗ рд▓рд┐рдП рдЧреБрдг рд╕реЗрдЯ рдХрд░реЗрдВ:

 @property (strong, nonatomic) GameSprite *playerBat; @property (strong, nonatomic) GameSprite *ball; @property (strong, nonatomic) GameSprite *background; @property (strong, nonatomic) GameSprite *menuDimmer; @property (strong, nonatomic) GameSprite *menuCaption; @property (strong, nonatomic) GameSprite *menuCaptionWon; @property (strong, nonatomic) GameSprite *menuCaptionLose; @property (strong, nonatomic) GameSprite *menuStartButton; @property (strong, nonatomic) NSMutableArray *bricks; 


рдЗрди рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЗ рд▓рд┐рдП, рдЬрд┐рдореНрдк / рдлреЛрдЯреЛрд╢реЙрдк / рдЕрдиреНрдп рдореЗрдВ рдЙрдкрдпреБрдХреНрдд рдЖрдХрд╛рд░реЛрдВ рдХреА рдЫрд╡рд┐рдпрд╛рдВ рдмрдирд╛рдПрдВред рдмрддрд╛ рджреЗрдВ рдХрд┐ рдИрдВрдЯреЛрдВ рдореЗрдВ 50x10 рдкрд┐рдХреНрд╕рд▓реНрд╕, рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдЖрдХрд╛рд░ рд╣реИред рдЖрдк рдПрдХ рдЧреЗрдВрдж рдЦреАрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рдЗрд╕реЗ рдиреЗрдЯ рдкрд░ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдореИрдВрдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд┐рдпрд╛ рдерд╛ред рдХреЙрдорд░реЗрдб рдЬреВрдирд┐рдпрд░ рдиреЗ рдкреГрд╖реНрдарднреВрдорд┐ рдХреЗ рд╕рд╛рде рдорджрдж рдХреА (рдФрд░ рд╡реИрд╕реЗ, рдореИрдВрдиреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдлреБрдЯрдмреЙрд▓ рдереАрдо рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛), рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдХреБрдЫ рдИрдВрдЯреЗрдВ рдФрд░ рдереЛрдбрд╝рд╛ рд╕рд╛ рдЦреБрдж рдХреЛ рдЖрдХрд░реНрд╖рд┐рдд рдХрд┐рдпрд╛ред рдореИрдВ рд╕рднреА рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЗрдирд┐рд╢рд┐рдпрд▓рд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛрдб рдирд╣реАрдВ рджреВрдВрдЧрд╛, рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рджрд┐рдП рдЧрдП рдПрдХ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдХреЗрд╡рд▓ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдЕрд▓рдЧ рд╣реИрдВред рд▓реЗрдХрд┐рди рдИрдВрдЯреЛрдВ рдХрд╛ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рдЙрдирдХрд╛ рд╕реНрдерд╛рди рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рд╣рд╛рд░реНрдбрдХреЛрдб рд╣реЛрдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рд╣реИ, рд╣реИ рдирд╛? рдФрд░ рдЕрдЧрд░ рд╣рдо рдЕрднреА рднреА рд╕реНрддрд░ рдореЗрдВ рдХрдЯреМрддреА рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ? рдЖрдЗрдП рдмреЗрд╣рддрд░ рд╣реИ рдХрд┐ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдлрд╝рд╛рдЗрд▓ рдкреНрд░рд╛рд░реВрдк рдХреЗ рд╕рд╛рде рдЖрдПрдВ рдЬрд┐рд╕рдореЗрдВ рдпреЗ рд╕реНрддрд░ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реЛрдВрдЧреЗред рдореЗрд░рд╛ рдкреНрд░рд╛рд░реВрдк рдмрд╣реБрдд рд╕рд░рд▓ рдирд┐рдХрд▓рд╛, рд▓реЗрдХрд┐рди рдЖрдк рдХрд▓реНрдкрдирд╛ рдХреЛ рд╕реНрд╡рддрдВрддреНрд░ рд░реВрдк рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рд╣реИрдВред рддреЛ, рдпрд╣рд╛рдБ рдкрд╣рд▓реА (рдФрд░ рдЕрдм рддрдХ рдХреЗрд╡рд▓) рд╕реНрддрд░ рдХреЗ рд▓рд┐рдП рдореЗрд░реА рдлрд╛рдЗрд▓ рд╣реИ:

 101101 111111 010010 111111 000000 111111 

рдкреНрд░рд╛рд░реВрдк рд╕реНрд╡-рд╕реНрдкрд╖реНрдЯ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ, рд╣реИ рдирд╛? 0 - рдХреЛрдИ рдИрдВрдЯ рдирд╣реАрдВ, 1 - рд╡рд╣рд╛рдБ рд╣реИред рдареАрдХ рд╣реИ, рдпрджрд┐ рдЖрдк рджреВрд╕рд░реЗ рдкреНрд░рдХрд╛рд░ рдХреА рдИрдВрдЯ рдмрдирд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╕рдВрдЦреНрдпрд╛ 2, 3, 4 рдФрд░ рдЗрддрдиреЗ рдкрд░ рдкреНрд░рд╡реЗрд╢ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрд╣ рднрд╡рд┐рд╖реНрдп рдХреЗ рд▓рд┐рдП рдЖрд╣рдд рд╣реИред рдИрдВрдЯ рд▓реЛрдбрд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рднреА рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ:

 - (void)loadBricks { // assuming 6x6 brick matrix, each brick is 50x10 NSError *error; [NSBundle mainBundle] ; NSStringEncoding encoding; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"level1" ofType:@"txt"]; NSString *levelData = [NSString stringWithContentsOfFile:filePath usedEncoding:&encoding error:&error]; if (levelData == nil) { NSLog(@"Error loading level data! %@", error); return; } levelData = [[levelData componentsSeparatedByCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString: @""]; if ([levelData length] < (6*6)) { NSLog(@"Level data has incorrect size!"); return; } NSMutableArray *loadedBricks = [NSMutableArray array]; UIImage *brickImage = [UIImage imageNamed:@"brick1"]; NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil]; GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:brickImage.CGImage options:options error:&error]; if (textureInfo == nil) { NSLog(@"Error loading image: %@", [error localizedDescription]); return; } for (int i = 0; i < 6; i++) { for (int j = 0; j < 6; j++) { if ([levelData characterAtIndex:j + i * 6] == '1') { GameSprite *brickSprite = [[GameSprite alloc] initWithTexture:textureInfo effect:self.effect]; brickSprite.position = GLKVector2Make((j + 1) * 50.f - 15.f, 480.f - (i + 1) * 10.f - 15.f); [loadedBricks addObject:brickSprite]; } } } self.bricks = loadedBricks; } 

рдЦреИрд░, рдЕрдм рд╣рдордиреЗ рдИрдВрдЯреЗрдВ рднреА рд▓рд╛рдж рджреАрдВред рдЖрдк рд╣рдорд╛рд░реЗ рдЦреЗрд▓ рдХреЛ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдИрдВрдЯреЛрдВ рдХреА рдкрдВрдХреНрддрд┐рдпреЛрдВ, рд╣рдорд╛рд░реЗ рдмрд▓реНрд▓реЗ рдФрд░ рдЧреЗрдВрдж рдХреА рдкреНрд░рд╢рдВрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рд╕рдм рд╣рдорд╛рд░реА рдкреГрд╖реНрдарднреВрдорд┐ рдХреА рдкреГрд╖реНрдарднреВрдорд┐ рдХреЗ рдЦрд┐рд▓рд╛рдл рд╣реИред рдЕрд░реЗ рд╣рд╛рдБ, рд╣рдо рдпрд╣ рдирд╣реАрдВ рджреЗрдЦ рдкрд╛рдП, рд╣рдо glkView:drawInRect: рдкреНрд░рддрд┐рдкрд╛рджрди рдЬреЛрдбрд╝рдирд╛ рднреВрд▓ рдЧрдП glkView:drawInRect: рдкреНрд░рддрд┐рдкрд╛рджрди рдХреЛ рдХреНрд░рдо рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ: рдкрд╣рд▓реЗ рдкреГрд╖реНрдарднреВрдорд┐, рдлрд┐рд░ рдмрд┐рдЯреНрд╕, рдлрд┐рд░ рд╕рднреА рдИрдВрдЯреЗрдВ, рдФрд░ рдЕрдВрдд рдореЗрдВ - рдЧреЗрдВрджред рдФрд░ рдЕрдм рдЖрдк рдкреНрд░рд╢рдВрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ! =)

рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдХреИрд╕реЗ? рдЧреЗрдВрдж рдХреНрдпреЛрдВ рдирд╣реАрдВ рдЪрд▓рддреА? рдпрд╣ рдПрдХ рддрд╕реНрд╡реАрд░ рдирд╣реАрдВ рд╣реИ, рдпрд╣ рдПрдХ рдЦреЗрд▓ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЧреЗрдВрдж рдХреЛ рдХрд╣реАрдВ рдЙрдбрд╝рдирд╛ рдЪрд╛рд╣рд┐рдП! рдЧреЗрдВрдж рдХреЛ рдЙрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрд╕реЗ рдЧрддрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рд╕реНрдкреНрд░рд╛рдЗрдЯ рд╡рд┐рдзрд┐ рдореЗрдВ update: рдЖрдкрдХреЛ рдЗрд╕ рдЧрддрд┐ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдмрджрд▓рдирд╛ рд╣реЛрдЧрд╛:

 - (void)update:(float)dt { GLKVector2 curMove = GLKVector2MultiplyScalar(self.moveVelocity, dt); self.position = GLKVector2Add(self.position, curMove); } 

рдФрд░ рд╣рдорд╛рд░реЗ ViewController рдХреЗ update рд╡рд┐рдзрд┐ рдореЗрдВ, рдЖрдкрдХреЛ рдЧреЗрдВрдж рдХреЗ рд╕реНрдкреНрд░рд╛рдЗрдЯ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

  [self.ball update:self.timeSinceLastUpdate]; 


рдЕрдм рдЖрдк startGame рдореЗрдВ рдЧреЗрдВрдж рдХреЛ рдЧреИрд░-рд╢реВрдиреНрдп рдЧрддрд┐ рдкрд░ рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ - рдФрд░ рдЧреЗрдВрдж рдЙрдбрд╝ рдЬрд╛рдПрдЧреА!

 - (void)startGame { self.gameRunning = YES; self.gameState = kGameStateNone; [selfloadBricks]; self.ball.position = GLKVector2Make(160, 80); self.ball.moveVelocity = GLKVector2Make(120, 240); } 

рдареАрдХ рд╣реИ, рдЕрдм рдЪрд▓реЛ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ viewDidLoad рдореЗрдВ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ - рдФрд░ рдЧреЗрдВрдж рдЙрдбрд╝ рдЬрд╛рдПрдЧреА, рд▓реЗрдХрд┐рди - рдЬрд▓реНрджреА рд╕реЗ рд╕реНрдХреНрд░реАрди рд╕реЗ рдЙрдбрд╝рд╛рди viewDidLoad ред рд╣рдореНрдо, рдЙрджрд╛рд╕! рдЦреИрд░, рд╣рдо рджреАрд╡рд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЧреЗрдВрдж рдХреЗ рдЯрдХрд░рд╛рд╡ рдФрд░ рдЯрдХрд░рд╛рд╡ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рддреИрдпрд╛рд░ update рд╡рд┐рдзрд┐ рдореЗрдВ, рджреАрд╡рд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЧреЗрдВрдж рдХреА рдЯрдХреНрдХрд░ рдЬреЛрдбрд╝реЗрдВ:

 // checking for walls // left if (self.ball.boundingRect.origin.x <= 0) { self.ball.moveVelocity = GLKVector2Make(-self.ball.moveVelocity.x, self.ball.moveVelocity.y); self.ball.position = GLKVector2Make(self.ball.position.x - self.ball.boundingRect.origin.x, self.ball.position.y); } // right if (self.ball.boundingRect.origin.x + self.ball.boundingRect.size.width >= 320) { self.ball.moveVelocity = GLKVector2Make(-self.ball.moveVelocity.x, self.ball.moveVelocity.y); self.ball.position = GLKVector2Make(self.ball.position.x - (self.ball.boundingRect.size.width + self.ball.boundingRect.origin.x - 320), self.ball.position.y); } // top if (self.ball.boundingRect.origin.y + self.ball.boundingRect.size.height >= 480) { self.ball.moveVelocity = GLKVector2Make(self.ball.moveVelocity.x, -self.ball.moveVelocity.y); self.ball.position = GLKVector2Make(self.ball.position.x, self.ball.position.y - (self.ball.boundingRect.origin.y + self.ball.boundingRect.size.height - 480)); } // bottom (player lose) if (self.ball.boundingRect.origin.y + self.ball.boundingRect.size.height <= 70) { [self endGameWithWin:NO]; } 

рддрд░реНрдХ рд╕рд░рд▓ рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рддреНрд░рд┐рдХреЛрдгрдорд┐рддрд┐ рдХреА рднреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ: рдЬрдм рд╣рдо рдмрд╛рдИрдВ рдФрд░ рджрд╛рдИрдВ рджреАрд╡рд╛рд░реЛрдВ рд╕реЗ рдЯрдХрд░рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рд╡реЗрдЧ рдХреЗ рдХреНрд╖реИрддрд┐рдЬ рдШрдЯрдХ рдХреЛ рдЙрд▓реНрдЯрд╛ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдКрдкрд░реА рджреАрд╡рд╛рд░, рдКрд░реНрдзреНрд╡рд╛рдзрд░ рдХреЗ рд╕рд╛рдеред рдШрдЯрдирд╛ рдХрд╛ рдХреЛрдг рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдХреЛрдг рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ - рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рднреМрддрд┐рдХреА рдХреЗ рдирд┐рдпрдо рджреЗрдЦреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдЦреИрд░, рдирд┐рдЪрд▓реА рд╕реАрдорд╛ рдХреЛ рдкрд╛рд░ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдиреБрдХрд╕рд╛рди рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рдЕрдлрд╕реЛрд╕ред рд╡реИрд╕реЗ, рд╣рдо рдкреНрд▓рдЧ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдЧреЗрдВрдж рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ "рд╕рд╣реА" рднреА рдХрд░рддреЗ рд╣реИрдВред

рднрд╛рдЧреЛ! рдЧреЗрдВрдж рдКрдкрд░ рд╕реЗ, рд╕рд╣реА рджреАрд╡рд╛рд░ рд╕реЗ рдЙрдЫрд▓реА - рдФрд░ рд╣рдо рд╣рд╛рд░ рдЧрдП, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рдерд╛ред рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмреБрд░рд╛ рдирд╣реАрдВ рд╣реИ! рдЕрдм рд╣рдореЗрдВ рдмрд▓реНрд▓реЗ рдХреЛ рдЙрдЫрд╛рд▓рдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ, рдФрд░, рдЬреИрд╕рд╛ рдХрд┐ рдЕрд░рдХрд╛рдиреЛрдЗрдб рдореЗрдВ рдкреНрд░рдерд╛рдЧрдд рд╣реИ, рдШрдЯрдирд╛ рдХрд╛ рдХреЛрдг рд╣рдореЗрд╢рд╛ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдХреЛрдг рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдЬреЛ рдЧреЗрдВрдж рдкрд░ рдмрд▓реНрд▓реЗ рдХреЗ рдЧрд┐рд░рдиреЗ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░реЗрдЧрд╛ред рддреНрд░рд┐рдХреЛрдгрдорд┐рддрд┐ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЗрд╕ рдХреЛрдг рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдпрд╣рд╛рдВ рд▓рд╛рдЧреВ рд╣реИ:

  // player strikes! if (CGRectIntersectsRect(self.ball.boundingRect, self.playerBat.boundingRect)) { float angleCoef = (self.ball.position.x - self.playerBat.position.x) / (self.playerBat.contentSize.width / 2); float newAngle = 90.f - angleCoef * 80.f; GLKVector2 ballDirection = GLKVector2Normalize(GLKVector2Make(1 / tanf(GLKMathDegreesToRadians(newAngle)), 1)); float ballSpeed = GLKVector2Length(self.ball.moveVelocity); self.ball.moveVelocity = GLKVector2MultiplyScalar(ballDirection, ballSpeed); self.ball.position = GLKVector2Make(self.ball.position.x, self.ball.position.y + (self.playerBat.boundingRect.origin.y + self.playerBat.boundingRect.size.height - self.ball.boundingRect.origin.y)); } 

рдЖрджрд┐рдо рдкрд░реНрдпрд╛рдкреНрддред рд▓реЗрдХрд┐рди рдЕрдм рдордЬрд╝реЗрджрд╛рд░ рд╣рд┐рд╕реНрд╕рд╛ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ: рдИрдВрдЯреЛрдВ рдХреЗ рд╕рд╛рде рдЯрдХрд░рд╛рд╡ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛, рдЙрдирдХрд╛ рд╡рд┐рдирд╛рд╢ рдФрд░ рдЧреЗрдВрдж рдХрд╛ рд╡рд┐рджреНрд░реЛрд╣ред

  // checking for broken bricks NSMutableArray *brokenBricks = [NSMutableArray array]; GLKVector2 initialBallVelocity = self.ball.moveVelocity; for (GameSprite *brick in self.bricks) { if (CGRectIntersectsRect(self.ball.boundingRect, brick.boundingRect)) { [brokenBricks addObject: brick]; if ((self.ball.position.y < brick.position.y - brick.contentSize.height / 2) || (self.ball.position.y > brick.position.y + brick.contentSize.height / 2)) { self.ball.moveVelocity = GLKVector2Make(initialBallVelocity.x, -initialBallVelocity.y); } else { self.ball.moveVelocity = GLKVector2Make(-initialBallVelocity.x, initialBallVelocity.y); } } } // removing them for (GameSprite *brick in brokenBricks) { [self.bricks removeObject:brick]; } if (self.bricks.count == 0) { [self endGameWithWin:YES]; } 

рдпрд╣рд╛рдВ рддрд░реНрдХ рдЕрдзрд┐рдХ рдЪрд╛рд▓рд╛рдХ рд╣реИ: рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЧреЗрдВрдж рдХрд┐рд╕ рддрд░рдл рдИрдВрдЯ рд╕реЗ рдЯрдХрд░рд╛рддреА рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╣рдо рдЧрддрд┐ рдХреЗ рдЖрд╡рд╢реНрдпрдХ рдШрдЯрдХ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ, рдФрд░ рдИрдВрдЯ рдХреЛ рдЯреВрдЯреА рд╣реБрдИ рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдареАрдХ рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рд╕рднреА рдЯреВрдЯреЗ рд╣реБрдП рдХреЛ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ, рдФрд░ рдЕрдЧрд░ рдХреЛрдИ рднреА рдирд╣реАрдВ рдмрдЪрд╛ рд╣реИ, рддреЛ рд╣рдо рдЦреЗрд▓ рдЦрддреНрдо рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдЬреАрдд рдЧрдП!

рдЦреИрд░, рдЕрдм рдЖрдк рдЦреЗрд▓ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдЧреЗрдВрдж рдХреИрд╕реЗ рдХреВрджрддреА рд╣реИ, рдИрдВрдЯреЗрдВ рддреЛрдбрд╝рддреА рд╣реИ рдФрд░ ... рд╣рд╛рдВ, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдХреИрд╕реЗ рд╣рд░рд╛рдПрдВ? рдПрдХ рдмрд▓реНрд▓рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХреНрдпрд╛ рд╣рдореЗрдВ рдЗрд╕реЗ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдирд╛ рд╣реИ? рдореИрдВрдиреЗ рдмрд▓реНрд▓реЗ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдЪреБрдирд╛: рдореИрдВрдиреЗ "рдХрд╛рди" рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреЗ рдиреАрдЪреЗ рдПрдХ рдЬрдЧрд╣ рдЖрд╡рдВрдЯрд┐рдд рдХреА, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЖрдк рдЗрд╕реЗ рдЕрдкрдиреЗ рдЕрдВрдЧреВрдареЗ рд╕реЗ рдЦреАрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдмрд┐рдЯреНрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЙрдВрдЧрд▓реА рдХреЛ рджрдмрд╛рдиреЗ рдФрд░ рд╣рд┐рд▓рд╛рдиреЗ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдЬреЗрд╕реНрдЪрд░ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ! рдЙрдиреНрд╣реЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:

 - (void)viewDidLoad { // ... // gestures UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)]; UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGestureFrom:)]; [self.view addGestureRecognizer:panRecognizer]; [self.view addGestureRecognizer:tapRecognizer]; } - (void)handleTapGestureFrom:(UITapGestureRecognizer *)recognizer { CGPoint touchLocation = [recognizer locationInView:recognizer.view]; if (self.gameRunning) { GLKVector2 target = GLKVector2Make(touchLocation.x, self.playerBat.position.y); self.playerBat.position = target; } } - (void)handlePanGesture:(UIGestureRecognizer *)gestureRecognizer { CGPoint touchLocation = [gestureRecognizer locationInView:gestureRecognizer.view]; if (self.gameRunning) { GLKVector2 target = GLKVector2Make(touchLocation.x, self.playerBat.position.y); self.playerBat.position = target; } } 

рдЕрдЪреНрдЫрд╛, рдХреНрдпрд╛ рдЖрдк рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ? рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛, рд╕рднреА рдИрдВрдЯреЛрдВ рдХреЛ рддреЛрдбрд╝ рджрд┐рдпрд╛! рддреЛ рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ? рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ рдХрд┐ рдЦрд┐рд▓рд╛рдбрд╝реА рдЕрдкрдиреЗ рдордЬрджреВрд░реЛрдВ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рджрд┐рдЦрд╛рдП, рдФрд░ рдЗрд╕рд▓рд┐рдП рдореЗрдиреВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред рдЖрдорддреМрд░ рдкрд░, рдЗрд╕ рддрд░рд╣ рдХреА рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рджреГрд╢реНрдп рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдЬреЛ рдЧреЗрдорд╕реНрдкреНрд░реЗ рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реЗ рдЧреЗрдорд╕реНрдХреАрди рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рддрдп рдХрд┐рдпрд╛ рдХрд┐ рдХреЛрдб рдХреЛ рдкрд░реЗрд╢рд╛рди рди рдХрд░реЗрдВ рдФрд░ рдпрдерд╛рд╕рдВрднрд╡ рд╕рд░рд▓ рдЫреЛрдбрд╝ рджреЗрдВред рдЗрд╕рд▓рд┐рдП рдореЗрдиреВ рдХреЛ рд╡рд┐рднрд┐рдиреНрди рд╕реНрдкреНрд░рд╛рдЗрдЯреНрд╕ рд╕реЗ рдЗрдХрдЯреНрдард╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЦреИрд░, glkView:drawInRect: рд╣рдореЗрдВ рдЦреЗрд▓ рдХреА рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдФрд░ рд╕рдмрдХреБрдЫ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП:

 - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(1.f, 1.f, 1.f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); [self.background render]; [self.playerBat render]; for (GameSprite *brick in self.bricks) { [brick render]; } [self.ball render]; if (!self.gameRunning) { [self.menuDimmer render]; [self.menuStartButton render]; switch (self.gameState) { case kGameStateWon: [self.menuCaptionWon render]; break; case kGameStateLose: [self.menuCaptionLose render]; break; case kGameStateNone: default: [self.menuCaption render]; break; } } } 

рдпрд╣рд╛рдВ, рдлрд┐рд░ рд╕реЗ, рд╕рдм рдХреБрдЫ рдмреЗрд╣рдж рд╕рд░рд▓ рд╣реИ, рдореИрдВ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдирд╛ рднреА рдирд╣реАрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдпрд╣ "play" рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП handleTapGestureFrom: "рдФрд░" рдмреНрд▓реЙрдХ handleTapGestureFrom: :

  else if (CGRectContainsPoint(self.menuStartButton.boundingRect, touchLocation)) { [self startGame]; } 

рд╡рд╣ рд╕рдм рд╣реИ! рднрд╛рдЧреЛ, рдЦреЗрд▓реЛ, рдЬреАрддреЛ рдФрд░ рд╣рд╛рд░реЛ! рдФрд░ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд - рдЖрдирдиреНрдж! рд╣рдо рд╢реБрджреНрдз OpenGL рдкрд░ рдЕрдкрдиреЗ рдореВрд▓, рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд iPhone рдЧреЗрдо рдореЗрдВ рдЖрдирдиреНрджрд┐рдд рд╣реЛрддреЗ рд╣реИрдВ!


рдлреВрд╣, рд╕рдм рдХреБрдЫ рд▓рдЧрддрд╛ рд╣реИред рдЕрдм рдореИрдВ рдПрдХ рдмреНрд░реЗрдХ рд▓реЗ рд╕рдХрддрд╛ рд╣реВрдВ рдФрд░ рдореЗрд░реЗ рд╕рд╛рде рдЬреЛ рд╣реБрдЖ, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдЧреАрдереВрдм рдкрд░ рд╕реВрддреНрд░реЛрдВ рдХрд╛ рд▓рд┐рдВрдХ рджреЗ рд╕рдХрддрд╛ рд╣реВрдВ ред (рдПрдХ рдЪреМрдХрд╕ рдкрд╛рдардХ рдкрд╣рд▓реЗ рд╣реА рджреЗрдЦ рдЪреБрдХрд╛ рд╣реИ рдХрд┐ рдЧреЗрдВрдж рд╡реАрдбрд┐рдпреЛ рдореЗрдВ рдШреВрдорддреА рд╣реИ; рдЦреИрд░, рдЗрд╕рдХреЗ рд▓рд┐рдП рдЧрд┐рдердм рдкрд░ рдПрдХ рдХреЛрдб рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВ рд▓реЗрдЦ рдХреЛ рдЕрдзрд┐рднрд╛рд░ рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛)

рдмреЗрд╢рдХ, рдпрд╣ рдЦреЗрд▓ рдПрдХрджрдо рд╕рд╣реА рд╣реИред рдЗрд╕рдореЗрдВ рдПрдХ рдИрдВрдЯ рдХреЛ рддреЛрдбрд╝рдиреЗ, рдмреЛрдирд╕ рдЧрд┐рд░рдиреЗ, рд╕реНрдХреЛрд░рд┐рдВрдЧ, рдмрджрд▓рддреЗ рд╕реНрддрд░, рдЯрдХрд░рд╛рд╡ рдХреА рдмреЗрд╣рддрд░ рдкрд░рд┐рднрд╛рд╖рд╛, рдзреНрд╡рдирд┐рдпреЛрдВ рдХреЗ рд╣рдорд▓реЛрдВ рдХреЗ рдПрдиреАрдореЗрд╢рди рдХрд╛ рдЕрднрд╛рд╡ рд╣реИред рдареАрдХ рд╣реИ, рдЖрдк рдПрдХ рдЙрдЪреНрдЪ рдЕрдВрдХ рддрд╛рд▓рд┐рдХрд╛, рдЧреЗрдо рд╕реЗрдВрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг, рдЖрдИрдХреНрд▓рд╛рдЙрдб рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдмрдЪрдд, рдлреЗрд╕рдмреБрдХ / рдЯреНрд╡рд┐рдЯрд░, рдЙрдкрд▓рдмреНрдзрд┐рдпреЛрдВ рдФрд░ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХреЛ рднреЗрдЬ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдЖрдзреБрдирд┐рдХ рдЧреЗрдо рдХреЛ рдЧрдВрднреАрд░рддрд╛ рд╕реЗ рдирд╣реАрдВ рд▓рд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореЗрд░реА рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдРрдк рд╕реНрдЯреЛрд░ рдореЗрдВ рдЧреЗрдо рдХреЛ рд░рд┐рд▓реАрдЬрд╝ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЗрд╕ рд╕рдм рд╕реЗ рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдп рдЗрд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рдерд╛ред

PS рдпрд╛ рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ:рдФрд░ рддрдм рдХреБрдЫ рднреА рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рдерд╛ред рдореИрдВ ZeptoLab рдореЗрдВ рдПрдХ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдЬрд▓реНрджреА рдПрдХ рдЧрд╣рд░реЗ рд╕реНрддрд░ рдкрд░ OpenGL рдХреА рдЕрдЬреНрдЮрд╛рдирддрд╛ рдореЗрдВ рдЧрд┐рд░ рдЧрдпрд╛ред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдореЗрд░рд╛ рд▓рд╛рдн рдорд┐рд▓рд╛: рдЕрдм рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реБрдЖ рддреЛ рдореИрдВ рдПрдХ рд╕рд░рд▓ рдЦреЗрд▓ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВ, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░ рдореБрдЭреЗ рдЕрдкрдиреЗ рд▓рд┐рдП рдПрдХ рдирдП рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдереЛрдбрд╝рд╛ рдкрддрд╛ рд▓рдЧрд╛ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдЕрдм рдЖрдк рдПрдХ рдЦреЗрд▓ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдореЗрд░реЗ рдкреНрд░рд┐рдп рдкрд╛рдардХ рднреА! рд╕рд┐рдо рдХреЗ рд▓рд┐рдП, рдореБрдЭреЗ рдЕрдкрдиреА рдЫреБрдЯреНрдЯреА рд▓реЗрдиреЗ рджреЗрдВ, рдЕрд▓рд╡рд┐рджрд╛ред

Source: https://habr.com/ru/post/In151762/


All Articles