• Nie Znaleziono Wyników

С.В. Максимчук РОЗРОБКА ГРИ ПІД ПЛАТФОРМУ iOS ДЛЯ iPHONE

N/A
N/A
Protected

Academic year: 2021

Share "С.В. Максимчук РОЗРОБКА ГРИ ПІД ПЛАТФОРМУ iOS ДЛЯ iPHONE"

Copied!
156
0
0

Pełen tekst

(1)
(2)

2 УДК 614.2 Максимчук С.В. Розробка гри під платформу iOS для iPhone. Науковий керівник Літнарович Р.М. . МЕГУ, Рівне, 2012.-155 с. Рецензенти: В.Г.Бурачек, доктор технічних наук, професор Є.С. Парняков, доктор технічних наук, професор В.О.Боровий , доктор технічних наук, професор Відповідальний за випуск: Й.В. Джунь, доктор фізико-математичних наук, професор Сучасна комп’ютерна гра – це багатофункціональна програма, яку використовують не тільки з розважальними, а й із навчальними та пропагандистськими цілями. Гра заявлена в даній роботі має розвиваючий характер. Адже в ній гравець підвищує свою реакцію, за рахунок швидкої зміни цільових об’єктів. Також за рахунок цікавого дизайну, має більш привабливий сприйняття вигляд. Монографія містить повноцінну iPhone гру, та інформацію про засоби які необхідні розробнику для створення аналогічного продукту. Ключові слова: мобільна гра, iPhone ігри, розробка гри, iOS . Современная компьютерная игра - это многофункциональная программа, которую используют не только с развлекательными, но и с учебными и пропагандистскими целями. Игра заявлена в данной работе имеет развивающий характер. Ведь в ней игрок повышает свою реакцию, за счет быстрой смены целевых объектов. Также за счет интересного дизайна, имеет более привлекательный восприятия вид. Монография содержит полноценную iPhone игру, и информацию о средствах необходимых разработчику для создания аналогичного продукта. Ключевые слова: мобильная игра, iPhone игры, разработка игры, iOS

Modern computer games - is a multipurpose program that is used not only entertaining, but also educational and propaganda purposes. The game is stated in this paper is developing character. Because in it the player raises his reaction by quickly changing targets. Also, due to interesting design has a more attractive form of perception. The monograph contains a full iPhone game, and information on the means necessary for developers to create a similar product.

Keywords: mobile game, iPhone Games, Game Development, iOS.

(3)

3

(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)

13

(14)
(15)
(16)
(17)
(18)
(19)
(20)
(21)
(22)

22

(23)

23 призначений для безпосереднього контакту користувача з екраном пристрою. Внутрішній акселерометр використовуються деякими програмами для реагування на струшування пристрою, яке є також загальною командою скасування, або обертати пристрій у трьох вимірах, що є загальною командою перемикання між книжковим та альбомним режимами. В якості операційної системи iOS була

(24)

24

(25)
(26)
(27)

27 Звукові карти спочатку були розроблені для інтегрування якісного цифрового звуку в комп'ютерні ігри, і тільки потім звукове обладнання було вдосконалено під потреби меломанів[3]. Графічні карти, які на зорі комп'ютерної епохи еволюціонували у напрямі збільшення кількості підтримуваних кольорів, пізніше стали розвиватися для графічних інтерфейсів користувача (англ. GUI) та ігор. GUI зіграв роль у збільшенні дозволів екрану, а ігри - в 3D прискорення і винаході таких технологій, як SLI і CrossFire. Використання CD і DVD дисків для розповсюдження ігор породив необхідність у збільшенні обсягів і швидкостей читання.

(28)
(29)
(30)
(31)
(32)
(33)
(34)
(35)

35

(36)
(37)

37

(38)
(39)
(40)
(41)
(42)
(43)
(44)
(45)
(46)
(47)
(48)

48 масштабу. Торік було продано понад 10 млн ліцензійних копій комп’ютерних іграшок. На думку генпродюсера однієї з російських компаній Сергія Клімова, до 2008 року Україна й Росія разом випускатимуть по 10–12 великих і прибуткових ігор щороку. Харківська команда CRAZY HOUSE зараз працює над національно-свідомим квестом - "Вій: історія, розказана знову", за Гоголем. У грі співіснуватимуть "живі" герої (для цього на відео знімали харківських акторів театру, серед яких, як гордо заявили представники "скаженої фірми", є кілька заслужених і, навіть, один народний артист) разом із тривимірними анімованими моделями нечисті. А, наприклад, IRBIS Development Group створює не менш патріотичний проект "Футбольний менеджер: серце

тренера", присвячений пам'яті Валерія

Лобановського...

До слова: Росія нас у ігровій індустрії поки що

(49)

49

іноземців. Ті або купують їх, або вкладають в них свої гроші. Наші ж поки що працюють переважно самотужки.

App Store

App Store — розділ онлайн супермаркету iTunes Store, що продає власникам мобільних телефонів iPhone, плеєрів iPod Touch та планшетних ПК iPad різні додатки. Українська версія відсутня. App Store містить понад 550 тисяч додатків (станом на початок 2012 року). Вартість цих програм/додатків складає від $0,99 до $9,99, за деякими винятками. В Україні можливе придбання програмного забезпечення за допомогою банківської картки Visa. В магазині App Store також є розділ з безкоштовними програмами, або пробними версіями звичайних.

(50)

50

Але попередня модель потребувала оновлення ПЗ. Доступ до App Store також можливий з iTunes, починаючи з версії 7.7. За магазином слідкують спеціалісти Apple і кожен застосунок проходить перевірку та отримує електронний сертифікат. Від продажу застосунків автор отримує 70 %, Apple 30 %, для підтримки магазину.

(51)

51

6.1 Підкатегоріїї: Action; Adventure; Arcade; Board; Card; Casino; Dice; Educational; Family; Kids; Music; Puzzle; Racing; Role Playing; Simulation; Sports; Strategy; Trivia Word

(52)
(53)

53

(54)
(55)

55

(56)
(57)
(58)
(59)

59

[object doSmthWithParams:data otherData: data1];

В цьому випадку іменем повідомлення є ”

doSmthWithParams:otherData:”

Також об’єкт, який обробив повідомлення може

повертати значення

output = [object doSmth];

Можна використовувати вкладені повідомлення,

тобто результат одного повідомлення може

використовуватись як параметр іншого

[object doSmthWithParams:data otherData:

[object doSmth]];

(60)

60 використання універсального типу даних id. Змінна типу id фактично являється вказівником на будь-який об’єкт. Для нульових вказівників використовується константа nil. До речі, відправка повідомлення нульовому об’єкту є цілком законною операцією на відміну від С++. Результатом буде повернення теж нульового об’єкта. Можна ще згадати відсутність вбудованого булєвого типу даних для логічних величин. Тому замість нього використовується штучний тип даних BOOL із двома можливими значеннями YES і NO.

(61)

61

правило класи описуються в заголовочних файлах з розширенням *.h

@interface HelloWorldViewController : UIViewController {

UITextField* edText; UILabel* lbText; }

@property(nonatomic,retain) (IBOutlet) UITextField* edText;

@property(nonatomic,retain) (IBOutlet) UILabel* lbText;

(62)

62 інтерфейс, тобто клас, методи якого не можуть бути реалізовані, позначається як @protocol. Директива @class також використовується, але попередньої декларації класу. Для об’єктів дозволено наслідування, але тільки не множинне. Об’єкт може бути породженний від іншого об’єкту і одночасно реалізовувати багато протоколів. Варто звернути увагу, що всі методи класу є віртуальними, тому можуть бути перевизначені в нащадках. На відміну наприклад від С++, методи класу є завжди публічними (public). Хоча видимістю даних (полів) екземплярів класу можна керувати за допомогою аналогічних

директив @private, @public, @protected. По

замовчуванню, всі вони є @protected. Для доступу до полів об’єкта використовується таке поняття як властивості - @property

(63)
(64)
(65)
(66)

66 використовувати властивість в межах, описаних її атрибутами. Все просто. Далі хотілося б згадати ще одну корисну річ, яка досить широко використовується – це @selector. Селектор дозволяє однозначно ідентифікувати метод об’єкта і передавати його як параметр при відправці повідомлення. Це чимось схоже на вказівник на функцію в С++. Типом селектора є SEL. Отримати селектор по імені метода можна за допомогою наступної конструкції

SEL doSmth = @selector(doSmth); //метод doSmth або

SEL doSmthWithParams = @selector(doSmth:) //метод doSmth:(id)data

(67)

67

об’єкт певний метод за допомогою відправки об’єкту повідомлення respondsToSelector:

if ( [object respondsToSelector: @selector(doSmth:)] ) [object doSmth: data];

(68)

68

[anyObject performSelector:@selector(doSmth:)

withObject: nil afterDelay: 30.0];

(69)

69 реалізовуватись по потребі. Для цього слугують директиви відповідно @required i @optional. По замовчуванню використовується @optional. Нижче приведено приклад опису протоколу. @protocol Serializable @required

- (id) initWithCoder: (NSCoder *) coder; @optional

- (void) encodeWithCoder: (NSCoder *) coder; @end

Протокол може наслідувати довільну кількість

протоколів. Для перевірки чи підтримує об’єкт певний

протокол, можна скористатись повідомленням

conformsToProtocol

(70)
(71)

71

описати і реалізувати необхідні додаткові методи для існуючого класу. Нижче поданий приклад опису і реалізації методів описаних категоріями.

#import "HelloWorldViewController.h"

@interface HelloWorldViewController ( CategoryName ) -(void) doMore; @end #import "HelloWorldViewController.h" @implementation HelloWorldViewController ( CategoryName ) -(void) doMore{

NSLog(@" We are doing more!"); }

@end

Обробка виключних ситуацій

(72)

72 Наприклад: @try { [obj doSmth]; } @catch ( NSException * e ) {

NSLog ( @"Exception caught: %@", e ); } @finally { [obj release]; } І відповідно для генерації виключної ситуації використовується @throw

(73)
(74)
(75)
(76)
(77)

77 [super dealloc]; } Autorelease pool Ви мабуть помітили, що вказано ще один метод, який використовується для вивільнення пам’ятті. Це – autorelease. По назві можна здогадатись, що щось схоже на release, тільки автоматично. Часто при реалізації певного методу необхідно повернути посилання на створений об’єкт. //некоректна реалізація!!! -(NSString*) getString {

NSString* str= [NSString alloc];

(78)

78 Але не відомо, де, коли, ким і чи взагалі він буде знищений. Звідси виходить, що ми самі повинні подбати про його знищення, викликавши release. Виникає питання – де? Якщо до виклику return, то об’єкт буде знищений ще до його повернення. В цьому випадку на допомогу приходить autorelease. Цей механізм ще можна назвати “відкладеним звільненням”. Тобто, відправивши об’єкту повідомлення autorelease ми кладемо його в спеціальний пул, де він зберігається до того моменту, коли цей пул також буде знищений. -(NSString*) getString {

NSString* str= [[NSString alloc] autorelease];

(79)

79 Що ж таке Autorelease pool? Це спеціальний об’єкт – екземпляр класуNSAutoreleasePool. Якщо глянути на файл проекту main.m, який створюється по замовчуванню можна побачити, що весь процес запуску програми відбувається між створенням і знищенням Autorelease pool.

int main(int argc, char *argv[]) {

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

(80)
(81)
(82)
(83)

83 Багато інших англомовних термінів де присутнє слово framework легко замінюється в українському варіанті загалом на слова: основа, несуча конструкція, структура, каркас, в автоматиці та аудиті може бути концепція, в механіці стержнева система, або це може бути просто механізм. Отже, якщо ми визначилися з тим, що ж таке фреймворк, то нам потрібно обрати той, працювати з яким буде найзручніше(звісно можна обійтися взагалі без нього, але ми такий варіант не розглядаєм).

Існує багато фреймворків під іOS: Box2D, Bullet, Chipmunk, iTorque 2D, Oolong Engine, ShiVa3D, SIO2, Unity, cocos2d, Sparrow, Wibble Quest, RestKit, LRResty, HTTPRiot, FlowCover, OpenFlow, iCarousel, Tapku, Core Plot, iVisualization, PowerPlot та багато інших.

Ми зупинимося на фреймворку cocos2d.

сocos2d написаний для вирішення різних задач у двохвимірному просторі. Він є основою для створення

2D-ігор, демонстрацій та інших

(84)
(85)

85

затверджено більше 2500 ігор, серед яких багато хітових ігрор.

(86)
(87)
(88)

88

2.2 Виложення продукту на ринок

AppStore

Як влаштований Apple App Store?

App Store є одним з розділів онлайн магазину ITunes Store, який займається продажем різних додатків власникам плеєрів IPod Touch, мобільних телефонів iPhone і планшетів IPad.

(89)
(90)
(91)

91

(92)

92

(93)

93

секцію AppIDs. Якщо не брати до уваги «пакетну» концепцію ідентифікації додатків, то все просто: натискаємо Новий App ID, вводимо

- Description (напр, My Awesome App)

- Bundle Seed ID (App ID Prefix) - якщо це наше перше додаток, то в списку буде всього один пункт - Generate New, в іншому випадку в ньому будуть ідентифікатори раніше створених додатків (за задумом, додатки можна об'єднувати в пакети (suite))

(94)

94 - Devices - ставимо мітку на тих девайсах, які зареєстровані, їх може бути більше одного. Створили профіль, дочекалися його аппрува, завантажуємо файл профілю (. Provisionprofile), відкриваємо вікно Organizer і кидаємо туди драг-енд-дропом файл профілю. Він успішно інсталюється. Тепер

(95)

95 Після того, як ми налагодили додаток на девайсі, настає пора збирати дистрибутив для публікації. Для цього повторюємо процес створення профілю дистрибуції. Він схожий з створенням девелопмент-профілю. Інсталюємо профіль в xCode, а далі потрібно здійснити наступне. Необхідно створити нову конфігурацію Distribution. Відкриваємо опції проекту, секцію Configuration, вибираємо там конфігурацію Release і натискаємо Duplicate. Вводимо назву Distribution. Далі у вікні Target в секції Build вибираємо настройки для конфігурації Distribution і в поле Code Signing Identity - Any iPhone OS Device вибираємо наш Distribution Profile. На закладці Properties не забуваємо вписати Bundle Identifier, якщо ще не зробили. Закриваємо опції, і в головному вікні xCode вибираємо конфігурацію Device | Distribution. Далі непогано б простежити за процесом складання. Для цього йдемо в меню Build - Build Results. Там налаштовуємо щоб

показувався лог компіляції. Натискаємо Build.

(96)
(97)
(98)
(99)
(100)
(101)

101

Література

1. Програмирование для iPhone / Махер Али ; [пер. с англ. ]. – М.: Эксмо, 2010. – 368 с.

2. More iPhone Cool Projects: Cool Developers Reveal the Details of Their Cooler Apps and Discuss Their iPad Development Experiences / Danton Chin, Claus Hцfele, Ben Kazez, Saul Mora, Leon Palm, Scott Penberthy, Ben Britten Smith, Chuck Smith, David Smith, Arne de Vries, and Joost van de Wijgerd; 2010, – 345 p.

3. Learn cocos2d Game Development with iOS 5 / Steffen Itterheim; 2011. – 677 p.

4. Learn iPhone and iPad cocos2d Game Development / Steffen Itterheim; 2010. - 397 p.

(102)

102

6. Начни программировать под Mac OS X используя Objective-C / Bert Altenberg, Alex Clarke, Philippe Mougin.: - 2008ю – 84 с. 7. iPhone SDK 3 Programming Advanced Mobile

Development for Apple iPhone and iPod touch / Maher Ali; 2009, - 621 p.

8. Objective-C for Absolute Beginners: iPhone, iPad, and Mac Programming Made Easy / Gary Bennett, Mitch Fisher, Brad Lees; 2010. – 263 p.

9. iOS Programming: The Big Nerd Ranch Guide / Joe Conway, Aaron Hillegass; 2011. – 505 p.

10. iPhone Programming: The Big Nerd Ranch Guide / Joe Conway, Aaron Hillegass; 2010. – 464 p.

11. iPhone. Разработка приложений / Здзиарски Дж.: . 2009.: - 360 c.

12. Programming iOS 4 / Matt Neuburg; 2011.: - 789 p. 13. iOS 4 Programming Cookbook / Vandad

Nahavandipoor; 2011.: - 595 p.

14. Beginning iPhone SDK Programming with

(103)

103

15. Xcode 4 iOS Development Beginner's Guide / Packt Publishing; 2011.: - 395 p.

16. Head First iPhone Development / Dan Pilone, Tracey Pilone; 2009.: - 560 p.

17. Building iPhone Apps with HTML, CSS, and JavaScript / Making App Store Apps Without Objective-C or Cocoa; Jonathan Stark; O'Reilly Media; 2010.: - 186 p.

18. Learning iPhone Programming / From Xcode to App Store; Alasdair Allan; O'Reilly Media; 2010.: - 384 p.

19. iOS 5 Programming Cookbook / Vandad Nahavandipoor; 2012.: - 876 p.

20. Concurrent Programming in Mac OS X and iOS / Vandad Nahavandipoor; 2011.: - 60 p.

21. Writing Game Center Apps in iOS / Vandad Nahavandipoor; 2011.: - 80 p.

(104)

104

(105)

105 Додатки Код програми: AppDelegate.h #import <UIKit/UIKit.h> #import "GKWizard.h" @class RootViewController;

@interface AppDelegate : NSObject <UIAlertViewDelegate, UIApplicationDelegate,GKLeaderboardView ControllerDelegate> { UIWindow *window; RootViewController *viewController; BOOL hasPlayedBefore,whacked3,whacked4; NSString *currentSkin; GKWizard *wiz; int timesPlayed,currentAction,greenMolesWha cked,blueMolesWhacked,yellowMolesWhacke d; }

(106)
(107)

107

- (void) removeStartupFlicker {

//

// THIS CODE REMOVES THE STARTUP FLICKER

//

// Uncomment the following code if you Application only supports landscape mode

//

#if GAME_AUTOROTATION ==

kGameAutorotationUIViewController // CC_ENABLE_DEFAULT_GL_STATES();

// CCDirector *director = [CCDirector sharedDirector];

// CGSize size = [director winSize]; // CCSprite *sprite = [CCSprite

(108)

108 } - (void) applicationDidFinishLaunching:(UIApplic ation*)application {

// Init the window

window = [[UIWindow alloc]

initWithFrame:[[UIScreen mainScreen] bounds]]; timesPlayed = [[NSUserDefaults standardUserDefaults] integerForKey:kTimesPlayed]; currentSkin = SKIN_MOLE;

// Try to use CADisplayLink director

// if it fails (SDK < 3.1) use the default director if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayL ink] ) [CCDirector setDirectorType:kCCDirectorTypeDefault] ;

wiz = [[GKWizard alloc] init]; CCDirector *director = [CCDirector sharedDirector];

(109)

109 viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil]; viewController.wantsFullScreenLayou t = YES; //

// Create the EAGLView manually // 1. Create a RGB565 format. Alternative: RGBA8

// 2. depth format of 0 bit. Use 16 or 24 bit for 3d effects, like

CCPageTurnTransition //

//

EAGLView *glView = [EAGLView viewWithFrame:[window bounds] pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8 depthFormat:0 // GL_DEPTH_COMPONENT16_OES ];

// attach the openglView to the director

(110)

110

//

// VERY IMPORTANT:

// If the rotation is going to be controlled by a UIViewController

// then the device orientation should be "Portrait".

//

// IMPORTANT:

// By default, this template only supports Landscape orientations.

// Edit the RootViewController.m file to edit the supported

(111)

111 //[director setDisplayFPS:YES]; [CCTexture2D PVRImagesHavePremultipliedAlpha:YES]; [viewController setView:glView]; // make the OpenGLView a child of the view controller

// // Enables High Res mode

(Retina Display) on iPhone 4 and

maintains low res on all other devices //[director

enableRetinaDisplay:YES]

// make the View Controller a child of the main window

[window addSubview: viewController.view];

[window makeKeyAndVisible]; // Default texture format for PNG/BMP/TIFF/JPEG/GIF images

// It can be RGBA8888, RGBA4444, RGB5_A1, RGB565

(112)

112

[CCTexture2D

setDefaultAlphaPixelFormat:kCCTexture2D PixelFormat_RGBA4444];

// Removes the startup flicker [self removeStartupFlicker]; // Run the intro Scene

(113)
(114)

114 [[CCDirector sharedDirector] startAnimation]; } - (void)applicationWillTerminate:(UIAppli cation *)application {

(115)

115

-(void)finishedWithScore: (int)score {

/*if(score > [self getHighScore]) { [[NSUserDefaults standardUserDefaults] setInteger:score forKey:kHighScoreKey]; [wiz reportScore:score forLeaderboard:kHighScoreKey]; } timesPlayed++; [[NSUserDefaults standardUserDefaults] setInteger:timesPlayed forKey:kTimesPlayed]; if (timesPlayed % 10 == 0 && ![[NSUserDefaults standardUserDefaults] boolForKey:kDidRate]) { UIAlertView *alert = [[UIAlertView alloc]

initWithTitle:@"Like Mole It?"

message:@"If you like Mole It, please rate it to show your support."

(116)
(117)
(118)
(119)

119 [viewController dismissModalViewControllerAnimated:YES] ; } - (void)dealloc {

[[CCDirector sharedDirector] end]; [window release]; [wiz release]; [super dealloc]; } @end MainMenu.h #import "cocos2d.h" @class AppDelegate;

(120)

120 #import "Game.h" #import "AppDelegate.h" #import "SimpleAudioEngine.h" #import "Constants.h" #import "PopUp.h" #import "GameButton.h" #import "CCMenuPopup.h" @implementation MainMenu - (id)init {

self = [super init]; if (self) {

// Initialization code here. CGSize s = [[CCDirector sharedDirector] winSize]; [[SimpleAudioEngine sharedEngine] stopBackgroundMusic]; delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

NSString *fileName = [NSString stringWithFormat: @"%@.plist",

(121)

121

(122)
(123)

123

selectedSprite:NULL target:self selector:@selector(otherGames)]; //[CCMenuItemFont

setFontSize:fSize];

CCMenu *menu = [CCMenu menuWithItems: /*leaderboardsButton,otherGamesButton,* / selectSkinButton, nil]; [menu alignItemsHorizontallyWithPadding:20]; menu.position = ccp(s.width/2, 45); [self addChild:menu];

(124)
(125)

125

selectedSprite:NULL target:self selector:@selector(mSkin)];

CCMenuPopup *menu = [CCMenuPopup menuWithItems:jetIcon,moleIcon, nil]; [menu alignItemsHorizontallyWithPadding:20]; CCMenuItemSprite *btnCancel = [CCMenuItemSprite itemFromNormalSprite:[GameButton buttonWithText:@"Cancel"] selectedSprite:NULL]; CGSize s = [[CCDirector sharedDirector] winSize]; CCMenuPopup *cancelMenu = [CCMenuPopup menuWithItems:btnCancel, nil]; btnCancel.position = ccp(0,- s.height/3);

CCSprite *container = [CCSprite node];

[container addChild:menu];

[container addChild:cancelMenu];

(126)

126

description:@"Select a skin to use or preview" sprite:container]; [self addChild:pop z:1000]; } -(void)otherGames {

NSString *search = @"wedgekase games";

NSString *sstring = [NSString

(127)

127 -(void)mSkin { [delegate setCurrentSkin:SKIN_MOLE]; } -(void)showLeaderboard { [delegate showLeaderboard]; } - (void)dealloc { CCLOG(@"dealloc: %@", self); [super dealloc]; } @end GameButton.h #import "cocos2d.h"

@interface GameButton: CCSprite {

}

(128)

128 +(id)buttonWithText: (NSString *)buttonText; -(id)initWithText: (NSString *)buttonText isBig:(BOOL)big; @end GameButton.m #import "GameButton.h" @implementation GameButton +(id)buttonWithText: (NSString *)buttonText isBig:(BOOL)big {

return [[[GameButton alloc] initWithText:buttonText isBig:big] autorelease]; } +(id)buttonWithText: (NSString *)buttonText {

return [[[GameButton alloc] initWithText:buttonText isBig:NO] autorelease];

(129)

129

-(id)initWithText: (NSString *)buttonText isBig:(BOOL)big {

if((self == [super init])) {

NSString *btnFrame = (big) ? @"button_big.png" : @"button_small.png"; int fSize = 12; [self setDisplayFrame:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:btnFrame]];

(130)

130 labelShadow.color = ccBLACK; labelShadow.opacity = 150; [self addChild:labelShadow]; } return self; } @end Game.h #import "cocos2d.h" @class AppDelegate,Mole; @interface Game : CCScene <CCStandardTouchDelegate> { CCArray *moles, *carrots;

float timeBetweenMoles,timeElapsed, increaseMolesAtTime, increaseElapsed, lastMoleHitTime,totalTime;

CCLabelBMFont *scoreLabel; int carrotsLeft, score, molesAtOnce;

CGSize s;

AppDelegate *delegate;

CCMenuItemSprite *pauseButton;

(131)
(132)

132 #import "GameButton.h" #import "CCMenuPopup.h" @implementation Game - (id)init {

(133)

133 missSound = [NSString stringWithFormat:@"%@_miss.wav", [delegate getCurrentSkin]]; hitSound = [NSString stringWithFormat:@"%@_ouch.wav", [delegate getCurrentSkin]]; [[SimpleAudioEngine sharedEngine] preloadEffect:missSound]; [[SimpleAudioEngine sharedEngine] preloadEffect:hitSound]; [[SimpleAudioEngine sharedEngine] preloadEffect:@"splat.wav"]; [[SimpleAudioEngine sharedEngine] preloadBackgroundMusic:[NSString stringWithFormat:@"%@_bg.mp3", [delegate getCurrentSkin]]];

NSString *fileName = [NSString

(134)

134 fntFile:[NSString stringWithFormat:@"%i.fnt", fSize]]; scoreLabel.anchorPoint = ccp(0,1); scoreLabel.position = ccp(0,s.height); [self addChild:scoreLabel z:10];

carrots = [[CCArray alloc] init]; moles = [[CCArray alloc] init];

float hPad = 20; float vPad = 25;

for (int i = 1; i <= 4; i++) { for (int j = 1; j <= 6; j++) { Mole *mole = [Mole

(135)

135 CCSprite *bg = [CCSprite spriteWithFile:[NSString stringWithFormat:@"%@_bg.png", [delegate getCurrentSkin]]]; bg.anchorPoint = ccp(0,0); [self addChild:bg z:-1]; [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2D PixelFormat_RGBA4444];

for (int i = 0; i < carrotsLeft; i++) { CCSprite *c = [CCSprite spriteWithSpriteFrameName:@"life.png"]; c.anchorPoint = ccp(1,1); c.position = ccp(s.width - i * c.contentSize.width, s.height); [carrots addObject:c]; [self addChild:c z:10]; } pauseButton = [CCMenuItemSprite itemFromNormalSprite:[CCSprite spriteWithSpriteFrameName:@"pause_butto n.png"] selectedSprite:NULL target:self selector:@selector(pauseGame)];

CCMenu *menu = [CCMenu

(136)

136 pauseButton.position = ccp(s.width/2 - pauseButton.contentSize.width/2, (-s.height/2) + pauseButton.contentSize.height/2); [self addChild:menu z:100]; [self startGame]; } -(void)startGame { [[SimpleAudioEngine sharedEngine] playBackgroundMusic:[NSString stringWithFormat:@"%@_bg.mp3",

(137)

137

if ([self getMolesUp] < molesAtOnce - 1 && CCRANDOM_0_1() < .1 &&

(138)

138 increaseMolesAtTime += 10.0f; } if (canShowBlueMoles) { canShowYellowMoles = YES; } else { canShowBlueMoles = YES; } } } -(void)showMole {

Mole *mole = [[CCArray

(139)

139 [downMoles addObject:m]; } } return downMoles; } -(NSArray *)getUpMoles { NSMutableArray *upMoles = [[NSMutableArray alloc] init]; for (Mole *m in moles) { if ([m getIsUp]) { [upMoles addObject:m]; } } return upMoles; } -(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if (isPaused) { return; } NSMutableArray *molesTappedAtOnce = [[NSMutableArray alloc] init];

(140)

140

for (Mole *mole in moles) { CGPoint location = [touch locationInView:touch.view]; location = [[CCDirector sharedDirector] convertToGL:location]; if (CGRectContainsPoint([mole boundingBox], location)) { if(![mole getIsUp] || [molesTappedAtOnce containsObject:mole]) { continue; } if([[mole getType] isEqualToString:MOLE_TYPE_C]) { [molesTappedAtOnce addObject:mole]; } bool

greenMoleWasWhacked = ([[mole getType] isEqualToString:MOLE_TYPE_A]);

bool blueMoleWasWhacked = ([[mole getType]

(141)

141 if(greenMoleWasWhacked || blueMoleWasWhacked) { [mole wasTapped]; [self didScore]; [[SimpleAudioEngine sharedEngine] playEffect:hitSound

pitch:1 pan:1 gain:.25];

[[SimpleAudioEngine sharedEngine] playEffect:@"splat.wav"]; } } } } if ([molesTappedAtOnce count] > 1) { for (Mole *m in molesTappedAtOnce) { [m wasTapped]; [self didScore]; } [[SimpleAudioEngine sharedEngine] playEffect:hitSound pitch:1 pan:1 gain:.25];

[[SimpleAudioEngine

(142)
(143)

143

else {

for (Mole *m in [self getUpMoles]) { [m stopEarly]; } } } -(void)gameOver {

(144)

144

buttonWithText:@"main menu"] selectedSprite:NULL target:self selector:@selector(mainMenu)];

CCMenuPopup *menu = [CCMenuPopup menuWithItems:playAgainButton,mainButto n, nil];

[menu

alignItemsHorizontallyWithPadding:10]; PopUp *pop = [PopUp

popUpWithTitle:@"-game over-" description:@"" sprite:menu]; [self addChild:pop z:1000]; } -(int)getMolesUp { int upMoles = 0;

(145)

145 { return; } CCMenuItemSprite *resumeButton = [CCMenuItemSprite itemFromNormalSprite:[GameButton buttonWithText:@"resume"] selectedSprite:NULL target:self selector:@selector(resumeGame)]; CCMenuItemSprite *mainButton = [CCMenuItemSprite itemFromNormalSprite:[GameButton buttonWithText:@"main menu"] selectedSprite:NULL target:self selector:@selector(mainMenu)];

CCMenuPopup *menu = [CCMenuPopup menuWithItems:resumeButton,mainButton, nil];

[menu

alignItemsHorizontallyWithPadding:10]; PopUp *pop = [PopUp

popUpWithTitle:@"-pause-" description:@"" sprite:menu]; [self addChild:pop z:1000]; pauseButton.visible = NO;

for (Mole *m in [self getUpMoles]) {

(146)
(147)
(148)

148 [super dealloc]; } @end CCMenuPopup.h #import "cocos2d.h"

(149)

149

{

if (![super itemForTouch:touch]) { return NO;

}

NSArray *ancestors = [NSArray

arrayWithObjects:self.parent,self.paren t.parent,self.parent.parent.parent, nil];

for (CCNode *n in ancestors) { if ([n isKindOfClass:[PopUp class]]) { [(PopUp *)n closePopUp]; } }

return [super ccTouchBegan:touch withEvent:event]; } @end GKWizard.h #import <Foundation/Foundation.h> #import <GameKit/GameKit.h>

@interface GKWizard : NSObject { BOOL isLoggedinToGC;

(150)

150 -(void)reportScore: (int)score forLeaderboard:(NSString *)leaderboard; -(bool) isGameCenterAvailable; - (void) authenticateLocalPlayer; -(int)getHighScore; @end GKWizard.m #import "GKWizard.h" #import "Constants.h" #import "cocos2d.h" @implementation GKWizard - (id)init {

self = [super init]; if (self) {

(151)

151 -(void)reportScore: (int)score forLeaderboard:(NSString *)leaderboard { if (![self isGameCenterAvailable]) { return; }

GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:leaderboard] autorelease]; if (scoreReporter.value < score) { scoreReporter.value = score; } else { return; } [scoreReporter reportScoreWithCompletionHandler:^(NSEr ror *error) { if (error != nil) {

// handle the reporting error

(152)

152 - (void) authenticateLocalPlayer { /*if (![self isGameCenterAvailable]) { UIAlertView *alert = [[UIAlertView alloc]

initWithTitle:@"Feature Not Available" message:@"Game Center features require supported devices/operating systems." delegate:NULL cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; } [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSE rror *error) { if (error == nil) {

// Insert code here to handle a successful authentication.

isLoggedinToGC = YES; }

(153)

153

// Your application can process the error parameter to report the error to the player.

//NSLog(@"error logging in");

} }];*/ }

- (void) reportScore: (int64_t) score forCategory: (NSString*) category {

}

-(bool) isGameCenterAvailable {

// Check for presence of GKLocalPlayer API.

Class gcClass =

(NSClassFromString(@"GKLocalPlayer")); // The device must be running

running iOS 4.1 or later. bool isIPAD = [[UIDevice

currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;

(154)

154

NSString *currSysVer = [[UIDevice currentDevice] systemVersion];

BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);

(155)

155

Сергій Валентинович Максимчук

магістрант інформаційних технологій

Розробка гри під

платформу iOS для

iPHONE

ІН 21М

Комп’ютерний набір, верстка і макетування та дизайн в редакторі Microsoft®Office® Word 2003 C.В.

(156)

Cytaty

Powiązane dokumenty

F MARKOWICE – układ złożony – pojedyncze zabudo- wania zagrodowe w odstępach w czę- ści centralnej i przy drogach bocznych, folwark z ogrodem na południu przy

Перехід створення E-learning систем управління навчанням на принцип open source не тільки дає змогу знизити сукупні витрати навчальних закладів на

(Тернопільський національний педагогічний університет ім. Гнатюка) АПРОКСИМАЦІЯ ДАНИХ НАВЧАЛЬНОГО ФІЗИЧНОГО ЕКСПЕРИМЕНТУ ЯК АЛЬТЕРНАТИВА

Ось чому економічна термінологія може розглядатися (і розглядається) у сучасній лінгвістиці не тільки як маркована мова, але і як складова

Тому українські мовознавці особливу увагу звертають на семантику терміна й особливості вияву парадигматичних відношень (синонімних, омонімних,

В разглеждания период основа за образуване на нови фразеологизми стават най-вече рекламни слогани, оригинални изрази на съвременни

У статті окреслено склад та специфіку терміносистеми українського музейництва, виділено основні тематичні групи, визначено особливості