2010-10-20 157 views
1

新的Obj C和一般的編程 - 從這個網站學到很多東西,非常感謝大家的貢獻。從另一個類訪問類的實例變量(NSMutable Array)

我的情況如下(編程的iPhone遊戲,這解釋了有趣的名字)

在我的主要gameLoop(這是在我的視圖控制器)如果一定條件滿足我製造一個敵人 - 櫻桃炸彈

if (bounceCounterGlobal % 2 == 0 && bounceCounterGlobal > 1 && cherryBombSwitch == 0){ 
    [self addCherryBomb]; 
} 

的addCherryBomb方法如下:

-(void) addCherryBomb{ 
    CherryBomb *myCherryBomb = [[CherryBomb alloc] init]; 
    [cherryBombArray insertObject:myCherryBomb atIndex:0]; 
    [myCherryBomb release]; 
    [[cherryBombArray objectAtIndex:0] initializeCherryBomb]; 
    [self.view addSubview:[[cherryBombArray objectAtIndex:0] cherryBombView]]; 
    cherryBombSwitch = 1; 
} 

的櫻桃炸彈頭文件短:

#import <Foundation/Foundation.h> 
#import "SimpleGameViewController.h" 

    @interface CherryBomb : NSObject { 

     UIImageView *cherryBombView; 
     NSTimer *cherryBombDetonateTimer; 
     NSTimer *cherryBombMoveTimer; 
    } 

    @property (nonatomic, retain) UIView *cherryBombView; 

    -(void) initializeCherryBomb; 
    -(void) detonateCherryBomb; 
    -(void) moveCherryBomb; 

    @end 

我想要做的是當櫻桃炸彈引爆(這是在櫻桃炸彈對象內部確定的)時,我希望該對象從櫻桃炸彈陣列中移除,而櫻桃炸彈陣列是視圖控制器的一個ivar。我試圖調用一個視圖控制器類方法來做到這一點 - 但我無法訪問視圖控制器的ivars(因爲它是一個類方法)。我不知道如何通知視圖控制器類來告訴它去除分解對象。

@implementation CherryBomb 
... 
-(void) detonateCherryBomb{ 
    NSLog(@"KABOOM!"); 
    cherryBombDetonateTimer = nil; 
    [cherryBombMoveTimer invalidate]; 
    [cherryBombView removeFromSuperview]; 
    //I would like to remove this object from the view controller's cherryBombArray 
} 
@end 

您的幫助是非常感謝。先謝謝你!

回答

2

我建議你創建一些能處理所有遊戲邏輯的「環境」對象。

櫻桃炸彈不應該對付它的爆炸。櫻桃炸彈可以存儲許多信息(爆炸的大小,爆炸的類型等),但櫻桃炸彈對其他「物體」(角色,炸彈等)的影響不應該由櫻桃炸彈本身來計算。

我不是很習慣遊戲編程,但是這個架構/設計方面很常見:每個對象/類都有其職責。

櫻桃炸彈代表炸彈,不再是(也不是「圖形」方面)。

環境代表當前時刻的「世界」,並模擬世界各元素之間的行爲/相互作用。

有很多說要設計一個遊戲的最佳途徑......

反正給你的問題的答案,你仍然可以使用「事件」。炸彈可以向你的控制器發送一條消息告訴他:「我爆炸了,把我移開」。

在炸彈:

[[NSNotificationCenter defaultCenter] postNotificationName:@"kaBOOM" 
                object:self]; 

在控制器:

[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(methodToCallWhenKaBOOM) 
              name:@"kaBOOM" 
              object:nil]; 

而且

- (void)methodToCallWhenKaBOOM:(NSNotification *)note 
{ 
    // do stuffs 
} 

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

1

有許多方法可以做到日是的,你可能想要從控制器和模型的角度思考這裏的確切分工。如果你有太多的來回呼叫,事情可能會變得很苗條。

但是,沒有深入瞭解所有這些,爲了讓一個對象訪問另一個對象,你需要做的基本事情是給第一個對象引用第二個對象。

在這種情況下,您實際上在視圖控制器中創建了CherryBomb,因此在此處傳遞參考很容易。給你的CherryBomb類另一個伊娃這樣的:

SimpleGameViewController* cherryBombViewController; 

修改CherryBomb,以使這些init方法或您的initializeCherryBomb一個(這也許應該只是一個單一的方法,順便說一句)採取這樣的指針,並將其分配給伊娃:

- (void) initializeCherryBomb:(SimpleGameViewController*)vc 
{ 
    // ... whatever other stuff you do in here, plus something like: 
    cherryBombViewController = vc; 
} 

當你調用該方法,通過它selfvc參數。再後來,當你的炸彈引爆它可以調用一些你在控制器上添加方法來去掉自己:

[cherryBombViewController handleDetonationOfCherryBomb:self]; 

請注意,您絕對不應該直接存取控制器的陣列 - 這是一個實現細節你的炸彈應該不知道。在簡單的情況下,您可以避免在控制結構中存在一些瑕疵,但是永遠不會有螺絲與您的封裝。

0

閱讀MVC設計模式。如果你發現你需要在視圖之間共享的ivars,他們可能應該進入更高層的Model對象(MVC的M),而不是讓某些視圖到達其他視圖的ivars。然後可以將指向此Model對象的指針傳遞給需要訪問它的所有視圖對象。

0

我覺得這是一個很好的應用key value observing。你需要代表其狀態的櫻桃炸彈屬性,例如

@property (assign) BOOL isExploded; 

的任何對象,它是感興趣的櫻桃炸彈是否爆裂寄存器本身志願的isExploded財產。例如,視圖控制器可能會做:

[cherryBomb addObserver: self 
      forKeyPath: @"isExploded" 
       options: .... 
       context: ....]; 

-observeValueForKeyPath:ofObject:change:context:爲視圖控制器從數組中刪除該櫻桃炸彈。

你引爆方法執行以下操作以及其他一切它目前正在做:

[self setExploded: YES];