2012-07-29 63 views
0

我一直在用随机脚本遭遇的核心图形构建一个更简单的游戏,如果这样做有任何意义,并且它开始成为视图控制器中的一个巨大方法。客观c大随机方法,我是这样做的吗?

-(void)spawnStuff{ 
CGPoint position; 
CGPoint position1; 

int chance = random()%10; 
switch (chance) { 
    case 0: 
      [self spawnWall]; 
     Position.y = 580; 
     Position.x = 160; 
     wall.center = Position; 

     [self spawnWall]; 
     Position1.y = 480; 
     Position1.x = 80; 
     wall.center = Position1; 

} 
-(void)spawnWall{ 
UIImage* myImage = [UIImage imageNamed:@"Wall.png"]; 
Wall = [[Sprite alloc] initWithImage:myImage]; 

CGRect rect = CGRectMake(0, 0, 90, 50); 
more initilization stuff } 

,我可能会重复这一行代码20 - 这些墙的位置30不同,只有10左右在类的代码的第三个不同场景的,它开始变得律redonkulous我编程方面还很新,巨大的方法让我感到恐慌。这是处理这个问题的正确方法吗?

+2

不,你没有这样做。你的代码格式是全部关闭的......你应该使用'arc4random_uniform'而不是模数。 – 2012-07-29 19:11:53

回答

0

如果你经常这样做,我会建议保留一系列可能的操作,然后在必要时随机选择一个。像下面的东西应该告诉你如何做到这一点。

请注意,您可以随意从数组中添加/减去,这会更改可用块......这只是显示,在底部,随机选取并执行块100次。

您可以从代码中的相应位置添加/删除块以保持其位置。这至少应该让你开始...

// If we want to perform some action randomly, then we build an array 
// of possibly actions (blocks), and then randomly pick one and execute it. 
// Figure out what type of block you want... 

typedef void(^ActionBlock)(void); 
NSMutableArray *possibleActions = [NSMutableArray array]; 
[possibleActions addObject:^{ 
    NSLog(@"Doing Action Foo"); 
}]; 
[possibleActions addObject:^{ 
    NSLog(@"Doing Action Bar"); 
}]; 
[possibleActions addObject:^{ 
    NSLog(@"Doing Action Baz"); 
}]; 
[possibleActions addObject:^{ 
    NSLog(@"Doing Action FooBar"); 
}]; 
[possibleActions addObject:^{ 
    NSLog(@"Doing Action Blarg"); 
}]; 
[possibleActions addObject:^{ 
    NSLog(@"Doing Action Zip"); 
}]; 

// Now, when I want to pick an action to perform... 
for (int i = 0; i < 100; ++i) { 
    ActionBlock block = [possibleActions objectAtIndex:arc4random_uniform(possibleActions.count)]; 
    block(); 
} 

编辑 线

typedef void(^ActionBlock)(void); 

是一个typedef,并定义了一种特定的块的类型。当然,函数和块的语法有点难以阅读。也许我应该退后一步。我希望它不会冒犯你,并且如果它以任何方式光顾,请提前道歉。它类似于

typedef int IntType; 
typedef void const * OpaqueType; 

哪个更容易阅读。第一个定义了一个类型,IntType类型为integer,第二个定义了类型为“pointer-to-const-void”的类型OpaqueType。然后,你可以声明变量如...

IntType someInteger; 
OpaqueType someOpaqueValue; 

现在,在基本的C中,我们也可以声明函数指针。比方说我们有一些功能...

int functionOne(int arg1, double arg2) { 
    // do whatever... 
} 
int functionTwo(int arg1, double arg2) { 
    // do whatever... 
} 

您可以调用该函数很轻松地...

int result = functionOne(42, 3.14159); 

好了,你还可以创建一个指向函数的变量,你可以称之为任何其他功能。

int(*function)(int,double) = functionOne; 
int result = function(42, 3.14159); // Calls functionOne 
function = functionTwo; 
result = function(42, 3.14159); // calls functionTwo 

但是,该语法对于输入类型有点遗憾。所以,特别是对于函数和块,我们创建了typedefs。为一个函数创建一个typedef,它和创建一个函数指针变量是一样的,但是你只需要把这个类型放在变量名的地方。所以......

typedef int(*MyFunction)(int, double); 

声明表示指针返回一个int的函数,有两个参数,int和double类型的类型。

现在,块的语法就像函数指针一样,除了交易^为*。所以,输出...

typedef void(^ActionBlock)(void); 

意味着ActionBlock是一种表示返回void且不带参数的块的类型。

因此,您可以声明ActionBlock类型的变量,并将它们分配给具有void返回值和无参数的块。在这个例子中,这正是我所做的。

注意,在代码中,我们创建了一堆这样的块...

[possibleActions addObject:^{ 
    NSLog(@"Doing Action Foo"); 
}]; 

编译器允许你离开了的东西,很明显,这样的代码真的说...创建一个没有参数的块,并且返回类型为void,然后将它添加到集合中。

我们多次这样做,然后,当准备调用函数时,我们只是遍历集合。然而,编译器想知道如何调用函数/块,并且它从集合中获得的只是一个。所以,我们想把我们得到的对象转换成一个类型,告诉编译器它是一个返回void的块,并且不带任何参数。

当我们这样做时,我们可以调用函数/块。那么,让我们来看看这最后一块又(有一些评论),和一点点不太紧凑

for (int i = 0; i < 100; ++i) { 
    // We have a bunch of blocks stored in the array. 
    // We want to pick one at random, so we will get a random number 
    // between [0, size of our array). 
    uint32_t index = arc4random_uniform(possibleActions.count); 

    // Now, we have a random index into our array. Get the object in that position. 
    id randomObject = [possibleActions objectAtIndex:index]; 

    // We have an opaque id type, but we know it's a block. Cast it to a block type. 
    ActionBlock block = randomObject; 

    // Now, we have our block, in a type that the compiler will let us invoke. 
    // Call it like any other function. 
    block(); 
} 

编辑

OK,在这里你去。创建一个iVar,NSTimer * _timer。将它安排在didLoad中,并在didUnload和dealloc中使其无效。

- (void)dealloc { 
    [_timer invalidate]; 
} 

typedef void(^ActionBlock)(void); 

- (void)callRandomFunction:(NSTimer*)timer { 
    // Our userInfo is actually our array of blocks 
    NSArray *actions = timer.userInfo; 
    ActionBlock block = [actions objectAtIndex:arc4random_uniform(actions.count)]; 
    block(); 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    NSMutableArray *possibleActions = [NSMutableArray array]; 

    // Create the list of possible functions that can be called... 

    // Now setup a timer that performs callRandomFunction: every second 
    // Pass the array of blocks as the userInfo of the timer. 
    _timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(callRandomFunction:) userInfo:possibleActions repeats:YES]; 

    // Whatever else you need in here... 
} 

- (void)viewDidUnload 
{ 
    [_timer invalidate]; 

    // Any other unload stuff... 

    [super viewDidUnload]; 
} 
+0

非常感谢!但是我有一个关于你的第一行代码的问题,typedef void(^ actionBlock)(void)声明了什么? – anonamousUsername 2012-08-01 16:11:17

+0

谢谢!我已经在家自学了几个月的自编程序,但仍然很难理解这些概念。我还有最后一个问题,如果我想每分钟执行一次随机动作,我该怎么做?我把possibleActions数组放在viewDidLoad中,并且一个计时器为ActionBlock块= randomObject调用一个单独的方法;东西,我把possibleActions放在头文件中,所以两种方法都知道它,当我测试应用程序时,它只是崩溃了一分钟。 – anonamousUsername 2012-08-02 21:51:19

+0

非常感谢你阻止我,这真的帮了很多,它的效果很好:) – anonamousUsername 2012-08-02 23:02:41