Prevent overlap between two SKPhysicBody's of the same type












0















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?










share|improve this question



























    0















    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?










    share|improve this question

























      0












      0








      0








      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?










      share|improve this question














      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






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 13 '18 at 15:20









      HaroldHarold

      5819




      5819
























          1 Answer
          1






          active

          oldest

          votes


















          0














          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





          share|improve this answer























            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            0














            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





            share|improve this answer




























              0














              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





              share|improve this answer


























                0












                0








                0







                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





                share|improve this answer













                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






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 15 '18 at 2:21









                Skyler LaurenSkyler Lauren

                3,34531327




                3,34531327






























                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    這個網誌中的熱門文章

                    Tangent Lines Diagram Along Smooth Curve

                    Yusuf al-Mu'taman ibn Hud

                    Zucchini