使用SKShapeNode和CGPath在Sprite Kit中绘制虚线

时间:2013-12-26 03:16:32

标签: ios sprite-kit uibezierpath cgpath skshapenode

我想在我的精灵工具包游戏中绘制一条虚线,我可以使用SKShapeNode节点绘制如下的法线:

 UIBezierPath *_path=[UIBezierPath bezierPath];
 //1
 CGPoint point1 = CGPointMake(100,100);
 CGPoint point2 = CGPointMake(150,150);
 [_path moveToPoint:point1];
 [_path addLineToPoint:point2];
 //2
 SKShapeNode *line = [SKShapeNode node];
 line.path = _path.CGPath;

我尝试将虚线模式设置为UIBezierPath,如下所示:

// adding this code at location 1 or 2 above but no effect
CGFloat dashes[] = {6, 2};
[_path setLineDash:dashes count:2 phase:0];

但未应用虚线图案。

我还尝试直接从UIBezierpath.CGPath属性创建CGPath的虚线副本:

 CGFloat dashes[] = {6, 2};
 CGPathRef aCGPath= CGPathCreateCopyByDashingPath(_path.CGPath,NULL,0,dashes,2);
line.path = aCGPath;

但也一样。

我真的很感激,如果有人可以解释是什么问题,我怎么能通过将虚线cgpath应用到skshapenode来在两点之间画一条虚线。

编辑:我知道这个简单的例子我可以将这两个点之间的距离分成小的固定距离,并通过bezeirpath移动和绘制虚线但是考虑一个带有点来自触摸的自由手路径,它是一个非常复杂的使用固定长度点重绘路径效率低,然后绘制破折号。我想知道是否有办法将虚线模式应用于路径并使skshapenode使用它是我的问题。

2 个答案:

答案 0 :(得分:9)

如果有人仍然对这个问题的简单答案感兴趣:

使用CGPathCreateCopyByDashingPath创建- [UIBezierCurve CGPath]

虚线副本
CGPathRef CGPathCreateCopyByDashingPath(
   CGPathRef path,
   const CGAffineTransform *transform,
   CGFloat phase,
   const CGFloat *lengths,
   size_t count
);

并将其添加到SKShapeNode的{​​{1}}媒体资源中。

示例:

path

编辑:为了提高效果,您可以向 // creates a dashed pattern CGFloat pattern[2]; pattern[0] = 10.0; pattern[1] = 10.0; CGPathRef dashed = CGPathCreateCopyByDashingPath([bezierPath CGPath], NULL, 0, pattern, 2); self.myShapeNode.path = dashed; CGPathRelease(dashed); 添加SKShapeNode并将SKEffectNode属性设置为shouldRasterize

答案 1 :(得分:0)

将位置1的代码更改为以下内容:

UIBezierPath *_path=[UIBezierPath bezierPath];
CGPoint point1 = CGPointMake(100,100);
CGPoint point2 = CGPointMake(150,150);
CGFloat deltaX = 1;
CGFloat deltaY = 1;
CGPoint tmpPoint = point1;
[_path moveToPoint:point1];
while(tmpPoint.x<point2.x && tmpPoint.y<point2.y){
    tmpPoint.x+=deltaX;
    tmpPoint.y+=deltaY;
    if((tmpPoint.y-point1.y)%2==1){
       [_path addLineToPoint:tmpPoint];
    }else{
      [_path moveToPoint:tmpPoint];
    }
}
// If the line is not a 45 degree straight line
// Please modify the while loop accordingly
[_path addLineToPoint:point2];