使用 Touch iOS Sprite Kit 画线

Posted

技术标签:

【中文标题】使用 Touch iOS Sprite Kit 画线【英文标题】:Drawing line with Touch iOS Sprite Kit 【发布时间】:2014-09-25 16:21:08 【问题描述】:

我正在使用以下代码在我的精灵套件场景中绘制线条,但没有显示任何内容。但是节点数增加了。任何人都可以看到可能是什么问题。我一直在与这段代码作斗争

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    pathToDraw = CGPathCreateMutable();
    CGPathMoveToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);

    lineNode = [SKShapeNode node];
    lineNode.path = pathToDraw;
    lineNode.strokeColor = [SKColor redColor];
    //lineNode.lineWidth = 2;
    [self addChild:lineNode];


- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
    lineNode.path = pathToDraw;



- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event


  //  lineNode.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:pathToDraw];
  //  lineNode.physicsBody.dynamic = NO;
  //  lineNode.physicsBody.categoryBitMask = lines;
  //  lineNode.physicsBody.contactTestBitMask = 0;
  //  lineNode.physicsBody.collisionBitMask = blueParticles | redParticles| yellowParticles;

    CGPathRelease(pathToDraw);

编辑------ 删除后台节点后代码可以工作。如何设置后台节点以便可以在上面运行?谢谢

SKSpriteNode *background;

        if(screenHeight == 480)
            background = [SKSpriteNode spriteNodeWithImageNamed:@"iPhone4BG.png"];
        
        if(screenHeight == 568)
            background = [SKSpriteNode spriteNodeWithImageNamed:@"iPhone5BG.png"];
        
        if(screenHeight == 667)
            background = [SKSpriteNode spriteNodeWithImageNamed:@"iPhone6BG.png"];
        
        if(screenHeight == 736)
            background = [SKSpriteNode spriteNodeWithImageNamed:@"iPhone6PlusBG.png"];
        

        background.position = CGPointMake(screenWidth/2, screenHeight/2);
        background.size = CGSizeMake(screenWidth, screenHeight);

       // [self addChild:background];

【问题讨论】:

这应该会有所帮助:***.com/questions/24553245/… 没有解释为什么这条线没有显示? @原型 添加了一个答案。但我认为当前的两个答案都会遇到链接中定义的问题。所以如果你要画长线,你应该去那里跳过这种方法。海事组织 您是使用模拟器还是实际设备进行测试? @原型 我在 iPad mini 上测试过。 【参考方案1】:

注意 核心问题是模拟器未呈现未关闭的路径。在设备上,问题不存在。还涉及到原始海报未提及且未在代码中表示的背景元素。这个答案将解决模拟器上的问题。

要解决您的问题,请按如下方式修改您的代码:

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
    // add this line to fix your issue
    CGPathMoveToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
    lineNode.path = pathToDraw;


核心问题是当它去渲染路径时,它没有完整的路径。您当前的方法是不断修改每个 touchMove 的路径。

关闭子路径的方式是:

CGPathCloseSubpath(pathToDraw);

但是,每次您在路径中添加一个段时,我都选择只使用CGPathMoveToPoint

来自CGPathMoveToPoint 的 CGPath 参考:

这个函数结束已经在进行的子路径(如果有的话)并开始一个新的子路径,在一个可选的变换之后将起点和当前点初始化到指定的位置(x,y)。

我在渲染之前关闭当前子路径,并设置下一段的起始位置。

但是,如果您要绘制一条长线或多条线,您将遇到 cmets 中链接中定义的主要性能问题。画一条很长的线,你就会明白我的意思。通过最少的线条绘制,您可能会摆脱当前的方法。

遗憾的是,使用SKShapeNode 绘制的这种性质并没有得到应有的优化。

【讨论】:

这对我不起作用..可能是什么问题?我仍然有同样的问题节点数增加,但看不到可见线 对我来说很好用,我只是将您的代码复制到一个空项目中,添加了 iVar 和一行,它就可以正常工作了吗?也许您的 ViewController 设置不正确?如果你想要一个我可以看的,你可以 github 项目,但这绝对有效,并且问题存在于上面的代码之外。 我发现问题在于我正在添加的后台节点。我将添加上面的代码,向您展示我是如何做到的。我不允许绘制节点吗?解决方法是什么? @原型 如果您有分层问题,请相应地设置您的 zPosition。 嗨@prototypical 我可以使用另一个问题的帮助.. 我在这一行之后添加了一个物理体(如您在注释掉的代码中所见)。我的原始代码会发生什么,该行没有显示,但身体形状是正确的。当对象与这条线交互时,我知道这一点。但是通过您的代码修改,您会看到该行,但身体形状不正确,它采用您触摸的第一个位置的形状,而忽略了该行的其余部分。我知道它在我们关闭子路径的地方,但我该如何解决这个问题。【参考方案2】:

我认为这就是您想要实现的。它会在您移动手指时绘制一条临时线(白色),并在您抬起手指时绘制一条最终线(红色)。您将需要声明一个名为startingPoint 的CGPoint 实例变量并删除名为pathToDraw 的CGMutablePathRef ivar。也可以修改代码以绘制多个连接的线段。

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    startingPoint = positionInScene;


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    // Remove temporary line if it exist
    [lineNode removeFromParent];

    CGMutablePathRef pathToDraw = CGPathCreateMutable();
    CGPathMoveToPoint(pathToDraw, NULL, startingPoint.x, startingPoint.y);
    CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);

    lineNode = [SKShapeNode node];
    lineNode.path = pathToDraw;
    //CGPathRelease(pathToDraw);
    lineNode.strokeColor = [SKColor whiteColor];
    lineNode.lineWidth = 1;
    [self addChild:lineNode];


- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event

    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];

    // Remove temporary line
    [lineNode removeFromParent];

    CGMutablePathRef pathToDraw = CGPathCreateMutable();
    CGPathMoveToPoint(pathToDraw, NULL, startingPoint.x, startingPoint.y);
    CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);

    SKShapeNode *finalLineNode = [SKShapeNode node];
    finalLineNode.path = pathToDraw;
    //CGPathRelease(pathToDraw);
    finalLineNode.strokeColor = [SKColor redColor];
    finalLineNode.lineWidth = 1;
    [self addChild:finalLineNode];

【讨论】:

这对我不起作用..可能是什么问题?我仍然有同样的问题节点数增加,但看不到可见线 运行时会发生什么? 它运行良好,只是当你用手指滑动时没有画线。虽然当触摸结束时节点数会增加 xCode 6.1 因为我正在处理很多粒子文件,当你打开它们时 6.0 崩溃 我在 6.0.1 中运行只是为了测试,但仍然是同样的问题

以上是关于使用 Touch iOS Sprite Kit 画线的主要内容,如果未能解决你的问题,请参考以下文章

Touch Function 方法中的多个函数 Sprite Kit

使用 Sprite Kit 画线时播放声音

Xcode 7 Sprite Kit X Coordinate Off-Center in iOS Simulator

如何在 Sprite-kit 中画一条线

Sprite-Kit:节点不会向左移动

ios Sprite Kit 截图?