c 和 Objective-c 变量

发布于 2024-08-14 03:23:16 字数 454 浏览 2 评论 0原文

让我看看我是否能清楚地表达出我正在尝试做的事情......我会将其提炼为核心问题。

我有一个 Objective-C 程序和 ac 回调函数。背景是我正在使用 cocos2d 和花栗鼠物理与 iphone sdk。我想做的是在子弹和怪物碰撞时更新“分数”。除了更新分数之外,一切正常。

游戏逻辑在 obj-c 中,但实际的碰撞逻辑是在 ac 函数中完成的,当物体碰撞时会调用该函数。例如,我就是在那里渲染碰撞的火焰/爆炸。我也想在那里更新分数。

问题是这样的: 但分数是“GAME”对象的实例变量,我看不到该实例变量。我想我可以通过引用将另一个参数传递给 c 函数,称为 &addscore 或其他东西,但想知道是否有更明显的方法来做到这一点,因为除了“分数”之外可能还有一堆其他变量必须更新碰撞时。

网络是我需要对象中的变量才能被c函数看到,反之亦然:在函数中设置的那些变量才能在对象中看到。

提前致谢。

Let me see if I can articulate what I'm trying to do... I'll distill it to the core issue.

I have an objective-c program and a c callback function. The context is I am using cocos2d and chipmunk physics with the iphone sdk. What I am trying to do is update "score" upon a collision between a bullet and a monster. Everything works fine except for updating the score.

the game logic is in obj-c but the actual collision logic is done in a c function that gets called when things collide. For example, it is there that I render the flames/explosion of the collision. It is also there that I want to update the score.

Here's the problem:
But score is an instance variable of the "GAME" object and I do not have visibility into that instance variable. I suppose I can pass into the c function another parameter by reference called &addscore or something, but was wondering if there is a more obvious way to do it since there might be a bunch of other variables beyond 'score' that must be updated upon the collission.

the net is I need variables in the object to be seen by the c function, and vice versa: those variables set in the function to be seen in the object.

thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

橘寄 2024-08-21 03:23:16

您关于通过引用传递来访问 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];
}

第三种选择是更改 C 函数的返回值,以指示是否检测到碰撞,然后将其留给 GAME 类中的 Objective-C 代码来更新分数和任何其他可能发生的操作。需要发生。

Your knowledge and thoughts about gaining access to Obj-C instance variables within C code by passing them by reference seems correct.

If you need to pass a number of variables I assume they collectively make up some kind of "game state" description. Perhaps these could be grouped into a seperate object or structure and passed into the C function via a single parameter?

As an example, the following class:

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

@interface GAME : NSObject {
  GameState state;
}

...

@end

Would work well with a C function such as the following

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

If your existing GAME object has suitable properties or messages, you may even be able to do something like the following, where you simply pass your entire Objective-C object:

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

A third alternative would be to change the return value of your C function to indicate if a collision has been detected and then leave it up to the Objective-C code within the GAME class to update the score and any other actions which may need to occur.

七堇年 2024-08-21 03:23:16

为了进一步改进最后一个答案,您可以执行以下操作:

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 源代码内部所做的事情,它更加干净。

To improve on that last answer a bit more, you can do the following:

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

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

No need to cast the pointer inside of the function, you can cast the function pointer instead. That's what I've done internally with the Chipmunk source and it's a lot cleaner.

骄兵必败 2024-08-21 03:23:16

不,您不需要对象中的变量对函数可见。这会破坏封装,这是一个坏主意。当您希望对象执行某些操作(例如更改某些内部值(例如分数))时,您应该提供一种方法来实现该效果。

如果您允许类外部的代码更改实例变量,那么您就放弃了面向对象编程的一个关键优势。

No, you do not need variables in your object to be visible by the function. That breaks encapsulation, and it's a bad idea. When you want an object to do something (like changing some internal value such as the score) you should provide a method to accomplish that effect.

If you allow code outside your class to alter your instance variables, then you're throwing away a key advantage of object-oriented programming.

孤云独去闲 2024-08-21 03:23:16

如果游戏对象是单例,您可以从任何范围(包括 C 回调)访问它。如果您只希望某个对象存在一个实例,则可以创建单例。通过向类发送消息来检索单例实例,始终可以从任何地方访问单例:

[Game sharedGameInstance];

或者,chipmunk 允许您将 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.
}

If the game object is a singleton you can access it from any scope (which includes your C callback). You would make a singleton if you only ever want one instance of some object to exist. A singleton can always be reached from anywhere by sending a message to the class to retrieve the singleton instance:

[Game sharedGameInstance];

Alternatively, chipmunk allows for you to pass a void * data to the callback. This is to accommodate the programmer to send information he needs to the callback.

You can send a pointer to your game object instance in that void * to the callback, like so:

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.
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文