2009-07-24 7 views
0

Мой вопрос включает в себя простую игру, в которой могут играть 2-4 человека. Это игра, которая воспроизводится на одном iphone/ipod touch, поэтому нет необходимости в сети. Когда игра начнется, пользователь выберет количество игроков, которые будут играть.Создание экземпляров нескольких экземпляров на лету

Для каждого игрока мне нужно создать и экземпляр класса Player. Мой вопрос заключается в том, как мне закодировать, чтобы было сделано только необходимое количество классов, и все они названы по-разному. Я подумал о следующем, но я знаю, что это не сработает.

Предположим, у меня есть массив с именем «имена игроков», в котором хранятся имена игроков в игре.

for (int i = 0; i < [playerNames count]; i++) { 

    Player *playeri = [[Player alloc] init]; 

    //other code 

} 

Я не могу просто поставить «я» там, как счетчик для цикла и получить четыре экземпляра из имени player1, player2 и т.д. Как мне это сделать?

Заранее за вашу помощь.

ответ

2

Вы не можете создавать переменные экземпляры на лету - вам нужна коллекция для хранения полученных игроков. C-массив или NSMutableArray будут работать хорошо. Вы можете добавить эту коллекцию к своему контроллеру или просмотреть, чтобы игроки были доступны через игру.

Кроме того, вы можете использовать autorelease, чтобы автоматически освобождать игроков или, альтернативно, освобождать предметы в коллекции в вашем методе dealloc во избежание утечек памяти.

Вот код, используя NSMutableArray, что я предположил, что вы бы добавить в свой класс интерфейс (и где-нибудь инициализирован, как правило, в viewDidLoad)

-(void) CreatePlayers:(int)playerCount 
{ 
    for(int i = 0; i < [playerNames count]; i++) 
    { 
     [playersArray insertObject:[[[Player alloc] init] autorelease] 
         atIndex:i]; 
    } 
} 
0

Вы не можете точно назвать переменные программно, как это.

Однако вы можете создавать эти объекты и добавлять их в NSMutableArray, а затем вызывать их позже.

Если вы действительно хотите связать имя «PlayerN» с каждым объектом, используйте NSMutableDictionary. Храните объект игрока в качестве значения для ключа @ «PlayerN» (NSString).

Создание ключа можно сделать так:

NSString *key = [NSString stringWithFormat:@"Player%d", i]; 
0

Самым основным решением для этого будет хранить игроков в любом массиве или словаре (шпонкой на имя игрока). Принимая подход массива:

// assume we have an NSArray property, players 
NSMutableArray *tempPlayers = [NSMutableArray arrayWithCapacity:[playerNames count]]; 
for (NSString *name in playerNames) { 
    Player *player = [[Player alloc] init]; 
    [tempPlayers addObject:player]; 
    [player release]; 
} 
self.players = tempPlayers; 

Теперь Вы можете получить доступ к каждому игроку от players собственности по телефону objectAtIndex:.

Слово о дизайне - во-первых, считаете ли вы, что добавьте name свой класс Player? Это кажется естественным местом для хранения этой информации после ее захвата. Например:

for (NSString *name in playerNames) { 
    // you might also have a designated initializer 
    // e.g. [[Player alloc] initWithName:name] 

    Player *player = [[Player alloc] init]; 
    player.name = name; 
    [tempPlayers addObject:player]; 
    [player release]; 
} 

В целом это самое простое, что работает, и все, что я делаю сейчас. Однако в будущем ...

В какой-то момент вы можете представить себе какой-то класс Game, который представляет каждую новую игру, которую создает ваш пользователь. Это было бы естественное место для хранения вашего массива игроков и позволит вам создать более сплоченный интерфейс, например:

Game *newGame = [[Game alloc] init]; 
for(NSString *name) in playerNames) { 
    [newGame addPlayerNamed:name]; 
} 

Вашего Game класс должен инкапсулировать массив игроков и метод addPlayerNamed бы инкапсулировать процесс создания нового Player и сохранения его в этом массиве, что делает ваш код контроллера намного проще (и проявляет намерение) в этом процессе.

Другим преимуществом этого является то, что он дает вам возможность получить доступ к этим данным во всем приложении, а не привязывать его к этому конкретному контроллеру. Вы можете реализовать какой-то однопользовательский доступ к «currentGame». Не настоящий одноточечно конечно, но что-то, как это будет хорошо работать:

Game *newGame = [[Game alloc init]; 
.. // configure game as above 
[Game setCurrentGame:newGame]; 

Так что теперь, когда вам нужен доступ к текущей игре (или игрока) информация:

// in some other controller 
Game *currentGame = [Game currentGame]; 
for(Player *player in currentGame.players) { 
    // etc... 
} 
Смежные вопросы