问题
Im using the following code to draw lines in my sprite kit scene but nothing shows up. But the node counts goes up. Can anyone see what could be the problem. Ive been fighting with this code forever
- (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);
}
Edit------ Code works when background node removed..How can I set up my background node so that I can daw overtop? Thanks
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];
回答1:
NOTE Core issue was Simulator not rendering a path that isn't closed. On the device the issue doesn't exist. Also a background element was involved that the original poster didn't mention and wasn't represented in code. This answer will solve the issue on the simulator.
To fix your problem, modify your code as follows :
- (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;
}
The core issue is that when it goes to render the path, it doesn't have a complete path. Your current approach is to be constantly modifying the path on each touchMove.
The way you close a sub path is :
CGPathCloseSubpath(pathToDraw);
However I chose to just use CGPathMoveToPoint
each time you added a segment to the path.
From CGPath reference for CGPathMoveToPoint
:
This function ends the subpath already in progress (if any) and starts a new subpath, initializing the starting point and the current point to the specified location (x,y) after an optional transformation.
I am closing the current subpath before it gets rendered, and also setting the start location for the next segment.
However, you are going to run into major issues with performance as defined in the link in the the comments if you are going to be drawing a long line or many lines. Draw a really long line, and you will see what I mean. With minimal line drawing, you might get away with the current approach.
Sadly, drawing of this nature with SKShapeNode
is not as optimized as it should be.
回答2:
I think this is what you are trying to implement. It draws a temporary line (white) as you move your finger and draws a final line (red) when you lift your finger. You will need to declare a CGPoint instance variable named startingPoint and delete the CGMutablePathRef ivar named pathToDraw. The code can be modified to draw multiple, connected line segments as well.
- (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];
}
来源:https://stackoverflow.com/questions/26043447/drawing-line-with-touch-ios-sprite-kit