переменные c и target-c - PullRequest
       19

переменные c и target-c

2 голосов
/ 02 декабря 2009

Дайте мне посмотреть, смогу ли я сформулировать, что я пытаюсь сделать ... Я перейду к основной проблеме.

У меня есть программа target-c и функция обратного вызова c. Суть в том, что я использую cocos2d и физику бурундука с iphone SDK. То, что я пытаюсь сделать, это обновить «счет» при столкновении пули и монстра. Все отлично работает, кроме обновления счета.

игровая логика в obj-c, но фактическая логика столкновений выполняется в функции c, которая вызывается при столкновении вещей. Например, именно там я представляю пламя / взрыв столкновения. Также там я хочу обновить счет.

Вот проблема: Но Score - это переменная экземпляра объекта «GAME», и у меня нет видимости этой переменной экземпляра. Я полагаю, что я могу передать в функцию c другой параметр по ссылке с именем & addcore или что-то в этом роде, но мне было интересно, есть ли более очевидный способ сделать это, поскольку может существовать куча других переменных, кроме «Score», которые должны быть обновлены после collission.

В сети мне нужны переменные в объекте, которые будут видны функцией c, и наоборот: эти переменные, заданные в функции, будут видны в объекте.

спасибо заранее.

Ответы [ 4 ]

1 голос
/ 03 декабря 2009

Чтобы улучшить этот последний ответ, вы можете сделать следующее:

cpSpaceAddCollisionPairFunc( space, 1, 2, (cpCollFunc)functionName, game);

void functionName( cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, GameClass *game) {
    [game doSomethingToScoreSomething];
}

Нет необходимости приводить указатель внутри функции, вместо этого вы можете привести указатель функции. Это то, что я сделал внутри с источником Бурундука, и он намного чище.

1 голос
/ 03 декабря 2009

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

Если вам нужно передать несколько переменных, я предполагаю, что они вместе составляют какое-то описание "игрового состояния". Возможно, их можно сгруппировать в отдельный объект или структуру и передать в функцию C через один параметр?

В качестве примера приведен следующий класс:

typedef struct GameState {
  int score;
  int numberOfBulletsLeft;
} GameState;

@interface GAME : NSObject {
  GameState state;
}

...

@end

будет хорошо работать с функцией C, такой как следующее

void myCFunctionThatDoesCollisiondetectionEtc(GameState * state) {
  NSLog(@"You have %d bullets left", state->numberOfBulletsLeft);
}

Если ваш существующий объект GAME имеет подходящие свойства или сообщения, вы можете даже сделать что-то вроде следующего, где вы просто передаете весь объект Objective-C:

void myCFunctionThatDoesCollisionDetectionEtc(GAME * myGame) {
  if (...)
    [myGame increaseScore:50];
  else
    [myGame decreaseScore:50];
}

Третий вариант - изменить возвращаемое значение вашей функции C, чтобы указать, было ли обнаружено столкновение, а затем оставить его на усмотрение кода Objective-C в классе GAME, чтобы обновить счет и любые другие действия, которые могут должно произойти.

0 голосов
/ 03 декабря 2009

Если игровой объект является одноэлементным, вы можете получить к нему доступ из любой области (включая ваш обратный вызов C). Вы бы сделали синглтон, если бы вы когда-либо хотели, чтобы существовал только один экземпляр какого-либо объекта. Одиночка всегда может быть доступна из любого места, посылая сообщение классу для извлечения экземпляра синглтона:

[Game sharedGameInstance];

В качестве альтернативы, бурундук позволяет вам передать void * data обратному вызову. Это делается для того, чтобы программист мог отправить необходимую ему информацию в обратный вызов.

Вы можете отправить указатель на ваш экземпляр игрового объекта в этом void * на обратный вызов, например, так:

cpSpaceAddCollisionPairFunc( space, 1, 2, &functionName, (void *)game );

void functionName( cpShape *a, cpShape *b, cpContact *contacts, int numContacts, cpFloat normal_coef, void *data ) {
    GameClass * game = (GameClass *)data;
    // do whatever you need here. You can call messages on game as per usual.
}
0 голосов
/ 03 декабря 2009

Нет, вам не нужны переменные в вашем объекте, чтобы быть видимыми функцией. Это нарушает инкапсуляцию, и это плохая идея. Когда вы хотите, чтобы объект что-то сделал (например, изменил какое-то внутреннее значение, такое как оценка), вы должны предоставить метод для достижения этого эффекта.

Если вы позволяете коду вне вашего класса изменять переменные вашего экземпляра, то вы отбрасываете ключевое преимущество объектно-ориентированного программирования.

...