For my program I need to take a line drawn using touches moved and SKShapeNode and give it collision properties.
I looked at this thread: draw a line in sprite kit in touchesmoved where a line is drawn, but I am having trouble making it a physics body.
What I'm trying to accomplish is to drive a car through obstacles from above and below by a user drawn road. So I'm trying to get the car to touch the line and move along it...technically the car doesn't move because only the background moves.
How would I go about doing this?
Here is the important parts of my code:
I have made 3 more classes (GameHelper, StartGame, and GameOver), but they are irrelevant to my question. Here is where I have declared a CGMutablePathRef called pathToDraw and a SKShapeNode called lineNode.
#import "MyScene.h"
#import "MyScene.h"
#import "StartGameLayer.h"
#import "GameOverLayer.h"
#define TIME 1.5
#define MINIMUM_ROCK_HEIGHT 200.0f
#define GAP_BETWEEN_TOP_AND_BOTTOM_ROCK 50.0f
#define BACKGROUND_Z_POSITION 100
#define START_GAME_LAYER_Z_POSITION 150
#define GAME_OVER_LAYER_Z_POSITION 200
static const uint32_t rockCategory = 0x1 << 0;
static const uint32_t mineCartCategory = 0x1 << 1;
static const uint32_t lineCategory = 0x1 << 1;
static const float BG_VELOCITY = (TIME * 60);
static inline CGPoint CGPointAdd(const CGPoint a, const CGPoint b)
{
return CGPointMake(a.x + b.x, a.y + b.y);
}
static inline CGPoint CGPointMultiplyScalar(const CGPoint a, const CGFloat b)
{
return CGPointMake(a.x * b, a.y * b);
}
@interface MyScene() <SKPhysicsContactDelegate, StartGameLayerDelegate, GameOverLayerDelegate>
{
NSTimeInterval _dt;
float bottomScrollerHeight;
BOOL _gameStarted;
BOOL _gameOver;
CGMutablePathRef pathToDraw;
SKShapeNode *lineNode;
StartGameLayer* _startGameLayer;
GameOverLayer* _gameOverLayer;
int _score;
}
@property (nonatomic) SKSpriteNode* backgroundImageNode;
@property (nonatomic) SKSpriteNode* mineCart;
@property (nonatomic) NSTimeInterval lastSpawnTimeInterval;
@property (nonatomic) NSTimeInterval lastUpdateTimeInterval;
@property (nonatomic) NSArray* mineCartFrames;
@end
Then here is my code to draw the line:
#pragma mark - Touches
- (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.zPosition = 125;
lineNode.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:lineNode.path];
lineNode.physicsBody.categoryBitMask = lineCategory;
lineNode.physicsBody.contactTestBitMask = mineCartCategory;
lineNode.physicsBody.collisionBitMask = 0;
lineNode.physicsBody.affectedByGravity = NO;
[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;
}
Here I have tried to make lineNode a physicsBody but when I run this the collision doesn't work. (It runs with no errors)
Below is the collision code:
- (void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
firstBody = contact.bodyA;
secondBody = contact.bodyB;
}
else
{
firstBody = contact.bodyB;
secondBody = contact.bodyA;
}
if ((firstBody.categoryBitMask & rockCategory) != 0 &&
(secondBody.categoryBitMask & mineCartCategory) != 0)
{
[self rock:(SKSpriteNode *) firstBody.node didCollideWithCart:(SKSpriteNode *) secondBody.node];
}
else if ((firstBody.categoryBitMask & lineCategory) != 0 &&
(secondBody.categoryBitMask & mineCartCategory) != 0)
{
[self line:(SKSpriteNode *) firstBody.node didCollideWithCart:(SKSpriteNode *) secondBody.node];
}
}