如何在 SpriteKit 中高效地画一条线
How to draw a line in SpriteKit efficiently
在我的 SpriteKit 场景中,用户应该可以用 his/her 手指画线。我有一个可行的解决方案,如果线很长,FPS 会下降到 4-6,线开始变成多边形,如下图:
为了画myline
(SKShapeNode*
),我在一个NSMutableArray* noteLinePoints
中收集了触动点
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint touchPoint = [[touches anyObject] locationInNode:self.scene];
SKNode *node = [self nodeAtPoint:touchPoint];
if(noteWritingActive)
{
[noteLinePoints removeAllObjects];
touchPoint = [[touches anyObject] locationInNode:_background];
[noteLinePoints addObject:[NSValue valueWithCGPoint:touchPoint]];
myline = (SKShapeNode*)node;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if(myline)
{
CGPoint touchPoint = [[touches anyObject] locationInNode:_background];
[noteLinePoints addObject:[NSValue valueWithCGPoint:touchPoint]];
[self drawCurrentNoteLine];
}
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if(myline)
{
myline.name = @"note";
myline = nil;
}
NSLog(@"touch ended");
}
我也是这样划线的
- (CGPathRef)createPathOfCurrentNoteLine
{
CGMutablePathRef ref = CGPathCreateMutable();
for(int i = 0; i < [noteLinePoints count]; ++i)
{
CGPoint p = [noteLinePoints[i] CGPointValue];
if(i == 0)
{
CGPathMoveToPoint(ref, NULL, p.x, p.y);
}
else
{
CGPathAddLineToPoint(ref, NULL, p.x, p.y);
}
}
return ref;
}
- (void)drawCurrentNoteLine
{
if(myline)
{
SKNode* oldLine = [self childNodeWithName:@"line"];
if(oldLine)
[self removeChildrenInArray:[NSArray arrayWithObject:oldLine]];
myline = nil;
myline = [SKShapeNode node];
myline.name = @"line";
[myline setStrokeColor:[SKColor grayColor]];
CGPathRef path = [self createPathOfCurrentNoteLine];
myline.path = path;
CGPathRelease(path);
[_background addChild:myline];
}
}
我该如何解决这个问题?因为所有后续线条都是多边形的,我认为是因为 fps 非常低,触摸采样率自动变得非常低...
请注意,在测试中我使用了 iPad 3(我的应用程序需要使用 iPad 2 模型和 iOS7)
不要不断地创建新的 SKShapeNodes
,有一个错误会导致您的速度变慢。相反,只使用 1 SKShapeNode
(或创建一堆但重复使用它们),并在路径中附加新信息(因此无需不断将 myline 添加到后台)
选择:
使用 1 个社区 SKSkapeNode
渲染路径,然后将 SKShapeNode
转换为具有 view.textureFromNode
的纹理,然后添加具有此新纹理的 SKSpriteNode
形状节点
在我的 SpriteKit 场景中,用户应该可以用 his/her 手指画线。我有一个可行的解决方案,如果线很长,FPS 会下降到 4-6,线开始变成多边形,如下图:
为了画myline
(SKShapeNode*
),我在一个NSMutableArray* noteLinePoints
中收集了触动点
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint touchPoint = [[touches anyObject] locationInNode:self.scene];
SKNode *node = [self nodeAtPoint:touchPoint];
if(noteWritingActive)
{
[noteLinePoints removeAllObjects];
touchPoint = [[touches anyObject] locationInNode:_background];
[noteLinePoints addObject:[NSValue valueWithCGPoint:touchPoint]];
myline = (SKShapeNode*)node;
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
if(myline)
{
CGPoint touchPoint = [[touches anyObject] locationInNode:_background];
[noteLinePoints addObject:[NSValue valueWithCGPoint:touchPoint]];
[self drawCurrentNoteLine];
}
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
if(myline)
{
myline.name = @"note";
myline = nil;
}
NSLog(@"touch ended");
}
我也是这样划线的
- (CGPathRef)createPathOfCurrentNoteLine
{
CGMutablePathRef ref = CGPathCreateMutable();
for(int i = 0; i < [noteLinePoints count]; ++i)
{
CGPoint p = [noteLinePoints[i] CGPointValue];
if(i == 0)
{
CGPathMoveToPoint(ref, NULL, p.x, p.y);
}
else
{
CGPathAddLineToPoint(ref, NULL, p.x, p.y);
}
}
return ref;
}
- (void)drawCurrentNoteLine
{
if(myline)
{
SKNode* oldLine = [self childNodeWithName:@"line"];
if(oldLine)
[self removeChildrenInArray:[NSArray arrayWithObject:oldLine]];
myline = nil;
myline = [SKShapeNode node];
myline.name = @"line";
[myline setStrokeColor:[SKColor grayColor]];
CGPathRef path = [self createPathOfCurrentNoteLine];
myline.path = path;
CGPathRelease(path);
[_background addChild:myline];
}
}
我该如何解决这个问题?因为所有后续线条都是多边形的,我认为是因为 fps 非常低,触摸采样率自动变得非常低...
请注意,在测试中我使用了 iPad 3(我的应用程序需要使用 iPad 2 模型和 iOS7)
不要不断地创建新的 SKShapeNodes
,有一个错误会导致您的速度变慢。相反,只使用 1 SKShapeNode
(或创建一堆但重复使用它们),并在路径中附加新信息(因此无需不断将 myline 添加到后台)
选择:
使用 1 个社区 SKSkapeNode
渲染路径,然后将 SKShapeNode
转换为具有 view.textureFromNode
的纹理,然后添加具有此新纹理的 SKSpriteNode
形状节点