【问题标题】:Multiple instances of a method?一个方法的多个实例?
【发布时间】:2011-05-22 20:32:07
【问题描述】:

以下代码呈现具有可互换坐标的僵尸。唯一的问题是我必须自己复制代码并为每个僵尸创建新的坐标变量。有什么方法可以创建变量的副本,因此我只需为多个僵尸提供一种方法,而不是为三个僵尸提供三种方法和三个单独的变量?

int zombieyCord;
int zombiexCord;

    -(void)renderZombie
{
    NSBezierPath * path = [NSBezierPath bezierPath];
    [path setLineWidth:4];
    NSPoint center = {zombieyCord,zombiexCord};
    [path moveToPoint: center];
    [path appendBezierPathWithArcWithCenter:center 
                                     radius:5
                                 startAngle:0 
                                   endAngle:360]; 
    [[NSColor greenColor] set];
    [path fill];
    [[NSColor greenColor] set];
    [path stroke];

}

编辑

生成效果很好,效果很好,但我希望僵尸能够正常移动。之前的代码是在玩家移动时调用该方法。这不再有效,因为我必须在方法中调用一个整数。

+(void)entityZombie:(int)zombiexCord andY:(int)zombieyCord
{
    /* Handle Zombie Movement*/
    if (xcord != zombiexCord || ycord != zombieyCord)
    {
        if (xcord > zombiexCord){zombiexCord=zombiexCord+1;}
        if (xcord < zombiexCord){zombiexCord=zombiexCord-1;}
        if (ycord < zombieyCord){zombieyCord=zombieyCord-1;}
        if (ycord > zombieyCord){zombieyCord=zombieyCord+1;}

        /* Handle Zombie Render*/

        NSBezierPath * path = [NSBezierPath bezierPath];
        [path setLineWidth:4];
        NSPoint center = {zombieyCord,zombiexCord};
        [path moveToPoint: center];
        [path appendBezierPathWithArcWithCenter:center 
                                         radius:5
                                     startAngle:0 
                                       endAngle:360]; 
        [[NSColor greenColor] set];
        [path fill];
        [[NSColor greenColor] set];
        [path stroke];

    }
}

玩家移动处理只涉及渲染玩家然后 [Entity entityZombie]; 但如上所述,不再有效。

【问题讨论】:

  • 我是否正确地假设{xcord, ycord} 是玩家的坐标,并且您希望僵尸在每次迭代时向玩家移动一步,然后在新位置渲染?
  • @Regexident 那么我该怎么做呢?
  • 在这种情况下,您应该将僵尸的移动和渲染拆分为单独的方法。您可能应该重构您的代码并创建一个僵尸类,其中 NSPoint 作为其坐标的实例变量。 Zombie 类会得到一个 - (void)moveTowardsPlayerAt:(NSPoint)playerCoords;和 - (无效)平局;方法。这将使我们远离您最初的问题,并且更适合关于“简单的人类与僵尸游戏控制器”的新问题。我现在要去睡觉了,所以我只是在这里倾倒了一些示例代码:pastie.org/private/utesja0hf9poecidegj4ea :)
  • @evdude100:打开一个询问基本“简单的人类与僵尸游戏控制器设计”的问题可能是个好主意,因此(希望)有用的代码不会隐藏在粘贴链接中,但获得良好的曝光。一旦问题出现,请在此处给我留言/链接。

标签: objective-c methods multiple-instances


【解决方案1】:
-(void)renderZombieWithX:(int)xCoord andY:(int)yCoord {
    NSBezierPath * path = [NSBezierPath bezierPath];
    [path setLineWidth:4];
    NSPoint center = {xCoord,yCoord};
    [path moveToPoint: center];
    [path appendBezierPathWithArcWithCenter:center 
                                     radius:5
                                 startAngle:0 
                                   endAngle:360]; 
    [[NSColor greenColor] set];
    [path fill];
    [[NSColor greenColor] set];
    [path stroke];
}

这样称呼它:

[self renderZombieWithX:10 andY:20];
[self renderZombieWithX:13 andY:37];
//...

还有一个dedicated function 用于创建 NSPoints:

NSPoint center = NSMakePoint(xCoord, yCoord);

您可能希望使用它来支持:

NSPoint center = {xCoord,yCoord};

(请参阅我的答案之一,了解原因)


如果性能至关重要,则如下所示的缓存方法可能会带来性能提升:

static NSImage *sharedZombieStamp;
- (NSImage *)sharedZombie    {
    @synchronized(sharedZombieStamp) {
        if (!sharedZombieStamp) {
            CGFloat lineWidth = 4.0;
            CGFloat radius = 5.0;
            sharedZombieStamp = [[NSImage alloc] initWithSize:NSMakeSize((lineWidth + radius) * 2, (lineWidth + radius) * 2];

            [zombieImage lockFocus];
            NSBezierPath *path = [NSBezierPath bezierPath];
            [path setLineWidth:4];
            NSPoint center = NSMakePoint(lineWidth + radius, lineWidth + radius);
            [path moveToPoint: center];
            [path appendBezierPathWithArcWithCenter:center 
                                             radius:radius
                                         startAngle:0 
                                           endAngle:360]; 
            [[NSColor greenColor] set];
            [path fill];
            [[NSColor greenColor] set];
            [path stroke];
            [zombieImage unlockFocus];
        }
    }
    return sharedZombieStamp;
}

-(void)renderZombieWithX:(int)xCoord andY:(int)yCoord {
    NSImage *zombie = [self sharedZombie];
    NSSize zombieSize = [zombie size];
    [zombie drawAtPoint:NSMakePoint(xCoord - zombieSize.width / 2, yCoord - zombieSize.height / 2)
               fromRect:NSMakeRect(0.0, 0.0, zombieSize.width, zombieSize.height)
              operation:NSCompositeSourceOver
               fraction:1.0];
}

不过,这段代码让我想不通。没有通过任何测试。谨慎使用;)

【讨论】:

  • 不,你这样称呼它:[self renderZombieWithX:10 andY:20];,正如我在回答中所说的那样;)
  • 如果您要一次渲染数百个甚至数千个僵尸,您可能想尝试使用一个共享的 NSBezierpath 实例,并通过 NSAffineTransform 简单地移动每个坐标以获得性能,因为没有一遍又一遍地初始化相同的形状。或者将它渲染到一个 NSImage 中,您只需在每个给定坐标处标记它。绘制图像通常比绘制复杂路径更快。您的并不复杂,但如果性能至关重要,仍然值得牢记。
  • 如果我知道你在说什么,我会的。 :-)
  • 请注意,使用 NSMakePoint() 代替 struct 初始化程序没有实际好处。
  • 我添加了一个缓存方法的粗略原型。特别是对于复杂的贝塞尔形状(几十个或更多点和交叉线),绘图变得非常详尽。因此,如果您不以任何方式更改路径形状,那么最好创建一个实例,将其绘制到内存中的 NSImage 中,然后一遍又一遍地标记它。重复绘制图像通常比重复绘制原始路径要快得多。
猜你喜欢
  • 2020-10-15
  • 1970-01-01
  • 1970-01-01
  • 2016-05-22
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多