Prevent overlap between two SKPhysicBody's of the same type
I have a game in which two balls should be able to pass through a third object, which functions as a finish line. The two balls are SKShapeNodes
, the finish 'line' is an SKSpriteNode
. All of them have SKPhysicBodys
attached to them with categories set as follows:
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = 1
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 1
Since I want the balls to be able to cross the finish line without collision, while still being able to get notified about this, I have set the collisionBitMask
for both the balls and line to the same value.
This gives me the result I'm looking for. However, this seems to have as a side-effect that the two balls are able to pass through each other as well, which shouldn't happen.
Also, if I set the value of collisionBitMask
to anything other than 1, the balls and line bump of each other. I have read through Apple's documentation on this, but I think I misunderstood / missed something here.
My guess is that since both balls see each other as having the same collisionBitMask
. the overlap happening is to be expected. What I don't get is how I can avoid this, without having to add a separate category per ball.
Can anyone point me in the right direction? How can I make the balls pass through the finish line, while not being able to overlap each other?
swift sprite-kit skphysicsbody
add a comment |
I have a game in which two balls should be able to pass through a third object, which functions as a finish line. The two balls are SKShapeNodes
, the finish 'line' is an SKSpriteNode
. All of them have SKPhysicBodys
attached to them with categories set as follows:
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = 1
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 1
Since I want the balls to be able to cross the finish line without collision, while still being able to get notified about this, I have set the collisionBitMask
for both the balls and line to the same value.
This gives me the result I'm looking for. However, this seems to have as a side-effect that the two balls are able to pass through each other as well, which shouldn't happen.
Also, if I set the value of collisionBitMask
to anything other than 1, the balls and line bump of each other. I have read through Apple's documentation on this, but I think I misunderstood / missed something here.
My guess is that since both balls see each other as having the same collisionBitMask
. the overlap happening is to be expected. What I don't get is how I can avoid this, without having to add a separate category per ball.
Can anyone point me in the right direction? How can I make the balls pass through the finish line, while not being able to overlap each other?
swift sprite-kit skphysicsbody
add a comment |
I have a game in which two balls should be able to pass through a third object, which functions as a finish line. The two balls are SKShapeNodes
, the finish 'line' is an SKSpriteNode
. All of them have SKPhysicBodys
attached to them with categories set as follows:
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = 1
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 1
Since I want the balls to be able to cross the finish line without collision, while still being able to get notified about this, I have set the collisionBitMask
for both the balls and line to the same value.
This gives me the result I'm looking for. However, this seems to have as a side-effect that the two balls are able to pass through each other as well, which shouldn't happen.
Also, if I set the value of collisionBitMask
to anything other than 1, the balls and line bump of each other. I have read through Apple's documentation on this, but I think I misunderstood / missed something here.
My guess is that since both balls see each other as having the same collisionBitMask
. the overlap happening is to be expected. What I don't get is how I can avoid this, without having to add a separate category per ball.
Can anyone point me in the right direction? How can I make the balls pass through the finish line, while not being able to overlap each other?
swift sprite-kit skphysicsbody
I have a game in which two balls should be able to pass through a third object, which functions as a finish line. The two balls are SKShapeNodes
, the finish 'line' is an SKSpriteNode
. All of them have SKPhysicBodys
attached to them with categories set as follows:
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = 1
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 1
Since I want the balls to be able to cross the finish line without collision, while still being able to get notified about this, I have set the collisionBitMask
for both the balls and line to the same value.
This gives me the result I'm looking for. However, this seems to have as a side-effect that the two balls are able to pass through each other as well, which shouldn't happen.
Also, if I set the value of collisionBitMask
to anything other than 1, the balls and line bump of each other. I have read through Apple's documentation on this, but I think I misunderstood / missed something here.
My guess is that since both balls see each other as having the same collisionBitMask
. the overlap happening is to be expected. What I don't get is how I can avoid this, without having to add a separate category per ball.
Can anyone point me in the right direction? How can I make the balls pass through the finish line, while not being able to overlap each other?
swift sprite-kit skphysicsbody
swift sprite-kit skphysicsbody
asked Nov 13 '18 at 15:20
HaroldHarold
5819
5819
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
I tend to get this mixed up from time to time, but hopefully I am recalling this correctly.
If all you care about is getting the collision call back on the line that is primarily controlled by contactTestBitMask
to ball as you have. That is what sends the contact to the delegate method. collisionBitMask
controls what actually controls physic calculations ie what will bounce off each other.
By default collisionBitMask
will collide with everything so you want to specify only the things you want it to calculate physics on. You have everything set to 1 which isn't anything specific in your scene. This is why everything passes through each other. I believe 2 would be ball and 4 is line with what you provided (if you print out PhysicsCategory.ball and PhysicsCategory.line that is what it logs out). Typically is is best practice to use the enums or structs you create instead of specifying a number. With that said I tend to use 0 for nothing.
To fix this you want to tell your balls that you want them to collide with PhysicsCategory.ball and you want your line to collide with nothing so you want to set it to 0.
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = PhysicsCategory.ball //changed to ball
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 0 //you want no physics calculations
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284159%2fprevent-overlap-between-two-skphysicbodys-of-the-same-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I tend to get this mixed up from time to time, but hopefully I am recalling this correctly.
If all you care about is getting the collision call back on the line that is primarily controlled by contactTestBitMask
to ball as you have. That is what sends the contact to the delegate method. collisionBitMask
controls what actually controls physic calculations ie what will bounce off each other.
By default collisionBitMask
will collide with everything so you want to specify only the things you want it to calculate physics on. You have everything set to 1 which isn't anything specific in your scene. This is why everything passes through each other. I believe 2 would be ball and 4 is line with what you provided (if you print out PhysicsCategory.ball and PhysicsCategory.line that is what it logs out). Typically is is best practice to use the enums or structs you create instead of specifying a number. With that said I tend to use 0 for nothing.
To fix this you want to tell your balls that you want them to collide with PhysicsCategory.ball and you want your line to collide with nothing so you want to set it to 0.
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = PhysicsCategory.ball //changed to ball
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 0 //you want no physics calculations
add a comment |
I tend to get this mixed up from time to time, but hopefully I am recalling this correctly.
If all you care about is getting the collision call back on the line that is primarily controlled by contactTestBitMask
to ball as you have. That is what sends the contact to the delegate method. collisionBitMask
controls what actually controls physic calculations ie what will bounce off each other.
By default collisionBitMask
will collide with everything so you want to specify only the things you want it to calculate physics on. You have everything set to 1 which isn't anything specific in your scene. This is why everything passes through each other. I believe 2 would be ball and 4 is line with what you provided (if you print out PhysicsCategory.ball and PhysicsCategory.line that is what it logs out). Typically is is best practice to use the enums or structs you create instead of specifying a number. With that said I tend to use 0 for nothing.
To fix this you want to tell your balls that you want them to collide with PhysicsCategory.ball and you want your line to collide with nothing so you want to set it to 0.
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = PhysicsCategory.ball //changed to ball
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 0 //you want no physics calculations
add a comment |
I tend to get this mixed up from time to time, but hopefully I am recalling this correctly.
If all you care about is getting the collision call back on the line that is primarily controlled by contactTestBitMask
to ball as you have. That is what sends the contact to the delegate method. collisionBitMask
controls what actually controls physic calculations ie what will bounce off each other.
By default collisionBitMask
will collide with everything so you want to specify only the things you want it to calculate physics on. You have everything set to 1 which isn't anything specific in your scene. This is why everything passes through each other. I believe 2 would be ball and 4 is line with what you provided (if you print out PhysicsCategory.ball and PhysicsCategory.line that is what it logs out). Typically is is best practice to use the enums or structs you create instead of specifying a number. With that said I tend to use 0 for nothing.
To fix this you want to tell your balls that you want them to collide with PhysicsCategory.ball and you want your line to collide with nothing so you want to set it to 0.
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = PhysicsCategory.ball //changed to ball
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 0 //you want no physics calculations
I tend to get this mixed up from time to time, but hopefully I am recalling this correctly.
If all you care about is getting the collision call back on the line that is primarily controlled by contactTestBitMask
to ball as you have. That is what sends the contact to the delegate method. collisionBitMask
controls what actually controls physic calculations ie what will bounce off each other.
By default collisionBitMask
will collide with everything so you want to specify only the things you want it to calculate physics on. You have everything set to 1 which isn't anything specific in your scene. This is why everything passes through each other. I believe 2 would be ball and 4 is line with what you provided (if you print out PhysicsCategory.ball and PhysicsCategory.line that is what it logs out). Typically is is best practice to use the enums or structs you create instead of specifying a number. With that said I tend to use 0 for nothing.
To fix this you want to tell your balls that you want them to collide with PhysicsCategory.ball and you want your line to collide with nothing so you want to set it to 0.
struct PhysicsCategory {
static let ball: UInt32 = 0x1 << 1
static let line: UInt32 = 0x1 << 2
}
ball.physicsBody = SKPhysicsBody(circleOfRadius: ballSize)
ball.physicsBody?.categoryBitMask = PhysicsCategory.ball
ball.physicsBody?.contactTestBitMask = PhysicsCategory.line
ball.physicsBody!.collisionBitMask = PhysicsCategory.ball //changed to ball
line.physicsBody = SKPhysicsBody(rectangleOf: line.size)
line.physicsBody?.isDynamic = false
line.physicsBody?.categoryBitMask = PhysicsCategory.line
line.physicsBody?.contactTestBitMask = PhysicsCategory.ball
line.physicsBody!.collisionBitMask = 0 //you want no physics calculations
answered Nov 15 '18 at 2:21
Skyler LaurenSkyler Lauren
3,34531327
3,34531327
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53284159%2fprevent-overlap-between-two-skphysicbodys-of-the-same-type%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown