2

私がやろうとしていることを明確に説明できるかどうか見てみましょう...私はそれを核心の問題に絞り込みます。

私は客観的な c プログラムと ac コールバック関数を持っています。コンテキストは、iPhone SDK で cocos2d とシマリスの物理学を使用していることです。私がやろうとしているのは、弾丸とモンスターの衝突時に「スコア」を更新することです。スコアの更新を除いて、すべて正常に動作します。

ゲーム ロジックは obj-c にありますが、実際の衝突ロジックは、衝突時に呼び出される ac 関数で行われます。たとえば、衝突の炎/爆発をレンダリングするのはそこです。スコアを更新したいのもそこです。

ここに問題があります。しかし、score は「GAME」オブジェクトのインスタンス変数であり、そのインスタンス変数への可視性がありません。&addscore などと呼ばれる参照によって c 関数に別のパラメーターを渡すことができると思いますが、「スコア」以外にも更新する必要がある他の変数がたくさんある可能性があるため、より明白な方法があるかどうか疑問に思っていました。衝突。

つまり、オブジェクト内の変数が c 関数から見えるようにする必要があり、逆もまた同様です。関数内に設定された変数がオブジェクト内で見えるようにする必要があります。

前もって感謝します。

4

4 に答える 4

1

参照渡しによって C コード内の Obj-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];
}

3 つ目の方法は、C 関数の戻り値を変更して衝突が検出されたかどうかを示し、GAME クラス内の Objective-C コードに任せて、スコアやその他の必要なアクションを更新することです。 .

于 2009-12-02T22:06:33.460 に答える
1

最後の回答をもう少し改善するには、次のことができます。

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

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

関数内でポインターをキャストする必要はありません。代わりに関数ポインターをキャストできます。これは私が Chipmunk のソースを使って内部的に行ったことであり、非常にクリーンです。

于 2009-12-03T14:27:56.293 に答える
0

いいえ、関数で表示するためにオブジェクト内の変数は必要ありません。それはカプセル化を破ります、そしてそれは悪い考えです。オブジェクトに何かを実行させたい場合(スコアなどの内部値を変更するなど)、その効果を実現するためのメソッドを提供する必要があります。

クラス外のコードでインスタンス変数を変更できるようにすると、オブジェクト指向プログラミングの重要な利点が失われます。

于 2009-12-03T06:03:56.287 に答える
0

ゲーム オブジェクトがシングルトンの場合、任意のスコープ (C コールバックを含む) からアクセスできます。オブジェクトのインスタンスを 1 つだけ存在させたい場合は、シングルトンを作成します。シングルトン インスタンスを取得するためにクラスにメッセージを送信することで、いつでもどこからでもシングルトンにアクセスできます。

[Game sharedGameInstance];

または、シマリスを使用すると、 avoid * 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.
}
于 2009-12-03T13:19:12.977 に答える