Bạn không thể nhận được hành vi mong muốn vì bạn chưa đặt mặt nạ bit danh mục, liên hệ và va chạm đúng cách. Dưới đây là một ví dụ về cách bạn có thể thiết lập để làm việc này:
greenBall.physicsBody?.categoryBitMask = GreenBallCategory //Category is GreenBall
greenBall.physicsBody?.contactTestBitMask = RedBarCategory | WallCategory //Contact will be detected when GreenBall make a contact with RedBar or a Wall (assuming that redBar's masks are already properly set)
greenBall.physicsBody?.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory //Collision will occur when GreenBall hits GreenBall, RedBall or hits a Wall
redBall.physicsBody?.categoryBitMask = RedBallCategory //Category is RedBall
redBall.physicsBody?.contactTestBitMask = GreenBarCategory | GreenBallCategory | WallCategory //Contact will be detected when RedBall make a contact with GreenBar , GreenBall or a Wall
redBall.physicsBody?.collisionBitMask = RedBallCategory | GreenBallCategory | WallCategory //Collision will occur when RedBall meets RedBall, GreenBall or hits a Wall
let borderBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody = borderBody
self.physicsBody?.friction = 0
borderBody.contactTestBitMask = RedBallCategory | GreenBallCategory //Contact will be detected when red or green ball hit the wall
borderBody.categoryBitMask = WallCategory
borderBody.collisionBitMask = RedBallCategory | GreenBallCategory // Collisions between RedBall GreenBall and a Wall will be detected
tôi sẽ khuyên bạn nên đọc tài liệu về categoryBitMask mà là một mặt nạ xác định thể loại mà cơ thể vật lý thuộc về:
Mỗi cơ thể vật lý trong một cảnh có thể được gán cho tối đa 32 loại khác nhau , mỗi loại tương ứng với một chút trong mặt nạ bit. Bạn xác định giá trị mặt nạ được sử dụng trong trò chơi của mình. Cùng với các thuộc tính va chạm BitMask và contactTestBitMask, bạn xác định các đối tượng vật lý nào tương tác với nhau và khi trò chơi của bạn được thông báo các tương tác này.
contactTestBitMask - Mặt nạ xác định loại thể loại nào gây ra thông báo giao lộ với cơ thể vật lý hiện tại.
Khi hai cơ quan chia sẻ cùng một không gian, chủng loại mặt nạ của mỗi cơ thể là thử nghiệm chống lại mặt nạ tiếp xúc các cơ quan khác của bằng cách thực hiện một logic VÀ hoạt động. Nếu một trong hai so sánh dẫn đến một giá trị khác, đối tượng SKPhysicsContact được tạo và được chuyển đến đại diện của của thế giới vật lý. Để đạt hiệu quả tốt nhất, chỉ thiết lập bit trong địa chỉ liên lạc mặt nạ cho tương tác mà bạn đang quan tâm
collisionBitmask -. Một mặt nạ định nghĩa mà loại của các cơ quan vật lý có thể va chạm với cơ thể vật lý này.
Khi hai vật lý liên hệ với nhau, có thể xảy ra va chạm. Mặt nạ va chạm của cơ thể này được so sánh với mặt nạ của cơ thể khác bằng cách thực hiện thao tác logic AND. Nếu kết quả là giá trị không đồng nhất, phần thân này sẽ bị ảnh hưởng bởi va chạm. Mỗi cơ thể độc lập chọn xem nó có bị ảnh hưởng bởi cơ thể khác không. Đối với ví dụ , bạn có thể sử dụng điều này để tránh các phép tính va chạm sẽ thay đổi không đáng kể với vận tốc của cơ thể.
Vì vậy, về cơ bản, thiết lập tất cả các, bạn nên tự hỏi bản thân một cái gì đó của bạn như:
Được rồi, tôi có một quả bóng màu xanh lá cây, và một quả bóng đỏ, và các đối tượng tường trên sân khấu. Giữa những cơ quan nào tôi muốn va chạm xảy ra, hoặc khi tôi muốn đăng ký địa chỉ liên lạc? Tôi muốn một quả bóng màu xanh lá cây và một quả bóng màu đỏ va chạm với nhau và va vào tường. Không thành vấn đề. đầu tiên tôi sẽ thiết lập danh mục đúng cách, và sau đó tôi sẽ thiết lập mặt nạ chút va chạm như thế này:
greenBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory; //greenBall will collide with greenBall, redBall and a wall
redBall.collisionBitMask = GreenBallCategory | RedBallCategory | WallCategory
wall.collisionBitMask = GreenBall | RedBall
Bây giờ, tôi muốn để phát hiện khi một số địa chỉ liên lạc xảy ra (trong didBeginContact
: Phương pháp) ... Nhưng tôi không muốn được thông báo về tất cả các địa chỉ liên lạc có thể, nhưng thay vào đó được thông báo về địa chỉ liên hệ giữa các quả bóng (các liên hệ giữa các quả bóng và tường sẽ bị bỏ qua). Vì vậy, hãy đặt contactTestBitMasks
để đạt được điều này:
greenBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
redBall.contactTestBitMask = GreenBallCategory | RedBallCategory;
Và đó là nó. Điều quan trọng là khi bạn không sử dụng tính năng phát hiện liên hệ, bạn không nên đặt contactTestBitMask
. Điều này là do lý do hiệu suất. Nếu bạn không cần phát hiện xung đột và bạn chỉ quan tâm đến việc phát hiện danh bạ, bạn có thể đặt collisionBitMask = 0
.
Chú ý:
Hãy chắc chắn rằng bạn đã thiết lập đại biểu tiếp xúc vật lý thế giới để sử dụng didBeginContact
và didEndContact
phương pháp:
self.physicsWorld.contactDelegate = self; //where self is a current scene
Hope this helps một chút.
Câu trả lời tuyệt vời, cảm ơn bạn rất nhiều vì đã dành thời gian viết tất cả điều đó. Nó hoạt động hoàn hảo. Phần "tự hỏi mình" này chắc chắn sẽ xóa những gì tôi đã nhầm lẫn. Cảm ơn bạn rất nhiều! – Noowoo
Còn nếu bạn có nhiều hơn thì 32? – cnzac
@Abcdefg Làm thế nào bạn có thể phát hiện sự kết thúc của va chạm trong hàm didEnd? – Marin